A skeleton for a ring protocol

A simple ring protocol

Do a ring between your Arduinos, teensys, esp32 or whatever serial devices you have

  • Information travels onoy in one direction

  • what about latency ? max min

  • what about ID of packages so they can be removed

  • direct and multi or broadcast


   (RX)arduino1(TX) -----> (RX)arduino2(TX)--(RX)arduino2(TX)--
    ^                                                         |
    |                                                         \/
    |----------------------------------------------------------

MY VERY FIRST TRIAL

Breaks if you loose chars



// frame

#define STARTDELIM '('
#define STOPDELIM ')'

#define FRAMELGT 10

//  '(' char data 0 1 2 3 4 5 6 7 8 9 ')'
// data can be '0'-'9' or '+' to '}' (ascii 0x2a to 0x7D)
// if data byte == '#' there is no update

/*
           2 3 4 5 6 7
 -------------
 0:   0 @ P ` p
 1:   1 A Q a q
 2:   2 B R b r
 3:   3 C S c s
 4:   4 D T d t
 5:   5 E U e u
 6:   6 F V f v
 7:   7 G W g w
 8:   8 H X h x
 9:   9 I Y i y
 A: * : J Z j z
 B: + ; K [ k {
 C: , < L \ l |
 D: - = M ] m }
 E: . > N ^ n
 F: / ? O _ o
 */

char data[FRAMELGT],newData[FRAMELGT], rcvData[FRAMELGT];

int frameSnd(char *frameData, int lgt)
{
  Serial.write(STARTDELIM);

  while (lgt) {
    Serial.write( *(frameData));
    frameData++;
    lgt--;
  }
  Serial.write(STOPDELIM);
}

int frameRcv(char *frame,int lgt)
{
  int c;

  // skip until STARTDELIM
  do {
    c = Serial.read();
  }
  while (c !=STARTDELIM);

  do {
    c = Serial.read();
    if (c != -1)
    {
      *(frame) = (char)c;
      lgt --;
      frame++;
      if (0 >= lgt )
        break;  // Just to be sure
      // could do a return (-1); indicating err
    }
  }
  while (c != STOPDELIM);

  return 0; // ok
}

void updateFrame(char data[], char rcv[])
{
  int i;
  for (i=0 ; i < FRAMELGT; i++) {
    if (rcv[i] != '#')
      data[i] = rcv[i];
  }
}

void initData(char ar[] ,char val)
{
  int i;
  for (i=0; i < FRAMELGT; i++)
    ar[i] = val;
}


void dmpFrame(char d[], int l)
{
  int i;
  for (i=0; i < l ; i++) {
    Serial.write(d[i]);
  }
  Serial.println("zz");
}

void setup()
{
  Serial.begin(9600);
  pinMode(13,OUTPUT);
  initData(data,'0');
}
void loop()
{
  static int i=0,j=0;

  initData(newData,'#'); // mark all as no new value
  newData[i] = (char)j + '0';
  i++;
  if (FRAMELGT <= i)
    i = 0;
  j++;
  if (FRAMELGT-3 <=j)
    j = 0;
  frameSnd(newData,FRAMELGT);
  Serial.println(">>>");

  frameRcv(rcvData,FRAMELGT);

  dmpFrame(data,FRAMELGT); // old
  updateFrame(data,rcvData);
  dmpFrame(data,FRAMELGT);  // new

   delay(500);
}






So …

Design a simple ring protocol

  1. ascii information only in

  2. simple fixed format including start and stop characters:

    1. s: start

    2. S: stop

  3. dest machine

    1. 1,2,3,4 up to 9 (maybe 0 coul dbe broadcast

    2. source mach (me) 1,2,3,4,5

  4. Two field each consists of RWP

    1. R: read

    2. W: write:

    3. P: Passive (not in use but we do send all 4 vars every time)

    4. and 6 digits +/- 12345

  • Think about a checksum if needed.

  • Think about how to resynchronize (hint read until s)

  • How do we initiate the travelling package around the ring ?

    • one master ?

  • Why shall we send data in visual text mode ?

  • What if the protocol breaks down ?

  • What about capacity ?

    • can more than one telegram at a time be travellling

    • how does it scale ?

So in the end you shall end up with a set of interface functions like

  • initFB

  • txFB

  • rxFB

  • statusFB

See also http://en.wikipedia.org/wiki/High-Level_Data_Link_Control how to do it in real life

I will strongly suggest to do it a little bit more simple than HDLC …