Best way to convert an unsigned int array to a signed decimal number

I'm reading in some data in little endian, something like

247 249 255 255

And in big endian is

255 255 249 247

which is in an unsigned int array and in hex is

FF FF F9 F7

Which I need to convert to -1545 which is the signed decimal form of 0xFFFFF9F7

Not sure what the most efficient way is .

I'm reading in some data

That implies you have some code. Why didn't you post it?

#include <FlexCAN.h>
#include <kinetis_flexcan.h>


String dataIN = "";
unsigned int test[4];
uint8_t test2;
unsigned char buff[4];
String crIN = "";
short CR = 10;
int led = 13;
int end2 = 7;
int end1 = 55;
// create CAN object
FlexCAN canBus(1000000);
static CAN_message_t msg;


void setup() {
 // init CAN bus
 canBus.begin();
 pinMode(led, OUTPUT); 
 delay(1000);
 Serial.println("Teensy 3.2 CAN Test.");
 Serial.println("Press -> t <- Test 1");
 Serial.println("Press -> r <- Test 2");
}

void loop() {
  if (Serial.available() > 0) {
    dataIN = Serial.readStringUntil(CR);
    crIN = Serial.readString();

    // --------------- Test 1 --------------- // 
    if(dataIN == 't'){
     
       // ========== Sending ========== //
       digitalWrite(led, 1);
       msg.id = 0x620;
       msg.len = 8;
       msg.buf[0] = 0x40;
       msg.buf[1] = 0x64;
       msg.buf[2] = 0x60;
       msg.buf[3] = 0x00;
       msg.buf[4] = 0x00;
       msg.buf[5] = 0x00;
       msg.buf[6] = 0x00;
       msg.buf[7] = 0x00;
       Serial.println("========== Sending ==========");
       canBus.write(msg);        
       delay(500);
       digitalWrite(led, 0);

       // ========== Receiving ========== // 
       while(canBus.read(msg)) {
         dataIN = Serial.readStringUntil(CR);          
         Serial.println("========= Receiving =========");
         for(int i=0; i<msg.len; i++) {
           digitalWrite(led, 1);
           Serial.print(msg.buf[i], HEX); 
           if (i > 3) {
             test[7-i] = msg.buf[i]; 
           }
           Serial.print(" ");
           digitalWrite(led, 0);
         }
         Serial.println("");
         Serial.println(msg.id, HEX);
         for (int i = 0; i < 4; i++) {
           test2 = test[i];         
           Serial.print(test2);
           Serial.print(" ");
         }
         Serial.println("");
         


         if ((msg.buf[8] == end1) || (dataIN == 'q')){
           break;
         }
       }
    }

    // --------------- Instructions --------------- // 
    else{
      Serial.println("Press -> t <- Test 1");
      Serial.println("Press -> r <- Test 2");
      digitalWrite(led, 0);
    }
  }
}

Welcome to the Forum. Please read these two posts:

How to use this forum - please read.
and
Read this before posting a programming question ...
You may also find useful information that would answer your question here:
Useful links - check here for reference posts / tutorials

You have posted code without using code tags. The code tags make the code look

like this

when posting source code files. It makes it easier to read, and can be copied with a single mouse click. Also, if you don't do it, some of the character sequences in the code can be misinterpred by the forum code as italics or funny emoticons. The "Code: [Select]" feature allows someone to select the entire sketch so it can be easily copied and pasted into the IDE for testing.
If you have already posted without using code tags, open your message and select "modify" from the pull down menu labelled, "More", at the lower left corner of the message. Highlight your code by selecting it (it turns blue), and then click on the "</>" icon at the upper left hand corner. Click on the "Save" button. Code tags can also be inserted manually in the forum text using the code and /code metatags.

Unless the sketch is too large, it's better if you post your code, rather than attach it. When it's attached, we have to download it, create a folder then open your code in our IDE. And afterwards, the folder remains unless we navigate to the "Temp" folder and manually remove it. It's much easier to just view the code in your post.

One thing I noticed, is that you have total control over what order you read the bytes in msg.buf[]. Why not just store them in the endian-ness that you desire? You lost track when you stored them as 16 bit ints. They are probably bytes. You can use a union to create a long word that you can store bytes in.

If you read the code that is what I did. All stored in an unsigned int array in big endian. Some solutions for int, hex, string, char conversions that I have found can be easily changed for either so i didn't want to rule out a conversion from the read in little endian. simpler code is better code.

kvasir:
If you read the code that is what I did. All stored in an unsigned int array in big endian. Some solutions for int, hex, string, char conversions that I have found can be easily changed for either so i didn't want to rule out a conversion from the read in little endian. simpler code is better code.

You are lecturing me on simplicity? I gave you the simple solution. Also, you have not yet followed the forum guidelines on posting code which makes it hard to read, so many people are likely to ignore it.

Reading bytes into an array of 16 bit ints is hardly conducive to any kind of simplicity.

Didn't mean to offend. I'll give your suggestion a shot. I'm use to C#, Java, and Python than C. Time to go hunt down the union command.

kvasir:
Didn't mean to offend. I'll give your suggestion a shot. I'm use to C#, Java, and Python than C. Time to go hunt down the union command.

It's the standard approach in AVR C++. You can also use bit shifting if you want more platform independence but it is rarely important with Arduino sketches.

Basically, I am saying that if you assign the bytes in the right order, there is no need to convert endian-ness later.

  Serial.println("Press -> t <- Test 1");
  Serial.println("Press -> r <- Test 2");
}

void loop() {
   if (Serial.available() > 0) {
     dataIN = Serial.readStringUntil(CR);

Why on earth do you need to piss away resources on the String class to read ONE letter?

I'll clean up my code later. This was primarily a trivial example and apparently a some snarky people hang around arduino forums. It's about as bad as an Arch Linux forum. Anyways here is the solution to anyone else who looks

          if (buf[0] == 255) {
            PositionVal = (~(buf[0] + (buf[1] << 8) + (buf[2] << 16) + (buf[3] << 24)))+1;
            Serial.print("-");
            Serial.println(PositionVal);
          }
          else {
            PositionVal = buf[0] + (buf[1] << 8) + (buf[2] << 16) + (buf[3] << 24);
            Serial.println(PositionVal);
          }

For big endian just use

uint32_t myInt1 = (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];

Keep the change, ya filthy animals!

Apparently too trivial... it doesn't work. Not unless buf[] is unsigned long or uint32_t. You can't left shift a 16 bit expression by 24 bits.

byte buf[] = {1,1,1,1};

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  uint32_t myInt1 = (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];
  Serial.println (myInt1, HEX);
}

void loop() {
}

output:

101

Yup snarky as ever, aaaaaaand it works. You guessed correct.

uint8_t buf[4];
int PositionVal;

Output:

========== Sending =========
========= Receiving =========
67 100 96 0 84 241 255 255
5A0
-3756
54 F1 FF FF

I have no idea what you mean. Honestly. Not snarky. I really didn't guess anything. I just showed you an error. If it worked as you showed, my example sketch would print, "1010101", not "101".

Welp It works here, Gives the correct value for the position of the motor as compared to the default PID controller.

#include <FlexCAN.h>
#include <kinetis_flexcan.h>

/*
// ========== Receiving ========== // 
while(CANReceiver.read(msg)) {
  // toggle LEDs
  
  Serial.print("Receiving: ");
  for(int i=0; i<msg.len; i++) {
    Serial.print(msg.buf[i]); 
    Serial.print(" ");
  }
  Serial.println("");
}

// ========== Sending ========== //
Serial.print("Sending: ");
msg.id = 0x222;
msg.len = 8;
for(int i=0; i<msg.len; i++) { 
  msg.buf[i] = i + '0';
  Serial.print(msg.buf[i]); Serial.print(" ");
}
Serial.println("");
canBus.write(msg);

delay(500);
*/

String userInput = "";
uint8_t buf[4];
int PositionVal; 
String crIN = "";
short CR = 10;
int led = 13;
int end2 = 7;
int end1 = 55;
// create CAN object
FlexCAN canBus(1000000);
static CAN_message_t msg,rxmsg;


void setup() {
  // init CAN bus
  canBus.begin();
  pinMode(led, OUTPUT); 
  delay(1000);
  Serial.println("Teensy 3.2 CAN Test.");
  Serial.println("Press -> t <- Test 1");
  Serial.println("Press -> r <- Test 2");
}

void loop() {
   if (Serial.available() > 0) {
     userInput = Serial.read();

     // --------------- Test 1 --------------- // 
     if(userInput == 't'){
      
        digitalWrite(led, 1);
        msg.id = 0x620;
        msg.len = 8;
        msg.buf[0] = 0x40;
        msg.buf[1] = 0x64;
        msg.buf[2] = 0x60;
        msg.buf[3] = 0x00;
        msg.buf[4] = 0x00;
        msg.buf[5] = 0x00;
        msg.buf[6] = 0x00;
        msg.buf[7] = 0x00;
        Serial.println("========== Sending ==========");
        canBus.write(msg);        
        delay(500);
        digitalWrite(led, 0);

        while(canBus.read(rxmsg)) {
          userInput = Serial.readStringUntil(CR);          
          Serial.println("========= Receiving =========");
          for(int i=0; i<rxmsg.len; i++) {
            digitalWrite(led, 1);
            Serial.print(rxmsg.buf[i]); 
            if (i > 3) {
              buf[i - 4] = rxmsg.buf[i]; 
            }
            Serial.print(" ");
            digitalWrite(led, 0);
          }
          Serial.println("");
          Serial.println(rxmsg.id, HEX);
          if (buf[0] == 255) {
            PositionVal = (~(buf[0] + (buf[1] << 8) + (buf[2] << 16) + (buf[3] << 24)))+1;
            Serial.print("-");
            Serial.println(PositionVal);
          }
          else {
            PositionVal = buf[0] + (buf[1] << 8) + (buf[2] << 16) + (buf[3] << 24);
            Serial.println(PositionVal);
          }
          

          for (int i = 0; i < 4; i++) {;         
            Serial.print(buf[i], HEX);
            Serial.print(" ");
          }
          Serial.println("");
          


          if ((rxmsg.buf[7] == end1) || (userInput == 'q')){
            break;
          }
        }
     }

     // --------------- Test 1 --------------- // 
     else if(userInput == 'r'){
      
        digitalWrite(led, 1);
        msg.id = 0x004;
        msg.len = 1;
        msg.buf[0] = 2;
        Serial.println("========== Sending ==========");
        canBus.write(msg);        
        delay(500);
        digitalWrite(led, 0);

        while(canBus.read(rxmsg)) {
          
          Serial.println("========= Receiving =========");
          for(int i=0; i<rxmsg.len; i++) {
            digitalWrite(led, 1);
            Serial.print(rxmsg.buf[i]); 
            Serial.print(" ");
            digitalWrite(led, 0);
          }
          Serial.println("");
          Serial.println("");

          if (rxmsg.buf[7] == end2){
            break;
          }
        }
     }

     // --------------- Instructions --------------- // 
     else{
       Serial.println("Press -> t <- Test 1");
       Serial.println("Press -> r <- Test 2");
       digitalWrite(led, 0);
     }
   }
}

kvasir:
Welp It works here, Gives the correct value for the position of the motor as compared to the default PID controller.

Maybe the range of data values that it handles happens to not exceed 2^16. If that is the case you would not see any error.

Yeah an overflow will likely never happen. At most these values get up 2^14. The indexing of the motion of the motor is fairly small and only four hex bytes are used to hold the position value.