Shop OBEX P1 Docs P2 Docs Learn Events
SRF235 Basic Stamp VB6 — Parallax Forums

SRF235 Basic Stamp VB6

DocDoc Posts: 25
edited 2007-04-21 14:24 in BASIC Stamp
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

Comments

  • allanlane5allanlane5 Posts: 3,815
    edited 2007-04-17 17:53
    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 SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2007-04-17 17:54
    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
  • DocDoc Posts: 25
    edited 2007-04-17 18:25
    Hi again,

    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
  • Chris SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2007-04-17 19:00
    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
  • DocDoc Posts: 25
    edited 2007-04-17 19:22
    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
  • allanlane5allanlane5 Posts: 3,815
    edited 2007-04-17 20:03
    SEROUT 16, 16780, [noparse][[/noparse]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 SavageChris Savage Parallax Engineering Posts: 14,406
    edited 2007-04-17 20:52
    Allan,

    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
  • allanlane5allanlane5 Posts: 3,815
    edited 2007-04-17 21:52
    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.
  • UnsoundcodeUnsoundcode Posts: 1,532
    edited 2007-04-17 21:58
    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,[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.
  • DocDoc Posts: 25
    edited 2007-04-18 08:22
    Hello Everybody,

    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
  • allanlane5allanlane5 Posts: 3,815
    edited 2007-04-18 12:51
    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
  • DocDoc Posts: 25
    edited 2007-04-18 14:05
    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
  • allanlane5allanlane5 Posts: 3,815
    edited 2007-04-18 14:42
    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.
  • DocDoc Posts: 25
    edited 2007-04-18 17:02
    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
  • allanlane5allanlane5 Posts: 3,815
    edited 2007-04-18 17:39
    Write a small program for the BS2px which just sends data every 5 seconds.

    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.
  • UnsoundcodeUnsoundcode Posts: 1,532
    edited 2007-04-18 22:32
    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
  • DocDoc Posts: 25
    edited 2007-04-20 07:57
    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, [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·
  • allanlane5allanlane5 Posts: 3,815
    edited 2007-04-20 14:19
    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
  • DocDoc Posts: 25
    edited 2007-04-20 14:25
    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.
  • UnsoundcodeUnsoundcode Posts: 1,532
    edited 2007-04-20 21:50
    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, [noparse][[/noparse]DEC4 Dist]

    SEROUT 16, 16572, [noparse][[/noparse]DEC Dist]

    Jeff T.
  • DocDoc Posts: 25
    edited 2007-04-21 10:51
    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, [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
  • UnsoundcodeUnsoundcode Posts: 1,532
    edited 2007-04-21 14:24
    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.
Sign In or Register to comment.