Getting 3 bytes from UART


#1

Hi everyone,

I’m stuck on this issue on trying to obtain 3 bytes of data from the UART.

Setup goes like this: Arduino Mega Software Serial -> Electric Imp (imp001)

I’m sending one byte whose bits will represent indicators and the other two will be the upper/lower byte of a 10-bit ADC value as I want the full 10-bit resolution.

UART on the imp and software serial on the Mega both run at 1200 baud (I’ve also tried 9600).

The Mega will send the 3 bytes, here is the snippet:

byte payload[3] = {indicatorByte, LowerByte, UpperByte}; impSerial.write(payload, sizeof(payload)); // in form (array, length of buffer)

Now on the Imp device side I want to read each byte and place them in a blob, which I send the whole blob to a function in the agent side that will parse the bytes and concatenate LowerByte and UpperByte.

Here is the snippet that reads the data coming in (DEVICE):

//Counter to obtain the 3 bytes of payload payload_counter <- 0; //Blob of binary payload data 3 bytes large payloadBlob <- blob(3);
.
.
.
`
function serialRead() {
local data = arduino.read();
//server.log(data);
if(payload_counter < 3)
{
payloadBlob.writen(data, ‘b’);
payload_counter++;
}
else
{
payload_counter = 0;
if(payloadBlob.eos() != null) // is pointer at the end of the blob
payloadBlob.seek(0, ‘b’); // reset pointer to beginning of blob

agent.send("parseBlob", payloadBlob);

}
}
. . .
arduino.configure(1200, 8, PARITY_NONE, 1, NO_CTSRTS, serialRead);
`

Here is the code snippet that will parse the results (AGENT):

`
function parsePayload(payload)
{
local status = payload[0];
local LowerByte = payload[1];
local UpperByte = payload[2];

statusFunction(status);

local value10bit = ((UpperByte << 8) | LowerByte);
status10bit(value10bit);
}
`

This was one method I have tried and I’ve tried a few other ways, but the data keeps on getting out of sync.
I tried having flag variables before each set of data, but that still didn’t work.

If anyone has any tips and solutions, it would be appreciated!

Thanks


#2

More additional information.

For software serial I am using pin 10 as RX and pin 11 as TX.

Mega Imp (001)
pin 10 <— pin 5
pin 11 —> pin 7


#3

What is the Mega Imp 001? I’ve never heard of that.


#4

Suggest you read the documentation as you are not implementing correctly. See: https://electricimp.com/docs/api/hardware/uart/

Here it tells you that a read() function only reads 1 byte.

The readblob() on the other hand might be better for you, or use a loop function with read(). Check the read() documentation. There is an example at bottom of page. Hope that helps you.


#5

The Mega is a 5V board and the imp is a 3.3v one. How is this difference being handled? Also, you can do a loopback test on either one by wiring RX to TX and of course test reading what you write to the uart.


#6

So it sounds like you’re getting data, but it’s “out of sync”? You are not checking the data you are reading from the UART is -1 (indicating no more data available). That shouldn’t necessarily be an issue, but it’s generally good practice.

Also, the software serial booting on the arduino side will almost certainly glitch the line enough to cause the imp to get one byte out of sync.

Generally, serial protocols have a way to regain sync - be it a start of packet marker, or an end of packet signal. In general, I would suggest here, for clarity, to simply use text to send the value, and then a CR to terminate the line.

eg, you might do this:

`buffer <- “”;

function readSerial() {
local data = arduino.read();
while(data != -1) {
if (data >=32 && data <= 127) buffer += data.tochar();
if (data == 0x0d || buffer.len() > 32) {
// Process the data
agent.send(“line”, buffer);
buffer = “”;
}
data = arduino.read();
}
}
`

…here, non ASCII characters are ignored (often a glitch on serial will look like 0xff, as it’s a false start bit), as are any characters <32 aside from CR.

The arduino side can then just printf() the string you want to send. 9600 is a good serial rate, though you can obviously go faster.