Shop OBEX P1 Docs P2 Docs Learn Events
Looking for a good prop<->prop example project — Parallax Forums

Looking for a good prop<->prop example project

idbruceidbruce Posts: 6,197
edited 2011-01-26 17:21 in Propeller 1
lllllllllllllllll
«1345

Comments

  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-01-18 15:44
    The are a lot of posts pertaining to inter-prop communication, but I have yet to find a rock solid and well documented example, that demonstrates sending and receiving strings, sending and receiving numbers, handshaking, acknowledgment, etc

    I have done that, but not in a way I would recommend (A propeller running a CP/M emulation which is then running MP/M with multiple users on one screen, some of which are remote boards in another room communicating wirelessly. I've transferred files, and even run Wordstar in another room. But the catch is that MP/M is not rock solid).

    So...

    How fast do you want to go?

    If you are happy with 300 baud, 1200 baud, 9600, 38400 and 115200, then Xmodem can transfer files. It has some error correction and can move files between sd cards on different boards.

    Faster than that - I'll have to defer to other experts.

    I have a board next to me that can talk to a terminal program, and can use xmodem on Hyperterminal to transfer files. The board has two serial ports, so it can then talk to a different propeller board as well.

    But when you talk about handshaking and acknowledgment, that implies more complex data transfer, eg it implies an unreliable link. So how many times do you send an negative acknowledgment before you give up? (xmodem gives up after 10 errors for instance).

    I've pondered something like bittorrent where data is sent in self contained packets in any random order.

    The solution depends very much on the application eg, speed, reliability of the data links, wireless vs wired connections, amount of data, raw data vs packets with internal checksums.

    What is your application?
  • idbruceidbruce Posts: 6,197
    edited 2011-01-18 15:59
    Dr_Acula

    I am just talking basics here. Lets say a baud rate of 9600 - 115200 with hardwired communication lines.

    Prop 1 TX -> RX Prop 2
    Prop 1 RX <- TX Prop 2
    Prop 1 VSS <-> Prop 2

    Just something to learn from.

    Bruce
  • Capt. QuirkCapt. Quirk Posts: 872
    edited 2011-01-18 16:21
    Look in the Basic Stamp syntax manual. Explains the basics quite nice. Then apply it to a prop.
  • idbruceidbruce Posts: 6,197
    edited 2011-01-18 16:34
    Capt. Quirk

    That's funny LOL. I can't even believe that. You are right though, they document it well for the basic stamp.

    Now why in the world couldn't they do that in the Propeller Manual? Just unbelievable.

    Bruce
  • Mike GreenMike Green Posts: 23,101
    edited 2011-01-18 16:43
    It's not at all unbelievable. You're asking for something "rock solid", "well documented". Prop to Prop communications is not that often used, certainly nowhere as often as video output or SD card access or PS/2 keyboard use. A number of people have experimented with different schemes for Prop to Prop communications, some emphasizing raw speed and some emphasizing simplicity, using direct serial I/O with no error checking. Some people have implemented XModem, YModem and Kermit protocols, but there's not been enough usage or interest to warrant "rock solid" or "well documented". Parallax has enough irons in the fire as it were and there's no money to justify the time and effort to produce a polished system. Have a look at the existing XModem code. I know I wrote a simple Kermit implementation long ago and posted it as part of one of my projects. If you want something more complex than this basic file transfer stuff, you'll probably have to do it yourself. Kermit, because of its block numbering and checksum use is probably closest to what you want.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-01-18 16:44
    There are many serial objects out there. I have settled on a design with two serial ports - one for programming and one for comms, as I find debugging is a lot easier that way. Tim Moore wrote a serial object with 4 ports. Pullmoll modified it to have two ports but buffers big enough for an xmodem packet. That is the one I use but hardly anyone else uses it. However, for practical purposes it is identical to Tim Moore's code. It is very similar to the standard serial driver, except that every time you do something, you have to specify which port. eg
        sio.string(pstring)
    
    becomes
        sio.str(0,pstring)                                 ' send to com port  0
    
    First, in the CON section
    CON
      _baudRateSpeed = 115200
      _receiverPin = 31
      _transmitterPin = 30
    
    Then in the Obj section
    OBJ
      sio     : "pcFullDuplexSerial2FC"   
    
    then in the Main program
      sio.AddPort(0, _receiverPin, _transmitterPin, -1, -1, 0, 0, _baudRateSpeed) ' adds a port
      sio.start ' starts the port
      sio.rxflush(0)  ' I like to flush the receiver on startup. Flush port 0
    
    Then to send a byte
          sio.tx(0,c)
    
    to send a string
        sio.str(0,pstring)                                 ' send to com port
    

    I use the following routine all the time. Check for any data, and then read it. If no data, go on to something else
            if sio.rxavail(0)
              result :=sio.rx(0) ' get the data
    
    eg as part of scanning both the keyboard and the com port for data
          result:=0
          repeat
            if key.gotkey <>0        ' scan both the local keyboard and the com port
              result:=key.getkey
            if sio.rxavail(0)
              result :=sio.rx(0)  
          until result <>0           ' until something comes in either port
    

    I'll attach the code. If you only need to use one port that is fine. If you want to use two ports you can even have them at different speeds
      sio.AddPort(1, _port2receiverPin, _port2transmitterPin, -1, -1, 0, 0, 9600)
    
  • idbruceidbruce Posts: 6,197
    edited 2011-01-18 17:11
    Dr_Acula

    Thanks for the pointers and code. I truly appreciate it.

    Mike

    I realize there are an infinite amount of points on a line segment. There will always be people that are willing to settle for minimum and there will always be people that strive for the maximum. However, from my own personal view, I see basic communication between two Propeller IC's as a high probability for many users. At the very least, I believe there should be some documention and an example that shows the minimal setup, the minimal requirements, and how to send and receive strings properly, send and receive integers properly. I am not asking you to do this, but what would it take for someone with your caliber of skills to do that? 1/2 an hour 1 hour max? And I don't know where this file transfer stuff came from, because I never mentioned it. I would be happy with a simple basic example to send strings. But if I have to read the Basic Stamp Manual to get an idea of whats going on. I will.

    But it isn't right.

    Bruce

    P.S. I am a grown man trying to build my business. I want my documentation.
  • Mike GreenMike Green Posts: 23,101
    edited 2011-01-18 17:49
    It takes much more time than you think to come up with comprehensive documentation, complete with tested examples. Talk to Andy Lindsay sometime about how long it's taken to produce each of the Propeller Education Kit tutorials. You did ask for "rock solid" and "well documented". If you're interested in something less, please define your experience level and say more about what sort of Prop to Prop communications you're looking for. If you're ok with "raw" serial I/O between the two Props, without error checking or retries built-in, say so. That's a whole different level of sophistication and is much easier to document and show examples for than something inherently more reliable. Still, it takes more work than you think.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-01-18 17:50
    Hi idbruce,

    I think one problem is that a lot of propeller things are cutting edge. Maybe there are few standards because it is just a free for all with many people contributing to coding. When I look at this I think that I don't want to invent yet another standard. That is why I sought out the documentation for xmodem and used that standard.

    RS232 has standards, and when you talk about handshaking, that could mean hardware, xon/xoff or none. Hardware RS232 handshaking is the old workhorse standard, but it uses up precious propeller pins. I suppose historically, once people started using modems then one had to find code solutions that did not have hardware handshaking.

    So if you want a serial standard, the one I like is "3 wire RS232". A D9 with pins 2 and 3 for data, and pin 5 for ground. And I like to use max232 chips even when my propeller chips are only 10cm apart, because the max232 can handle faults like shorts, Tx lines connected together, negative voltages and the chip won't get zapped if you send volts to it when it is not powered up.

    There is of course a valid argument saying that all the above can be replaced with a 1k resistor.

    So my standard (which isn't really all that original) for inter prop comms is D9 plugs/sockets, max232 chips using 3 wires (though I am lazy and generally use IDC connectors with 9 way ribbon cable) and a variety of baud rates, usually 1200, 9600, 38400 and 115200.

    As for data protocols, you can do whatever you want.

    You could send everything in lines of text, ie keep buffering till you get a Carriage Return ascii 13.

    You could decide to send everything as strings. Strings are zero terminated, so keep storing until you get an ascii zero. Then turn those strings to numbers with existing string function code.

    You could send data in packets. I've got some radio packet protocols that have a start character, number of bytes, data, checksum, stop character. Ascii 2 is "start of text" and ascii 3 is "end of text" so just look for a 2, start reading, get the number of characters, keep reading that number and the last character should be a 3.

    Or you could use the xmodem packet protocol, which is a fixed 131 bytes - start, complement, 128 bytes, checksum.

    For xmodem, ok, there is no documentation in the propeller manual, but xmodem is well documented on the internet so I got that documentation and wrote the code. And then found others had also written code, and had done ymodem and other standard protocols as well.

    I see above you don't need file transfer. Just strings. That ought to be pretty easy. Clear your string, set up a repeat loop and keep reading the serial port until you get a zero. Build the string using Kye's string handling routine that builds a string.

    You should be able to do that with the serial object and a string object. Attached is Kye's string object and you can see the first PUB is building a string one byte at a time.

    Actually, strings are not a bad way to send data, as you can then convert strings later into byte, binary, hex, integer, long, floating point (all included in the code attached). The protocol becomes very simple. Data is of any length (maybe a max of 80 bytes) and ends in a zero.
  • idbruceidbruce Posts: 6,197
    edited 2011-01-18 18:29
    Mike

    Okay, perhaps "rock solid" and "well documented" was pushing it over the top a little. However I am fully aware of the time it takes to provide comprehensive documentation. There is not a more stringent critic than the United States Patent and Trademark Office. I have written two patent applications, one is patented and the other is pending. They just don't settle for documents that are poorly written or ideas that are poorly conveyed.

    Pertaining to electronics, Spin programming, serial transmission, and serial reception, I would have to classify my skill level as a beginner. As a researcher, expert level.

    As far as my application, which it shouldn't apply in this case, because I was just talking about a general example so that all beginners could benefit from it, and considering mine is more specific. I simply need to send commands followed by numeric data. For instance:

    G1:21000
    G1:450766
    G5:34373
    F21:79564

    As you can see, something like this is no problem for a seasoned Spin professional, but for me, someone that has never done bi-directional serial communication, it's a puzzle.

    Bruce
  • Mike GreenMike Green Posts: 23,101
    edited 2011-01-18 18:58
    I would look at the Extended FullDuplexSerial object in the object exchange. This sits on top of FullDuplexSerial and adds some input functionality where it reads the contents of a line up to a carriage return into a string buffer. There are routines to convert sequences of digits into a number. These are written to use the carriage return as the delimiter, but can be easily modified to use ":" as the delimiter and you'd have two routines, one for the first value and one for the second. I'll show you some examples later, after I get home from work.
  • idbruceidbruce Posts: 6,197
    edited 2011-01-18 19:06
    Mike
    I'll show you some examples later, after I get home from work.

    Now that will make feel guilty. I am certain that you have had a hard day already. Go home and get some rest. I will study the Basic Stamp Manual to get the basic concepts (pun intended). Besides it is interesting reading about it.

    Bruce
  • Cluso99Cluso99 Posts: 18,069
    edited 2011-01-18 20:32
    Bruce: You said you are just trying to send out some data. For sending those string you just need to:

    fdx.str(string("G1:21000",13))

    Now that is just a string and I would expect you need to vary the data it sends out. The 13 is just a carriage return character.

    Now let's extend that a little...

    fdx.tx(char) ' to send out a variable character
    fdx.dec(num1) ' to send out a decimal number - you will need to check the PUB DEC command in fdx to see if it required a number of digits in the parameters IIRC it sends as many as reqd
    fdx.tx(":") ' send out a colon
    fdx.dec(num2) 'to send out the next decimal number
    fdx.tx(13) 'to send out a carriage return <cr>

    Input is more complex as string handling is not part of fdx for input. There are no doubt routines for building strings in the obex. You just need to feed a handler with the characters you read until you find a <cr> as a terminator. Be careful, sometimes 10 <lf> line feeds are used and sometimes a combination of both, depending on the device sending to you.
  • idbruceidbruce Posts: 6,197
    edited 2011-01-18 20:43
    Ray

    It doesn't seem that the output is that difficult, however as you said, input is more complex.

    Let me ask you this. Suppose I send fdx.str(string("G1:21000",13)), now on the other end, can I bust it up to be a (G1 string)(: delimiter)(21000 decimal)(13 End of TX)

    Bruce
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-01-18 21:09
    Yes you can do that. Your example is using : as the delimiter so you need to find that character. Basic has always been very good with strings. But Spin is flexible enough that you can write functions that replicate Basic.

    1) Define some space for a string - byte mystring[80]
    2) Read it into a string array using Kye's string code and Tim Moore's serial code. Exit when you get a 13, but store that as a 0 as strings use 0 as the end character.
    3) Find the : eg i:= str.instr(@mystring,":")
    4) Get the left part eg str.left(@mystring,@mystring2,i-1) ' left part is now in mystring2
    5) get the length eg j := str.len(@mystring)
    5) Get the right part eg str.mid(@mystring,@mystring3,i+1,j-i) ' start at i+1, length minus the position of : is the number of characters.
    6) if you wish, convert "21000" into a decimal value
    PUB decimalToInteger(characters) | sign
    '' ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    '' // Converts a decimal string into an integer number. Expects a string with only "+-0123456789" characters.
    '' //

    You may not be able to find a comms object to do all that, but it is certainly possible to build strings and then chop them up again.

    I have a generic subroutine in Basic that I use over and over to cut up strings.

    item1|item2|item3|mylongstring|item4

    You can use any delimiter character you like - I chose a | because at the time it wasn't being used for much, but it is quite a fundamental part of Spin (and C) so maybe a different character eg : or ~ or use a comma like Excel .csv files do.
    Sub CutUpString(l As String) ' VB6 version 
    ' separator is |
    'returns cutup() array does not alter string
        Dim linetocutup As String
        Dim leftpt As Integer
        Dim rightpt As Integer
        Dim counter As Integer
         linetocutup = l
         Erase Cutup
         linetocutup = linetocutup + "|"
         leftpt = 1
         rightpt = InStr(1, linetocutup, "|")
         counter = 1
         Do
           Cutup(counter) = Mid$(linetocutup, leftpt, rightpt - leftpt)
           leftpt = rightpt + 1
           rightpt = InStr(leftpt, linetocutup, "|")
           If rightpt = 0 Then Exit Do
           counter = counter + 1
        Loop
    End Sub
    

    And if you prefer C syntax, we can rewrite mid and instr etc so they are more like C.
  • JonnyMacJonnyMac Posts: 9,208
    edited 2011-01-18 21:41
    Now why in the world couldn't they do that in the Propeller Manual? Just unbelievable.

    In what part of the manual would those examples appear? Think about it. There is no built-in command for serial in Spin, it must be added with an object. The reason for SEROUT examples in the BASIC Stamp manual is that SEROUT is part of the core language.

    I'm surprised this is a challenge given your experience with C/C++. I'm not a C programmer but I refer to the K&R book a lot to learn and apply what I can to Spin. I whipped up the attached demo in about 30 minutes (I'm an actor so it can't be that hard <grin>) that is one possible solution to parsing the command character and numeric data from a stream. For the demo, I've embedded the strings into a DAT section; in practical application you would read characters into a suitably sized buffer.

    As I have said or implied several times: it's best to keep routines as atomic as possible so they can be re-used. That is to say that I think it would be a mistake to attach parsing routines to a serial object; just capture your stream into a buffer with a standard serial object and go from there. Even the parsing is built up of discrete elements so that they can be reused.
  • idbruceidbruce Posts: 6,197
    edited 2011-01-18 22:07
    Thank You So Much Jon!

    I truly appreciate the effort that you put into this. I know I am being thick headed here, but I still don't have a full grasp on it.
    just capture your stream into a buffer with a standard serial object and go from there.

    I am assuming that I would use something such as:
    PUB rx : rxbyte
    '' Receive byte (may wait for byte)
    '' returns $00..$FF
      repeat while (rxbyte := rxcheck) < 0
    

    to capture the information then add it to the forementioned buffer. After which I would use the parse function?????

    Bruce
  • idbruceidbruce Posts: 6,197
    edited 2011-01-18 22:20
    Jon

    That's pretty cool code. And what is K & R?

    Bruce
  • Cluso99Cluso99 Posts: 18,069
    edited 2011-01-18 22:22
    Jon: Yes, string handling would be better done in some routines. If there are none in the obex, then perhaps that's where some should be. Then they can be used for generalised things such as TV, VGA and LCD displays as well.

    I think what is frustrating Bruce here is that he is not sure how to do it because C handles it automatically. We think it is too simple because we know how to do it, and make the assumption he should too.

    Reminds me of a tale... I'll tell it here... I went to wire my boat (a 35ft sailing cat - see my icon). The first electrical surveyor told me how he would design it for me (I am in electronics, so the alternators used in vessels like mine are quite foreign to me). I thought he was expensive so went to another. He was so cheap so I asked him about what to do. I asked for a schematic and he drew one on a scrap of paper. I went away very uncertain about what to do. Like, he was 1/10th of the other guy and I was doing the work! So I rang the second guy up again and explained I was uneasy as he said it was so simple. Anyway, I went to his place and he just explained it simply and I realised that it was in fact just that simple! Couldn't see the forest for the trees!

    Anyway, I digress...

    What is needed is perhaps another section in the obex just for code snippets such as these. I know others mentioned this quite recently. They are not necessarily full-blown objects, just useful routines to do specific things.
  • JonnyMacJonnyMac Posts: 9,208
    edited 2011-01-18 22:30
    I am assuming that I would use something such as:

    You gave little information on your stream. Is the end of each command terminated by a known character -- a CR, for example? If so, you might do something like this (pulling this from my backside, so be careful):
    pub fillbuf(bufpntr, size, tchar) | c
    
      bytefill(bufpntr, 0, size)                                    ' clear with zeroes
      repeat size
        c := term.rx                                                ' no timeout
        ' c := term.rxtime(250)                                     ' use timeout
        if (c == tchar) or (c == -1)                                ' if terminator
          quit                                                      '  exit
        else
          byte[bufpntr++] := c                                      ' else add to buffer
    

    This starts by filling your buffer (an array of bytes), then pulls characters from your serial buffer until it hits a the terminating character (tchar) or there is a timeout (if rxtime() used). Now you can use the routines above. I've attached an updated demo that lets you enter command strings in the PST terminal window.

    And what is K & R?

    http://en.wikipedia.org/wiki/C_%28programming_language%29
    Yes, string handling would be better done in some routines. If there are none in the obex, then perhaps that's where some should be.

    There probably are, but I never look. For me, there is great fun in the learning by doing, and ducking into ObEx first robs me of that opportunity.
  • idbruceidbruce Posts: 6,197
    edited 2011-01-18 22:51
    Jon

    Ahhhh see. I have only been programming for a little over 10 years.

    My C++ references include:
    • Programming Windows With MFC - Jeff Prosise
    • Programming Windows - Charles Petzold
    • Visual C++ Windows Shell Programming - Dino Esposito
    • Programming Visual C++ - Microsoft
    • Visual C++ 6.0 - Microsoft
    • Writing Secure Code - Microsoft
    • MFC Programming With With Visual C++ 6 Unleashed - SAMS
    • Learn Visual C++ Now - Microsoft
    Never once have I ever heard of K&R until you mentioned it.

    You must be another one of those oooolllldddd men here in the forum. :)

    Bruce
  • JonnyMacJonnyMac Posts: 9,208
    edited 2011-01-18 22:56
    If 48 is old then, yes, I'm old. Thankfully, nobody thinks I look that old (that is me in the avatar photo, taken in October, 2010) which lets me audition for more parts than other guys my age.

    I attached a new demo above that shows how to fill a buffer -- this one uses the keyboard, but the stream could be anything as I'm using the FDS object.
  • idbruceidbruce Posts: 6,197
    edited 2011-01-18 23:03
    Jon

    Nah you don't look 48, heck I am 45, and look older than you, my excuse, beer and cigarettes :)
    Thankfully, nobody thinks I look that old which lets me audition for more parts than other guys my age.

    That's to cool Jon. So have you played in any major motion pictures that I can check out?

    Hey Jon, just want you to know that when I say thank you, I really mean it. Thank you Jon.

    Bruce
  • JonnyMacJonnyMac Posts: 9,208
    edited 2011-01-18 23:17
    That's to cool Jon. So have you played in any major motion pictures that I can check out?

    It wasn't a major movie but I did beat 200 actors to work (for a day) with major Hollywood stars, Tom Wilkinson and Frances Fisher
    -- The Night of The White Pants

    ...and it got me my SAG card. This is a second career for me so I'm really just getting started.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-01-18 23:20
    Cool, you are on the cast list on the main page http://www.imdb.com/title/tt0468521/
  • idbruceidbruce Posts: 6,197
    edited 2011-01-18 23:20
    Jon

    The Night of The White Pants. I'll check it out. SAG I know what that is. :)

    Bruce
  • idbruceidbruce Posts: 6,197
    edited 2011-01-18 23:23
    Impressive - A fellow patent holder.Not just one 3
  • idbruceidbruce Posts: 6,197
    edited 2011-01-18 23:32
    Hey Jon

    This website says your a holder of three patents. Being the curious guy I tried to research them. All I found was medical stuff. If you feel like sharing, tell me more. Always interested in fellow inventors.

    Bruce
  • JonnyMacJonnyMac Posts: 9,208
    edited 2011-01-19 00:34
    #5,956,248 and #6,459,959 are both for the Toro ECx sprinkler controller; I was the primary inventor with my friend and consultant, Peter Tam, also on the patents. That was a very big part of my career at Toro -- at one time Toro was selling 250K units per month.

    # 6,076,994 is a flexible lake inlet for a water pumping system (for Flowtronex) -- I was part of a team and with my normally non-mechanical view of the world I helped solve a couple mechanical problems, hence I was included on the patent.
  • Graham StablerGraham Stabler Posts: 2,510
    edited 2011-01-19 03:38
    Cluso99 wrote: »
    What is needed is perhaps another section in the obex just for code snippets such as these. I know others mentioned this quite recently. They are not necessarily full-blown objects, just useful routines to do specific things.

    I could not agree more:

    http://forums.parallax.com/showthread.php?105791-Code-snippet-repository

    Graham

    p.s. Wow the search function for the forum really works!
Sign In or Register to comment.