9

I am new to Arduino (and computer programming in general), so I apologize if this question looks silly.

Once I set up a basic arduino-LED connection, I have problems sending INTEGERS to arduino through the serial port. I can easily send characters such as 'm', 'o' and so on.. However if I send a number it looks like it simply does not get it.

Here is the Arduino code, ideally it should get a value from the usb port through python or the serial monitor and then adjust the brightness of the LED according to the value. (value must be in range [0,255]).

NOTE: I am using ARDUINO UNO and PYTHON 3

//--------------------------

int LED = 10;
int number;

void setup(){

pinMode(LED,OUTPUT);
Serial.begin(9600);
}

void loop(){

number = Serial.read();
Serial.print(number);
Serial.print('\n');
if(number == -1){
number = 0;
}

else if(number > 255){

number = 255;

}

else if(number < 0){

number = 0;
}

analogWrite(LED,number);
delay(1000);
}

However, when I input a value into the Serial port or through Python, for instance 0, it gives me 48 as answer (which, interestingly, is the ASCII code for 0!) and lights up the LED which is not what should happen since at 0 the LED should be off!! I am missing something but I cannot find what... Could you please tell me what is wrong?

Here is the code I use in Python:

import serial
import time
try:
    arduino = serial.Serial(port,speed)
    time.sleep(2)
    print("Connection to " + port + " established succesfully!\n")
except Exception as e:
    print(e)

#Note: for characters such as 'a' I set data = b'a' to convert the data in bytes
#However the same thing does not work with numbers...
data = 0
data = arduino.write(valueToWrite)
time.sleep(2)
arduino.close()

what am I doing wrong or misunderstanding? Thank you.

2
  • 1
    Try arduino.write(chr(valueToWrite))
    – Gerben
    Aug 12, 2014 at 16:40
  • This solution does not work even for characters.. Furthermore, as far as characters are concerned, it works fine just sending them as bytes such as: b'm'. Anyway, thanks for the answer.
    – mickkk
    Aug 12, 2014 at 23:11

2 Answers 2

6

Parsing on the Arduino can be slow and time-consuming (which is bad if you use clock prescaling or have time-critical tasks), so let's do it in Python.

The problem is that you're sending the numbers as ASCII whereas you need to be sending them as raw binary. This is where struct comes in.

3>> import struct
3>> print(struct.pack('>B', 0))
b'\x00'
3>> print(struct.pack('>B', 255))
b'\xff'
3>> print(struct.pack('>2B', 255, 0))
b'\xff\x00'
3>> print(struct.pack('>H', 9000))
b'#('

So what you really want is:

data = arduino.write(struct.pack('>B', valueToWrite))

or something to that effect.

2
  • Thank you very much! This is exactly what I was looking for!
    – mickkk
    Aug 12, 2014 at 23:12
  • Despite what the empty comment box greyed text says, I'm going to say thanks! Was trying to write a bit-stream (FPGA .bin program file) to a SPI flash chip using a Teensy 3.2 with Arduino as the PC -> flash interface, and this was the key to making it work on the PC end.
    – KyranF
    Feb 25, 2017 at 21:22
1

Serial.read() reads only ONE character from the serial port and returns its ASCII value, which explains the 48 you got.

To read a complete number, you have 2 options:

  1. Use Serial.parseInt() that reads as many characters as needed and performs the conversion before returning the read number as an int. Please further check the reference here.
  2. You read eachn character in a loop (with Serial.read()) until the last one, put each read charcater into a buffer (char array) then convert the resulting string to a number with the standard C function atoi.

Of course, the first option is the easiest one but it will return 0 if nothing is read after a 1s timeout (configurable with Serial.setTimeout()).

1
  • This answer was not exactly what I was asking for, however it has been very useful and I'll be using it! Thank you very much for the help!
    – mickkk
    Aug 12, 2014 at 23:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.