XBEE or Peer Serial IO Control Protocol Example

Hi all,

I’ve just finished writing a 2-Byte / 4-Byte Serial IO Control Protocol. Been testing and debugging on Arduino Mega. The plan is to implement this into an XBEE AT Serial Control project although it also works with just 2-Serially connected Arduiono’s. I’d highly suggest using the Mega ( Due to multiple Ports allowing Debug Messages ).

Anyways, wanted to share it in case someone else also was looking to do the same thing. It is fresh and may still have bugs - please mention them if you find them.

Below is just a quick code snippet of the attached code.

(UPDATE) I’ve uploaded this to https://github.com/tgit23/PeerIOSerialControl as a library

/**************************************************************************************************
 
  Arduino Sketch for Peer I/O Control of Arduino boards through Serial.
  - This sketch uses a Byte level protocol; thus it is NOT for Serial Monitor text control
  
  Usage:
  - Connect Serial communications between multiple Arduino's
  - Set the 'ArduinoID' variable (Line #63) below to a unique ID for each Arduino
  - Upload this same sketch to every Arduino connected
  
  [[[ Serial Control Communication Protocol ]]]

  Byte  |   7   |   6   |   5   |   4   |   3   |   2   |   1   |   0   | - Bit
    0   |       |  D/A  |  R/W  |  S/R  |  ID3  |  ID2  |  ID1  |  ID0  | - ArduinoID
    1   |       |  H/L  | PIN5  | PIN4  | PIN3  | PIN2  | PIN1  | PIN0  | - Pin Number (6D/7A-bits)
    2   |       |  AV6  |  AV5  |  AV4  |  AV3  |  AV2  |  AV1  |  AV0  | - Analog Value (0-6)
    3   |  1    | AV13  | AV12  | AV11  | AV10  |  AV9  |  AV8  |  AV7  | - Analog Value (7-13)
    
  Using (4) Bytes to represent all possible scenario's as follows:
    - D/A         = Digital or Analog Flag
    - R/W         = Read or Write Flag
    - H/L         = High or Low Flag          ( Only used on Digital; set by D/A Flag )
    - ID(4-bits)  = Arduino Board Identifier  ( Range 0-15 )
    - S/R         = Send or Reply Flag
    - PIN(6-bits) = Arduino Pin Number        ( Range 0-63 Digital or 0-127 Analog  )
    - AV(14-bits) = Analog Value              ( Range 0-16,382 )

  - End of packet flag 'END_BIT' is bit-7 on ANYONE of the 4-bytes.
    Byte data is always 7-bit unless the END_BIT flags the end of the packet

  - When not using Analog Values the last two bytes are omitted ( 2-byte communications )
    
*****************************************************************************************************/
#define ID_MASK 0x0F    // Bytes[0] [0000 1111] ArduinoID ( 0-15 )
#define REPLY_BIT 4     // Bytes[0] [0001 0000] Reply-1, Send-0
#define RW_BIT 5        // Bytes[0] [0010 0000] Read-1, Write-0
#define DA_BIT 6        // Bytes[0] [0100 0000] Digital-1, Analog-0
#define DPIN_MASK 0x3F  // Bytes[1] [0011 1111] Digital Pins ( 0 - 63 )
#define APIN_MASK 0x7F  // Bytes[1] [0111 1111] Analog Pins ( 0 - 127 )
#define HL_BIT 6        // Bytes[1] [0100 0000] High-1, Low-0
#define END_BIT 7       // Bytes[?} [1000 0000] Any set 8th bit flags END-OF-PACKET
#define READ 1
#define WRITE 0
#define DIGITAL 1
#define ANALOG 0

//-----------------------------------------------------------------------------------------------------
// -----------------------[    SETTINGS    ]-----------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
#define DEBUG 1         // Set to 1 for Debug messages ( For Multi-Serial Port Arduinos ONLY )
#if DEBUG>0
    #define DBL(x) Serial.println x
    #define DB(x) Serial.print x
    #define DBC Serial.print(",")
#else
  #define DBL(x)
  #define DB(x)
  #define DBC
#endif

int ArduinoID = 12; // Range = 0 to 15

//-----------------------------------------------------------------------------------------------------
int Bytes[4] = { 0,0,0,0 };
struct uBuffer {
  byte CBytes[4];
  int CReply = -1;
} Buff[10];
int BI = 0;                         // Command Buffer Index
int idx = 0;                        // Byte Counter

//-----------------------------------------------------------------------------------------------------
// SendBytes()
//-----------------------------------------------------------------------------------------------------
void SendBytes() {
  DB(("SendBytes( "));
  Serial1.write(Bytes[0]);
  Serial1.write(Bytes[1]);
  if ( Bytes[2] != 0 ) Serial1.write(Bytes[2]);
  if ( Bytes[3] != 0 ) Serial1.write(Bytes[3]);
  DB((Bytes[0],HEX));DBC;DB((Bytes[1],HEX));DBC;DB((Bytes[2],HEX));DBC;DB((Bytes[3],HEX));DBL((" )"));
  for(int i=0;i<4;i++) Buff[BI].CBytes[i]=Bytes[i];
}


//-----------------------------------------------------------------------------------------------------
// serialEvent() - Event Driven Functions
//-----------------------------------------------------------------------------------------------------
void serialEvent() {
  if (Serial.available()) {
    char rbyte = Serial.read();
    if ( rbyte == 'a' ) {
      SendCommand(13,DIGITAL,READ,3);
    }
    if ( rbyte == 's' ) {
      SendCommand(13,DIGITAL,WRITE,3,HIGH);
    }
  }
}

void serialEvent1() {
  // Receive Bytes
  if (Serial1.available()) {
    Bytes[idx] = Serial1.read();
    if ( Bytes[idx] != -1 ) {
      //DBL((Bytes[idx],HEX));
      if ( bitRead(Bytes[idx],END_BIT) ) {
        DBL(("-----------------------------------------------------------"));
        DB(("Packet Received @ Size: "));DBL((idx+1));
        idx = 0;
        ProcessPacket();
      } else {
        idx++;
      }
    }
  }
}


//-----------------------------------------------------------------------------------------------------
// setup() & loop()
//-----------------------------------------------------------------------------------------------------
void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);
}

void loop () {

  if (Buff[BI].CReply != -1) {
    DB(("Reply Received : "));DBL((Buff[BI].CReply));
    Buff[BI].CReply = -1;
  }
}

SerialControlPlus.ino (10.1 KB)

  • PIN(6-bits) = Arduino Pin Number ( Range 0-63 Digital or 0-127 Analog )

Useful for all those Arduinos that have 127 analog pins. Which models are they?

But, I’m curious how you got 127 discrete values in 6 bits. And, I’m curious how you distinguish, in 6 bits, whether the pin is analog or digital.

Byte-0 Sets Digital/Analog and Allows 7-bit values on Byte-1 for Analog only since it won't need the H/L flag.

The extra pins as you mentioned for analog are IO useless; but I implemented them for perhaps internal variable access. Say, Pin(120) on Arduino#5 actually points to variable X in the program on Arduino #5. The ability was there so I added it :slight_smile: