# handling of large numbers from serial data

I am building a display unit to show prices of products, which can be packed 10 or 20 per box.
There will be a lot of different products, but I will start with just one product, to get my head round it.

I have the tenbox price at the top showing up to 999.99
below that is the twentybox price also showing up to 999.99
Then there is a "save" display which only needs to go to 99.99 ( and will be 2xtenbox - twentybox )

The data for updating the prices will be coming in via serial with a buffer holding 10 bytes, each of which will be 0-9 representing one 7segment display.
This I can display easily, but my problem comes with the "save" calculation.

Should I convert each price to a long representing the price in cents ( by bitshifting, and perhaps upper and lower byte ? ), do the subtraction and ,then converting back to integer.

or should I do the same in decimal by multiplying each byte by ten and adding the next byte five times to get a 5 digit long cent decimal value, do the subtraction, then convert back with divide by ten and modulo to get the digits to display.

Why not just save as a byte/display? Get 5 digits coming in, including leading 0s, save them that way. Map to the seven segments in software.

Yes, thats what I do for the display side, but how do you do the subtracting ?

Boffin1:
or should I do the same in decimal by multiplying each byte by ten and adding the next byte five times to get a 5 digit long cent decimal value, do the subtraction, then convert back with divide by ten and modulo to get the digits to display.

I'd think there would be plenty of times when you want the incoming data saved as an integer. I'm sure there are better ways to read in ASCII characters to a numeric value but here is one example.

``````    if (lrfSerial.available() > 0) // If there are any bytes available to read, then the LRF must have responded
{
//lrfData[offset] = lrfSerial.read();  // Get the byte and store it in our buffer
newInputValue = lrfSerial.read();  //
if (newInputValue == ':')          // If a ":" character is received, all data has been sent and the LRF is ready to accept the next command
{
range = inputNumber; // use previousRange in other parts of the program, previousRange needs to be defined elsewhere
inputNumber = 0; // reset local range for next read
break;               // Break out of the loop
}
else if ((newInputValue >= '0') && (newInputValue <= '9'))
{
inputNumber *= 10; // get ready to add next digit
inputNumber += newInputValue - '0'; // convert the ASCII character to a number and add it to the value of range.
}

}
``````

I thought I saw an example in the Arduino IDE of how to do something like this. I'm sure the example code does it better than my hack.

I don't think it would be hard to break the integer back into the single digits when you're ready to display the number. Use a variable to keep track of how many decimal places the value has been shifted. It wouldn't be hard to watch for the incoming decimal point if you didn't want to use a set decimal value.

BTW, The code above was to read the range value from a laser rangefinder. Let me know if you need me to decipher any of the code.

Make sure and change the end of message character to match your protocol.

Thanks guys, I tried doing it the integer way, and couldn't get modulo to work properly, so I did a basic sketch as below and it works.

``````int a = 2;  //  digits as they come in for displays
int b = 1;
int c = 4;
int d = 6;
int e = 5;
int f = 3;
int g = 4;
int h = 7;
int i = 5;
int j = 8;
int k ;  //  digits to generate for save displays
int l ;
int m ;
int n ;

long top = 0;
long bottom = 0;
int save = 0;
long temp = 0 ;
void setup () {

Serial.begin(9600);
}
void loop ()
{
temp = 0;
temp = temp + e;
temp = temp + 10 * d;
temp = temp + 100 * c;
temp = temp + 1000 * b;
temp = temp + 10000 * a;
top = temp;
Serial.print(" top = ");    Serial.println(top);

temp = 0;
temp = temp + j;
temp = temp + 10 * i;
temp = temp + 100 * h;
temp = temp + 1000 * g;
temp = temp + 10000 * f;
bottom = temp;
Serial.print(" bottom = ");    Serial.println(bottom);

if ( top * 2 > bottom ) {   //  dont want negative save
save = top * 2 - bottom;
Serial.print(" save = ");     Serial.println(save);
temp = 0;
k = save / 1000;     Serial.print(" k= ");     Serial.println(k);
temp = save - 1000 * k ;
l = temp / 100;  Serial.print(" l = ");     Serial.println(l);
temp = temp- 100 *l;
m = temp / 10;   Serial.print(" m = ");     Serial.println(m);
n = temp - 10 * m;  Serial.print(" n = ");     Serial.println(n);
}
else
{ k=0;l=0;m=0;n=0; temp = 0;}

Serial.print(" save digits= "); Serial.print(k); Serial.print(l); Serial.print(m); Serial.print(n);
delay ( 20000 );
}
``````

The examples in Serial Input Basics are simple reliable wasy to receive data. There is also a parse example to convert ascii data to integers or floats.

...R

Thanks Robin

That looks very interesting, I will have a read through when I get some time.