|
Post by alwichita on Jan 24, 2022 12:57:35 GMT -5
There isnt much in the manual... Its basically a dumb device... All that it requires is DTR set and it spews out random numbers as fast as it can, so no handshaking required, no baud rate required, etc.
Im just glad it works sometimes !!! Technically I can let it run and generate a huge amount of random numbers, store them in a file and just access the file from any program that needs True random numbers. Thats a work around and of course, I want to get it to work 100% of the time. I'll play with the timing. etc.
Regarding the port number, im guessing that since it is a virtual Serial device on the USB, not the actual serial port, it assigns a different port number every time the software is stopped/closed then run again.
That doesn't seem to be an issue, the port # stays the same for days until the port is closed.
|
|
|
Post by Rod on Jan 24, 2022 16:02:02 GMT -5
Serial port activity takes time. When you plug the device in it takes time to establish a port, first windows has to recognise it is a serial port device, it has to find drivers then establish the port. Many seconds in some cases. Then when it closes it may still be processing data, queuing it in the hope that you will read it. If it closes before you plug it in again it should just open the same port number, something is causing it to move port.
Try rebooting the computer to see what port it chooses over a couple of tries with a fresh start. Also plug it in and leave it in. Only when you open the port should it start sending info.
It is using handshaking lines if it needs DTR and as I read it DTR toggles the stream on and off. RTS was also meant to be set but perhaps Liberty sets that for us.
Be methodical test a step at a time to know what works and what fails.
Anyways if it does run you just need to find what sequence makes that happen reliably
|
|
|
Post by alwichita on Jan 24, 2022 17:45:59 GMT -5
Rod, thanks for all of your help ! We are zeroing in on it !
I have left it plugged in for several days now, so that part hasn't changed.
I have also inserted it and removed it several times as well.
It is always comm port #4, so long as it is plugged into the same USB slot, however, the hFileHandle is a different pointer every time I stop and start the code.
RTS doesn't matter, Set or Reset, including on the terminal emulator, nothing matters except DTR, Set= it streams out numbers, reset= it stops.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' From the device FAQ: ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Question: Does the TrueRNG have any serial commands ?
No, the only ‘command’ is toggling the DTR line on the virtual serial port. The DTR flag being set will cause the TrueRNG to start sending data as fast as it can. When the DTR flag is cleared, it will stop.
''''''''''''''''''''''''''''''''''' What baud rate should I use when opening the USB Serial port ?
Baud rate doesn’t matter, since the port is virtualized and not connected to an actual timing sensitive UART, 9600, 57600, 115200 all produce the same results. Most people feel better setting it to 115200 and there is nothing wrong with that.
|
|
|
Post by Rod on Jan 25, 2022 4:17:50 GMT -5
Ok, it is most likely the port handle that is giving us the problem. We don’t have a command in Liberty to get the port handle. You never needed the port handle in the early days because the four hardware port handles were fixed and actually addressed chips on the motherboard.
Now we are virtualised and bios systems handle this in their own way. Often virtual ports are com10+ and we never see com1-4 but things change, now we do.
What we did to solve this problem was to open the port with an API call and get the handle. Then without unplugging the port we closed it and reopened it in Liberty (after a delay) hoping it would be assigned the same com port handle. It usually worked.
But you say you are getting different handles. I suspect that the port is not closed so Windows can’t assign the same com port. Net result is we are using the wrong port handle, the previous one. Try extending the gap between the API close statement and the new Liberty open statement.
The other thing to try is just to repeatedly open and close the port with api and see what handle is assigned. Is it always the same handle if you leave the dongle plugged in? Remember to give everything time to work. Liberty runs at 100 miles an hour the serial port crawls. Also remember that the port needs closed.
So is there a difference in the set DTR return value when it works and when it does not? Print the return value to see what is returned.
Also consider that the port may not be fully established by the time you send the set DTR message so be sure that it is given time to establish. There are two establishment times to think of, plugging it in and opening it later with the open command. That takes time as the port awakens and sees what is connected.
|
|
|
Post by Rod on Jan 25, 2022 7:56:36 GMT -5
I also read this, so it is best to leave it plugged in.
|
|
|
Post by alwichita on Jan 25, 2022 12:46:43 GMT -5
Rod, You are indeed correct!
If I just run the api section, loop 100x, it does indeed have a different port handle quite often, but usually it is the same several times in a row.
if it happens to be the same port handle then it works !
If I ck the result of the DTR it returns a '0" when it doesn't work, a '1' when it does, as a result of having the same port handle.
So, I can ck the DTR result, close the port if a '0' is returned, reopen it, repeat until it's a '1', then it should work !
Do this at start up (even if it takes a few seconds to resolve), then for my purposes, once working, leave the port open all day until my software is closed.
It's crude but I think that will work !
I'll try it tonight and let you know !
FYI, when it works the lof(#com) is usually from 8k to 12k string of ascii characters !
oh ! and the reason I want a True RNG is I wrote some dartboard software with simulated players and I need it to be truly random, for example, if I (human) hit a bullseye 1 in 5 times, my avatar need to hit 1 in 5 bullseyes, if I hit 1 in 7 Triple 20's, my avatar needs to hit 1 in 7 T20's... etc. That way the avatars can mimic the skill level of their human. I already have the code to determine what to shoot at working. There are only a few strategies so that's in there as well !
|
|
|
Post by alwichita on Jan 25, 2022 14:27:55 GMT -5
Rod,
The following code works 100% of the time !!! It only takes a second or two to resolve the correct port handle !
Next I need to leave the port open for several hours and see if it is still functional, if so were good to go !
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
[top]
for lp=1 to 5
'Open the port briefly using an API call to determine the handle given by Windows 'We will use this handle later in Liberty, its the only way to get it. 'substitute your own port number lpFileName$ = "Com4" dwCreationDistribution = _OPEN_EXISTING hTemplateFile = _NULL calldll #kernel32, "CreateFileA", _ lpFileName$ as ptr, _ dwDesiredAccess as ulong, _ dwShareMode as ulong, _ lpSecurityAttributes as ulong, _ dwCreationDistribution as ulong, _ dwFlagsAndAttributes as ulong, _ hTemplateFile as ulong, _ hFileHandle as ulong
print "Serial port handle is ";hFileHandle
calldll #kernel32, "CloseHandle", _ hFileHandle as ulong, _ result as long
'hFileHandle now contains 'the #handle, a number, that identifies the port
timer 100,[delay5] wait [delay5]
next ' lp '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' timer 100,[delay1] wait [delay1] 'Now open the com port in Liberty and use the hFileHandle value in API calls open lpFileName$;":57600,n,8,1,ds0,cs0,rs" for random as #com
'give the port some time to establish timer 100,[delay] wait [delay]
print "Port opened in Liberty"
print "setting DTR" CALLDLL #kernel32, "EscapeCommFunction", hFileHandle as ulong, _SETDTR as long,_ result as long print "result "; result
if result=0 then close #com goto [top] end if
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' timer 10, [bufferread] wait
[bufferread] count =count+1
numBytes = lof(#com) print "xxxxxx", numBytes
If numBytes >0 then ' usually between 8k and 12k ascii characters ck=ck+1 dctr=dctr+1
dataRead$ = input$(#com, 10) ' set to how many random numbers to read as a string
print dataRead$ count =0
end if
[stop]
if count >10 then timer 0 Print "No data!" Print "Closing com port" close #com end end if wait
''''''''''''''''''''''''''
|
|
|
Post by Rod on Jan 25, 2022 15:11:28 GMT -5
Ok cool, but if it is streaming 8k random numbers at you every 10ms you need to use them. No point in reading in just 10 because the rest just sit in the buffer which will grow and grow till it chokes.
The timer actually only ever ticks every 16ms so even if you say 10ms it only cycles every 16ms (a windows thing) you need to clear whatever is in the buffer every cycle.
Then the problem becomes how do you process soooo many random numbers?
Don’t get me wrong but Liberty’s own prng would have provided all that you need.
|
|
|
Post by alwichita on Jan 26, 2022 2:21:27 GMT -5
Oh, the timer set to 10ms was a leftover from just playing around with the timers... I don't know how fast it actually reads, it has to be way longer than 10 ms, I havent actually tested it, it just cranks as fast as it can and it grabs what ever happens to be there at that time. It just reads 8-12k character chunks at the rate we are reading. Even baud rate make no difference, plus it takes a lot of time to print a huge string before it reads again. But ya, we get a huge number of random numbers so I need to figure out how to integrate this.
The reason why I only read in 10 char is so that I could print it easily. It was printing 8-12k char (as 1 long string) to the screen, for every read. It can be set to anything up to the lof.
I have used the PRNG from Liberty Basic for many applications, and it works great! I currently use it heavily in the dartboard software. I once wrote a video draw poker game and no matter what I did, after a 1000 hands or so I would recognize hands that I had before (tested not to be imagining things). Made scatter plots of the card data, etc. I even tried seeding based on random times for human key presses, still not truly random. On the dartboard I keep human and avatar stats, so over time there will be a bias in the randomness for the avatars. Since I wish to ensure that the darts are truly random (based on avatar skill level), I figured that it cant hurt to make it as close to true randomness as possible. Hence, here we are, just having fun playin' with a new device !
It has a long way to go but the core seems to be working (with the work around) !
I cant thank you enough for all of your help, and the time you personally took to help me ! I couldn't have made it this far without you !!! I was about ready to give up on it !
I'll keep you posted, esp. with any significant discoveries...
Thanks again ! Al
|
|
|
Post by alwichita on Jan 27, 2022 14:16:56 GMT -5
S0, I have run 50 tests or more... Works 100% of the time!
If you wait 500ms the LOF is 24k bytes, wait any longer and it's still 24k bytes. So it's best to wait 500ms for the entropy pool to populate.
I have run several cases of 50k random #'s between 1 and 100, the random distribution is amazingly even. It works as advertised !
I'll write some code to test how it's going to be integrated into the dartboard software.
This is awesome !
Thanks again Rod !
|
|
|
Post by Rod on Jan 27, 2022 14:24:50 GMT -5
The receive buffer is a finite size, it will be getting full if you don’t suck it dry and the device will stop sending. Not sure what the 1 and 100 is about since the numbers range between 0 and 255.
But it works and you are progressing.with an interesting project. Real random numbers, wow!
|
|
|
Post by Brandon Parker on Jan 27, 2022 17:27:21 GMT -5
Just to put this out there... MSDN has this to say about the serial port input buffer... Also, I believe we can change each port's buffer size as we please unless something has changed. Straight from the help file... {:0) Brandon Parker
|
|
|
Post by alwichita on Jan 28, 2022 10:48:11 GMT -5
Thanks Rod !
Yes it outputs random numbers between 0-255.
1 to 100 is just the random range I set for the last test, is all. The range can be set anywhere between 0 and 255. On the dartboard, for example, a level "B" player hits about 1 in 5 bullseyes, 1 in 8 Triple 20's etc. So I need to generate a random number between 1 and 5 when a level 8 Avatar is aiming at bulls, 1 in 8 when a level 8 Avatar is aiming at T20, and so on...
How it works is exactly that, if I know how often you hit what you are aiming for, then your Avatar can replicate your skill level, and therefore replicate you quite well !
If I know your general strategy, your avatar can replicate that as well. For example, some people like to score a lot of points and maintain a large point lead, some like to maintain a small point lead, some like to prevent you from scoring by closing your numbers thus preventing you from scoring. Sometimes a human can't decide which strategy to use, and so the avatars also make random decisions sometimes as well, in order to make them feel more human.
Thanks Brandon ! I'll experiment/test the buffer size as well !
|
|