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.
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.
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.
@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.
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
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. *_
// 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!!!
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.
@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.