Sending analog value as two bytes from teensy 3.6 to HUZZAH over serial

Status
Not open for further replies.
Heyy:D

For my newest project I need to send sensor value from my Teensy 3.6 to my Adafruit HUZZAH.
But as it is I am only receiving a value of 0 on the HUZZAH.
It should be a value going from 0 to 1023.

These are the codes I'm using right now:

Teensy 3.6 code:


Code:
void setup() {
  // put your setup code here, to run once:
Serial1.begin (115200);
Serial.begin (115200);

}

void loop() {
  // put your main code here, to run repeatedly:

static int number = 0;
Serial1.write(highByte(number));
Serial1.write(lowByte(number));

number ++;

if (number == 1024);
number = 0;
delay(100);

}

HUZZAH code:

Code:
void setup() {
  // put your setup code here, to run once:
Serial1.begin (115200);
Serial.begin  (115200);
}

void loop() {

// put your main code here, to run repeatedly:
byte highByte , lowByte;
int value;
highByte = Serial.read();
lowByte = Serial.read();
value = (highByte << 8) | lowByte ;

Serial.println (value);
delay (1000);

}

Thank you for reading,

Please let me know if you have any clue what I should change ;)
 
3 problems here.

First, you need to use Serial.available() to check whether bytes have been received. Only call Serial.read() after Serial.available() returns more than 0. These chips run much faster than 115200 baud, so Serial.available() will almost always return 0.

Second, your receiving code doesn't have any reliable way to distinguish which byte really is the high half and which is the low half. If it start that code at random times, there's a strong possibility it will get them mixed up. Normally more encoding is done to make the bytes distinct, or libraries like EasyTransfer (which do that for you) are used.

Third, the use of delays is going to cause problems. Teensy will transmit about 10 times per second. But the full 1 second delay on the receiving side means it can't possibly keep up. Usually you would not want to have any delays on the receiving side, since you would use Serial.available() to know when bytes arrive.
 
Thank you for the reply!

I now have the code like this:

Code:
void setup() {
  // put your setup code here, to run once:
Serial1.begin (115200);
Serial.begin  (115200);
}

void loop() {

// put your main code here, to run repeatedly:
 if (Serial.available() > 0)
 {
byte highByte , lowByte;
int value;
highByte = Serial.read();
lowByte = Serial.read();
value = (highByte << 8) | lowByte ;

Serial.println (value);
//delay (100);
}
}

But I am still only getting a 0.
Even without handling the bytes in the right order I should now receive something other then 0, right?
So I guess there is still something wrong in my code.

Any clue?

Thanks for reading!
 
You're sending 0.

Delete that semicolon in the sending sketch where check number for 1024... (if... )

This sets number always to 0 - the if does nothing.
 
The next step would be to wait for TWO bytes in the receiving sketch ;)

After that, you may want to add a simple sync mechanism to get the bytes in the right order.
 
Ahh, that makes a lot more sense!
The new code without the " ; "
I'm now receiving 225 and sometimes 0 on the HUZZAH.
I will now try to wait for two bytes.


Code:
void setup() {
  // put your setup code here, to run once:
Serial1.begin (115200);
Serial.begin (115200);

}

void loop() {
  // put your main code here, to run repeatedly:

static int number = 0;
Serial1.write(highByte(number));
Serial1.write(lowByte(number));

number ++;

if (number == 1023) number = 0;


}

Should I add: if (Serial.available() < 2) to the receiving code to wait for 2 bytes?

Thnx!
 
Should I add: if (Serial.available() < 2) to the receiving code to wait for 2 bytes?

That still doesn't tell you which byte is high vs low. If the receiver starts up or reboots in the middle of an incoming stream of bytes, it could possibly miss the first low byte, and then forever get them mixed up.

That's why encoding schemes and libraries like EasyTransfer exist, so multi-byte messages can be decoded properly, even after an error condition.
 
Yes, but it's better to learn how to do it, before using a library for that.
Its not that hard to add a simple sync.
 
As you're using values <1024 , an idea for a sync could be to use a larger value as sync. For example something like 0xffaa.
 
@PaulStoffregen

I'll take a look into the EasyTransfer :D


@Frank B

Do you maybe have any example with how to use a larger value as sync?
Or maybe some documentation?

Thank you!
 
That depends only on your imagination:)

A simple way:
1. on the sender, send the value 0xffaa in intervals (once per second for example).
2. receiver:
- if you receive 0xaaff (<- note, bytes swapped) skip the next byte, if you receive 0xffaa just ignore it.
- now, it's still possible that the first received values (before sync) are wrong. So, after start wait for 0xffaa for example (!might be byteswapped, too!) or use a flag that ignores all incoming data until you got 0xffaa

3. as "addon", optional.. insert a "timeout" - if you receive no data for a long time (just longer than your delay - might be caused by a reset of the sender), make sure that you begin with first byte when the transmission restarts.

That's just a idea for your special case. Try this, or your own idea.. and after that, when it is working and you want to send more or other data, take a look at the library.

ps.: 0xffaa is a good value, because it a) will never be in your data, b) you can detect if the bytes are swapped.
 
Oef this is hard to grasp but I will do my best, why the value of 0xaa (170)?
Then I also don't know how to skip a byte.

This is what I can come up with at the moment but I'm sure its not even close to how it should be, I'm very new to sending bytes.

Code:
void setup() {
  // put your setup code here, to run once:
Serial1.begin (115200);
Serial.begin  (115200);
}

void loop() {

// put your main code here, to run repeatedly:
 if (Serial.available() > 1)
 {
byte highByte , lowByte;
int value;
highByte = Serial.read();
lowByte = Serial.read();
value = (highByte << 8) | lowByte ;

if (highByte == (0xaa))

{ 
lowByte = Serial.read();
}

else

{ 
highByte = Serial.read();
}

Serial.println (value);
}
}
 
Usually I agree with Frank, but in this case I believe simply using a library like EasyTransfer is best. You don't need to learn how to solve every type of technical challenge. Simply knowing the issues exists and using a library that solves it can help you get this project working and then focus your efforts on things that matter to you.
 
It looks like EasyTransfer does not work with my HUZZAH.
when Uploading it to the Teensy 3.6 it works just fine.

I get this when I try to verify it in the IDE:

Code:
EasyTransferReceive:1:26: error: EasyTransfer.h: No such file or directory
 #include <EasyTransfer.h>
                          ^
compilation terminated.
exit status 1
EasyTransfer.h: No such file or directory

Is it possible to add it to the huzzah's library?

Thanks!
 
Everything fixed and working now! :D

Thanks Paul and Frank your comments were very helpfull and it would have taken me much longer without your help.

Fixed it by putting the .h and .cpp file one folder up directly into /home/ko/Arduino/libraries/Arduino-EasyTransfer-master.
instead of in /home/ko/Arduino/libraries/Arduino-EasyTransfer-master/EasyTransfer.

I don't get why Teensy could get there but the HUZZAH did not. But at least its fixed.

The Final working codes:

Teensy 3.6

Code:
#include <EasyTransfer.h>

//create object
EasyTransfer ET; 

struct SEND_DATA_STRUCTURE{
int16_t number;
};

SEND_DATA_STRUCTURE mydata;

void setup() {
  // put your setup code here, to run once:
Serial1.begin(112500);
ET.begin(details(mydata), &Serial1);

}

void loop() {
  // put your main code here, to run repeatedly:
mydata.number = (1020);
ET.sendData();
delay (100);

}

HUZZAH

Code:
#include <EasyTransfer.h>

//create object
EasyTransfer ET; 

struct RECEIVE_DATA_STRUCTURE{
int16_t number;
};

//give a name to the group of data
RECEIVE_DATA_STRUCTURE mydata;


void setup() {
  // put your setup code here, to run once:
Serial.begin(112500);
ET.begin(details(mydata), &Serial);

}

void loop() {
  
// put your main code here, to run repeatedly:
if(ET.receiveData()) {
Serial.println (mydata.number);
}

delay (10);

}
 
Status
Not open for further replies.
Back
Top