1

I am a bit confused. So I want to send messages between two arduinos over RS485, but these are not fixed length, naturally, I have to send the length of the message or add a delimiter to understand that my message has ended.

Suppose, now I create a placeholder for the message, and both ends communicating are receiving the placeholder, rather than the message itself. This placeholder is x bytes long always, and each arduino can look it up from its memory what message corresponds to the placeholder.

Lets say I create a message.h file with contents like this

#define A "First Message"
#define B "Second Message"

When the two devices are communicating, they send each other A or B, and the Arduino looks it up in its .h file what A and B mean.

My question is when the Arduino recieves the A, it recieves a character 'A', but how can I use this to fetch the value assigned to variable A in memory?

  • Seems you #define A you arduinos will see the stuff in the " " and not just A – RSM Jul 19 '15 at 12:24
2

There is no "variable A" - there is only a macro called "A" which gets replaced by the contents of the #define for "A" at compile time.

You have to remember that the "A" that the Arduino receives is just a number. It is only us humans who choose to associate that number with the letter A, and write software that takes that number and display it as an A. The letter A is number 65. The mapping between numbers and letters is called ASCII - or American Standard Code for Information Interchange.

What you do with that number is entirely up to you. If you want to use it to display pre-defined messages, then there's a number of ways you could do it. You could:

  • Use a series of if statements to compare the number you have
  • Use a switch/case construct in a similar way
  • Store the messages in an array and use the received number as the index

For string constants the last option is tricky to get right on an Arduino where there is very limited RAM - you have to ensure that you use PROGMEM and access it properly, and doing that from an array is not as trivial as it would otherwise be.

The best method would probably be the switch/case option:

switch (letter) {
    case 'A': Serial.println(F("First Message")); break;
    case 'B': Serial.println(F("Second Message")); break;
}
1

I have a write-up about RS485 including a small library to handle this situation.

It can be downloaded from http://www.gammon.com.au/Arduino/RS485_protocol.zip.


Library features

  • Handles "packets" of between 1 and 255 bytes.

  • Uses a "begin packet" character (Start of Text, STX, 0x02) to reliably indicate that a packet is starting.

  • Uses an "end packet" character (End of Text, ETX, 0x03) to reliably indicate that a packet is ending.

  • Each data byte (other than STX/ETX) is sent in a "doubled/inverted" form. That is, each nibble (4 bits) is sent twice, once normally, and once inverted. Thus the only valid values for each nibble are:

    0F, 1E, 2D, 3C, 4B, 5A, 69, 78, 87, 96, A5, B4, C3, D2, E1, F0
    
  • The inverse (ones complement) of 0 is F, hence 0 becomes 0F. The inverse of 1 is E, hence 1 becomes 1E. And so on.

  • This guards somewhat against "bursts" of noise. A burst of either 0s or 1s is unlikely to corrupt a byte preserving this normal/inverse relationship. Also there are only 16/256 valid combinations, so noise has only a 6% chance of becoming a valid byte.

  • Because of this, also, the STX and ETX characters cannot appear in ordinary data (they are not one of the 16 valid values).

  • Each packet is followed by a CRC (cyclic redundancy check). This is a further test that the packet was received completely. It guards against noise, or possibly some bytes just becoming missing.


More details on the linked page, but basically you provide a few functions to:

  • test if a byte is available for reading
  • read a byte
  • write a byte

These could be with SoftwareSerial, HardwareSerial, or whatever you choose.

Then you either send or receive a "packet" which is the data you want transmitted to the other end.

There is a "blocking" and "non-blocking" version. The blocking version (when reading) waits for an entire packet to arrive. The non-blocking one lets you do other things while waiting for the entire packet.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.