Shop OBEX P1 Docs P2 Docs Learn Events
Prop to Prop protocol — Parallax Forums

Prop to Prop protocol

lmclarenlmclaren Posts: 104
edited 2011-09-02 10:09 in Propeller 1
Hi,
Prop to Prop communications again.

Has anyone done / published a protocol to use between 2 propellers talking to each other?

I have in mind a basic master slave relationship where the master polls the slave and the slave just responds.

I am not referring to the physical communications method, more the data format / data checking.

Only 2 props involved.

Lee

Comments

  • TubularTubular Posts: 4,717
    edited 2011-08-31 23:27
    I know there was some work started by Parallax to properly document one or more options
    http://forums.parallax.com/showthread.php?131610-AppNote-Content-Input-Request-Propeller-to-Propeller-Communication
  • lmclarenlmclaren Posts: 104
    edited 2011-08-31 23:50
    Thanks Tubular,

    I have seen that one before, seems to have lost momentum.
  • TubularTubular Posts: 4,717
    edited 2011-09-01 00:06
    I wouldn't assume anything but perhaps check in with Parallax Semiconductor to see where its at. These things take a while to document, revise, publish.

    What kind of speed are you looking for?

    Sounds like you want something like Modbus, but there are probably simpler alternatives. Will your master prop be loading the program into the slave prop, or just exchanging data after booting from separate eeproms?
  • lmclarenlmclaren Posts: 104
    edited 2011-09-01 01:56
    To answer the question, I will explain why.

    I am building a coffee roaster, not just any roaster, this one will have a full gui.

    Unfortunately, by the time I add the gui I want and all the I/O I am out of cogs.

    So the basic need is to have the gui and sd card interface on one prop and all the I/O on the other.

    No need to be able to load the other prop from the master.

    What I am thinking of is the following:

    The master (gui) will poll the slave and send various commands,

    Eg Send Datablock 1

    The slave will reply with Datablock 1, it will be a fixed length so I dont have to worry about delimiters etc. Say 32 bytes.

    Datablock 1 will have all the fast updating values I want to show on a gui etc as well as some size bytes for other datablocks.

    If the master sees that there is a non zero for datablock 2 it can then request it and it know how much to ask for /expect.
    Datablock 2 would have messages to be logged or displayed on the gui.

    One other need would be for the master to load a program from SD and send it to the slave. So one command might be to the slave, say Receive Datablock 3 and how many bytes.

    I want to do the transfers as byte values instead of converting to ascii so I expect I need to spec sizes etc.

    Suggestions anyone?

    Lee
  • Clock LoopClock Loop Posts: 2,069
    edited 2011-09-01 04:35
    Two projects I did involve prop to prop communications
    1. Black Box sequencer has 1 master and 3 slaves
    http://forums.parallax.com/showthread.php?115258-TheBlackBox-Release-v2.0-Propeller-HSS-FX-Sequencer-with-Digital-Audio-SPDIF



    2. 55 propeller communication scheme with 1 master and 54 slaves.
    http://forums.parallax.com/showthread.php?127983-55-Parallax-Propeller-s-Parallells-Processing-of-Permanent-Perturbations
  • pjvpjv Posts: 1,903
    edited 2011-09-01 06:50
    Hello Lee;

    Have you considered using a "Multi Threading Scheduler" to let a single cog run a number (maybe a half dozen) of small, independent, low level assembler routines, all supervised by a Spin program?

    My bet is that you have plenty of room in a single Prop to do all you want, and can eliminate the rather messy (altough pleasantly challenging) two Prop scenario.

    One caviat however, is that you must be able to program in assembler, otherwise you are out of luck.

    If that all fits, I can give you some pointers, and perhaps the Scheduler Kernel.

    Cheers,

    Peter (pjv)
  • lmclarenlmclaren Posts: 104
    edited 2011-09-01 15:41
    Hi PJV,

    Some of the things I do are already multi threaded but not all, a quick overview of what I have:

    Using a cog for the engine
    2 current MAX6675 via SPI (maybe 1 or 2 more later)
    1 current A/D via SPI

    Using a cog for the engine
    2 channel mains A/C phase dimmer (my own assembly)
    This is time critical, I am controlling 40A loads and don't want gitches

    Using a cog for the engine
    Full Duplex Serial

    Using 4 cogs and a lot of memory
    Full colour video display with mouse and kb

    I still want to add a SD card to load programs and store logs so the SD card must stay mounted the whole time.

    I am using the first cog to answer and log over serial and to schedule the reading of the SPI devices and update display.

    I still need to add a IR Thermometer, I am unsure if I will be able to reuse the SPI engine.
    I still need to add the PID control, I expect I can use the main cog again.

    Is Multi Threading Scheduler avail on the obex? I am interested in looking at it.

    Thanks for the suggestion clock loop.

    I would like the use the gui interface off the object exchange, this has quite a large memory foot print as well.

    I expect someone with more skill than me (nearly everyone) could make it fit, this is my first exposure to propeller.

    As I am playing with high powered heaters and blowers that will self destruct if fans stop while heat is on etc, I want to code in a large amount of SOE checking to be on the safe side.

    Always open to suggestions!
  • tonyp12tonyp12 Posts: 1,951
    edited 2011-09-01 16:07
    4 cogs for the vga with mouse/keyboard I can understand.

    But all the SPI peripheral should be able to run from one cog.
    Does the SPI driver in the Obex support up to 4 or more devices by Chip_Select?

    Should not be to hard to modifiy it to do so.
    What spi driver does the C3 use as it have chip_select?
  • pjvpjv Posts: 1,903
    edited 2011-09-01 16:09
    Hi Lee;

    Capacity of the Scheduler is very much a function of the rate at which the various threads need to be serviced. I suspet that if you don't push things too hard, then the codes running in your first three cogs listed could readily be handled by a single cog.

    Can't say too much about the 4 videos, but their mouse an keyboard should also readily be incorporated with other things such as the IR thermometer into a second cog.

    The whole SD card thing is still a mystery to me so can't really comment on that.I am working with another chap on that issue though, and anticipate some positive results.

    The PID in the main cog as you suggest.

    The Kernel is not available in the OBEX due to the MIT license issue, and I'm trying to find a resolution to that.

    But dont't forget, to get the desired performance, assembly IS required. You did not indicate if that was an issue for you.

    Cheers,

    Peter (pjv)
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-09-01 18:03
    The whole SD card thing is still a mystery to me so can't really comment on that.I am working with another chap on that issue though, and anticipate some positive results.

    Kye wrote a really good SD driver - he made the front end as simple as possible - openfile(),readbytes(n), closefile(). And on the hardware side, it is 4 propeller pins to the SD card with some 10k pullup resistors. And a 0.1uF bypass and a 22uF tant close to the sd card on the supply pins.

    re fast interprop comms, I'm looking at this as well. Initially a main prop and a graphics prop, but possible a third I/O prop.

    At the moment I'm using slow serial (38400 baud) with the standard serial objects. But I know the prop can go faster than that!

    There is a 1 pin common bus protocol - pull the bus high with a 10k resistor and every prop listens to the bus and if one is a master, there would be no data clashes. I've used this with about 20 picaxe chips on one bus and it is a simple system.

    I wonder what you gain by going to a 2 wire common bus? Both bus lines pulled up with 10k resistors, and use an SPI like protocol where one line is clock and one is data. Because it is synchronised, can you get this down to just a few pasm instructions per loop. Clock goes high for 3 pasm instructions. On the receive side, detect a high, read the value, wait for next high. Can you go faster than this? I seem to recall 12Mbs as a figure someone talked about a while back.
  • lmclarenlmclaren Posts: 104
    edited 2011-09-01 18:42
    Hi Dr_Acula

    Re 2 wires, what I am trying to achieve is the ability of the master to interrupt / restart coms if needed.

    Eg, Master requests Block1, if for some reason the data is corrupted or short or long then the master can just send a request for block1 again, as soon as the slave sees the start bit, it stops what it is doing, resets the state of the protocol and answers the new question.

    I am intending to do something like the following:

    Master Requests Block 1 by sending a start char, command, size and waits size x bytetime for a response to complete, If at any time it there is an error, the Master just send the next command.

    That way, even if coms was interrupted or garbled, it should still work, just slower if it can eventually get a message through.

    I will track errors to warn of potential problems.

    Maybe I am over engineering it but I want it to be robust.

    I will keep all the PID and Output / Input for the heat and air on one prop, I will also have to wire in a shutdown button direct to the slave prop so that I can fail safe incase the gui is lost.

    I am also writing a control language for the roaster, I was going to put the interpreter on the master (gui) prop but transfer the interpreted instructions to the slave, that way the gui can show the English version while the slave can run without the master.

    It would be easy peasy with a few more cogs and bit more memory. I am sure someone more competent could do it in one prop.

    To answer PJV's question, I am neither comfortable with SPIN or ASSY but are happy to give either a go, I wrote my own phase dimmer for the prop in ASSY the first week, still have a huge amount to learn.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-09-01 20:01
    Re 2 wires, what I am trying to achieve is the ability of the master to interrupt / restart coms if needed.

    Eg, Master requests Block1, if for some reason the data is corrupted or short or long then the master can just send a request for block1 again, as soon as the slave sees the start bit, it stops what it is doing, resets the state of the protocol and answers the new question.

    Yes that makes sense.

    One protocol could be to have a checksum, simply add all the bytes together and then logical & with 255. Xmodem uses this protocol. So a two byte message with values of 200 and 150 will give a checksum of 94. The checksum is pretty easy to do in pasm - just add the bytes as they come in, and then "and myvalue,#256" and then compare with the checksum at the end of the packet. If the checksum is correct, send an ACK (ascii value 6 http://www.asciitable.com/) and if not correct, send a NAK (ascii value 21).

    I wrote some code that had a simple packet protocol.
    Byte 1 = ascii 2 = start of text
    Byte 2 = n = number of bytes in the packet
    Byte 3 and up are the data bytes
    second to last byte = checksum
    last byte = ascii 3 = end of text

    You could also add a 'destination' byte in there as well if the packets are going to several different propellers.
  • lmclarenlmclaren Posts: 104
    edited 2011-09-01 20:24
    I like the idea of a checksum, especially if I am sending commands to turn on heaters or blowers, I was going to research that, you have saved me some time.

    I wont be able to send an end of text byte as I will be sending blocks of raw data, eg non ascii values. There would always be a chance of sending the end value by mistake.

    That is why I as going to tell the slave how many bytes to send, that way the master knows when to stop receiving, no need for end of string.

    Still use the checksum idea though.

    Good thing about my idea, if I get an error, I just need to ignore what I received and ask again. No need for Nak or Ack.

    Destination could form part of the first byte after the start, I dont think I will need more than 16 commands so would leave the option to address 16 (or 15 unicast and 1 multicast). That way the slave can ignore after the first byte if it is not its.

    Lee
  • pjvpjv Posts: 1,903
    edited 2011-09-01 20:39
    Hi Lee;

    Seems to me you are leaning toward multiple Props rather than multiple threads (which I think is WAY simpler), so I'll just sit in the background, and watch. Holler if you need a hand!

    Cheers

    Peter (pjv)
  • pjvpjv Posts: 1,903
    edited 2011-09-01 20:46
    Dr_Acula;

    I have yet to explore the SD issue, but plan to in the next week or so. Kye does indeed seem to work some miracles, and hopefully I can learn from what he is providing.

    It will be VERY interesting for me to see how the concepts might integrate with my Scheduler.

    Thanks for reccommending!

    Cheers,

    Peter (pjv)
  • lmclarenlmclaren Posts: 104
    edited 2011-09-01 21:51
    Hi PJV,

    Not so much leaning towards but unable to compare as I have not seen examples of multiple threads (yet?), still flexible with the solution but as mentioned before, I am also hitting memory limits.

    If you can point me to some examples, I would love to look into it. I still may need to do both anyway.

    I have done multi threading on PIC's in the distant past using interrupts, I would like to see examples for the Prop.

    best regards

    Lee
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-09-01 23:31
    Thinking aloud here, in pasm you have the wrlong and rdlong instructions that move data from a cog to and from a hub.

    So - think of a memory map for two propellers - prop 1 is 0 to 31k and prop 2 is 32k to 63k. Imagine a subroutine (in pasm) where you can do a wrlong to a hub location in another propeller

    address = 36000
    wrlong(address,data)

    and the function/subroutine wrlong then does several things. It checks the address to see if it is for another prop (which it always would be because if you were doing a local hub write you would use wrlong instead).

    Then if this is the master prop, it puts together some bytes/longs for a message and sends that out the 1 or 2 line comms port.
    If it is a slave prop, it might wait for the master to poll around asking 'do you have any messages' and then send them to the destination.

    The master prop polls all the slave props in turn, does all the reads, then all the writes.

    There would need to be a buffer so you could queue up some data until polled again.

    There could also be postboxes in hub ram for other cogs. Put the data and the destination address and it will get cleared by the mailbox cog.

    Hard to write, but simple to use, and the concept of stacking hub ram addresses one above the other is extendable to any number of props.

    Not the fastest solution, but you could effectively parallel up propeller chips. Devote one cog to interprop comms, and so you could have a two prop, 64k, 14 cog solution.

    Maybe with mailboxes, use a small buffer eg 16 bytes, with a 'head' and 'tail' counter like the serial objects use.

    Has this been done already?
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-09-02 00:12
    I frequently use a communication protocol similar to what Dr_Acula suggested.

    I found I was frequently moving incoming data into a temporary buffer as the program watched for an end of message character.

    After increasing the rx buffer of Tim Moore's four-port serial object, I realized I could keep the entire message in the rx buffer until an end of message character was received. Post #9 of this thread has the modified driver attached.

    I've found having the serial driver watching for the end of the message has made my programs much easier to manage.
    Dr_Acula wrote: »
    just add the bytes as they come in, and then "and myvalue,#256" and then compare with the checksum at the end of the packet.

    @Dr_Acula,

    #256 is a typo, isn't it? Don't you want to use #255 (or in hex $FF)?

    Duane
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-09-02 01:13
    D'oh, yes of course your are correct! I mean #255. <goes and hides under a rock>

    @Duane, thanks for that code posting - very helpful :)
  • pjvpjv Posts: 1,903
    edited 2011-09-02 07:09
    Hi Lee;

    There is still the question of assembler. If you are not proficient at that then trying to squeeze all your needs into a single prop will be difficult, if indeed it is at all possible.

    As for pointing you to examples, there are not many out there as my concept seems not to be favored for main stream use, at least not yet. I have a few posts on the subject sprinkled thoughout, so not so easy to find. There was a contest entry a couple of years ago that published the concept. You can find that on the Parallax site.

    But rather than look at examples which are not terribly meaningful without being proficient at assembler, and having a solid understanding of my Scheduler, why do you not post the speed or frequency as well as resolution of the various things you need to run. Again, do not over-spec your requirements..... asking for the moon will complicate things unnecessarily, and may make your project unpracticable.

    Cheers,

    Peter (pjv)
  • prof_brainoprof_braino Posts: 4,313
    edited 2011-09-02 10:09
    do not over-spec your requirements..... asking for the moon will complicate things unnecessarily, and may make your project unpracticable.

    Be aware there is a "recommended" process for requirements (translating request to requirements to code)
    A. Highest level request (coffee roaster)
    B. High level functions (roast coffee at x degrees C for x seconds, etc)
    C. Functional specification to do the things in B (monitor temp and control heating element)
    D. Systems for provide functions in C (control circuit and user interface)
    E. Software functions to implement the systems in D (drivers and app)
    F. code to implement the functions in E

    So the issue in not exactly "over specifying" your requirements, things to be avoided are
    1) to impose restrictions too early (don't say "code it this way" until you get to the coding step)
    2) for a given function, don't start a later step before an earlier step is complete. You should FINISH E for any given function before you start coding. Otherwise a change in A-E could cause a change later and mess you up.
    3) "function creep"; adding superfluous functions that don't directly advance to the goal.
Sign In or Register to comment.