Simple change calculator

I'm fairly new to the arduino programming language, but from what i can tell, it shares some similarities to Java. So, using my pretty basic knowledge of that, I tried to adapt a simple Java application I wrote that used integer division to calculate the amount of dollars, quarters, dimes, nickels, and pennies (I live in the US) you would get back if your change was, say, $9.31 for example, using the serial monitor.

What I have now, is this:

int incomingByte = 0;
int dollar, quarter, dime, nickel, penny;

void setup() {
  Serial.begin(9600);
  Serial.println("What is the change?");
}

void loop() {
  
  
  if (Serial.available() > 0) {
    incomingByte = Serial.read();
    
    dollar = incomingByte/100;
    quarter = (incomingByte%100)/25;
    dime = ((incomingByte%100)%25)/10;
    nickel = (((incomingByte%100)%25)%10)/5;
    penny = ((((incomingByte%100)%25)%10)%5);
    
    Serial.print(dollar, DEC);
    Serial.print(" dollars, ");
    Serial.print(quarter, DEC);
    Serial.print(" quarters, ");
    Serial.print(dime, DEC);
    Serial.print(" dimes, ");
    Serial.print(nickel, DEC);
    Serial.print(" nickels, and ");
    Serial.print(penny, DEC);
    Serial.println(" pennies.");
  }
 
}

This compiles fine, and uploads with no issues, but when I open the serial monitor, and try and type in 931, I get the result below:

Any help is appreciated, and thanks in advance!

Serial.read() reads in one byte, the character "9" by itself counts as one byte with a value of 57

Serial.read() reads in one byte, the character "9" by itself counts as one byte with a value of 57

Try not to think in decimal - the character '0' (note the single quotes) has the value 0x30, and the character '7' has the value 0x37

AWOL:

Serial.read() reads in one byte, the character "9" by itself counts as one byte with a value of 57

Try not to think in decimal - the character '0' (note the single quotes) has the value 0x30, and the character '7' has the value 0x37

I knew that, but in a price calculation, it's more useful to show why he got the results he got since it's finding change for 57 cents

frank26080115:

AWOL:

Serial.read() reads in one byte, the character "9" by itself counts as one byte with a value of 57

Try not to think in decimal - the character '0' (note the single quotes) has the value 0x30, and the character '7' has the value 0x37

I knew that, but in a price calculation, it's more useful to show why he got the results he got since it's finding change for 57 cents

So, basically what your saying is that it's calculating the decimal ASCII value for each digit, instead of the value 900, 30, 1 etc. Is there any other Serial function that can read more than one byte, or maybe a function that converts the string "931" into an int, like var = scan.nextInt(); does in java while using the Scanner library?

how about this instead

allocate an array for the string

fill the string until the enter key has been hit, at which point you null-terminate and reset the write index

run strtod on the string to convert the string to a double
http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#ga5ee4d110a3bb55d2eadda05e3ebedf8a

@StormedWolf

I read your code and AWOL is correct. incomingbyte=Serial.Read() will read only a Hex value ( from 0 to 255 or 0 to FF ) and it read a byte at a time, So you need to read the bytes and place the bytes into a array. Read the incoming bytes within a for() loop. Than manipulate the array and the bytes into decimal format. And figure the following change : Twoonies, Lonnies, quarters, dime, nickel and penny <-- Opps... that is Canadian change :grin:

Is there any other Serial function that can read more than one byte

No. You have to do that using some sort of looping construct.

or maybe a function that converts the string "931" into an int

There are a couple of ways, but you don't have a string yet, so the question is academic.

Which brings up the question of how do you know how many characters there are in the string. If you need to make change for 931 cents, it hardly seems useful to program the Arduino to do that.

If you need to make change for different amounts, do you really want to have to enter the same number of digits every time? 000931 or 019238 or 182764 or 000020 or 000008. Looks a little silly, eh?

You need some way of detecting the end of a number. You should not rely on the fact that the next character will arrive within a small amount of time after the previous character, so a significant delay represents the end of a packet.

You should, instead, be sending some explicit end of packet marker. With 0022, the Serial Monitor makes that easy. There are options at the lower, right that allow you to choose what kind of end of packet marker to send.

Make the Arduino read until that marker arrives (or an unreasonable amount of time has elapsed without that marker arriving).

Read the incoming bytes within a for() loop.

How many times should that loop iterate?

@Pauls

How many times should that loop iterate?

Well if you know how many keystrokes ( numbers) , a for() loop will work. If it is unknow, well your ( Pauls) method to wait for a marker is better idea.

Well if you know how many keystrokes ( numbers) , a for() loop will work.

And there are no lost bytes - not a sure thing.