SRF235 Basic Stamp VB6
Doc
Posts: 25
Hello,
I would like to collect data from the SRF235 sonar in VB6.
The SRF235 is connected (I2C) to a BS2px microcontroller.
I am using· DEBUG in Basic Stamp to display the range and then, in VB6, the MSComm.Input with a timer to collect the measurments.
Is there a more accurate way to do it in order to avoid the delay between PBasic and VB6, and to be able to get only the range measured from the sonar·without any·additional useless characters?
Thank you,
Doc
I would like to collect data from the SRF235 sonar in VB6.
The SRF235 is connected (I2C) to a BS2px microcontroller.
I am using· DEBUG in Basic Stamp to display the range and then, in VB6, the MSComm.Input with a timer to collect the measurments.
Is there a more accurate way to do it in order to avoid the delay between PBasic and VB6, and to be able to get only the range measured from the sonar·without any·additional useless characters?
Thank you,
Doc
Comments
If you're using the Programming port on the BS2, then yes, you'll have to remove any 'echoed' characters -- the BS2 hardware does this, and there's no way to defeat it.
Without knowing what your code is doing it’s hard to say. What information are you sending? In theory you need only send the 8-bit or 16-bit reading to the VB application. This would consist or 1 or 2 bytes.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chris Savage
Parallax Tech Support
My PBasic program is:
SDA···· PIN 8··········
V1······ VAR Byte
V2······ VAR Byte
Dist···· VAR Word··
·····
DO
· I2COUT SDA, $e0, 0, [noparse][[/noparse]82]····
· PAUSE 20
· I2CIN SDA, $e1, 0, [noparse][[/noparse]V1, V2, Dist.HIGHBYTE, Dist.LOWBYTE]
· DEBUG 1, DEC4·Dist
·LOOP
and in VB6 :
Private Sub tmrdetect_Timer()
··A = MSComm.Input
··txtDist.Text = A * 0.1725·· % microsec to mm
·····
End Sub
Thanks
Doc
The answer is there in your I2CIN routine…The data is coming in HIGBYTE then LOWBYTE…That is how you should send it back out rather than converting it to an ASCII string. Also you’re sending a HOME command before you send the string out which probably isn’t needed. Take care.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chris Savage
Parallax Tech Support
But if you please, can you give me a hint how can I do it? What command shall I use instead of DEBUG, to avoid sending a string without junk characters?!!
Is the VB6 section correct, or shall it be modified also?! The timer function is necessary or the "pause" in pbasic could be enough to synchronise data sending?!
Regards,
Doc
The above sends the data out pin 16 (the programming port) at 9600 baud, and terminates your string with a carriage return to keep VB happy.
That code still sends the value as ASCII characters. I would recommend something more like:
SEROUT 16, 16780, [noparse][[/noparse]Dist.HIGHBYTE, Dist.LOWBYTE]
If you're worried about synchronization errors then you can pad the beginning with a single header byte such as:
SEROUT 16, 16780, [noparse][[/noparse]"!", Dist.HIGHBYTE, Dist.LOWBYTE]
Then in your VB code you wait for the ! and the next two bytes are your Word (16-bit)·variable.· There's no need to send a CR unless your input routine expects it for termination of the data.· Take care.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chris Savage
Parallax Tech Support
Personally, I'd recieve everything as a string into VB, then use VB "VAL" formatters to make sure I got a valid value. That's much easier to debug than sending a lowbyte / highbyte pair of values, and hope that VB properly stuffs them into a 'long' variable value.
Long story made short -- I think his VB code will only recieve one byte of a two byte pair right now.
The simplest and easiest method is one way communication, Stamp to PC because you don't have to worry about echo on the serial line, if you use the OnComm event as allan suggested in his first post of this thread then you don't have to worry about synchronization.
Chris, this may differ from VB6 I don't know but in the express version it will recieve a decimal formatted word value without any string to integer conversion.
I transmit with a string similar to this, I have found no need to declare how many characters I am sending.
SEROUT 16,16468,[noparse][[/noparse]DEC Word_value,10]
In the OnComm event I would put something like this
Dim in_data As Int16
in_data = SerialPort1.ReadLine
TextBox1.Text = in_data
Jeff T.
Thank you very much for your help.
I tried it with SEROUT using these commands:
· SEROUT 16, 16780,50, [noparse][[/noparse]Dist.HIGHBYTE, Dist.LOWBYTE]
· SEROUT 16, 16780,50, [noparse][[/noparse]"!", Dist.HIGHBYTE, Dist.LOWBYTE]
· SEROUT 16, 16780,50, [noparse][[/noparse]DEC4 Dist, CR]
In all cases I only got strange ascii characters in my text box.
My MSComm settings are :
19200,n,8,1
MSComm.InBufferSize = 2
Private Sub MSComm_OnComm()
··· Dim distdata As String
·· distdata = MSComm.Input
·· test.Text = distdata
End Sub
Do you have any idea please? Why I am not able to get the distance measured with the sonar?
Thank you
Regards,
Doc
So, if you try to read that at 19200 in VB, I'm not surprised you're getting "odd characters".
The calc for the BS2px is: BS2px = INT(4,000,000
I put 19200 since in the bs2px doc the PC prog interface indicates it is "serial 19200 baud".
Following the calculation in the PBasic manual for all bs2p with 8bits no parity and inverted : "INT(2500000/baud rate) -20"
Then + 16384 = 16494.
It did not work either with 16494 or 16572· (sorry for the bad news), not even odd characters.
Even I tried with 9600,n,8,1 in VB6 MSComm settings and 16780 or 16624 in SEROUT, no hope.
Any idea please?
Regards,
Doc
The best way to debug this would be to use the DEC4 modifier, and recieve it with Hyperterminal (or the Debug terminal, for that matter). Get the numbers coming out correctly, so you can see them.
Then, make a really simple BS2px program, that outputs "5000" every 5 seconds. Use that to validate your VB side program.
THEN, you can put the 'real' version of your BS2px program and the 'real' version of your VB program together, and they should work.
Right now, you're just shot-gunning the problem, and it's hard to tell where the failure is.
Thank you for your help.
So as I understood from your last reply, DEBUG is the only solution through which data could be collected with the MSComm in VB6? Honestly I did not get well your idea!
Cheers,
Doc
MAIN:
SEROUT 16, 16780, [noparse][[/noparse]"5000", CR]
PAUSE 5000
GOTO MAIN
Program this program into your BS2px. Start it running.
Bring up Hyperterm. Verify that every 5 seconds, you get a "5000" string at 9600 baud. Work with your hardware until this is true (it should be true almost immediately, if you're using a serial port and a BOE board). This debugs your hardware.
Bring up your VB program. Verify that every 5 seconds it is getting a value of "5000". Work with your program (you've already debugged your hardware at this point, right?) until it can reliably recieve this data. this debugs your VB6 to hardware interface.
Now, put into your BS2px the REAL program you wanted, using the lessons learned above. Oh, and the 16780 above is for 9600 baud. Use 9600 baud in your VB program.
http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q194922&
http://msdn2.microsoft.com/en-us/library/ms364066(vs.80).aspx
I extracted a piece from their web page and tried it with MScomm, enough to where I got reasonable results. It's pretty much the same as the VB express code I posted earlier but no CR. The MS code is much more thorough , its whatever works best for you.
Jeff T.
EDIT........you will have to adjust the baud (9600) suitable for your particular Stamp
Post Edited (Unsoundcode) : 4/18/2007 10:46:59 PM GMT
Thank you for all the info.
Well the connection and the reading are established with this code:
For the BS2px with Baud rate 19200:
SDA···· PIN 8··········
Version····· VAR Byte
LEDsens····· VAR Byte
Dist·· VAR Word·······
DO
·I2COUT SDA, $e0, 0, [noparse][[/noparse]82]
·PAUSE 50
·I2CIN SDA, $e1, 0, [noparse][[/noparse]Version, LEDsens, Dist.HIGHBYTE, Dist.LOWBYTE]
·SEROUT 16, 16572, [noparse][[/noparse]DEC4 Dist]
LOOP
**************************************
In VB6, with settings : 19200,n,8,1
Private Sub MSComm_OnComm()
·A = MSComm.Input
·txtY.Text = A
End Sub
**********************************
Till here, everything works fine for the connection, but, for the same distance with the SRF235(e.g. 891 microsec), I get 0891 or 91 or 089 etc. in VB6. If I add CR or HOME in SEROUT, I get this character | in addition. And in both cases, I cannot convert the MSComm.Input to Single so I can transfer the microsec data into millimeter, with a Type-missmatch or overflow error message. I tried it with the simple prog just SEROUT 16, 16572, [noparse][[/noparse]DEC 1000, CR]·, the results were the same in VB6, 1000 or 100 or 00, etc.
Any idea please?
Cheers,
Doc·
Yup, MSComm.InputMode = 0.· This sets up the recieve so it returns its stuff as a VB 'String', which is probably what you want.
It looks like the problem you're having is one of synchronization between the output of the BS2 and when you read the serial port.· If the BS2 is sending "5000", CR, and you read after it's sent the "50", then the VB program will get "50", and on the next read "00<CR>" (where <CR> is replaced by the CHR(13) character).
This is why everybody always recommends recieving things from the outside world, and validity checking it, before you try to use it.
You can fix this problem by collecting bytes into a local 'Static' string, until you finally get the <CR>.· Then you can convert the bytes in the String into a VAL value and proceed.
In other words, the BS2 and the PBasic code is working fine.· It's all on the VB side now.
To make your VB6·job easier, you might try sending from the BS2 with·a beginning 'sync' character, like "!", for each data value sent.
Post Edited (allanlane5) : 4/20/2007 2:36:20 PM GMT
I am using text as I used to do with DEBUG (instead of SEROUT) and MSComm. Input with a vb6 Timer.
Cheers.
In fact I did find a difference in data types, you don't show how you declare the variable A if it's declared as a string it should show in the text box ok, if its declared as an integer it should be declared as LONG. In VB6 an integer is 16 bits and long is 32 bits.
The only other thing I could think of that might be different is the MScomm properties, thats why I initialised them in the Form Load event. The two items that had the greatest effect (assuming the On_Comm event)·were RThreshold which I set to 1 and RTSEnable which I set to False.
.RThreshold = 1
.CommPort = 1
.Settings = "19200,n,8,1"
.InBufferSize = 2
.RTSEnable = False
.PortOpen = True
Both the following serial statements worked out fine from the Stamp
SEROUT 16, 16572, [noparse][[/noparse]DEC4 Dist]
SEROUT 16, 16572, [noparse][[/noparse]DEC Dist]
Jeff T.
Thank you very much guys for all the help! For the moment, everything is running, smooth and great, hope no surprises.
Here is the final code:
Stamp:
SDA·········· ·PIN 8··········· ' SDA on PIN 8, US Detector Output
Version·······VAR Byte
LEDsens····· VAR Byte
TOF·········· VAR Word······· ' Time of Flight
DO
· I2COUT SDA, $e0, 0, [noparse][[/noparse]82]··· ' Rangeing command in for microSec
· PAUSE 40··················· ' 40 millisecond
· I2CIN SDA, $e1, 0, [noparse][[/noparse]Version, LEDsens, TOF.HIGHBYTE, TOF.LOWBYTE]
· SEROUT 16, 16572, [noparse][[/noparse] "!", DEC5 TOF, HOME]
LOOP
VB6:
Private Sub MSComm_OnComm()
Dim A As String
A = MSComm.Input
If InStr(A, "!") = 1 And Len(A) > 5 Then
··· A = Mid(A, 2, 5)
···
txtY.Text = Format(A * 0.1725, "###.#0")
End If
End Sub
with
·.RThreshold = 1
.Settings = "19200,n,8,1"
.InBufferSize = 2
Thank you again!
Cheers,
Doc
It might be because I use express on a regular basis that I find it easier, but it certainly takes less lines of code and less configuration. Unless there is a specific reason you need to use VB6 Doc I would consider installing the express version.
regards
Jeff T.