Int16_t seriell senden und wieder zusammensetzen

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

Übertrage int16_t als uint16_t, 2 mal uint_8, uint16_t und cast in int16_t.

Habe es so angepasst, funktioniert jedoch noch nicht. Habe ich das falsch verstanden?

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] = (uint16_t)value >> 8;                         //write movement speed in data array
  data[3] = (uint16_t)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 = (int16_t)incomingData[3] + ((int16_t)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
    }
  }
}

Hast du geprüft ob das falsche gesendet wird oder falsch dekodiert wird?

Ich kann mir das nie merken... Ist char signed oder unsigned? Das hat Einfluss auf die Vorzeichenexpansion char -> int16_t.

https://docs.arduino.cc/language-reference/de/variablen/data-types/char/

Das stimmt, char ist signed, das funktiiniert nicht. Jetzt gehts, vielen Dank an alle!

byte data[6];                 //data array for sending characters
byte incomingData[6];         //incomingData array for receiving characters
byte 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, const 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] = (uint16_t)value >> 8;                         //write movement speed in data array
  data[3] = (uint16_t)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 = (int16_t)incomingData[3] + ((int16_t)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
    }
  }
}

Das beantwortet die Frage nicht!
Ist aber in anderer Sache dagegen klar!

Es wird empfohlen, char nur zum Speichern von Zeichen zu verwenden.

Einfach den Compiler fragen:

#include <type_traits>

#include <Streaming.h> // die Lib findest du selber ;-)
Print &cout = Serial; // cout Emulation für "Arme"

void setup() 
{
  Serial.begin(9600);
  cout << "std::is_signed<char>::value "   << std::is_signed<char>::value   << endl;
  cout << "std::is_unsigned<char>::value " << std::is_unsigned<char>::value << endl;


void loop() 
{

}

Ausgabe:

std::is_signed<char>::value 1
std::is_unsigned<char>::value 0

Das ist jetzt für den AVR.
Ob das auf andern µC auch so aussieht?

char — type for character representation which can be most efficiently processed on the target system (has the same representation and alignment as either signed char or unsigned char, but is always a distinct type).

Aus: Fundamental types - cppreference.com

Es gibt auf die Frage also keine eindeutige Antwort.

Ich habe mir gemerkt, immer den richtigen Datentyp zu verwenden.
Für uint8_t bietet Arduino auch den aus Java entlehnten Datentype byte an.

Generell hat C/C++ die Besonderheit, dass einige Datentypen recht unbestimmt sind,
wenn es also drauf ankommt, sollte man diese nicht verwenden.
Aber wie immer, besteht das Problem meist darin, dass man nicht rechtzeitig merkt, dass man ein Problem hat.

Offiziell heißt das: "implementation defined".
So wie auch die Bitbreite von char, bzw. byte, implementation defined ist!

Siehe dazu: CHAR_BIT

Der Vorteil dieser implementation defined Datentypen ist die Verarbeitungsgeschwindigkeit!
Denn die "künstlichen" erfordern mehr Verarbeitungsaufwand.
.

Gibt es übrigens nicht überall, nur fast überall.

Sollte uint8_t sein.

Schreibe bitte ein kurzes Testprogramm.

Vielen Dank für den Hinweis, habe in Post #6 bereits den korrigierten Code meinerseits gepostet. Der Hinweis mit char reichte mir aus Post #4 :wink:

Es funktioniert jetzt problemlos, vielen Dank für die Hilfe!

Und ja, byte ist das gleiche wie uint8_t. Man sollte sich aber wohl mehr mit den allgemein (fast) überall gültigen Wertebereichen bedienen. Und dies auch konsequent durchziehen. Das Problem ist wohl, wenn man sich Abschnitte verschiedener Codes zusammensetzt und sich die Wertevereiche nicht immer genaustens überlegt.

Man kann so machen, aber besser ist den doppelt zeigen = vorher post 6, nacher nach Korrektur posr#11

Ich habe bisschen getestet mit dem Code. Wieso ist das Senden und Empfangen mit Serial.parseInt um einiges schneller? Theoretisch sende ich ja ein Buchstabe/Zeichen und eine Zahl. Habe dann aber keine Fehlerprüfung.

Gesendet habe ich zum Test mit print(Buchstabe); und println(Zahl);. Empfangen dann per Switch/Case in einer char eingelesen und per case für den zutreffenden Buchstaben parseInt();.

Problem mit parseInt war, dass es sehr oft nicht richtig einliest oder eine 0 ausgibt. Was macht hier parseInt falsch? Wie kann man mit parseInt “Fehlerfrei” einlesen/senden?

Ich dachte immer mit parseInt geht das Einlesen langsamer als mit einem Daten Array wie am Anfang gepostet.

Ich würde mal vermuten, das einfach keine Zeichen da sind, wenn index == 6 ist und du deshalb nicht in der While-Scheife bist und damit nicht in den Else-Zweig gehst, um newData = true zu setzen.

Das stimmt, habe ich übersehen. Danke!

    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
      }
      if(index == 6){                                           //else if index is equal than 5 (data received), 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
    }
  }
}

Aber irgendwie ist parseInt trotzdem einiges schneller. Liegt es daran, dass ich anstatt nur zwei Werte per parseInt, hier 5 Werte einlese?

Gibt es eine schnellere Übertragungsart als mit dem Array? ParseInt ist schneller als mit dem Array[6] zu senden und zu empfangen. Kann das sein?

Hmm... parseInt() sollte nicht schneller sein als ein paar Bytes zu verschieben.

Ich denke das irgendwas blockiert, weil auf Daten gewartet wird.

Sehe ich das richtig, das du Debugausgaben und die Kommunikation auf der selben seriellen Schnittstelle machst? Vielleicht kommt da was durcheinander.

Das ist so, habe ich aber bei ParseInt gleich drin mit Ausgabe der empfangenen Daten resp. gesendeten Daten auf derselben Schnittstelle.

Wenn ich das raus nehme ändert es ebenfalls nicht merklich was an der Geschwindigkeit. ParseInt scheint schneller zu sein. Also 2 Bytes vs. 6 Bytes.

Ich habe mal noch versucht mit strings die Daten zu senden. Viellleicht ist das schneller. Ich bekomme jedoch nichts in den Werten DP1, BUT2 und FDUD eingelesen. Es wird auch keine serielle Ausgabe gemacht von diesen mit der Funktion showParsedData(). Was mache ich falsch?

const byte numChars = 10;
char receivedData[numChars];
char tempData[numChars];        // temporary array for use when parsing
char sendData[numChars];
byte data[7];                   //data array for sending characters

// variables to hold the parsed data
char var[numChars] = {0};
int value = 0;

boolean newData = false;

byte DP1 = 0;
int16_t BUT2 = 0;
int16_t FDUD = 0;

void setup() {
    Serial.begin(38400);
    Serial.println("This demo expects 3 pieces of data - text, an integer and a floating point value");
    Serial.println("Enter data in this style <H, 12>  ");
    Serial.println();
}


void loop() {
    recvWithStartEndMarkers();
    if (newData == true) {
        strcpy(tempData, receivedData);
            // this temporary copy is necessary to protect the original data
            //   because strtok() used in parseData() replaces the commas with \0
        parseData();
        showParsedData();
        newData = false;
    }

    command('#',-360);
    command('s',45);
    command('Z',12);
    command('a',255);
}


void command(const char designation, const int value) {
  sprintf(sendData, "<%c,%d>", designation, value);
  Serial.println(sendData);
}


void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;

    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();
        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedData[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedData[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }
        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}


void parseData() {      // split the data into its parts

    char * strtokIndx; // this is used by strtok() as an index

    strtokIndx = strtok(tempData,",");      // get the first part - the string
    strcpy(var, strtokIndx); // copy it to messageFromPC
 
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    value = atoi(strtokIndx);     // convert this part to an integer

    switch(var[0]){
      case 'A' : DP1 = value;
                 break;
      case '#' : BUT2 = value;
                 break;
      case 'Z' : FDUD = value;
                 break;
    }
}


void showParsedData() {
    Serial.print("DP1 = ");
    Serial.println(DP1);
    Serial.print("BUT2 = ");
    Serial.println(BUT2);
    Serial.print("FDUD = ");
    Serial.println(FDUD);
}

Ich habe nochmal geändert, dass die Daten löscht, wenn es mehr Zeichen empfangen würde als das Array Platz hat. Irgendwie empfange ich aber nicht immer genau das was gesendet wird. Was habe ich übersehen?

Der Sendeteil:

const byte numChars = 7;
char receivedData[numChars];
char tempData[numChars];        // temporary array for use when parsing
char sendData[numChars];

// variables to hold the parsed data
char var[1] = {0};
int value = 0;

boolean newData = false;

byte DP12 = 0;
int16_t BUT5 = 0;
uint16_t FDLR = 0;

void setup() {
    Serial.begin(38400);
}


void loop() {

    readCommand(Serial);

    command('#',-360, Serial);
    command('s',45, Serial);
    command('Z',12, Serial);
    command('a',255, Serial);
}


void command(const char designation, const int16_t value, Stream& stream) {
  sprintf(sendData, "<%c,%d>", designation, value);
  stream.println(sendData);
  for(byte index = 0; index < numChars; index++){        //for index = 0 <= i < 6, make...
    sendData[index] = '\0';                              //delete the whole incomingData array
  }
}


void readCommand(Stream& stream){
  
  recvWithStartEndMarkers(stream);
    
    if (newData == true) {
        strcpy(tempData, receivedData);     // this temporary copy is necessary to protect the original data because strtok() used in parseData() replaces the commas with \0
        parseData();
        showParsedData();
        newData = false;
        for(byte index = 0; index < numChars; index++){        //for index = 0 <= i < 6, make...
          tempData[index] = '\0';                   //delete the whole incomingData array
          receivedData[index] = '\0';
        }
    }
}


void recvWithStartEndMarkers(Stream& stream) {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;

    while (stream.available() > 0 && newData == false) {
        rc = stream.read();
        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedData[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    for(byte index = 0; index < numChars; index++){        //for index = 0 <= i < 6, make...
                      receivedData[index] = '\0';                          //delete the whole incomingData array
                    }
                    recvInProgress = false;
                    ndx = 0;
                }
            }
            else if (rc == endMarker) {
                receivedData[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }
        else if (rc == startMarker && recvInProgress == false) {
            recvInProgress = true;
        }
    }
}


void parseData() {      // split the data into its parts

    char * strtokIndx; // this is used by strtok() as an index

    strtokIndx = strtok(tempData,",");      // get the first part - the string
    strcpy(var, strtokIndx); // copy it to messageFromPC
 
    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    value = atoi(strtokIndx);     // convert this part to an integer

    switch(var[0]){
      case '$' : DP12 = value;
                 break;
      case 'e' : BUT5 = value;
                 break;
      case 'p' : FDLR = value;
                 break;
    }
}


void showParsedData() {
    Serial.print("DP12 = ");
    Serial.println(DP12);
    Serial.print("BUT5 = ");
    Serial.println(BUT5);
    Serial.print("FDLR = ");
    Serial.println(FDLR);
}

Der Empfangsteil:

const byte numChars = 7;
char receivedData[numChars];
char tempData[numChars];        // temporary array for use when parsing
char sendData[numChars];

// variables to hold the parsed data
char var[1] = {0};
int value = 0;

boolean newData = false;

byte DP1 = 0;
int16_t BUT2 = 0;
uint16_t FDUD = 0;

void setup() {
    Serial.begin(38400);
}


void loop() {

    readCommand(Serial);

    command('$',12, Serial);
    command('p',360, Serial);
    command('Y',55, Serial);
    command('e',-180, Serial);
}


void command(const char designation, const int16_t value, Stream& stream) {
  sprintf(sendData, "<%c,%d>", designation, value);
  stream.println(sendData);
  for(byte index = 0; index < numChars; index++){        //for index = 0 <= i < 6, make...
    sendData[index] = '\0';                              //delete the whole incomingData array
  }
}


void readCommand(Stream& stream){
  
  recvWithStartEndMarkers(stream);
    
    if (newData == true) {
        strcpy(tempData, receivedData);     // this temporary copy is necessary to protect the original data because strtok() used in parseData() replaces the commas with \0
        parseData();
        showParsedData();
        newData = false;
        for(byte index = 0; index < numChars; index++){        //for index = 0 <= i < 6, make...
          tempData[index] = '\0';                              //delete the whole incomingData array
          receivedData[index] = '\0';
        }
    }
}


void recvWithStartEndMarkers(Stream& stream) {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;

    while (stream.available() > 0 && newData == false) {
        rc = stream.read();
        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedData[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    for(byte index = 0; index < numChars; index++){        //for index = 0 <= i < 6, make...
                      receivedData[index] = '\0';                          //delete the whole incomingData array
                    }
                    recvInProgress = false;
                    ndx = 0;
                }
            }
            else if (rc == endMarker){
                receivedData[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }
        else if (rc == startMarker && recvInProgress == false) {
            recvInProgress = true;
        }
    }
}


void parseData() {      // split the data into its parts

    char * strtokIndx; // this is used by strtok() as an index

    strtokIndx = strtok(tempData,",");      // get the first part - the string
    strcpy(var, strtokIndx); // copy it to messageFromPC

    strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
    value = atoi(strtokIndx);     // convert this part to an integer

    switch(var[0]){
      case 'A' : DP1 = value;
                 break;
      case '#' : BUT2 = value;
                 break;
      case 'Z' : FDUD = value;
                 break;
    }
}


void showParsedData() {
    Serial.print("DP1 = ");
    Serial.println(DP1);
    Serial.print("BUT2 = ");
    Serial.println(BUT2);
    Serial.print("FDUD = ");
    Serial.println(FDUD);
}

Um falsche Werte zu vermeiden, könnte man hier die CRC Püfsumme wie im ersten Sketch aus Post 1 ebenfalls einbauen? Wie müsste ich das einfügen? Ich sehe gerade nichts mehr wo was wie soll :expressionless: