int Array over Serial treated as unsigned int

Status
Not open for further replies.

joepip

Member
Hi folks,
I'm sending ints of serial one byte at a time, and putting the received data into an array declared as an int. The bytes are correctly assigned, but the program is treating the elements of the int array as unsigned ints, and I'm getting numbers over 60,000 whenever a negative is sent. The code is super long, and I know the correct bytes are being assigned so I'll only post the relevant portions of code. Note that I'm sending the data as total number of bytes first, then array location, MSB, LSB. Any thoughts on why I'm getting unsigned values would be appreciated.

Receive the data:
Code:
while (Serial1.available()) {
    if (debugOn) Serial.println("incoming");
    msb = Serial1.read();
    if (temp == 0xFFFF) {
      activedata = 1;
      i = 0;
      //temp = 0;
    }
    if (debugOn) Serial.println(msb);
    temp = (temp >> 8) + (msb << 8);


    if (activedata) {
      if (debugOn) Serial.print("i=");
      if (debugOn) Serial.println(i);
      if (i == 0) {
        if (msb <= maxRec) {
          inputs[i] = msb;
          i++;
        }
        else {
          activedata = 0;
          i = 0;
        }
      }
      else if (i < (inputs[0])) { //inputs[0] counts from 0.  Use < to ensure we only catch up to inputs[0] - 1
        inputs[i] = msb;
        i++;
      }
      else if (i == (inputs[0])) {
        inputs[i] = msb;
        i = 0;
        activedata = 0;
        if (debugOn) Serial.println("parse called");
        parse();
      }
}
}

And the parse code:
Code:
void parse() {
  int x = 1;
  int readMSB = 0;
  int recCheckSum = 0;
  int checkSum = 0;
  for (int j = 0; j <= (inputs[0] - 2); j++) {
    recCheckSum = recCheckSum + inputs[j];
  }
  if (debugOn) Serial.print("recCheckSum=");
  if (debugOn) Serial.println(recCheckSum);
  checkSum = inputs[inputs[0]];
  checkSum = inputs[inputs[0] - 1] + (checkSum << 8);
  if (debugOn) Serial.print("checkSum=");
  if (debugOn) Serial.println(checkSum);

  while ((x <= (inputs[0] - 2)) && (inputs[0] <= maxRec) && (checkSum == recCheckSum)) { //Use inputs[0] - 2 to avoid re-reading checksum.  maxRec to avoid overrun allocated memory.
    //inputsInts[(x>>1)] = inputs[x] + (inputs[x+1] << 8);
    readMSB = (int)inputs[x + 2];
    if (inputs[x] < 12) {
      inputsInts[inputs[x]] = inputs[x + 1] + ((int)readMSB << 8);
      //if (inputsInts[inputs[x]] >> 15) {
       //inputsInts[inputs[x]] = -1 * (~inputsInts[inputs[x]]);
      //}
    }
  
  x = x + 3;
  }
}
 
Which board? Note int on teensy 3.x are 32 bit numbers.

Also would help to see whole program so you can see defines and the like.
 
As requested here's the whole program:

Code:
/*  Serial configuration
  Start bit 1:  0xFF
  Start bit 2:  0XFF
  Data bit 0:  total number of bytes including check sum counting from 0
  Data bit 1:  ID number of first int
  Data bit 2:  First int LSB
  Data bit 3:  First int MSB
  .
  .
  .
  Data bit i:  Check sum LSB
  Data bit i+1:  Check sum MSB
*/

//#include <SoftwareSerial.h>
#include <Servo.h>

byte inputs[39];
byte outputs[39];
const byte maxRec = 38;  //maximum recieved serial bytes 0-38.  1 length byte [0], ID byte, 2 data bytes for up to 12 inputs, 2 checksum bytes
int debugOn = 0;
int debugOn2 = 1;
int i = 0;
int activedata = 0;
int inputsInts[12];
int msb = 0;
int lsb = 0;
int error = 0;
int temp = 0;
int potPos = 0;
//int i = 0;

Servo servo0;
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
Servo servo6;
Servo servo7;
Servo servo8;
Servo servo9;
Servo pitch;
Servo yaw;

int potPos0 = 0;
int potPos1 = 0;
int potPos2 = 0;
int potPos3 = 0;
int potPos4 = 0;
int potPos5 = 0;
int potPos6 = 0;
int potPos7 = 0;
int potPos8 = 0;
int potPos9 = 0;
int yawval = 0;
int pitchval = 0;

int outPos0 = 0;
int outPos1 = 0;
int outCheckSum = 0;

int testInt = 1025;
// set up a new serial object
//SoftwareSerial mySerial (7, 8);

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

  servo0.attach(2);
  servo1.attach(3);
  servo2.attach(4);
  servo3.attach(5);
  servo4.attach(6);
  servo5.attach(7);
  servo6.attach(8);
  servo7.attach(9);
  servo8.attach(10);
  servo9.attach(11);
  yaw.attach(12);
  pitch.attach(14);
}

void loop() {
  // put your main code here, to run repeatedly:
  //if (debugOn) Serial.println("hi");

  outPos0 = analogRead(A0);
  //Serial.println(potPos0);
  outPos1 = analogRead(A1);

  outputs[0] = 9;  //2 servos (4 bytes), 0 PPM (0 bytes), 2 IDs (2 bytes), length (1 byte), checksum (2 bytes)
  outputs[1] = 0;
  outputs[2] = (outPos0 & 0x00FF);
  outputs[3] = (outPos0 >> 8) & 0x00FF;
  outputs[4] = 1;
  outputs[5] = (outPos1 & 0x00FF);
  outputs[6] = (outPos1 >> 8) & 0x00FF;

  outCheckSum = 0;
  for (int z = 0; z <= 6; z++) {
    outCheckSum = outCheckSum + outputs[z];
  }
  outputs[7] = (outCheckSum & 0x00FF);
  outputs[8] = (outCheckSum >> 8) & 0x00FF;

  Serial1.write(0xFF);
  Serial1.write(0xFF);
  //mySerial.write(0xFF);
  //mySerial.write(0xFF);

  //for (int i = 0; i != 7; i++) {
  Serial1.write(outputs, 9);
  //}

  while (Serial1.available()) {
    if (debugOn) Serial.println("incoming");
    msb = Serial1.read();
    if (temp == 0xFFFF) {
      activedata = 1;
      i = 0;
      //temp = 0;
    }
    if (debugOn) Serial.println(msb);
    temp = (temp >> 8) + (msb << 8);


    if (activedata) {
      if (debugOn) Serial.print("i=");
      if (debugOn) Serial.println(i);
      if (i == 0) {
        if (msb <= maxRec) {
          inputs[i] = msb;
          i++;
        }
        else {
          activedata = 0;
          i = 0;
        }
      }
      else if (i < (inputs[0])) { //inputs[0] counts from 0.  Use < to ensure we only catch up to inputs[0] - 1
        inputs[i] = msb;
        i++;
      }
      else if (i == (inputs[0])) {
        inputs[i] = msb;
        i = 0;
        activedata = 0;
        if (debugOn) Serial.println("parse called");
        parse();
      }

    }
  }

  potPos0 = inputsInts[0];//map(inputsInts[0], 0, 1023, 700, 2300);
  //if (potPos0 > 1023) potPos0 = 1023;
  //if (potPos0 < 0) potPos0 = 0;
  if (debugOn2) Serial.print("potPos0=");
  if (debugOn2) Serial.println(potPos0);
  servo0.writeMicroseconds(potPos0);
  potPos1 = map(inputsInts[1], 0, 1023, 700, 2300);
  //if (potPos1 > 1023) potPos1 = 1023;
  //if (potPos1 < 0) potPos1 = 0;
  servo1.writeMicroseconds(potPos1);
  potPos2 = map(inputsInts[2], 0, 1023, 700, 2300);
  //if (potPos2 > 1023) potPos2 = 1023;
  //if (potPos2 < 0) potPos2 = 0;
  servo2.writeMicroseconds(potPos2);
  potPos3 = map(inputsInts[3], 0, 1023, 700, 2300);
  //if (potPos3 > 1023) potPos3 = 1023;
  //if (potPos3 < 0) potPos3 = 0;
  servo3.writeMicroseconds(potPos3);
  potPos4 = map(inputsInts[4], 0, 1023, 700, 2300);
  //if (potPos4 > 1023) potPos4 = 1023;
  //if (potPos4 < 0) potPos4 = 0;
  servo4.writeMicroseconds(potPos4);
  potPos5 = map(inputsInts[5], 0, 1023, 700, 2300);
  //if (potPos5 > 1023) potPos5 = 1023;
  //if (potPos5 < 0) potPos5 = 0;
  servo5.writeMicroseconds(potPos5);
  potPos6 = map(inputsInts[6], 0, 1023, 700, 2300);
  //if (potPos6 > 1023) potPos6 = 1023;
  //if (potPos6 < 0) potPos6 = 0;
  servo6.writeMicroseconds(potPos6);
  potPos7 = map(inputsInts[7], 0, 1023, 700, 2300);
  //if (potPos7 > 1023) potPos7 = 1023;
  //if (potPos7 < 0) potPos7 = 0;
  servo7.writeMicroseconds(potPos7);
  potPos8 = map(inputsInts[8], 0, 1023, 700, 2300);
  //if (potPos8 > 1023) potPos8 = 1023;
  //if (potPos8 < 0) potPos8 = 0;
  servo8.writeMicroseconds(potPos8);
  potPos9 = map(inputsInts[9], 0, 1023, 700, 2300);
  //if (potPos9 > 1023) potPos9 = 1023;
  //if (potPos9 < 0) potPos9 = 0;
  servo9.writeMicroseconds(potPos9);
  yawval = inputsInts[10];
  //if (yawval > 255) yawval = 255;
  //if (yawval < 0) yawval = 0;
  yaw.writeMicroseconds(map(yawval, 500, 2500, 2500, 500));
  pitchval = inputsInts[11];
  //if (pitchval > 255) pitchval = 255;
  //if (pitchval < 0) pitchval = 0;
  pitch.writeMicroseconds(pitchval);





  delayMicroseconds(500);

}

void parse() {
  int x = 1;
  int readMSB = 0;
  int recCheckSum = 0;
  int checkSum = 0;
  for (int j = 0; j <= (inputs[0] - 2); j++) {
    recCheckSum = recCheckSum + inputs[j];
  }
  if (debugOn) Serial.print("recCheckSum=");
  if (debugOn) Serial.println(recCheckSum);
  checkSum = inputs[inputs[0]];
  checkSum = inputs[inputs[0] - 1] + (checkSum << 8);
  if (debugOn) Serial.print("checkSum=");
  if (debugOn) Serial.println(checkSum);

  while ((x <= (inputs[0] - 2)) && (inputs[0] <= maxRec) && (checkSum == recCheckSum)) { //Use inputs[0] - 2 to avoid re-reading checksum.  maxRec to avoid overrun allocated memory.
    //inputsInts[(x>>1)] = inputs[x] + (inputs[x+1] << 8);
    readMSB = (int)inputs[x + 2];
    if (inputs[x] < 12) {
      inputsInts[inputs[x]] = inputs[x + 1] + ((int)readMSB << 8);
      //if (inputsInts[inputs[x]] >> 15) {
       //inputsInts[inputs[x]] = -1 * (~inputsInts[inputs[x]]);
      //}
    }
  
  x = x + 3;
  }
}
 
I hit that exact same problem doing the exact same thing.

Since then I switched to never using just int, always int16_t or uint16_t or however many bits I need, much less headaches and easier debugging when it goes wrong.
 
Status
Not open for further replies.
Back
Top