Hallo
Ich habe für die serielle Übertragung ein int16_t mit bitshift in ein array geschrieben und sende es seriell an einen anderen Arduino. Beim Empfangen setze ich die beiden Bytes des Arrays wieder zusammen.
Mit positiven Zahlen funktioniert das prima. Mit negativen erhalte ich nicht das Gleiche wie gesendet wird. Was ist hier falsch? Wie geht es richtig, damit auch negative Werte korrekt ankommen?
Sender:
char data[6]; //data array for sending characters
char incomingData[6]; //incomingData array for receiving characters
char crcData[2]; //crcData array for calculated checksum
uint16_t crc = 0; //crc checksum
boolean newData = false; //newData received = true, newData not received = false
const byte address = 0x82; //address from this device (sender)
const byte addressRX = 0x80; //address from other device where the data was sent from (expected receiving)
byte BUT10 = 0;
byte BUT11 = 0;
byte BUT12 = 0;
int16_t BUT13 = 0;
byte BUT14 = 0;
void setup() {
Serial.begin(38400);
}
void loop() {
readCommand(Serial); //function for reading transmitted data by serial
command('E',184, address, Serial); //function to sendby serial (command character, value, address, serial port)
command('H',359, address, Serial);
command('#',98, address, Serial);
command('K',31, address, Serial);
command('I',10, address, Serial);
command('L',44, address, Serial);
command('J',27, address, Serial);
}
//function for sending data by serial
void command(const char command, int16_t value, const byte address, Stream& stream){
data[0] = address; //write address in data array
data[1] = command; //write command (for forward/reverse/left/right) in data array
data[2] = value >> 8; //write movement speed in data array
data[3] = value;
for(byte index = 0; index < 4; index++){ //create the checksum for the array data[i] with 0 <= i < 4
crc16(data[index]); //call the function crc16 to calculate the checksum
}
data[4] = crc >> 8; //store 16-bit checksum in data array
data[5] = crc;
stream.write(data, sizeof(data)); //send the data array by serial
crc = 0; //clear the checksum
}
//Calculates CRC16 of nBytes of data[index] in byte array
void crc16(uint8_t data) {
int i;
crc = crc ^ ((uint16_t)data << 8);
for (i=0; i<8; i++){
if (crc & 0x8000){
crc = (crc << 1) ^ 0x1021;
}
else{
crc <<= 1;
}
}
}
//function to store the received data by serial
void readCommand(Stream& stream){
readData(stream); //function to receive the incoming data
if(newData == true){ //if newData is true = all data received, then make...
for(byte index = 0; index < 4; index++){ //create the checksum for the received array incomingData[i] with 0 <= i < 4
crc16(incomingData[index]); //call the function crc16
}
crcData[0] = crc >> 8; //store 16-bit checksum in data array
crcData[1] = crc;
if(crcData[0] == incomingData[4] && crcData[1] == incomingData[5]){ //if the received crc checksum is equal to the calculated checksum of received data, then make...
switch(incomingData[1]){ //switch the second array of incomingData that contains the command character
case 'A': BUT10 = incomingData[3]; //if the command character is A, then store the third array of incomingData that contains the value, to BUT10
break; //leave the switch/case function
case 'B': BUT11 = incomingData[3];
break;
case 'C': BUT12 = incomingData[3];
break;
case 'D': BUT13 = incomingData[3] + (incomingData[2] << 8); //if the command character is D, then store the fourth array of incomingData plus the third array of incomingData shifted 8 bytes to the left (uint16_t), to BUT13
break; //leave the switch/case function
case '@': BUT14 = incomingData[3];
break;
}
}
else{
Serial.println("ERROR: Corrupted data received!");
}
Serial.print("BUT10 = "); //only to show the received data, not used in the main program!
Serial.println(BUT10);
Serial.print("BUT11 = ");
Serial.println(BUT11);
Serial.print("BUT12 = ");
Serial.println(BUT12);
Serial.print("BUT13 = ");
Serial.println(BUT13);
Serial.print("BUT14 = ");
Serial.println(BUT14);
newData = false; //set newData to false => data were received now!
for(byte index = 0; index < 6; index++){ //for index = 0 <= i < 6, make...
incomingData[index] = '\0'; //delete the whole incomingData array
}
crc = 0; //set crc = 0
}
}
//function for reading the incoming data by serial
void readData(Stream& stream){
static boolean inProgress = false; //inProgree = true = receive incoming data, inProgress = false = ready to receive incoming data
static byte index = 0; //index for byte array incomingData
byte var = 0; //variable var to read the incoming serial data
while(stream.available() > 0 && newData == false){ //while serial is available and newData is not already received, make...
var = stream.read(); //read serial data and store it to var
if(inProgress == true){ //if inProgress is active, then make...
if(index < 6){ //if index is less than 6, then make...
incomingData[index] = var; //store var to incomingData array with [index]
index++; //index +1
}
else{ //else if index is not less than 5, then make...
inProgress = false; //inProgress is not active anymore
index = 0; //index is equal to 0
newData = true; //newData is true = all data received and ready to store it
}
}
else if(var == addressRX && inProgress == false){ //else if inProgress is not active and var is equal to addressRX, then make...
inProgress = true; //inProgress is active now
incomingData[0] = addressRX; //store the addressRX into the incomingData array 0
index++; //index +1
}
}
}
Empfänger:
char data[6]; //data array for sending characters
char incomingData[6]; //incomingData array for receiving characters
char crcData[2]; //crcData array for calculated checksum
uint16_t crc = 0; //crc checksum
boolean newData = false; //newData received = true, newData not received = false
const byte address = 0x80; //address from this device (sender)
const byte addressRX = 0x82; //address from other device where the data was sent from (expected receiving)
byte BUT1 = 0;
byte BUT2 = 0;
byte BUT3 = 0;
int16_t BUT4 = 0;
byte BUT5 = 0;
void setup() {
Serial.begin(38400);
}
void loop() {
readCommand(Serial); //function for reading transmitted data by serial
command('A',155, address, Serial); //function to send by serial (command character, value, address, serial port)
command('D',-360, address, Serial);
command('B',29, address, Serial);
}
//function for sending data by serial
void command(const char command, int16_t value, const byte address, Stream& stream){
data[0] = address; //write address in data array
data[1] = command; //write command (for forward/reverse/left/right) in data array
data[2] = value >> 8; //write movement speed in data array
data[3] = value;
for(byte index = 0; index < 4; index++){ //create the checksum for the array data[i] with 0 <= i < 4
crc16(data[index]); //call the function crc16 to calculate the checksum
}
data[4] = crc >> 8; //store 16-bit checksum in data array
data[5] = crc;
stream.write(data, sizeof(data)); //send the data array by serial
crc = 0; //clear the checksum
}
//Calculates CRC16 of nBytes of data[index] in byte array
void crc16(uint8_t data) {
int i;
crc = crc ^ ((uint16_t)data << 8);
for (i=0; i<8; i++){
if (crc & 0x8000){
crc = (crc << 1) ^ 0x1021;
}
else{
crc <<= 1;
}
}
}
//function to store the received data by serial
void readCommand(Stream& stream){
readData(stream); //function to receive the incoming data
if(newData == true){ //if newData is true = all data received, then make...
for(byte index = 0; index < 4; index++){ //create the checksum for the received array incomingData[i] with 0 <= i < 4
crc16(incomingData[index]); //call the function crc16
}
crcData[0] = crc >> 8; //store 16-bit checksum in data array
crcData[1] = crc;
if(crcData[0] == incomingData[4] && crcData[1] == incomingData[5]){ //if the received crc checksum is equal to the calculated checksum of received data, then make...
switch(incomingData[1]){ //switch the second array of incomingData that contains the command character
case 'E': BUT1 = incomingData[3]; //if the command character is E, then store the third array of incomingData that contains the value, to BUT1
break; //leave the switch/case function
case 'F': BUT2 = incomingData[3];
break;
case 'G': BUT3 = incomingData[3];
break;
case 'H': BUT4 = incomingData[3] + (incomingData[2] << 8); //if the command character is H, then store the fourth array of incomingData plus the third array of incomingData shifted 8 bytes to the left (uint16_t), to BUT4
break; //leave the switch/case function
case '#': BUT5 = incomingData[3];
break;
}
}
else{
Serial.println("ERROR: Corrupted data received!");
}
Serial.print("BUT1 = "); //only to show the received data, not used in the main program!
Serial.println(BUT1);
Serial.print("BUT2 = ");
Serial.println(BUT2);
Serial.print("BUT3 = ");
Serial.println(BUT3);
Serial.print("BUT4 = ");
Serial.println(BUT4);
Serial.print("BUT5 = ");
Serial.println(BUT5);
newData = false; //set newData to false => data were received now!
for(byte index = 0; index < 6; index++){ //for index = 0 <= i < 6, make...
incomingData[index] = '\0'; //delete the whole incomingData array
}
crc = 0; //set crc = 0
}
}
//function for reading the incoming data by serial
void readData(Stream& stream){
static boolean inProgress = false; //inProgree = true = receive incoming data, inProgress = false = ready to receive incoming data
static byte index = 0; //index for byte array incomingData
byte var = 0; //variable var to read the incoming serial data
while(stream.available() > 0 && newData == false){ //while serial is available and newData is not already received, make...
var = stream.read(); //read serial data and store it to var
if(inProgress == true){ //if inProgress is active, then make...
if(index < 6){ //if index is less than 6, then make...
incomingData[index] = var; //store var to incomingData array with [index]
index++; //index +1
}
else{ //else if index is not less than 5, then make...
inProgress = false; //inProgress is not active anymore
index = 0; //index is equal to 0
newData = true; //newData is true = all data received and ready to store it
}
}
else if(var == addressRX && inProgress == false){ //else if inProgress is not active and var is equal to addressRX, then make...
inProgress = true; //inProgress is active now
incomingData[0] = addressRX; //store the addressRX into the incomingData array 0
index++; //index +1
}
}
}
Grüsse Stef