Shop OBEX P1 Docs P2 Docs Learn Events
Windows Interface to send/recieve data with Protoboard — Parallax Forums

Windows Interface to send/recieve data with Protoboard

tae2010tae2010 Posts: 38
edited 2010-05-29 03:37 in Propeller 1
Hello there,

I wanted to write a VB.net program that will interface directly with my USB Protoboard so that I can read sensor data from my board. I also want to be able to send data to the board.

Does anyone know how to get started with the basics to communicate with the board? I realize that the board has to be preprogrammed with some SPIN code first, but then I want to have interaction with a PC.

Thanks
«1

Comments

  • LeonLeon Posts: 7,620
    edited 2010-05-10 14:51
    Use something like FullDuplexSerial from the Obex to write data to the PC. Your PC software can then read data from the COM port.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Leon Heller
    Amateur radio callsign: G1HSM
  • Ken GraceyKen Gracey Posts: 7,401
    edited 2010-05-10 15:15
    Take a look at Parallax Serial Terminal, too, along with the Propeller Education Kit for examples of using this tool.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Ken Gracey
    Parallax Inc.

    Follow me at http://twitter.com/ParallaxKen for some insider news.
  • David BDavid B Posts: 592
    edited 2010-05-10 15:23
    It works very well to share the serial line between programming use and client use.

    Your VB never has do any propeller spin preprogramming, if that was what you were thinking.

    You can program using the propeller tool over the serial line as you develop your spin code. Once your spin code is running, you can switch over to VB and have your VB code open the serial line and start using it. Once your propeller code is stable, you can write it to EEPROM and let the propeller boot from that. So your VB never has do any propeller spin preprogramming.

    The only tricky thing you'll run into is that your VB code has to release the serial port whenever you need to use the propeller tool to send new propeller code down the serial line to the propeller. Aside from that, once the propeller tool code download is complete, the serial line is yours to do whatever you want with.

    Then it's up to you to develop sender-listener routines on both ends, maybe using FullDuplexSerial on the propeller end, as Lean suggested.
  • Jim FouchJim Fouch Posts: 395
    edited 2010-05-10 15:25
    It all depends on how rich you want to the interface. I'd start with the basics and build from there.
    On a recent project I just needed to control 4 binary outputs. I used the Parallax Serial Terminal object so I could interact with a simple terminal program, then I added a VB.net program to use the same interface.
    Here is a very simple SPIN program that would get you started. It would allow me to set the output states and see the current states.
    OBJ
      pst   :       "Parallax Serial Terminal"
     
    PUB Main | value, base, width, offset, States, Key
      DIRA[noparse][[/noparse]LED1..LED4]~~ ' Set as Output
      DIRA[noparse][[/noparse]SSR1..SSR4]~~ ' Set as Output
      pst.Start(115_200) 'Set Parallax Serial Terminal to 115200 baud
      Banner ' Display Steris Banner
      repeat
        pst.Str(String(PST#NL,"IO States("))
        pst.dec(States)
        pst.Str(String(")"))    
    '    Key := pst.CharIn
        Case pst.CharIn
              
          "S", "s":
            Value:=PST.DECIN
            States:=  Value & %1111   
            OUTA[noparse][[/noparse]LED4..LED1]:=States & %1111
            OUTA[noparse][[/noparse]SSR4..SSR1]:=States & %1111
          "I", "i":
            Banner
          Other:      
     
    Pri Banner
      pst.NewLine
      pst.Str(@BANNER)
      
      
    DAT
                             
    BANNER  Byte "+------------------------------------+", pst#NL
            Byte "|Remote Quad Power Interrupter       |", pst#NL
            Byte "|Part # xxxxxx-xxxx  Rev x xx/xx/2010|", pst#NL
            Byte "+------------------------------------+", pst#NL ,0
    

    ·For a more·advanced interface·protocol,·I'd consider using some sort of CRC to ensure you have good data.

    If you start with a good protocol, you can then add more message/command types later without interfering with your existing ones.


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jim Fouch

    FOUCH SOFTWARE
  • TtailspinTtailspin Posts: 1,326
    edited 2010-05-10 15:34
    Greetings to All,

    I would like to·travel the same road·with You, tae2010.
    My Transportation will be the PPDB, which is an·AWESOME product by the way.

    I will be using VB express 2010,(cuz free is good for me right now), VB is·what I've been playing with since 3.0..
    and I do mean PLAYING with, as it is just a Hobby for Me. I Have lots of Respect·for the Pro's that write code,
    for a living. They make My Hobby Possable, Thank You Very Much..

    Anyways,
    tae2010 how far have You gone in this?

    Check this link out http://forums.parallax.com/showthread.php?p=671804
    I know it is for the stamp, but it is was somewhat helpfull.

    This link may have some answers in it...
    http://forums.parallax.com/showthread.php?p=879440

    Have You·studied·some of the·Serial Comm demonstrations from the Propeller Tool?,
    The fine folks here will have the ones I have missed posted shortly,smile.gif
    A·Small list here. There are many more than this.

    HelloFullDuplexSerial.spin, ·(Found in the Propeller Tool Example.Help.PE kit, Objects lesson #6)
    Parallax Serial Terminal Demo.spin,· (found in the Propeller Tool Example.help.library)
    PE Kit Tools Propeller to PC Terminal Communication· (found in the Object Exchange, Protocol object list)
    Eight talking Cogs.spin (found on the OBEX, Fun object list)
    TerminalLedControl.spin,·(found it in the Propeller Tool Example.Help.PE kit, objects lesson #6)

    This last one is of special interest to Myself, as it is exactly what I wish to do, Except I wish to use Labels and
    Check Boxes to send the desired Pin States back and forth, Instead of Serial Terminal or HyperTerminal..
    It's not that I don't like the Parallax Serial Terminal, it is a very good thing for debuging and such, I just want
    the User interface options that are VB.


    I have been able to·SEND all manner of data FROM Propeller TO VB, However, I have had no luck at all trying
    to·RECIEVE data on the Propeller FROM VB.

    My current attempt in VB, is·a Container with 8 CheckBoxes, linked to labels and TextBoxes that display the
    "Binary" of the·CheckBoxes, like if·CheckBox #1,3,5,and·7 are Checked then the·Label will display (10101010)..

    Then, with any luck and some fine code examples, I should be able to SEND the Label.Text on to the Propeller.
    Then from there,·divide, multiply, add , and throw in a few of these for good measure, %<=#>+=^&} and,
    Probably one or two of these just to be sure, @~~$_^ ... And I should be able to have complete control over
    the Pins and Leds in question.(0..7),(8..15),ect,

    I even have a Button that Toggle's all of the Pin States at once, for no reason at all, other then it will be so
    cool to·Blink·some or all·of the leds at once...

    At any rate, Please forgive(or at least be patient with) this rambling of a Reply, And good luck in this Quest.
    I·'am sure·the Wonderfully Talented People here will help to·put the right Spin on this turn.gif
  • sylvie369sylvie369 Posts: 1,622
    edited 2010-05-10 15:48
    This is the page that helped me get it running on the VB side:

    http://www.theabramgroup.com/basicstamp/
    ·
  • Jim FouchJim Fouch Posts: 395
    edited 2010-05-10 15:52
    The key to the VB.Net side is to understand multi-threading. You have to have the receiving code running in a separate thread than the UI and other code.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jim Fouch

    FOUCH SOFTWARE
  • tae2010tae2010 Posts: 38
    edited 2010-05-10 19:33
    Wow thanks for all the responses, this will surely help out a lot.

    @Ttailspin: Ive been coding with VB.net for a couple years now, and this'll be my third Windows application with VB.net, so Im not new to the language, Im just new to the serial communication with the Propeller and the SPIN code. Ive done serial communication in the past a few times, but very limited and not USB, so Id like to expand on that.

    I havent actually started coding on this just yet, Im just trying to get an idea of how to begin with the serial/usb communications. Once I get something going, I'll be sure to share my code to help anyone who needs it along.

    My application will be very simple to begin with: all I want to do initially is to read some sensor data from the board and display it on screen. So nothing too fancy, as Ive seen already.

    Id like to ask, is it possible to program multiple SPIN codes into the Propeller? Or does it need to be one massive program?

    Thanks.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2010-05-11 00:42
    I have all the vb.net code written for serial comms.

    You may learn more by starting from a blank form in vb.net and adding some text boxes and buttons and start to add some code. Then ask here for help if things are not working.

    Alternatively, the entire source code of my program is here smarthome.viviti.com/build go to step 11.

    To start simple, you need to set up the serial port. (these are code fragments)
        Dim WithEvents SerialPort As New IO.Ports.SerialPort ' serial port declare
    
    


    and I found some problems outputting and inputting strings (bit 7 problems) so I did it with arrays
        Dim InPacket(0 To 2000) As Byte ' Major bug with serial.write strings like chr(255) won't go out
        Dim OutPacket(0 To 2000) As Byte
    
    


    and set up the serial port
                SerialPort.Parity = IO.Ports.Parity.None ' no parity
                SerialPort.DataBits = 8 ' 8 bits
                SerialPort.StopBits = IO.Ports.StopBits.One ' one stop bit
                'SerialPort.ReadTimeout = 1000 ' milliseconds so times out in 1 second if no response
                SerialPort.Open() ' open the port
                SerialPort.DiscardInBuffer() ' clear the input buffer
            Catch ex As Exception
                MsgBox("Error opening serial port - is another program using the selected COM port?")
                SerialPortFound = False
            End Try
                     Timer1.Enabled = True   ' turn on the timer
    
    


    and then put a timer on the form and polled the serial port

    and to read some bytes
            If SerialPortFound = True Then
                Do
                    'Try
                    If SerialPort.BytesToRead = 0 Then Exit Do ' no more bytes
                    BytesToRead = SerialPort.BytesToRead
                    If BytesToRead > 2000 Then BytesToRead = 2000
                    SerialPort.Read(InPacket, 0, BytesToRead) ' read in a packet
                    For i = 1 To BytesToRead
                        Character = Strings.Chr(InPacket(i - 1))
                        Timer1.Enabled = False ' displaycharacter can take a while, more than one tick
    
    



    and to send a byte

                        SerialPort.Write(OutPacket, 0, 1)
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    www.smarthome.viviti.com/propeller
  • Mike GMike G Posts: 2,702
    edited 2010-05-11 01:30
    I prefer to use the DataReceived event and parse the response on the secondary thread or spin off a new thread if processing takes a long time.

    Be very careful with BytesToRead and the SerialPort.Read method. SerialPort.Read always returns the number of byte read. You should check the return value for the byte read and use it to enumerate the receive buffer, not BytesToRead.

    numBytes = serialPort.Read(readBuffer, 0, readBuffer.Length)
    
    For i As Integer = 0 To numBytes - 1
            Console.Write(readBuffer(i) & ".")
    Next i
    
    



    I like to handle the parsing above in the DataReceived event handler or maybe another method or class. Generally, the handler is a little more complex because I'm looking for specific chunks of data (packets).

    The other thing you'll need to handle is updating the UI if you're building a traditional Win Form application. Sorry, for the C#...

    // serial port data received thread safe delegate
    public delegate void SetTextCallback(String message);
    
    // Align the caller and control thread
    private void SetText(String message)
            {
                if (txtStatus.InvokeRequired)
                {
                    SetTextCallback del = new SetTextCallback(SetText);
                    this.Invoke(del, message);
                }
                else
                {
                    txtStatus.AppendText(message);
                    txtStatus.AppendText("\r\n");
                }
            }
    
    
    

    Post Edited (Mike G) : 5/11/2010 1:37:37 AM GMT
  • TtailspinTtailspin Posts: 1,326
    edited 2010-05-11 22:20
    Hello,

    The above examples are great for sending data TO the PC, and I am sure the information is there, but.
    I just can't seem to get it thru My thick skull, on how to RECIEVE data FROM the PC TO Propeller...

    I can SEND "Hello World" and "10101010" and all kinds of four letter words out TO the PC, FROM the·Propeller.
    But just can't seem to Recieve the data·as expected·with·FullDuplexSerialPlus.spin or Parallax Serial Terminal.spin

    ·This is the VB part I use to try and send what the Text Box (TxtSend.Text) contains...

    I use the same ·_port. setup·as I use to Recieve the "Hello World"s FROM the PROP, in other words,
    This·Button (CmdSend), is on the same Form as the (CmdRecieve) Button that I know works...
    [color=#0000ff][color=#0000ff][color=#0000ff]Private[/color][/color][/color] [color=#0000ff][color=#0000ff][color=#0000ff]Sub[/color][/color][/color] CmdSend_Click([color=#0000ff][color=#0000ff][color=#0000ff]ByVal[/color][/color][/color] sender [color=#0000ff][color=#0000ff][color=#0000ff]As[/color][/color][/color] System.[color=#2b91af][color=#2b91af][color=#2b91af]Object[/color][/color][/color], [color=#0000ff][color=#0000ff][color=#0000ff]ByVal[/color][/color][/color] e [color=#0000ff][color=#0000ff][color=#0000ff]As_[/color][/color][/color] System.[color=#2b91af][color=#2b91af][color=#2b91af]EventArgs[/color][/color][/color]) [color=#0000ff][color=#0000ff][color=#0000ff]Handles[/color][/color][/color] CmdSend.Click
     
    [color=#0000ff][color=#0000ff][color=#0000ff]Dim[/color][/color][/color] send [color=#0000ff][color=#0000ff][color=#0000ff]As[/color][/color][/color] [color=#0000ff][color=#0000ff][color=#0000ff]String[/color][/color][/color] = TxtSend.Text & vbCr  'I have tried with and without & vbCr
     
    [color=#0000ff][color=#0000ff][color=#0000ff]  If[/color][/color][/color] _port.IsOpen [color=#0000ff][color=#0000ff][color=#0000ff]Then[/color][/color][/color]
       _port.WriteLine(send)
    [color=#0000ff][color=#0000ff][color=#0000ff]  End[/color][/color][/color] [color=#0000ff][color=#0000ff][color=#0000ff]If[/color][/color][/color]
    [color=#0000ff][color=#0000ff][color=#0000ff]End[/color][/color][/color] [color=#0000ff][color=#0000ff][color=#0000ff]Sub[/color][/color][/color]
    
    

    The Spin Code... welllll.. She aint so nice..
    CON
        _clkmode = xtal1 + pll16x
        _xinfreq = 5_000_000
         
    VAR
      Byte StringToRecieve
      Byte WhatToDoWithIt
      
    OBJ
      pst : "Parallax Serial terminal"
    PUB Main 
      pst.StartRxTx(31, 30, 0, 115_200)
      
      WhatToDoWithIt :=pst.StrIn(StringToRecieve)
      
      repeat
        
         case WhatToDoWithIt
            "123":           
               Toggle(12)
              
            "111":
              Toggle(15)
            "222":
              Toggle(8)
          other:
              Toggle(10)
              waitcnt(3_000_000 + cnt)
              Toggle(9)
              
              
    PUB Toggle(pin)
      dira[noparse][[/noparse]pin]~~
      repeat 50
        !outa[noparse][[/noparse]pin]
        waitcnt(3_000_000 + cnt)
    

    It does flash the leds connected to pins(9) and (10) very nicely, just as bright and flashy as I could want...
    I just happen to want Pin(15)·and/or·Pin(8) or any other selected Pin( )·to be flashy·at·My whim...


    I am just going to throw My hands in the air, declare it can't be done,
    leave this code laying around, and see what happens...wink.gif
  • JonnyMacJonnyMac Posts: 9,208
    edited 2010-05-11 22:48
    Jan Axelson wrote about connecting VB.net to micros in Nuts & Volts -- have a look at her web site: www.lvr.com.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon McPhalen
    Hollywood, CA
  • David BDavid B Posts: 592
    edited 2010-05-11 23:15
    If it helps, here is a snippet of propeller receive code that works quite well..

    It's almost like your code, except for a few things -

    1. it uses single characters to flag particular actions, not multicharacter strings
    2. it declares a list of constants for the flags, because these must match between Windows and the propeller
    3. it receives everything inside the continuous loop, but discards unknown characters

    It looks to me like you're almost there!



     
      RETURN_HELLO         = 10   ' commands for communication with Delphi
      RESTART              = 11
      RETRIEVE_ARRAY       = 12
      GET_AVERAGE          = 13
      GET_INTEGRATE        = 14
      GET_STATUS           = 15
      GET_PEAK             = 16
    
      TXPIN                = 30          
      RXPIN                = 31
      RXTXMODE             =  0                 
      RXBAUD               = 115200     
      
    ...
    
    PUB receving routine:
    
       ...
    
      cog := serial.start(RXPIN, TXPIN, RXTXMODE, RXBAUD)
    
      lcd.clear
      lcd.[b]str[/b]1x([b]String[/b]("ser cog: "), cog, 4)
      delay(750)
                      
      pause := 0            
      loops := 0 
                                        
      [b]repeat[/b] 
          
        loops++
        
        [b]if[/b] (char := serial.rxcheck) > -1
          
          pause := 1000
                  
          [b]if[/b] char == RETURN_HELLO
            serial.[b]str[/b]([b]String[/b]("Hello World "))
    
          [b]elseif[/b] char == RESTART
            reboot
    
          [b]elseif[/b] char == GET_AVERAGE
            serial.sendLong(averagevalue)        
    
          [b]elseif[/b] char == GET_INTEGRATE
            serial.sendLong(integratetime)
    
          [b]elseif[/b] char == GET_STATUS
            serial.sendLong(statusflag)
    
        ...
    
    
    
  • Mike GMike G Posts: 2,702
    edited 2010-05-12 03:32
    @Ttailspin I did a quick look at Parallax Serial terminal.spin obejct. The StrIn(pointer) method takes a pointer argument. I don't see where you initialized the pointer or buffer. Also the pointer is a byte value, StringToRecieve, probably should be 32 bit? The WhatToDoWithIt VAR is a byte value but the case statement is evaluating a 3 byte string. Unless, I read this incorrectly (I'm a little rusty with spin) StrIn() does not return a value, it fills an array. So, at the conclusion of WhatToDoWithIt :=pst.StrIn(StringToRecieve), WhatToDoWithIt probably equals 0.

    Take a look at David B's stuff above or one of the FullDuplex objects.

    Post Edited (Mike G) : 5/12/2010 3:45:25 AM GMT
  • TtailspinTtailspin Posts: 1,326
    edited 2010-05-12 05:27
    @JonnyMac, Thanks for that Awesome link, Wow, I will be grinding My way thru those sample programs for some time to come,
    That is one fully loaded Serial Terminal Program, It will save Your com settings and load them on start up and everything...
    Pretty amazing, at least to a newbie like Myself, I swear She used every Keyword and Command available in VB.
    The Commenting is exellent, and I learned a ton from it, and still see a ton more to learn from the samples.
    However, I thought that it might be overkill for Me right now, and thought I could start with something a little less sophisticated.
    thanks again, I don't think I would have found that site anytime soon.

    @David B, Thank's for that Code snippet, I wonder if I made the right choice in using "Case" instead of "If and ElseIf",
    will it make a difference?, I thought that "Case" would look pretty. I like the idea of single char's instead of Strings,
    seems like I would have more Control over the individual Pins... hmmm...

    @Mike G, Thank You, and You are absolutly right, That is indeed Spin Language 101, I did not Declare or initialize a Pointer,
    Or a Buffer for that matter, I bet it would pay off, if I actually did Declare them...Sigh.. please be patient, some handholding may
    be Required for some of the harder stuff, Like declaring variables, and finding the AnyKey on My keyboard...

    I will School Myself on Byte, Word, and Long. Maybe actually paying attention this time..
    I did think that a byte would let me have a number(integer) from 0 to 255, and as long as I stayed in those bounds all would be well.
    Just for fun, I added a Case : "0" toggle(14), to see if the Variable "WhatToDoWithIt" was being made equal to 0,
    It did not seem to make a difference, it just went to other :, and pins (9) and (10) still do all the flashing...

    Anyways, Thanks again to all, and I will keep Grinding and Chipping away at the samples and tutorials.

    The leds WILL flash at My whim...
  • tae2010tae2010 Posts: 38
    edited 2010-05-12 05:58
    wow looks like you got a head start on me. Ive had finals the last couple of days, so I havent been able to start this, but I'll go ahead and give it a try tomorrow. Doesn't seem like it'll be too difficult.
  • Mike GMike G Posts: 2,702
    edited 2010-05-12 14:23
    @Ttailspin, load the code below in the prop then open the Parallax Serial Terminal. Note, the connection is 57600 baud. Type "LED16" in the Serial Terminal's transmit field (at the top) and press enter. LED16 should flash - I tested it. Once you verify it's working in your end, jump on your VB.NET app. In my opinion, your initial problem is related to Propeller (microcontroller) architecture and not so much spin syntax.

    CON
        _clkmode = xtal1 + pll16x
        _xinfreq = 5_000_000
    
    
    DAT
            led16 byte "LED16", 0    
            led17 byte "LED17", 0
            led18 byte "LED18", 0 
        
    VAR
      byte  rxString[noparse][[/noparse]50]  'Holds incoming serial bytes
      
     
    OBJ
      pst : "Parallax Serial terminal"
    
      
    PUB Main
      pst.StartRxTx(31, 30, 0, 57600)
     
      repeat
        pst.StrIn(@rxString)
        
        { Compare the received string to the DAT strings }
        if( strcomp(@rxString, @led16) )
          Toggle(16)
          next
          
        if( strcomp(@rxString, @led17) )
          Toggle(17)
          next
          
        if( strcomp(@rxString, @led18) )
          Toggle(18)
          next
    
        Toggle(23)
         
             
             
    PUB Toggle(pin)
      dira[noparse][[/noparse]pin]~~
      repeat 50
        !outa[noparse][[/noparse]pin]
        waitcnt(3_000_000 + cnt)
    
  • TtailspinTtailspin Posts: 1,326
    edited 2010-05-12 17:09
    @tae2010, It is easy when You have the power of the Parallax User Support Forums, and Mike G's guiding light...

    @Mike G, Thanks again, Thats it, thats what I was trying to do for now, Your snippet worked great...once.
    heh, when I ran it, it would let Me Pick anyone of the Pins and·Toggle it 50 times as expected,
    Then it would only Toggle Pin(23), and only a reset would allow a new Pin choice...

    So I thought along the lines of needing to clear the RxBuffer, when a new Pin is wanted. and Behold, there it was,
    Parallax Serial Terminal.RxFlush, To My utter amazement, it worked, I did'nt even have to threaten My PPDB
    With My cup of coffee.(It never fails to amaze Me how much coffee a bread board can hold..), Anyways here it is.

    Rough as it is, it will serve as a great starting point to educate Myself further in this endeaver..

    CON
        _clkmode = xtal1 + pll16x
        _xinfreq = 5_000_000
    
    DAT
            led8 byte "LED8", 0
            led12 byte "LED12", 0    
            led13 byte "LED13", 0
            led14 byte "LED14", 0 
            
    VAR
      byte  rxString[noparse][[/noparse]50]  'Holds incoming serial bytes
      
     
    OBJ
      pst : "Parallax Serial terminal"
      
    PUB Main
      pst.StartRxTx(31, 30, 0, 57600)
     
      repeat
    
        pst.RxFlush   'Adding this here, allows bad input to be reset, and make room for new input
     
        pst.StrIn(@rxString)
        
        { Compare the received string to the DAT strings }
        if( strcomp(@rxString, @led8) )
          
          Toggle(8)
          pst.RxFlush      
          next
        if( strcomp(@rxString, @led12) )
          Toggle(12)
          pst.RxFlush
          next
          
        if( strcomp(@rxString, @led13) )
          Toggle(13)
          pst.RxFlush
          next
          
        if( strcomp(@rxString, @led14) )
          Toggle(14)
          pst.RxFlush
          next
        
        Toggle(15)
         
             
             
    PUB Toggle(pin)
      dira[noparse][[/noparse]pin]~~
      repeat 50
        !outa[noparse][[/noparse]pin]
        waitcnt(3_000_000 + cnt)
    

    And·a VERY SMALL snippet of VB code, this is just for the Send Button, Add a TextBox and its good to go.

    [color=#0000ff][color=#0000ff][color=#0000ff]Private[/color][/color][/color] [color=#0000ff][color=#0000ff][color=#0000ff]Sub[/color][/color][/color][color=#000000] CmdSend_Click([/color][color=#0000ff][color=#0000ff][color=#0000ff]ByVal[/color][/color][/color][color=#000000] sender [/color][color=#0000ff][color=#0000ff][color=#0000ff]As[/color][/color][/color][color=#000000] System.[/color][color=#2b91af][color=#2b91af][color=#2b91af]Object[/color][/color][/color][color=#000000], [/color][color=#0000ff][color=#0000ff][color=#0000ff]ByVal[/color][/color][/color][color=#000000] e [/color][color=#0000ff][color=#0000ff][color=#0000ff]As[/color][/color][/color][color=#000000] System.[/color][color=#2b91af][color=#2b91af][color=#2b91af]EventArgs[/color][/color][/color][color=#000000]) [/color][color=#0000ff][color=#0000ff][color=#0000ff]Handles[/color][/color][/color][color=#000000] CmdSend.Click[/color]
     
    [color=#0000ff][color=#0000ff][color=#0000ff]Dim[/color][/color][/color] send [color=#0000ff][color=#0000ff][color=#0000ff]As[/color][/color][/color] [color=#0000ff][color=#0000ff][color=#0000ff]String[/color][/color][/color] = TxtSend.Text & vbCr  'The vbCr does make a difference
     
    [color=#0000ff][color=#0000ff][color=#0000ff] If[/color][/color][/color] _port.IsOpen [color=#0000ff][color=#0000ff][color=#0000ff]Then[/color][/color][/color]
        _port.WriteLine(send) 
     
    [color=#0000ff][color=#0000ff][color=#0000ff]  End[/color][/color][/color] [color=#0000ff][color=#0000ff][color=#0000ff]If[/color][/color][/color]
    [color=#0000ff][color=#0000ff][color=#0000ff]End[/color][/color][/color] [color=#0000ff][color=#0000ff][color=#0000ff]Sub[/color][/color][/color]
    

    ·Thanks again to all.

    I will see what kind of trouble, err.. refinements I can make from all this new knowledge I have gained...


    Post Edited (Ttailspin) : 5/12/2010 8:14:55 PM GMT
  • tae2010tae2010 Posts: 38
    edited 2010-05-12 17:41
    Would the part of the program that SENDS from the Propeller TO the PC be able to send something such as digital sensor data to the program? Just like how it shows up on the Prop Terminal? Im still building the sensor circuit, so I wanted to verify that this idea will work.

    Thanks.
  • Mike GMike G Posts: 2,702
    edited 2010-05-12 18:19
    @tae2010, You can think of serial communication as a stream of bytes. It's up to you to determine how the bytes are interpreted, where data begins and ends, and where the metadata begins and ends.

    @Ttailspin, cool - didn't know you had to flush the buffer.

    Post Edited (Mike G) : 5/12/2010 6:24:42 PM GMT
  • David BDavid B Posts: 592
    edited 2010-05-12 19:12
    Sure, you can return data.

    After the PC program sends a code to the propeller that requests some data value, the PC would then be expecting a series of bytes that represent a word, or long, or array of values.

    So the propeller's response to that code would be to send exactly those bytes, in the order that the PC will re-aassemble them into a word, or long, or array of values.

    In the example snippet of code I attached earlier in this thread, you can see references to a helper function I wrote called "sendlong(value)" to do just that - it sends the 4 bytes of a long in the same order that the PC reassembles then into a long in the format used by your PC language, VB, in your case.
  • tae2010tae2010 Posts: 38
    edited 2010-05-12 20:06
    @Ttailspin so according to your code, basically you would send one of those strings ("LED8", etc) via the VB code to the board, and it turns those pins on and off?
  • TtailspinTtailspin Posts: 1,326
    edited 2010-05-12 21:13
    @tae2010, Yes sir, the code, as it is written, works as described, However..

    There are some Rules to follow, the main one right now is obvious to some, but very easy to miss when You decide to not see it.

    You must send Data exactly as it is Declared in DAT. (I.E. sending led8 will flash led 15, where as sending LED8 WILL flash led 8)
    In other words, Check Your Spelling, including and especially capitilization...
    I know this can be fixed with all the various String Manipulators that are available from the OBEX, But keeping in the spirit of KISS,
    I will just say, "Check Your Spelling for now.."
    ·Duh, it's Visual Basic, use a Masked TextBox...

    You Must start the Spin Program before opening the PC Serial Port, I'm not making that up, it's just the way it is...

    You must SET MATCHING BAUD RATES, This example uses 57600 Baud, it could easily be changed to 115200, or 2400, or ????
    No matter, As long as BOTH the Propeller, and the PC are using the same Baud Rates.

    Oh and just to be clear, I am using the Prop Pro Development Board, I have jumpers from Pins(8..15) out to the Leds(8..15),
    And also some jumpers from Pins(0..7) out to the Push Buttons(0..7), but these have nothing to do with anything...YET..
    I see many If ina( )'s in My future...

    @Mike G, Thanks again for the strcomp tip, that is really where the magic happens in this code..
    and by the way, I really didn't know that "Flushing" the buffer was the way to go either, I just know that it is working,
    Maybe not the bestest or the cleanest, but I think I can roll up a phattie with what I have here, and refine, refine, refine...

    Post Edited (Ttailspin) : 5/12/2010 11:41:39 PM GMT
  • tae2010tae2010 Posts: 38
    edited 2010-05-12 23:40
    I wanted to ask how I can send a command to the board to enable the sending of data from the board.

    The code I have now is:

    CON
       
      _clkmode = xtal1 + pll16x                             ' Crystal and PLL settings.
      _xinfreq = 5_000_000                                  ' 5 MHz crystal (5 MHz x 16 = 80 MHz).
    
    DAT
      led5   byte   "LED5", 05
             
            
    VAR
      byte  rxString[noparse][[/noparse]50]  'Holds incoming serial bytes
     
     
    OBJ
    
      pst    : "Parallax Serial Terminal"                   ' Serial communication object
    
    
    PUB RelayOnOff | value
    
      
      pst.Start(115200)                                                             ' Start the Parallax Serial Terminal cog
        
    ''---------------- Replace the code below with your test code ----------------
      
      pst.Str(String("Test Program"))
      
    'Declare Pins
    
        dira[noparse][[/noparse]02] := 1                   'Set P02 to output
    
        dira[noparse][[/noparse]05] := 1                   'Set P05 to output
        outa[noparse][[/noparse]05] := 1                   'Set P05 to high
        
        dira[noparse][[/noparse]13] := 1                   'Set P13 to output
    
        dira[noparse][[/noparse]14] := 1                   'Set P14 to output
        outa[noparse][[/noparse]14] := 1                   'Set P14 to high
    
                    
        repeat
            outa := 1
            pst.Str(String(pst#NL, "ON"))
            waitcnt(clkfreq/2 + cnt)
            outa := 0
            pst.Str(String(pst#NL, "OFF"))
            waitcnt(clkfreq/2 + cnt)
    
    



    Im using the Serial Terminal for now to get the Propeller code perfected.

    What Im trying to do is change the code so that I send a string to the board, such as "SEND_ON", and then the the board will allow the strings to send TO the PC as the Pins go high and low. (The Text is simply "ON", "OFF") But the Problem is that I try to send text to the board through the terminal so that I can see if it receives or not, but the board continuously sends text via the Serial port, so I am unable to type a command.

    Im totally lost as to how I can send a command to the board to enable/disable the board sending data to the pc (and switching those pins high/low), instead of it just sending data nonstop.
  • Mike GMike G Posts: 2,702
    edited 2010-05-13 01:46
    I think this is what you're trying to do. Run the code below and open the Parallax Serial Terminal. By default any command will echo back to the caller. To turn echo off, enter "EchoOff" in the Serial Terminal. Turn it back on... "EchoOn"

    CON
        _clkmode = xtal1 + pll16x
        _xinfreq = 5_000_000
    
    
    DAT
            led16   byte "LED16", 0    
            led17   byte "LED17", 0
            led18   byte "LED18", 0
            echoOn  byte "EchoOn", 0
            echoOff byte "EchoOff", 0           
        
    VAR
      byte  echo
      byte  rxString[noparse][[/noparse]50]  'Holds incoming serial bytes
      
     
    OBJ
      pst : "Parallax Serial terminal"
    
      
    PUB Main
      pst.StartRxTx(31, 30, 0, 57600)
    
      ' Do not echo the command
      echo := 1 
     
      repeat
      { Flush the Rx buffer}
        pst.RxFlush
    
        { Read a string }
        pst.StrIn(@rxString)
        
        { Compare the received string to the DAT strings }
    
        ' If echo is on we'll echo the command back to the caller
        if( strcomp(@rxString, @echoOn) )
          pst.Str(@echoOn)
          pst.NewLine
          
          echo := 1
          next
    
        if( strcomp(@rxString, @echoOff) )
          pst.Str(@echoOff)
          pst.NewLine
          
          echo := 0
          next
    
        { Commands }
        ' LED 16 command handler
        if( strcomp(@rxString, @led16) )
          if(echo == 1)
            pst.Str(@led16)
            pst.NewLine
          
          Toggle(16)
          next
    
        ' LED 17 command handler  
        if( strcomp(@rxString, @led17) )
          if(echo == 1)
            pst.Str(@led17)
            pst.NewLine
          
          Toggle(17)
          next
    
        ' LED 18 command handler  
        if( strcomp(@rxString, @led18) )
          if(echo == 1)
            pst.Str(@led18)
            pst.NewLine
          
          Toggle(18)
          next
    
        Toggle(23)
    
        
         
             
             
    PUB Toggle(pin)
      dira[noparse][[/noparse]pin]~~
      repeat 50
        !outa[noparse][[/noparse]pin]
        waitcnt(3_000_000 + cnt)
    
    

    Post Edited (Mike G) : 5/13/2010 2:01:24 AM GMT
  • tae2010tae2010 Posts: 38
    edited 2010-05-13 06:09
    But then what does echo do? I think that code may be on the right track.

    From the code I posted, I was really trying to enable/disable the data that was being sent from the Propeller to the PC. So through my command to the board, it should turn this Sub Function on and off:

    Pub Code_Snippet
        dira[noparse][[/noparse]02] := 1                   'Set P02 to output
    
        dira[noparse][[/noparse]05] := 1                   'Set P05 to output
        outa[noparse][[/noparse]05] := 1                   'Set P05 to high
                    
        repeat
            outa [noparse][[/noparse]02] := 1
            pst.Str(String(pst#NL, "ON"))
            waitcnt(clkfreq/2 + cnt)
            outa [noparse][[/noparse]02]:= 0
            pst.Str(String(pst#NL, "OFF"))
            waitcnt(clkfreq/2 + cnt)
    
    



    So Im thinking maybe something along the lines of:

    
    if( strcomp(@rxString, @echoOn) )
          pst.Str(@echoOn)
          pst.NewLine
          
          Call Code_Snippet
          next
    
    
  • Mike GMike G Posts: 2,702
    edited 2010-05-13 14:03
    Well, <byte echo> is just a flag that that determines what code block is executed during run time. If <echo := 1> we send a message back to the client. If <echo := 0> we do not send a message back to the client.

    I think you're struggling with conditional statements. Look up the "If" statement in the Propeller help file.

    if flag == 1
      'do this
    else
      'do something else
    
    



    In your example, once you enter that repeat loop, you're in it forever.

    Post Edited (Mike G) : 5/13/2010 2:13:39 PM GMT
  • tae2010tae2010 Posts: 38
    edited 2010-05-14 23:42
    I was just using your code as an example. Im sure I understand how to use If statements, what Im struggling with is how to send a command to the board to enable/disable some part of the spin code. Like Cases I guess, where if I send a command to the board, it activates that piece of code to turn a relay on and off as in my code. Or if I send it another command to turn off, it stops doing that piece of code and just sits still.

    Heres an example of some Pseudo code (plus code):

    Case On:
    
    dira[noparse][[/noparse]02] := 1                   'Set P02 to output
    
        dira[noparse][[/noparse]05] := 1                   'Set P05 to output
        outa[noparse][[/noparse]05] := 1                   'Set P05 to high
             
    while the command is On do:       
            outa [noparse][[/noparse]02] := 1
            pst.Str(String(pst#NL, "ON"))
            waitcnt(clkfreq/2 + cnt)
            outa [noparse][[/noparse]02]:= 0
            pst.Str(String(pst#NL, "OFF"))
            waitcnt(clkfreq/2 + cnt)
    
    Case Off:
    
    do nothing
           
    
    
  • Mike GMike G Posts: 2,702
    edited 2010-05-15 01:12
    Try this... Load the code and open the Parallax Serial Terminal.

    Press "w" to flash LED 16
    Press "b" to stop
    Press "s" to flash LED 23
    Press "b" to stop

    You must press "b" to get out of the loop.

    CON
        _clkmode = xtal1 + pll16x
        _xinfreq = 5_000_000
    
    VAR
      byte  command
        
     
    OBJ
      serial : "FullDuplexSerial"
    
      
    PUB Main
      serial.start(31, 30, 0, 57600)
    
      repeat
    
        { Read a byte }
        command := serial.rxcheck
    
        if command == 119
          repeat until serial.rxcheck == 98 
           Toggle(16)
    
        if command == 115
          repeat until serial.rxcheck == 98 
           Toggle(23) 
           
    
        waitcnt(10_000_000 + cnt)
    
    
          
       
    PUB Toggle(pin)
      dira[noparse][[/noparse]pin]~~
      repeat 2
        !outa[noparse][[/noparse]pin]
        waitcnt(3_000_000 + cnt)
    
    



    Or

    Press "w" to flash LED 16
    Press "s" to flash LED 23
    press "enter" for idle mode

    
    CON
        _clkmode = xtal1 + pll16x
        _xinfreq = 5_000_000
    
    VAR
      byte  command
      byte  temp
        
     
    OBJ
      serial : "FullDuplexSerial"
    
      
    PUB Main
      serial.start(31, 30, 0, 57600)
    
      repeat
    
        { Read a byte }
        temp := serial.rxcheck
        if temp <> 255
          command := temp
    
        if command == 119
           Toggle(16)
    
        if command == 115 
           Toggle(23)
    
        if command == 13 
           
    
        waitcnt(1_000_000 + cnt)
    
    
          
       
    PUB Toggle(pin)
      dira[noparse][[/noparse]pin]~~
      repeat 2
        !outa[noparse][[/noparse]pin]
        waitcnt(3_000_000 + cnt)
    
    



    The key is the use of FullDuplexSerial since the method rxcheck does not block.


    Edit: this will display key press values

    CON
        _clkmode = xtal1 + pll16x
        _xinfreq = 5_000_000
    
    VAR
      byte  command 
        
     
    OBJ
      serial : "FullDuplexSerial"
    
      
    PUB Main
      serial.start(31, 30, 0, 57600)
    
      repeat
    
        { Read a byte }
        command := serial.rxcheck
    
        if command <> 255
          serial.dec(command)
          serial.tx($0D) 
    
        waitcnt(1_000_000 + cnt)
    
    
          
       
    PUB Toggle(pin)
      dira[noparse][[/noparse]pin]~~
      repeat 2
        !outa[noparse][[/noparse]pin]
        waitcnt(3_000_000 + cnt)
    

    Post Edited (Mike G) : 5/15/2010 3:07:54 AM GMT
  • TtailspinTtailspin Posts: 1,326
    edited 2010-05-15 03:32
    Mike G's code is way more practical than what I have here, this is just a small refinement of what I posted earlier.
    I have to comment everything in My own kind of babble, It may not be the best style, but it sure helps me to walk thru it.
    Anyways, to Recap what I've done so far...
    Made Visual Basic do this>>> http://forums.parallax.com/attachment.php?attachmentid=49017
    Then I asked for help on this forum and wound up with this...
    CON
        _clkmode = xtal1 + pll16x           'Set up the Clock, this is for 80MHz 
        _xinfreq = 5_000_000
     
    VAR
      byte  rxString[noparse][[/noparse]50]  'Holds [noparse][[/noparse]50] incoming serial bytes, 
                          'that should hold 49 letters or numbers, and the terminator char. 
            
      
     
    OBJ        
       pst : "Parallax Serial terminal"     'Maybe They should Name it "Propeller Serial Terminal" instead??...
      
      'HomeBrew : "Brew Tender 9000"       'You can add as many Spin Programs as You want!!
      
    PUB Main   ''Starts up all the action
      pst.StartRxTx(31, 30, 0, 57600)   'Gotta start the Parallax Serial Terminal up before You make any calls to it.
     
      repeat
        pst.RxFlush            'Adding this here, allows bad/old input to be reset, and make room for new input.
                                                            
        pst.StrIn(@rxString)   'Recieve the String from PC, and place it starting at (@rxString) for [noparse][[/noparse]50] byte's..
        
        
                { Compare the received string to the DAT strings, Then do something cool }
        
         if( strcomp(@rxString, @led8) )  'This compares the string at (rxString), with the one at (led8), decides IF its the same,
                                          'Or different, IF it's the same, Then stay, IF it's different then move on to next IF in line. 
                                          'STRCOMP (StringAddress1, StringAddress2 ) is in the "Memory" section of the Propeller Manual.
                                          'Right where You would expect to find it,..but not where I expected to find it...sigh..
                                          'Note to self: Reread the manual, this time pay attention...
                                                                                
                                           
            Toggle(8)     'Toggle(pin#) jumps to the Toggle routine, flashes the chosen Led 50 times and comes back to the next line
                         
            pst.RxFlush   'This Flushes the Input Buffer, so the next data sent will be not be mixed up with the old data.
                            
            next          'Skip remaining statements and start over from the top repeat.
          
                             'lather rinse and repeat (but only 8 pins for now)...Hrmm..(PropellerII, 100 pins??? Yeesh!!)...
                             'gotta be a better way than this, Gonna Have to read up on Indexing Stuff,
                             'But this is not to bad for 8 pins.
                                         
        if( strcomp(@rxString, @led9) )
          Toggle(9)
          pst.RxFlush
          next
        if( strcomp(@rxString, @led10) )
          Toggle(10)
          pst.RxFlush
          next
        if( strcomp(@rxString, @led11) )
          Toggle(11)  '<<<<<<<<<<<<<<<<<<<<<<No reason a different action could not be called here..
          
          'RotateServo(360') <<<<<<<<<<<<<<<<You can add any amount of procedures/functions,
          
          'HomeBrew.HeatMash <<<<<<<<<<<<<<<<And coolest of all, add whole different Spin Programs.
            
          pst.RxFlush
          next        
        if( strcomp(@rxString, @led12) )
          Toggle(12)
          pst.RxFlush
          next
          
        if( strcomp(@rxString, @led13) )
          Toggle(13) 
          pst.RxFlush
          next
          
        if( strcomp(@rxString, @led14) )
          Toggle(14)
          pst.RxFlush
          next
        if( strcomp(@rxString, @led15) )                
          Toggle(15) 
          pst.RxFlush
          next
        'if( strcomp(@rxString, @led16) )                
          'Toggle(16)                     'You could go on and on till You got tired or ran out of things for Your Pins to do..
          'pst.RxFlush                           
          'next
    
                                    'The end of the IF's, this is kinda like Else IF, except You don't have to type "Else IF"
        ElectricShock               'This is what You want to do if You get bad data or something the program does not expect.      
                                                   '!!!DO NOT SEND DATA THE PROPELLER DOES NOT EXPECT!!!
                                                 '(it will do bad things if You send garbage from the PC.)
              
             
    PUB Toggle(pin)    ''Toggle the Selected Pin as Selected on the PC
      dira[noparse][[/noparse]pin]~~
      repeat 50                    
        !outa[noparse][[/noparse]pin]
        waitcnt(3_000_000 + cnt)
        
    PUB ElectricShock  ''Use Your favorite Capacitor to Metal Chair circiut,
                       'and adjust the voltage as needed
      dira[noparse][[/noparse]8..15]~~
      
      pst.str(@WrongData)
      
      repeat 50                   
        !outa[noparse][[/noparse]8..15]
        waitcnt(3_000_000 + cnt)
        
        
    DAT       ''Line up all the expected Strings 
               'I still gotta learn up on indexing stuff     
            led8 byte "LED8", 0
            led9 byte "LED9", 0
            led10 byte "LED10", 0
            led11 byte "LED11", 0
            led12 byte "LED12", 0    
            led13 byte "LED13", 0
            led14 byte "LED14", 0 
            led15 byte "LED15", 0
            WrongData Byte "Don't Hand Me that Garbage",0
          
    

    All of My comment's are My own, Regard them at Your own Peril...

    Maybe this will help or Maybe not.
Sign In or Register to comment.