2
votes

I've been trying to find a way to send serial commands from my PC (Windows 7) to an Arduino Uno R3. I've been working on this simple program, where you're supposed to send a simple "1" through the USB cable, in order to turn on the onboard LED. My Arduino code should be working (what I know of, but I'll make sure to upload it). I've been trying to send this command using Python and pySerial, but I can't seem to get pySerial to work. Also I've tried using CMD, but it seems like CMD freezes when i type in my command (ECHO 1 > COM3 BAUD:9600). I'm the adminstrator of my PC.

This is my arduino coding

int var = 0;
int LEDPin = 13;
int val = 0;

void setup() {
  Serial.begin(9600);
  pinMode(LEDPin, OUTPUT);
}

void loop() {
  if (Serial.available()>0){
  val = Serial.read();
}

if (val == 1){
  digitalWrite(LEDPin, HIGH);
}

digitalRead(LEDPin);
if (LEDPin==HIGH){
  var ++;
  delay (1000);
  if(var==10){
     digitalWrite(LEDPin,LOW);
     var = 0;
     val = 0;
  }

} 
}

And the short Python program I've got :)

import serial
ser = serial.Serial('COM3', 9600, timeout=0)
while 1:
  var = 1
  ser.write(var)
  delay(12000)

With Kind Regards Michael Vedel.

6

6 Answers

0
votes

just to be sure - is Arduino really connected to COM3?

In order to check serial connection manually you can use for example Putty. With help of it you can connect to the needed serial port and send command manually. And in order to check whether Arduino received it, you can add Serial.println(val); just after val = Serial.read();, with this Arduino should sends back to serial whatever characters it receives.

0
votes

Does the code work when you type a '1' into the Serial Monitor in the Arduino IDE? If so, check the COM port. On my PC (also Windows 7), COM3 is never the Arduino port, as it is used internally for something else.

By the way everything after the digitalRead() statement will do nothing, since you're comparing LEDpin (which is declared as 13) to HIGH (which is defined as 1). I think you mean to see if the digitalRead output is HIGH, but I'm not sure that will work, either, since the pin is declared as an OUTPUT. You'd be much better off putting that logic in the (val == 1) section.

0
votes

just save this code as .bat and make sure that you are using com 6. This code lets you enter and sends your commands to serial port at 9600bpm

mode com6:9600,N,8,1
@echo off
:start
cls
Set /p commands="enter command:"
echo|set /p= %commands% >com6
goto start 

Now you have to read serial using this in Arduino

Serial.read();
0
votes

I think the root problem is in the Python code in the call to write. The argument has to be bytes (or something compatible). You're passing an integer value. You need to explicitly convert that value to a bytes object. I'm not a Python expert, but I think one way to do that is to replace:

var = 1

with

var = b'\x01'

Oh, and you might need to call flush as well.

BTW, your experiment with ECHO doesn't do what you intended. It sends the character value for '1', which is 49. Since 49 != 1, your Arduino code won't respond to it.

I find the easiest way to test serial commands is to use the Arduino Serial Monitor, which will have all the right defaults as long as you match the baud rate. This will enable you to ensure the Arduino code is right before debugging the Python code. (Then again, it may be difficult to send control characters with the Serial Monitor, so consider using printable text in your protocol. For example 'A' for on and 'B' for off. Printable text can be easy to work with among all these tools (Python, C, Serial Monitor, ECHO, etc.).)

-1
votes

do this it works better for me, just change the com4 for the port you have connected to

@echo off
:start
cls
set /p commands="enter command:"
mode com4 baud=115200 parity=n data=8 stop=1 to=on xon=off odsr=off octs=off dtr=off rts=off idsr=off && echo %commands% > com4
cls
goto start
-1
votes

I think Arduino is stable and easy enough to handle the data from serial, the cause of that as I used same library with Pyserial in python 3 was that event of reading the serial get fired once which is way faster than Arduino board and to solve that you should use a thread method that runs in the background and make it always try to read the incoming data from serial.
I've made this function that recieved the opened serial :

    def read_from_port(ser):
    while True:
        try:
            reading = ser.read().decode()
            handle_data(reading)
        except EXCEPTION:
            print("error while decoding" + str(EXCEPTION)) 

after I have got the serial from the list and assigned it with the desired baud rate and send it to the Thread :

     serial_me = serial.Serial(serial_port1, 115200, timeout=3)
     try:
       thread_x = threading.Thread(target=read_from_port, args=    (serial_me,))
        thread_x.daemon = True
        thread_x.start()
    except EXCEPTION:
        print('couldn\'t start thread')
        print(Exception)