2

So I'm trying to make a program that allows you to enter a number in decimal and it displays it in binary, and it's going fairly well after some initial struggles (for some reason it read integers as 48 more than they are (5 read as 53)) but there's something I still don't understand, and I'm scared that it may be a hardware issue.

For some reason, I can't display two-digit numbers. For example, if I input 12, it displays 1, and THEN it displays 2. Also, to make things worse, it ALWAYS outputs 10 after I input ANY number. For example, if I input 5, it displays 5, and then ALWAYS 10.

 void setup() {
 // put your setup code here, to run once:
 Serial.begin(9600);
 pinMode(2, OUTPUT);
 pinMode(3, OUTPUT);
 pinMode(4, OUTPUT);
 pinMode(5, OUTPUT);
}
void loop() {
 // put your main code here, to run repeatedly:
 int number;
 if (Serial.available() > 0) {
 number = Serial.read();
 Serial.print("Number to display: ");
 Serial.println(number);
 if (number <= 15){
 int LEDPin = 2;
 digitalWrite(2, LOW);
 digitalWrite(3, LOW);
 digitalWrite(4, LOW);
 digitalWrite(5, LOW);
 for (int n = 0; n <= 4; n++){
 int binval = bitRead(number, n);
 Serial.println(binval);
 digitalWrite(LEDPin, binval);
 LEDPin++;
 }
 }
 else{
 Serial.println("Number must be less than 16!");
 }
 delay(1000);
 }
}

EDIT: And of course, after asking the question I re-ran the code and its AGAIN showing ints as 48 bigger than they are (5 as 53).

At this point, I'm extremely confused. Am I doing something wrong? Is this a hardware issue? What can I do?

asked Mar 9, 2019 at 21:04
2

3 Answers 3

1

I would suggest getting the user input with Serial.readBytesUntil(), store it in a char array, then use itoa() to get the integer value. Here is a modified version of your sketch.

char inputBuffer[5];
byte number = 0;
void setup() {
 Serial.begin(9600);
 pinMode(2, OUTPUT);
 pinMode(3, OUTPUT);
 pinMode(4, OUTPUT);
 pinMode(5, OUTPUT);
}
void loop() {
 if (Serial.available() > 0) {
 Serial.readBytesUntil('\n', inputBuffer, 4);
 number = atoi(inputBuffer);
 Serial.print("Number to display: ");
 Serial.println(inputBuffer);
 if (number <= 15){
 int LEDPin = 2;
 digitalWrite(2, LOW);
 digitalWrite(3, LOW);
 digitalWrite(4, LOW);
 digitalWrite(5, LOW);
 for (int n = 0; n <= 4; n++){
 int binval = bitRead(number, n);
 Serial.println(binval);
 digitalWrite(LEDPin, binval);
 LEDPin++;
 }
 }
 else{
 Serial.println("Number must be less than 16!");
 }
 delay(1000);
 }
}
answered Mar 9, 2019 at 21:29
2
  • or use parseInt() Commented Mar 10, 2019 at 5:55
  • Using parseInt() will produce the same result as readBytesUntil() with the input buffer and atoi(). Changing the OP's sketch to useparseInt() will be 2 lines less code, but will cost you and extra 98 bytes compile size. One of the benefits of using parseInt() would be the ease at which you can parse a comma separated list of integers from the serial monitor. If the OP plans on doing anything more complicated than entering one integer, then parseInt() is the way to go. Thank you for your comment Juraj. Commented Mar 10, 2019 at 7:59
1

for some reason it read integers as 48 more than they are (5 read as 53)

That's because you're not entering numbers, you're entering ASCII characters that represent numbers.

Everything you see on a computer or similar device is not really what is there. It is all translated into a form that we mere humans can see. Every number is translated into readable characters, and readable characters have to be converted into numbers.

For example, the number 165 is the characters 1 (49), 6 (54) and 5(53). When you enter that number you are sending those three individual characters.

You see the entire ASCII table here.

Another effect of sending individual characters is that you also send a marker to say "This is the end of the line". That can either be character 13 (Carriage Return), character 10 (Line Feed), or a combination of the two. You can select which is sent in the Serial Monitor.

You should really use that line ending character or combination of characters to work out how many characters there are in your number so you can convert them into a proper integer value.

Some further reading:

answered Mar 9, 2019 at 21:29
0

Regarding your "it ALWAYS outputs 10 after I input ANY number", I had the same problem using ASCII, and I think I finally figured it out. When you use Serial.println anywhere, it will output a line feed. In ASCII that is called newline and its value is 10. I have not yet figured a way to get around that.


byte ASCII_Number;
void setup() {
 Serial.begin(9600);
}
 
void loop() {
 Serial.println("Enter any single ASCII character:");
 while (Serial.available()==0) {}
 char ASCII_Character = Serial.read();
 ASCII_Number = (int)ASCII_Character;
 Serial.print("For your ASCII Character: ");
 Serial.print(ASCII_Character);
 Serial.print(" the ASCII Number is: [");
 Serial.print(ASCII_Number);
 Serial.println("] "); // print line always generates ASCII 10 (newline).
 //This runs the loop again with a newline for the character.
 delay (5000);
 ASCII_Number = 0;
}
answered Jan 8, 2024 at 0:23
2
  • As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center. Commented Jan 8, 2024 at 0:25
  • 1
    1. The original question is about getting LF on input. 2. Serial.println() outputs both a CR (13) and LF (10). Commented Jan 8, 2024 at 8:10

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.