-2

I have a problem when trying to convert a 6 digits number into three hexa decimal numbers I'm using an Arduino Nano I already did the following

  • Converting to string Hexa
  • Cutting string with substring into three other strings But my CAN library want to receive char variables So i did convert the strings to char but it lack the "0x00" and use instead just "00" And my can library (mcp_can) doesn't want that

Thanks you for reading this

  • Tried sending the strings without the "0x" suffix : didn't work
  • Tried to add the "0x" suffix to the char : didn't work
  • Tried to send decimal : didn't work
  • If I send manually something in hexa with the "0x" suffix it work

Edit : The code, i think it's horrible

    void splitAndConvert(int bignumber)
    { 
      int ID6;
      int ID7;
      int ID8; 
      String FirstPart; 
      String SecondPart;
      String ThirdPart;

      String BigNumberHexa = String(bignumber, HEX);
      
      if (BigNumberHexa.length() <= 2) {
        FirstPart = "0"; 
        SecondPart = "0";    
        ThirdPart = BigNumberHexa;
      }
      else if (BigNumberHexa.length() < 4) {
        FirstPart = "0";
        SecondPart = BigNumberHexa.substring(0,BigNumberHexa.length() - 2);
        ThirdPart = BigNumberHexa.substring(BigNumberHexa.length() - 2,BigNumberHexa.length());
      }
      else if (BigNumberHexa.length() < 6) {
        FirstPart = BigNumberHexa.substring(0,BigNumberHexa.length()-4);
        SecondPart = BigNumberHexa.substring(BigNumberHexa.length() - 4,BigNumberHexa.length() - 2);
        ThirdPart = BigNumberHexa.substring(BigNumberHexa.length() - 2,BigNumberHexa.length());
      }
      else {

      }
      ID6 = ThirdPart.toInt();
      ID7 = SecondPart.toInt();
      ID8 = ThirdPart.toInt();
            
      unsigned char DataToSend[8] = {0x00, 0x00, 0x00, 0x00, 0x00, ID6, ID7, ID8};
      can.sendMsgBuf(0x001, 0, 8, DataToSend);
}
Exosys
  • 1
  • 2
  • `std::string` objects attach a null char automatically. So if s is a string, just use `s.c_str()` to get a ptr to a classic char string. – doug Feb 25 '23 at 21:24
  • Funny story, nano uses AVR and the int is 16bit wide so -32678 .. 32767. And you can bit masking + bit shifting bytes directly, no need to convert it to strings and then incorrectly convert it back to numeric values. – KIIV Feb 25 '23 at 21:47
  • I added the code, how can i use bitmask ? I know C++ a bit but when i come to stuff like this i'm a bit lost I tried to use the str.c_str() but it return 0 – Exosys Feb 25 '23 at 21:51
  • Step 1: get rid of all signed types and start using stdint.h. `bignumber >> 8` invokes poorly-defined behavior on Arduino in case `bignumber` is `int`. – Lundin Feb 27 '23 at 09:46

1 Answers1

2

If I understand what you are trying to archieve, your code should be:

void splitAndConvert(int bignumber)
{ 
  byte ID6 = 0x00;                    // int has only two bytes on AVR architecture
  byte ID7 = (bignumber >> 8) & 0xFF; // shift right by 8 bits and mask (mask is unnecessary if you are assigning it into byte)
  byte ID8 = bignumber & 0xFF;        // again bitmask is unnecessary, it'll be cut off to fit into the byte anyway
        
  unsigned char DataToSend[8] = {0x00, 0x00, 0x00, 0x00, 0x00, ID6, ID7, ID8};
  can.sendMsgBuf(0x001, 0, 8, DataToSend);
}

And if you really want to have bigger numbers:

void splitAndConvert(int32_t bignumber)
{ 
  byte ID6 = bignumber >> 16; // shift right by 16b, ommited unnecessary mask
  byte ID7 = bignumber >> 8;  // shift right by 8b 
  byte ID8 = bignumber;       // LSB will be assigned (but with ints you'll have to use bitmasking)
        
  unsigned char DataToSend[8] = {0x00, 0x00, 0x00, 0x00, 0x00, ID6, ID7, ID8};
  can.sendMsgBuf(0x001, 0, 8, DataToSend);
}
KIIV
  • 3,534
  • 2
  • 18
  • 23
  • Yes ! Thanks you ! It's working great and it's much much quicker – Exosys Feb 25 '23 at 22:11
  • 1
    "mask is unnecessary if you are assigning it into byte" Well who knows, since `some_int >> 8` could either result in arithmetic or logical shift in case MSB is set. Arduino has 16 bit integers. The key here is to be explicit with types and never use sloppy `int` in embedded systems. – Lundin Feb 27 '23 at 09:49