Increment "MessageIdentifier" and Serial.write

Good Day All,

I am facing a challenge in my early days, I am attempting to keep track of a variable (Not sure what data type to declare it as) I need to send on a serial 485 communication bus to a slave device. I need to increment a message identifier that starts at 0h and rolls over at FFFFh.

The Master needs to transmit this message <010100000A, the message is broken into these sections,

< - Message Header Identifying the command is sent from the master to a slave

0101h - 4char indicating the address on the bus, first 01 is the master address and next 01 is the slave address.

0000h - is the message identifier that will be incremented when a slave answers back the masters message it will send the same identifier only then will the master increment the identifier.

0A - this is the command of the master to the slave


The slave will answer the message with this message >0101000006

The Slave needs to transmit this message >0101000006 the message is broken into these sections,

  • Indicating a slave is answering to the master

0101h - 4char indicating the address on the bus, first 01 is the master address and next 01 is the slave address

0000h the message identifier of the message being answered

06h -The ACK that the message was executed

Should the master not receive a answer from the slave it will resend the same transaction until it receives a ACK, this is the code I have wrote but the results does work as I need it.

#include <TimerOne.h>
#define Tx485 2

char masterSOH = '>';
char slaveSOH = '<';
char masterAddress[] = "01";
char slaveAddress[] = "01";
unsigned int MessageIdentifier = 0X00; 
unsigned int MessageIdentifierRollober = 0xFFFF; 
int IncPoll;


int CalcIdentifier(){
    MessageIdentifier++;    
    if (MessageIdentifier == 0xFFFF)
      MessageIdentifier = 0;
  Serial.println(MessageIdentifier,HEX);
  return(MessageIdentifier);
}

void Poll(){
 digitalWrite(Tx485,HIGH);
 digitalWrite(3,HIGH);
 _delay_ms(5); 
 Serial1.write(masterSOH);
 Serial1.write(masterAddress);
 Serial1.write(slaveAddress);
 Serial1.write(MessageIdentifier);
 Serial1.write(0x0A); //Command
 _delay_ms(1);
 digitalWrite(Tx485,LOW);
 digitalWrite(3,LOW);
 _delay_ms(2);

}

void TimerTick(){
  CalcIdentifier();
  Poll();
}



void setup() {
  pinMode(Tx485,OUTPUT);
  pinMode(3,OUTPUT);
  digitalWrite(Tx485,LOW);
  digitalWrite(3,LOW);
  Serial.begin(38400);
  Serial1.begin(38400);
  Timer1.initialize(1000000);
  Timer1.attachInterrupt(TimerTick);
  
  // put your setup code here, to run once:
}





void loop() {


  // put your main code here, to run repeatedly:
}

The result of the Serial.write(MessageIdentifier); is, What I expect is:

1 0001
2 0002
3 0003
4
5
6
7
8
9
A
B
C… 000C

Please advise how I can achieve this,

my routine for sending data using a max485 chip. I use flush() to determine when the tx buffer is empty and the TX enable pin can be disabled

void
out (
    byte  vec [],
    int   nByte )
{
    int  n;

    digitalWrite (txEnPin, HIGH);
    delay (1);

    for (n = 0; n < nByte; n++)
    {
        cabSerial->write (vec [n]);

    }

    cabSerial->flush ();
    digitalWrite (txEnPin, LOW);
}

not sure what pin3 is. I put an LED/resistor on the TX enable pin

not sure why you’re sending ascii characters for addresses instead of a single byte. i would think a single byte is more than large enough to represent the number of endpoints on your bus.

since your using a master/slave polling scheme, I don’t believe there is a need a “<” or “>” prefix or for both a destination and source addresses (byte). address zero can be the master. The slave would send its address since the only time a master receives a message would be from the slave.

many transmission schemes use only 3 bits to represent a message sequence number. 3 bits would allow up to 8 unacknowledged messages to be pending. 8 messages would be buffered and any unacknowledged would be retransmitted. unless you intend to buffer messages and send more than one without acknowledgement is there a need for a msg seq #?

since in addition to sending a command you may also want to send data, you might consider either always send an extra byte or prefix you message with a length (see TLV)

in general, KIS (keep is simple)