I am fairly new to arduino coding. I am sending strings via serial port to and from a python program. on the Arduino code no matter what i do or command after the serial run , it skips through it. To check parts of the code, i have placed an infinite while loop after the serial communication is done. Interestingly this while loop only runs once and then goes back to the top of void loop. By that I mean the LED at pin 6 only flashes once. it even does not even flash for a second. That means it does not even execute the delay functions as well.
Please help!
Here is the code.
#include "Communicate.h"
#include "Sort.h"
String data;
Communicate Com;
Sort sr;
void setup() {
Serial.begin(115200);
Serial.setTimeout(1);
pinMode(LED_BUILTIN, OUTPUT);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(7,OUTPUT);
}
void loop() {
digitalWrite(5,LOW);
digitalWrite(6,LOW);
digitalWrite(7,LOW);
int s=0;
String p;
while(!Serial.available()){
digitalWrite(5, HIGH);
delay(200);
digitalWrite(5, LOW);
delay(200);}
if (Serial.available()>0)
{
s=Com.InOut(data); /*reads from serial and prints it*/
while(Serial.available()>0){char dump=Serial.read();} /*makes sure input buffer is clean*/
}
while(1){
digitalWrite(6,HIGH);
delay(100);
digitalWrite(7,LOW);
delay(100);} /*somehow this loop only runs once. this led blinks only once*/
}
I removed "Com" from your code and tested it on my Nano.
Because I don't have that.
I was able to confirm that I entered a while loop where the LED of pin6 blinks at high speed when serial data is received once.
Can't be reproduced in my environment...
Communication.InOut() is a method written by me. This time I am running it without the method calling. Rather I wrote the method body into the Serial.availble() block. It receives and echoes the data just like the method call. but the problem with the while(1) loop is still the same. Here is the code right now.
#include "Communicate.h"
#include "Sort.h"
String data;
Communicate Com;
Sort sr;
void setup() {
Serial.begin(115200);
Serial.setTimeout(1);
pinMode(LED_BUILTIN, OUTPUT);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(7,OUTPUT);
}
void loop() {
digitalWrite(5,LOW);
digitalWrite(6,LOW);
digitalWrite(7,LOW);
int s=0;
String p;
while(!Serial.available()){
digitalWrite(5, HIGH);
delay(200);
digitalWrite(5, LOW);
delay(200);}
if (Serial.available()>0)
{
if(Serial.available())
{
String _str=Serial.readStringUntil("\n");
delay(1000);
Serial.print(_str);
Serial.print("\n");
Serial.flush();
}
while(Serial.available()>0){char dump=Serial.read();} /*makes sure input buffer is clean*/
}
while(1){
digitalWrite(6,HIGH);
delay(3000);
digitalWrite(6,LOW);
delay(3000);} /*somehow this loop only runs once. this led blinks only once*/
}
I did some changes in the codes and it seems like whenever I open the serial from python the arduino code goes at the top of the void loop(). As if opening the serial port in the python program works as an interrupt and automatically breaks the while(1) loop in Arduino.
arduino code:
#include "Communicate.h"
#include "Sort.h"
String data;
Communicate Com;
Sort sr;
void setup() {
Serial.begin(115200);
Serial.setTimeout(1);
pinMode(LED_BUILTIN, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
}
void loop() {
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(7, LOW);
int s = 0;
String p;
while (!Serial.available()) {
digitalWrite(5, HIGH);
delay(200);
digitalWrite(5, LOW);
delay(200);
}
if (Serial.available() > 0)
{
if (Serial.available())
{
String _str = Serial.readStringUntil("\n");
delay(1000);
Serial.print(_str);
Serial.print("\n");
Serial.flush();
}
while (Serial.available() > 0) {
char dump = Serial.read(); /*makes sure input buffer is clean*/
}
}
while (1) {
digitalWrite(6, HIGH);
delay(3000);
digitalWrite(6, LOW);
delay(3000);
} /*somehow this loop only runs once. this led blinks only once*/
}
the python code :
import serial
import time
import io
import codecs
arduino = serial.Serial(port='COM4', baudrate=115200, timeout=None)
def write_read(x):
arduino.write(bytes(x, 'utf-8'))
arduino.close()
i=1
while i==1:
arduino.open()
strng = input("Write a line: ") # Taking input from user
strng="0123456789012345678901234567890123456789012 \n"
write_read(strng)
print('waiting for arduino')
value=arduino.read_until()
value=codecs.decode(value, 'UTF-8')
print(value) # printing the value
if value==strng:
print("success \n")
arduino.reset_output_buffer()
arduino.close()
else:
print("arduino timed out")
arduino.close()
i=0
time.sleep(10)
i=1
while i==1:
arduino.open()
strng = input("Write a line: ") # Taking input from user
strng="0123456789012345678901234567890123456789012 \n"
write_read(strng)
print('waiting for arduino')
value=arduino.read_until()
value=codecs.decode(value, 'UTF-8')
print(value) # printing the value
if value==strng:
print("success \n")
arduino.reset_output_buffer()
arduino.close()
else:
print("arduino timed out")
arduino.close()
during the 10 second delay in python serial communication. the LED pin at pin 6 blinks.
But when python opens the serial port. the while(1) loop breaks in arduino. this is working like an interrupt that i have not set up.
This is a problem on the Python code side.
The Arduino has a built-in auto reset circuit that is automatically reset by the DTR when the serial port is opened.
Not because it's out of the while loop, it means that the same to pressing the reset button when COM open.
Don't close or open the port at repeatedly.
Please COM open at first of code, and close COM when terminate it...
I don't know if you mentioned which Arduino you use. But most Arduinos reset when you open the serial port.
I'm not a python programmer; under Windows it should be possible to prevent this from happening. Check if there are options in python to setup the port without forcing DTR; it should be something in the line of DTRenable or so. Or open the port outside the while-loop
If you would have posted you python code in the beginning, somebody would probably straight away have been able to tell you
This is an uno board. Thanks a lot mentioning the fact that the board resets when serial port is opened. This was the problem here. Now I am trying to work around it at the python code.
In function 'void loop()':
sketch_jul01a:35:44: error: invalid conversion from 'const char*' to 'char' [-fpermissive]
35 | String _str = Serial.readStringUntil("\n");
| ^~~~
| |
| const char*
You meant: String _str = Serial.readStringUntil('\n');
Note the use of 'single quotes' for a character constant instead of "double quotes" for a string constant.
Here is the sketch simplified by removing redundant and unused code. It blinks the built-in LED fast until I send a message from Serial Monitor. Then it echoes the message and switches to blinking slowly.
void setup()
{
Serial.begin(115200);
Serial.setTimeout(1); // 1 millisecond?
pinMode(LED_BUILTIN, OUTPUT); // Not used
digitalWrite(LED_BUILTIN, LOW);
}
void loop()
{
while (!Serial.available())
{
digitalWrite(LED_BUILTIN, HIGH);
delay(200);
digitalWrite(LED_BUILTIN, LOW);
delay(200);
}
String _str = Serial.readStringUntil('\n');
Serial.println(_str);
Serial.flush();
/* makes sure input buffer is clean */
while (Serial.available())
Serial.read();
while (1)
{
digitalWrite(LED_BUILTIN, HIGH);
delay(3000);
digitalWrite(LED_BUILTIN, LOW);
delay(3000);
} /*somehow this loop only runs once. this led blinks only once*/
}