Long integer to uint8_t

Hi,
I have long integer which contains 7 numbers. I need convert to uint8_t.

If I do "brutal"

long integer = 1234567;
uint8_t data[] = integer;

I get:
initializer fails to determine size of 'data'

I have read (and tried) about sprintf(); and ltoa(); but no results :frowning:

Thanks
Einars!

Thanks!

But I need the same number not opposite :stuck_out_tongue:

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

}

void loop() {
  // put your main code here, to run repeatedly:
  long integer = 1234567;
uint8_t digits[7];

for(int i = 0; i < 7; i++){
     digits[i] = integer % 10;  // remainder of division with 10 gets the last digit
     integer /= 10;     // dividing by ten chops off the last digit.
     Serial.print(digits[i]);
     if(digits[i] == digits[6]){
      Serial.println();
     }
  }

}

As you mentioned output is 7654321. I need this integer send via 2.4Ghz wireless. That's why I need get long to uint8_t.

How does 1234567 fit into uint8_t which has a numeric range from 0 through 255? If you want the ASCII string, that's pretty easy to do.

I need send wirelessly 7 digits number.

Integer -> String -> uint8_t -> nRF24 -> Char -> Integer.

 uint8_t data[] = "Hello World!";  <------ I need there long integer
  nrf24.send(data, sizeof(data));

I am beginner in C. I know little bit PHP, Flash Actionscript, Javascript.

Einars!

Is this what you are trying to do? Forget about using the String class...that's a crutch you need not pick up. Use char arrays (i.e., a C string) instead. It will save you memory.

void setup() {
  Serial.begin(9600);

  char message[10];
  int i;
  long val = 1234567;

  Serial.print("The value is: ");               // Show the integer number
  Serial.println(val);

  ltoa(val, message, 10);
  
  Serial.print("As a string: ");
  for (i = 0; i < strlen(message); i++) {
    Serial.print(message[i]);                   // Show as a string
  }
}

void loop() {
}

On the receiving side, use atol() to convert message[] back to a long.

Einars:
I need send wirelessly 7 digits number.

Integer -> String -> uint8_t -> nRF24 -> Char -> Integer.

 uint8_t data[] = "Hello World!";  <------ I need there long integer

nrf24.send(data, sizeof(data));




I am beginner in C. I know little bit PHP, Flash Actionscript, Javascript.

Einars!

you could play around with sprintf() to do what you want:

uint32_t myNumber = 1234567;
void setup()
{
  Serial.begin(9600);
  char myArray[8] = "";
  sprintf(myArray, "%lu", myNumber);
  for (int i = 0; i < 7; i++)
  {
    Serial.println(myArray[i]);
  }
}

void loop()
{
  
}

sprintf() is a very powerful function and most Arduino programs don't need all of its power...just a small subset of it. As a result, the code size increases significantly...moreso than the gained functionality warrants. My version uses 2440 bytes of program space while the sprintf() version uses 3392 even though they are functionally about the same...almost a 40% increase in program size.

econjack:
sprintf() is a very powerful function and most Arduino programs don't need all of its power...just a small subset of it. As a result, the code size increases significantly...moreso than the gained functionality warrants. My version uses 2440 bytes of program space while the sprintf() version uses 3392 even though they are functionally about the same...almost a 40% increase in program size.

well, whoop-dee-doo for you!!!

maybe you can patent that algorithm...

well, whoop-dee-doo for you!!!

@BulldogLowell: Why the attitude? The OP is a beginner so why not tell him about the resources used when sprintf() is added to the code? That said, saying a function uses up memory without showing an alternative by which it can be judged seems to be missing the point, hence the comparison. The snarky remark was uncalled for.

econjack:
@BulldogLowell: Why the attitude? The OP is a beginner so why not tell him about the resources used when sprintf() is added to the code? That said, saying a function uses up memory without showing an alternative by which it can be judged seems to be missing the point, hence the comparison. The snarky remark was uncalled for.

@econJack,

It's a forum dude, a place for idea exchange... even some learning. Showing an alternative method, albeit using sooooooo much resource, is part of it.

I presented an alternative, a very easy-to-understand function that provides a lot of utility (and actually did what the OP was looking to accomplish)

:wink:

I'll try to pay more attention to your delicate sensibilities, nonetheless.

If what you're looking for is to send integer or long values to a serial device which expects byte-sized data, these routines might be helpful:

void WriteInt( int value )
{
  // Write high byte, low byte
  Serial.write( ( unsigned char )( value >> 8 ) );
  Serial.write( ( unsigned char )value ); 
}

void WriteLong( long value )
{
  // Write high word, low word
  WriteInt( ( unsigned int )( value >> 16 ) );
  WriteInt( ( unsigned int )value ); 
}

To read the data that was sent using the routines above, use these functions:

int ReadInt( )
{
  int value = Serial.read( );
  value = ( value << 8 ) + Serial.read( );
  
  return value;
}

long ReadLong( )
{
  long value = Serial.read( );
  value = ( value << 8 ) + Serial.read( );
  value = ( value << 8 ) + Serial.read( );
  value = ( value << 8 ) + Serial.read( );
  
  return value;
}

Note that "Serial.read( )" and "Serial.write( )" used in these examples just represent any serial device that expects byte sized data. The bytes could just as easily be coming from or going in to an array declared as storing uint8_t.

long myNumber = 1234567;
void setup()
{
  Serial.begin(9600);
  char myArray[8] = "";
  sprintf(myArray, "%lu", myNumber);
  for (int i = 0; i < 7; i++)
  {
   
    uint8_t int8[8] = myArray[i];
    Serial.print(int8[8]);
  }
}

void loop()
{
  
}
int_to_uint8_t.ino: In function 'void loop()':
int_to_uint8_t:16: error: array must be initialized with a brace-enclosed initializer
array must be initialized with a brace-enclosed initializer

Einars:

long myNumber = 1234567;

void setup()
{
 Serial.begin(9600);
 char myArray[8] = "";
 sprintf(myArray, "%lu", myNumber);
 for (int i = 0; i < 7; i++)
 {
 
   uint8_t int8[8] = myArray[i];
   Serial.print(int8[8]);

[quote author=Einars link=msg=2494948 date=1448479052]
[code]long myNumber = 1234567;
void setup()
{
  Serial.begin(9600);
  char myArray[8] = "";
  sprintf(myArray, "%lu", myNumber);
  for (int i = 0; i < 7; i++)
  {
   
    uint8_t int8[8] = myArray[i];
    Serial.print(int8[8]);
  }
}

void loop()
{
  
}
int_to_uint8_t.ino: In function 'void loop()':
int_to_uint8_t:16: error: array must be initialized with a brace-enclosed initializer
array must be initialized with a brace-enclosed initializer

[/quote]

Did the example I posted compile for you?

I would expect that your code above wouldn't compile without errors![/code]

It's a forum dude, a place for idea exchange... even some learning.

@BulldogLowell: I absolutely agree. I was simply pointing out...as part of the learning experience...that sprintf() has a lot of power, but most of it goes unused. As a result, the OP's task at hand could also be written in another way that uses less memory. I just compiled both forms to show the size difference. Hopefully, the OP learned something in the process.

I presented an alternative, a very easy-to-understand function...

I taught university-level C/C++ programming courses for almost three decades and sprintf() is not an easy function for beginning programmers to understand. Most would have much less difficulty understanding ltoa().

I'll try to pay more attention to your delicate sensibilities...

When not warranted, I hope you'll be more considerate of all people who post here, not just me. As to patenting the algorithm, I already have a software patent (US Patent #5,018,207) and don't need the hassle of getting another one.

Delta_G:
No, the array has the last number in element 1 but that doesn't mean you have to use it first.

If that really bothers you then reverse the for loop so it starts putting them in the last array slot and works backwards:

for (int i = 6; i >= 0; i--){

data[i] = integer % 10;
   integer /= 10;
}




_*And now the 1 will be in data[0] and the 7 will be in data[6].*_
_*Or you could have printed them in a loop working the other way. It doesn't matter. You've got the digits separated which is what you wanted. You can print them out in any order you like. *_
_*Or since you seem to have missed the question that went with that comment, you would notice that was to get out the actual numbers. If you are printing then you don't really care about the numbers you want the ascii text representations of those numbers. You could do that without ever separating the digits. You weren't real clear about what you really wanted to do with this number. *_
_*This is a case of the XY problem where instead of osking how to do what you actually want you are instead asking how to accomplish some unrelated thing that is how you think it should be done. If you describe what you actually need, the ends to these means, maybe the answers will get a little more relevant to you. *_

I have raw sensor data. I want send through the nrf24l01+ transceiver. I have chosen Radiohead library (RadioHead: RadioHead Packet Radio library for embedded microprocessors).

// nrf24_client.pde
// -*- mode: C++ -*-
// Example sketch showing how to create a simple messageing client
// with the RH_NRF24 class. RH_NRF24 class does not provide for addressing or
// reliability, so you should only use RH_NRF24 if you do not need the higher
// level messaging abilities.
// It is designed to work with the other example nrf24_server.
// Tested on Uno with Sparkfun NRF25L01 module
// Tested on Anarduino Mini (http://www.anarduino.com/mini/) with RFM73 module
// Tested on Arduino Mega with Sparkfun WRL-00691 NRF25L01 module

#include <SPI.h>
#include <RH_NRF24.h>

// Singleton instance of the radio driver
RH_NRF24 nrf24;
// RH_NRF24 nrf24(8, 7); // use this to be electrically compatible with Mirf
// RH_NRF24 nrf24(8, 10);// For Leonardo, need explicit SS pin
// RH_NRF24 nrf24(8, 7); // For RFM73 on Anarduino Mini

void setup() 
{
  Serial.begin(9600);
  while (!Serial) 
    ; // wait for serial port to connect. Needed for Leonardo only
  if (!nrf24.init())
    Serial.println("init failed");
  // Defaults after init are 2.402 GHz (channel 2), 2Mbps, 0dBm
  if (!nrf24.setChannel(1))
    Serial.println("setChannel failed");
  if (!nrf24.setRF(RH_NRF24::DataRate2Mbps, RH_NRF24::TransmitPower0dBm))
    Serial.println("setRF failed");    
}


void loop()
{
  Serial.println("Sending to nrf24_server");
  // Send a message to nrf24_server
  uint8_t data[] = "Hello World!";
  nrf24.send(data, sizeof(data));
  
  nrf24.waitPacketSent();
  // Now wait for a reply
  uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];
  uint8_t len = sizeof(buf);

  if (nrf24.waitAvailableTimeout(500))
  { 
    // Should be a reply message for us now   
    if (nrf24.recv(buf, &len))
    {
      Serial.print("got reply: ");
      Serial.println((char*)buf);
    }
    else
    {
      Serial.println("recv failed");
    }
  }
  else
  {
    Serial.println("No reply, is nrf24_server running?");
  }
  delay(400);
}
Serial.println("Sending to nrf24_server");
  // Send a message to nrf24_server
  uint8_t data[] = "Hello World!";
  nrf24.send(data, sizeof(data));
  
  nrf24.waitPacketSent();

I need replace "Hello World!" with sensor long integer which consists 7 digits. It is only what I need.
Thanks!!!

Readings:

Readings:
Reading: -0.009 KG
8234217
Reading: -0.006 KG
8234216

...

I need send these numbers to another Arduino. Nothing more. Read function from scale: long read();

I want make wireless scales.

agree with @Delta_G...

Just break up your int32_t into four bytes and transmit like (for example) this way:

union DataUnion{
  long reading;
  byte txByte[4];
};


void setup()
{
  Serial.begin(9600);
  DataUnion mySensor;
  mySensor.reading = 1234567; // pseudo code, use your function that returns your long
  Serial.println(mySensor.reading, HEX);
  for (byte i = 0; i < 4; i++)
  {
    //transmit(mySensor.txByte[3-i]); // pseudo function to send via RF
    Serial.print(mySensor.txByte[3-i], HEX);
  }
  Serial.println();
}

void loop()
{
  
}

and assemble the four bytes similarly on the other Arduino...

I printed in HEX to show you how the Union breaks up the four bytes that make up the long.

Is your scale really accurate to one part in 8 million? From the numbers in reply #20, it looks like there's an offset you haven't removed.

@Bulldog, the only really legitimate use for a union is for memory re-use. The order of the contents is implementation defined and not guaranteed to follow any particular plan. If the code at both ends is compiled by the same compiler for the same architecture, you should be okay, but it isn't really portable.

aarg:
@Bulldog, the only really legitimate use for a union is for memory re-use. The order of the contents is implementation defined and not guaranteed to follow any particular plan. If the code at both ends is compiled by the same compiler for the same architecture, you should be okay, but it isn't really portable.

I disagree, I think this is a VERY legitimate use of a union for Arduino.

If you want to port this C++ code to an iPhone app, yeah maybe you are right!!!

I read this:

I need send these numbers to another Arduino. Nothing more.

and understood it literally. :wink: