UART API for Two Microcontrollers

Thread Starter

Alex Sneed Miller

Joined Jan 8, 2016
4
Hi,
I'm working on a project with two different microcontrollers and I would like them to be able to commute with each other. One is primarily for user input (buttons, switches, etc) and the other is for output such as screens, lights, sounds, etc. I would like the first microcontroller to be able to command the second one to turn lights on or play sounds, etc. I thought that UART might be good because it's fairly easy to set up and will work with just about anything at a high data rate.

I'm wondering if anyone has any advice on creating an API over UART. I was thinking that the first microcontroller could just send the length of the communication, followed by some custom info (lights power and color, sound and volume, etc). I know that the lower level UART communication has start bits and stop bits. Would that be useful for a higher level protocol?
Thanks!
 

spinnaker

Joined Oct 29, 2009
7,830
It would help if you mentioned the microcontroller in question but most manufactures have libraries for serial communication.
 

philba

Joined Aug 17, 2017
959
Actually, you are referring to a protocol, not an API. Using TX and RX is a perfectly fine way to do it. You need to define what the data stream will look like. Typically a message will look something like this:
<header><data><eom>

header contains a signature, type of data and the size of the message
data will contain the information you want
eom is a short end-of-message sequence.

You may also want to include an acknowledgement response so the sender knows it was received.

You can get really elaborate in this but I'd keep it pretty simple.
 

Thread Starter

Alex Sneed Miller

Joined Jan 8, 2016
4
I'm starting out with just two Arduinos, but I'd like this protocol to extend to any other microcontroller that can support a uart baud rate of 115200. I can get the two to talk to each other, but as far as standardizing a higher level communication protocol I'm not sure if there is anything else I need besides the length (number of bytes) and the data. I looked at AT commands as a basic serial protocol that is used a lot, but I feel like there is a lot of waste transmitting things in ASCII instead of just raw hex, and the first two characters (AT) seems like a waste of 4 bytes to me, but maybe I'm missing something?
 

philba

Joined Aug 17, 2017
959
The advantage of using a text based protocol is it is easy (er, easier) to debug. Unless you are sending a lot of data or at really high speed, the inefficiency won't hurt.
 

Thread Starter

Alex Sneed Miller

Joined Jan 8, 2016
4
The advantage of using a text based protocol is it is easy (er, easier) to debug. Unless you are sending a lot of data or at really high speed, the inefficiency won't hurt.
Even when going to a text based system is there a need to have start bytes or end bytes?
 

philba

Joined Aug 17, 2017
959
You can do anything you want - there are no rules here. Though, I'd have a something akin to AT for a start sequence. The advantage of an eom sequence is it allows you to sync up in the event of a garbled transmission. In data comm, redundancy is generally good.
 

Thread Starter

Alex Sneed Miller

Joined Jan 8, 2016
4
If you have a start of message or end of message, is it possible to use those bytes within the communication? For example if you are uploading a new firmware binary do you have to ensure that your start of message or end of message does not exist within the binary?
 

philba

Joined Aug 17, 2017
959
If you have a start of message or end of message, is it possible to use those bytes within the communication? For example if you are uploading a new firmware binary do you have to ensure that your start of message or end of message does not exist within the binary?
Yes, you have to do that with an EOM. Nothing will break if you don't have an eom in your protocol.
 

be80be

Joined Jul 5, 2008
2,072
feel like there is a lot of waste transmitting things in ASCII instead of just raw hex
You may as well forget the arduino it sends everything out ASCII .
That's not to say it can't send hex but it doesn't send anything using the plain serial commands the monitor read them and displays
numbers but the data sent is ASCII
You'll run into this once you try to send a number you see it on the monitor and it's shows up like your thinking. But then you test it from a uC that is not looking for 49 48
but you though you sent a 10.
To better understand this try a program like putty and look at what the arduino is really sending.
Code:
Serial.println(analogValue, HEX);  // print as an ASCII-encoded hexadecimal
 
Last edited:

philba

Joined Aug 17, 2017
959
You may as well forget the arduino it sends everything out ASCII .
That's not to say it can't send hex but it doesn't send anything using the plain serial commands the monitor read them and displays
numbers but the data sent is ASCII
Uh, not exactly. The serial monitor only talks ascii but use write to send binary data, read to receive and so on.
 

be80be

Joined Jul 5, 2008
2,072
Have you tried what you speak
I can show you 100 of pages where it's been ask why is this not working I sent 100 to a and it seeing something else LOL

write() will return the number of bytes written try it with anything over 255 see where you get
I
 

be80be

Joined Jul 5, 2008
2,072
As you can see this is there sample code right from the link you posted
do you see a 45 nope just the hello
Screenshot from 2018-01-09 01-24-13.png
 
Last edited:

philba

Joined Aug 17, 2017
959
As you can see this is there sample code right from the link you posted
do you see a 10 nope just the hello
View attachment 143345
?? I see a '-' , the ascii code for 45. The whole point of that example is to show you can send arbitrary data. The receiving end (the arduino terminal in the example) just happens to interpret it as a character. It's up to the receiver what to do with the 8 bit unit that was sent. Two Arduinos could talk to each other via a binary protocol over the UARTs.

Async serial sends 8 bit units. If you want to send larger data units (16 or 32 bits, for example), you have to break them into a byte stream and reassemble on the other side.

Read() and write() don't care what the data is. It's all just bits. It is your code's interpretation of the received data that makes it binary or character data. The Arduino terminal program shows characters and interprets special characters like CR, LF and so on, that it's interpretation of the data stream. You could write a PC program that reads the data stream from the com port, makes the data into 16 bit integers and writes them to a file. It's all just bits.
 

be80be

Joined Jul 5, 2008
2,072
You see good but tell them for the next 100 post why they didn't get 45 the number and that to send bytes out in
hex takes more then just write 45 out.

The poster said send hex show how you would do that for easy one 0xFF
 

nsaspook

Joined Aug 27, 2009
13,315
You can do anything you want - there are no rules here. Though, I'd have a something akin to AT for a start sequence. The advantage of an eom sequence is it allows you to sync up in the event of a garbled transmission. In data comm, redundancy is generally good.
Exactly, I've made raw byte-sequence serial protocols with 9-bit uart modes between two PICs to transfer raw binary C data structures between 8 and 32 bit controllers. Bit 9 was the command/data band flag, with a simple crc32 for checking data transmission errors.
 

philba

Joined Aug 17, 2017
959
Exactly, I've made raw byte-sequence serial protocols with 9-bit uart modes between two PICs to transfer raw binary C data structures between 8 and 32 bit controllers. Bit 9 was the command/data band flag, with a simple crc32 for checking data transmission errors.
That reminds me, some sort of error checking is a good thing. CRC32 is a good choice but even a checksum would be ok. You can put it in the EOM sequence or even in the header. It's good to give the receiver a way to verify the validity of the received message.
 

philba

Joined Aug 17, 2017
959
Just to close the loop on the "Arduino doesn't send binary data" issue. I took an ArduinoMega that has 4 UARTs and used 1 and 2 to communicate. Serial1 TX was connected to Serial2 RX and Serial1 RX was connected to Serial2 TX. Wrote a simple program to take an integer and send it as 2 bytes and then reconstruct it after receive. Code available for those that want to try it for themselves. See the picture below. Note the transmission of values > 255. Note that the data type uint8_t is an unsigned 8 bit integer. No characters were harmed in the production of this movie. Serial 0 (AKA Serial) is connected to the terminal window via USB on the PC's COM6 port.
serial data.png
 
Last edited:

BobaMosfet

Joined Jul 1, 2009
2,113
You see good but tell them for the next 100 post why they didn't get 45 the number and that to send bytes out in
hex takes more then just write 45 out.

The poster said send hex show how you would do that for easy one 0xFF
Seriously, you're confused. You sent a 45. Your terminal interpreted (correctly) a 45 as a hyphen and displayed a hyphen. It doesn't know how to display the value 45 in two places when it's expecting a value from 0-255 to mean one and only one ASCII represented value. You weren't sending a string (text) you were sending an integer (value).

If you want to see a "45" on the terminal, send the ASCII value (ie. integer) of a '4', and then again of a '5'. the terminal will receive 2 characters, and display them as "45".
 
Top