I need to read values that are coming from Python via USB serial. In Python this value is as string ascii encoded and in the arduino I read the incoming string via readString() and the convert it to int using toInt(). However, I’m only able to read until 240(I’m measuring with a oscilloscope). After this value, the output on pin D8 is zero. Why is this happening?
Arduino
String dataPy;
int inPin = 2;
int i;
int dataIn;
volatile unsigned long timeout[4];
volatile int idx = 0;
volatile unsigned long actTime;
void setup() {
//mySerial.begin(115200);
pinMode(inPin,INPUT); // set pinD2 up to input
DDRB = 1 << DDB0; // set pinD8 up to output
Serial.begin(115200);
attachInterrupt(digitalPinToInterrupt(inPin),peakID,RISING); // declarying the interrupt to be triggered
}
void loop() {
if(Serial.available()>0){ //Serial communication
//mySerial.write(itoa(dataIn,str,10)); //convert int to char array in a decimal base and sends to ard2
dataPy = Serial.readString(); // read the string inside the buffer
dataIn = dataPy.toInt(); // convert income string to int
}
actTime = millis(); // actTime stores the amount of time since the program started
for(i=0; i<4; i=i+1){
if(actTime - timeout[i] == dataIn){
timeout[i]=0; //guarantee that the pulse is generated just one time
PORTB = 1 << PORTB0; // HIGH
delayMicroseconds(50); // pulse width
PORTB = 0 << PORTB0; // LOW
delayMicroseconds(50);
}
}
}
void peakID(){ // triggered interrupt
timeout[idx] = millis(); // assign the time when the interrupt is called to an array
if (idx == 3){ // pointer setup
idx = 0;
}
else{
idx = idx+1;
}
}
Python - I’m using serialCom1 for tests
import serial
import time as t
serialCom = serial.Serial(port = 'COM9', baudrate = 115200, bytesize = serial.EIGHTBITS, parity=serial.PARITY_NONE, timeout=1) #initializing serialCom
t.sleep(1)
serialCom1 = serial.Serial(port = 'COM8', baudrate = 115200, bytesize = serial.EIGHTBITS, parity=serial.PARITY_NONE, timeout=1) #initializing serialCom
t.sleep(1)
tau = 250 #desired delay in ms
serialCom.write(str(tau).encode('ascii')) #write on serialCom
#serialCom.close()
tau1 = 180 #desired delay in ms
serialCom1.write(str(tau1).encode('ascii'))
#serialCom1.close()
The pinD2 is related to an interrupt and D8 to a output. My code is generating a delayed pulse of 50us width every time I detect a spike with my interrupt. In order to turn the process of generating pulse into something faster, I manipulated the port instead of using digitalWrite() and digitalRead().
Regarding the > or ==, a couple of days ago I was using this code and it was working perfectly. Every value from Python was being transmitted , in ASCII.
I dont know why, but it stopped working as I desire.
The pinD2 is related to an interrupt and D8 to a output. My code is generating a delayed pulse of 50us width every time I detect a spike with my interrupt. In order to turn the process of generating pulse into something faster, I manipulated the port instead of using digitalWrite() and digitalRead().
That's the reason to use the direct port manipulations when producing the pulse but that's no reason to do the same when setting the pinMode. There the few microseconds are absolutely no problem but may be confusing while reading the code.
if(Serial.available()>0){ //Serial communication
dataPy = Serial.readString(); // read the string inside the buffer
dataIn = dataPy.toInt(); // convert income string to int
This code has at least two problems:
You're using the String class. The String class is not well suited for microcontrollers with little RAM as most parts of the Arduino world. It fragments the memory in a short time and sooner than you think your code doesn't get the memory it requests. As that is not detected it simply starts to act unpredictable.
You have a timing issue. Lets say you transfer the string "250" from the PC. At the time the "if" statement is reached in the code the first two characters were already transferred. So your code reads them and stores the value 25 in dataIn. In the next round it will have the next character received ("0"), which is read and dataIn is now 0. Probably not what you expected.