Python serial.write() not working for NodeMCU - python

I am fairly new to hardware. I want to control an LED light using NodeMCU and Python. I uploaded an Arduino code in nodeMCU and then used pyserial library to get the serial output. But when I try to give input to the port, it doesn't work. I don't know where the problem is.
Here is the arduino code:
int inputVal = 0;
const int ledPin = 5; //D1 pin of NodeMCU
void setup() {
Serial.begin(9600);
delay(100);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, 0);
}
void loop() {
while(Serial.available()>0){
inputVal = Serial.read();
}
Serial.println(inputVal);
if(inputVal==1){
digitalWrite(ledPin, HIGH);
Serial.println("LED is ON");
}
else{
digitalWrite(ledPin, LOW);
Serial.println("LED is OFF");
}
Serial.println("");
}
Here is the python code:
import serial
global ser
ser = serial.Serial("COM8", baudrate=9600, timeout=10,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS)
while(True):
ser.write(bytes(1))
line = ser.readline()
print(line.decode('utf8'))
The output in python comes out to be:
0
LED is OFF
0
LED is OFF
0
LED is OFF
and so on. The ser.write() function isn't writing the value as 1 on the serial port. When I change the value of inputVal in Arduino code, the LED turns on and the output on arduino serial monitor comes as 1 LED is ON, which implies that the circuit connection and Arduino code is working fine.
I also noticed that the COM port that I am using can work with either python or arduino at a time. After uploading the arduino code with inputVal=1, the LED turned on and arduino serial monitor started displaying (1 LED is ON). But, as soon as I ran the python code, the led turned off and the python output came out to be 0 LED is OFF. Please help me.
Also, is there a way for me to control NodeMCU totally by python, without using arduino code first?

the output from python is correct. bytes(integer) creates an array of provided size, all initialized to null in your case size = 1, bytes(1), so the output that you have is 0x00 if you try bytes(10) the out put will be b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'.
what you need to do is to change ser.write(bytes(1)) to ser.write(bytes('1',encoding= 'utf-8')) that should work

Related

Arduino to Raspberry Pi Pyserial Communication not working on Python

I have a Python script that takes in input from a camera. It then gets the position of an object in the image and sends it to the Arduino via pyserial and usb with the following format.
"Xpos-XYPos-Y" demo: 90X90Y would move the servos I have connected to 90 degrees.
What should happen when i run bellow should be that it moves the motors.
import serial
ser = serial.Serial('/dev/ttyACM1', 9600, timeout=1)
ser.flush()
ser.write(bytes("90X90Y", encoding='utf-8'))
But what really happens... Nothing?
So I thought okay, it might just be that my code is wrong so I tried many different variations.
I would list them but then it would take way too long to read. Basically, I changed the encoding and how I turn it into bytes.
I know the problem isn't my hardware (or at least I think) because I can download the Arduino IDE
onto the pi and send serial info through there. And it works!
Here is my Arduino code:
#include <Servo.h>
// Define Objects
Servo X;
Servo Y;
// Create varibles
String learndata;
String receiveX;
String receiveY;
int moveX;
int moveY;
// Straight forward
int defX = 95;
int defY = 5;
void setup(){
Serial.begin(9600);
//Attatch servos
X.attach(6);
Y.attach(7);
}
void loop(){
if (Serial.available() > 0){
// Parse servo input
receiveX = Serial.readStringUntil('X');
receiveY = Serial.readStringUntil('Y');
moveX = receiveX.toInt();
moveY = receiveY.toInt();
X.write(moveX);
Y.write(moveY);
}//if (Serial.available() > 0){
}//void loop(){
I also tried fully updating the raspberry pi to no avail.
Any help and what I should do? Are there any alternatives?

sending serial data to arduino works in serial monitor, but not in python

I'm trying to flip a single bit on my arduino from 0 to 1 via python script. The following arduino code works great to turn on an LED if I type 1 into the serial monitor and hit enter:
int x;
void setup() {
// this code proves that the LED is working
digitalWrite(7, HIGH);
delay(300);
digitalWrite(7, LOW);
Serial.begin(115200);
}
void loop() {
Serial.print(x);
if(Serial.available()){
x = Serial.parseInt();
// if x is anything other than 0, turn the LED on
if (x){
digitalWrite(7, HIGH);
}
}
}
but when I try to use this python script, the variable x presumably stays 0 because the LED isn't turning on:
import serial
import time
arduino = serial.Serial(port='COM3', baudrate=115200, timeout=5)
time.sleep(5)
print(arduino.read())
arduino.write(b"\x01")
print(arduino.read())
arduino.close()
I put the two print statements in to try to figure out what was happening, but I can't make sense of the output. Usually it's
b'0'
b'0'
but sometimes it's
b'0'
b''
or if I run the script right after plugging the arduino in it's:
b'\x10'
b'\x02'
or some other random number.
What am I doing wrong here?
Using bytes("1", "<encoding>") instead of b"\x01" might work, where encoding is the encoding of your python file (like utf-8), although I'm not sure what the difference is.
Another possible error cause: your baud rate is enormous. For something as simple as this, you don't need such a huge baud; using the standard 9600 will work fine. Try changing the baud and see if that helps.

Raspberry send data via serial USB to Arduino Python

Hi I have connected my raspberry to arduino via serial USB and on arduino there is a led that I want turn on if in the script in python I send a letter o a number
I have write this code in raspberry Python:
import serial
ser=serial.Serial('/dev/ttyUSB0', 9600)
ser.write('3')
In my arduino I have load this skatch:
const int ledPin = 12;
int val;
void setup(){
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
void loop(){
if (Serial.available()) {
val=Serial.read();
if(vale==3)
digitalWrite(ledpin, HIGH);
}
delay(500);
}
}
When I lunch the script py from rasp, I see that led not turn on, but turn on a onboard led of arduino.
I think that the problem is the type of data like ASCII or integer but I don't understand how to fix.
Serial device is ok and is USB0 and the pin of led on arduino is right
Please help me
There is a typo in the if statement, you have put vale instead of val.
ser.write('3')
takes 3 as a string.So try this in the if statement,
if(val=='3')

Hanging python script with arduino. Need help simplifying things

Ok so what I'm trying to do is turn an LED on with one python script and off with another one. Now the problem I'm facing is my python script has to keep hanging for the LED to stay on. I can't figure out how to read something from serial, close the coms while leaving the LED on.
'g' is what I'm sending from the on python script and 'h' will be sent from the off python script.
The arduino:
void setup(){
Serial.begin(9600);
pinMode(13, OUTPUT);
Serial.write('g');
Serial.write('h');
}
void loop(){
if(Serial.read() == 'g' ){
digitalWrite(13, HIGH);
Serial.end();
}
if(Serial.read() == 'h' ){
digitalWrite(13, LOW);
Serial.end();
}
}
And the python
#! /usr/bin/python
## import the serial library
import serial
## Boolean variable that will represent
## whether or not the arduino is connected
connected = False
## open the serial port that your ardiono
## is connected to.
ser = serial.Serial("/dev/cu.wchusbserial1410", 9600)
## loop until the arduino is ready
while not connected:
serin = ser.read()
connected = True
ser.write("g")
while ser.read() == 'g':
ser.read()
## close the port
ser.close()
the 'while ser.read() parts at the bottom was just me messing about trying to figure out what I need but so far no such luck.
Thanks in advance!
In python code instead of using this serial command, simply use print command. Suppose you wanna send character g on the serial port then simply write:
print "g"
and it will be sent over to serial port. Worked for me while using Arduino YUN.
Thanks for the feedback. I used a different method and thought it would be a good idea to share the code incase anyone is interested in doing the same.
Python:
import serial
import time
arduino = serial.Serial('/dev/tty.wchusbserial1410', 9600)
time.sleep(0.1) # wait
print("initialising")
arduino.write('off') # turns LED off
print("LED OFF")
time.sleep(0.1) # wait
arduino.close() # close serial
This is the code used to turn the light off. If you want to turn it on, it's the same procedure but create another script replacing arduino.write('off') with arduino.write('on')
And Arduino:
int led = 13; // Pin 13
void setup()
{
pinMode(led, OUTPUT); // Set pin 13 as digital out
// Start up serial connection
Serial.begin(9600);
Serial.flush();
}
void loop()
{
String input = "";
// Read any serial input
while (Serial.available() > 0)
{
input += (char) Serial.read(); // Read in one char at a time
delay(5); // Delay for 5 ms so the next char has time to be received
}
if (input == "on")
{
digitalWrite(led, HIGH); // on
}
else if (input == "off")
{
digitalWrite(led, LOW); // off
}
}
The one problem with this script is after the serial coms close the light turns off. To fix this, I used a 10uF electrolytic capacitor between the ground and reset pin to keep the serial port open. (Please note: only put the cap in AFTER you've programmed the Arduino. If you need to reprogram, pull it out first.)

Random character at the beginning of serial.readline() in python and arduino

I get random characters when I perform a serial.readline(), sometimes it is other umbers and sometimes it is whole messages. The output should be "1,2" or "2,2"
Here are a couple of screenshots of the output of serial.readline().
I have tried to put a delay at before serial.readline() but it did not make a difference.
There is usually a strange character at the beginning:
I have also received strange messages:
There is a problem later on in the program that causes the program to hand because sometimes I just receive a blank line.
Is there a way to get consistent output from serial?
Here is the arduino code:
void setup() {
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
Serial.begin(9600);
}
void loop(){
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
if (buttonState == HIGH) {
// turn LED on:
digitalWrite(ledPin, HIGH);
Serial.println("1,2");
}
else {
// turn LED off:
digitalWrite(ledPin, LOW);
Serial.println("2,2");
}
}
And here is the python code:
ser = serial.Serial('/dev/ttyUSB0', 9600)
line=ser.readline()
coord= line.strip()
print coord
EDIT:
I tried putting ser.flushInput() after the ser.open() and I get the same output.
Have you flushed the serial buffer
ser.flushInput()
I've been having the same issue when interfacing between pyserial and Arduino. This may be an old post, but in case someone else is having the same trouble, I remedied my problem by inserting:
ser.flushInput()
...right before my ser.readline() call.
How to Read serial data from an Arduino in Linux
Nothing fancy here. I’m getting the current port configuration, setting the input/output speed to 9600 baud, setting the data expectations to be 8 bits per word, with no parity bit and no stop bit, setting canonical mode, and then committing those changes back to the serial port.
If I am not mistaken you have to change the mentioned settings when connecting through serial port.
You do not mention it, but I guess you are using the pySerial library. Regardless you can use it with the correct settings to connect through serial. The constructor of the API allows all the parameters which are noted below:
Pyserial Library
I have not tested this approach as I have had a similar problem in C not Python.
What happens if you break it down to something simpler?
On the Arduino:
void setup()
{
Serial.begin(9600);
}
int i = 0;
void loop()
{
delay(1000);
Serial.print("Hello World ");
Serial.println(i);
i++;
}
And in the Python REPL...
import serial
ser = serial.Serial('/dev/ttyUSB0', 9600)
while(1):
ser.readline()
The first behavior you should observe is that when you initiate the serial connection, the Arduino reboots. This takes a few seconds.
The second behavior you should observe is that (if you're typing this in the REPL slowly) when the while(1) loop begins, you get all of the serial data that had accumulated since you initiated the serial connection. It takes me a few seconds to type all that out, so when I hit Enter after ser.readline() I see:
'Hello World 1\r\n'
'Hello World 2\r\n'
'Hello World 3\r\n'
I only mention this to make sure you're familiar with two things that burned me a bit the last time I messed with serial communication to an Arduino: it needs time to reboot after connecting, and the serial data buffers. readline() will only give you one line in the buffer - not everything that's in the buffer.
Is it possible you're trying to sent/receive data before it's done rebooting? What about button bounce - could a dozen high/low state detections be messing something up?

Categories