PDA

View Full Version : SRF235 Basic Stamp VB6



Doc
04-18-2007, 01:05 AM
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

allanlane5
04-18-2007, 01:53 AM
You can use the OnComm event of the MSComm control to know when bytes are coming in.

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.

Chris Savage
04-18-2007, 01:54 AM
Doc,

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

Doc
04-18-2007, 02:25 AM
Hi again,

My PBasic program is:

SDA···· PIN 8··········
V1······ VAR Byte
V2······ VAR Byte
Dist···· VAR Word··
·····
DO
· I2COUT SDA, $e0, 0, [82]····
· PAUSE 20
· I2CIN SDA, $e1, 0, [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

Chris Savage
04-18-2007, 03:00 AM
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

Doc
04-18-2007, 03:22 AM
Thank you Chris,

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

allanlane5
04-18-2007, 04:03 AM
SEROUT 16, 16780, [DEC4 Dist, CR]

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.

Chris Savage
04-18-2007, 04:52 AM
Allan,

That code still sends the value as ASCII characters. I would recommend something more like:

SEROUT 16, 16780, [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, ["!", 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

allanlane5
04-18-2007, 05:52 AM
Hmm. If he has his VB code set to recieve as "text", and then convert to a value, then the DEC4 'formatter' is needed. You're right, though, he currently has "A = MSComm.Input" -- which assumes MSComm.Input is returning a value.

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.

Unsoundcode
04-18-2007, 05:58 AM
Hi Doc, I use VB express quite a lot with Stamp applications and they work out very nicely. I know there are differences between the two versions so some of what I say might not apply directly to VB6 but I am sure it can be adapted.

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,[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.

Doc
04-18-2007, 04:22 PM
Hello Everybody,

Thank you very much for your help.

I tried it with SEROUT using these commands:

· SEROUT 16, 16780,50, [Dist.HIGHBYTE, Dist.LOWBYTE]
· SEROUT 16, 16780,50, ["!", Dist.HIGHBYTE, Dist.LOWBYTE]
· SEROUT 16, 16780,50, [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

allanlane5
04-18-2007, 08:51 PM
Well, it depends on which model BS2 which 'baudmode' constant you should use. The "16780" is for a bs2px at 9600 baud, 8 databits, no stop bits, "Inverted".

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 ÷ baud rate) - 20

So, if you plug in 19200 for 'baud_rate' above, the count is: 188. + $4000 if you want the "Inverted" mode (which I always use on "port 16"). 188 + $4000 == 16572.

So, 16572 should be 19200 baud, Inverted. Put that number in instead of your 16780 and something should work.

Doc
04-18-2007, 10:05 PM
Well yes,
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

allanlane5
04-18-2007, 10:42 PM
If you're using a BS2px, that's different than the 'plain' BS2p.

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.

Doc
04-19-2007, 01:02 AM
Allanlane5,

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

allanlane5
04-19-2007, 01:39 AM
Write a small program for the BS2px which just sends data every 5 seconds.

MAIN:
SEROUT 16, 16780, ["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.

Unsoundcode
04-19-2007, 06:32 AM
Hi, I found some info on MSDN regarding VB6 MScomm.· Here are the two links I looked at.

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

Doc
04-20-2007, 03:57 PM
Hello guys,

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, [82]
·PAUSE 50
·I2CIN SDA, $e1, 0, [Version, LEDsens, Dist.HIGHBYTE, Dist.LOWBYTE]
·SEROUT 16, 16572, [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, [DEC 1000, CR]·, the results were the same in VB6, 1000 or 100 or 00, etc.

Any idea please?

Cheers,
Doc·

allanlane5
04-20-2007, 10:19 PM
I think there's a "TEXT" setting on the MSComm port. Hang on, I'll check...

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

Doc
04-20-2007, 10:25 PM
Exactly, Text or Binary.

I am using text as I used to do with DEBUG (instead of SEROUT) and MSComm. Input with a vb6 Timer.

Cheers.

Unsoundcode
04-21-2007, 05:50 AM
Hi Doc, I think both you and allan are right in targeting VB as being the the piece to straighten out. I was surprised when my code didn't work for you so I looked into the possible reasons. When I tested it I used MScomm but I used it in the VB express environment, so there was one possible anomaly.

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, [DEC4 Dist]

SEROUT 16, 16572, [DEC Dist]

Jeff T.

Doc
04-21-2007, 06:51 PM
Allan, Jeff,

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, [82]··· ' Rangeing command in for microSec
· PAUSE 40··················· ' 40 millisecond
· I2CIN SDA, $e1, 0, [Version, LEDsens, TOF.HIGHBYTE, TOF.LOWBYTE]
· SEROUT 16, 16572, [ "!", 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

Unsoundcode
04-21-2007, 10:24 PM
Nice work Doc·and allan, I learnt quite a bit from this thread about the differences between VB6 and VB express, the differences are wider than I first thought. Nice idea about the sync byte.

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.