I need to convert a char array to int and i made use of atoi(). The values from the char array comes from a serial communication(Python Code) and the conversion is made inside if(Seria.available>0). This new value int will be used further in my loop to check one condition.However, I noticed that when I print the value outside the if(Serial.available()>0) it is zero.
How could I solve this problem?
Thanks
//#include<SoftwareSerial.h>
//SoftwareSerial newSerial (8,9)
int inPin = 2;
int i;
long int dataIn;
volatile unsigned long timeout[4];
volatile int idx = 0;
volatile unsigned long actTime;
const byte numChars = 5;
char receivedChars[numChars];
boolean newData = false;
static byte ndx = 0;
char endMarker = '\n';
char rc;
void setup() {
pinMode(inPin,INPUT); // set pinD2 up to input
DDRD = 1 << DDD7; // set pinD7 up to output
Serial.begin(9600);
//newSerial.begin(9600);
attachInterrupt(digitalPinToInterrupt(inPin),peakID,RISING); // declarying the interrupt to be triggered
}
void loop() {
if(Serial.available()>0){
rc = Serial.read();
if(rc!=endMarker){
receivedChars[ndx] = rc;
ndx++;
if(ndx >= numChars){
ndx = numChars - 1;
}
}
else{
receivedChars[ndx] = '\0';
ndx = 0;
newData = true;
}
if(newData == true){
int dataIn = atoi(receivedChars);
Serial.println(dataIn);
newData = false;
}
}
// Serial.println(dataIn);
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
PORTD = 1 << PD7; // HIGH
delayMicroseconds(50); // pulse width
PORTD = 0 << PD7; // LOW
delayMicroseconds(50);
}
}
}
// 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
// PORTD = 1 << PD7; // HIGH
// delayMicroseconds(50); // pulse width
// PORTD = 0 << PD7; // 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;
}
}
You are hiding the global dataIn variable in the scope of the if block. Remove the 'int' in that line and you should be good to go. Also atoi returns an int, so change your global dataIn variable type from long int to int.
I dont know why, but the income data from the serial com is probably not entering the buffer. Here how the value that is supposed to be written is declared in Python.
serialCom = serial.Serial(port = 'COM8', baudrate = 9600, bytesize = serial.EIGHTBITS, parity=serial.PARITY_NONE, timeout=1) #initializing serialCom
t.sleep(1)
tau = 200 #desired delay in ms
serialCom.write(str(tau).encode('ascii'))
You have solved the problem (to see SM shows the integer value) by--
1. Changing the code line long int dataIn; into int dataIn; in the global space and changing the code line int dataIn; into dataIn; in the loop() function.
OR
2. By enabling the 'Newline' Tab in the Serial Monitor.
I'm unable to open the serial monitor in Arduino IDE to check the output.
Not while the serial port is connected to the Python program. You can have only one thing connected to the serial port at a time. You could get a USB to TTL serial converter and set up a software serial port (or use an extra hardware port if available) to connect to serial monitor for debugging.
What do you suppose the str() and encode() bits are doing? If you guessed that they are converting the value 200 to the string "200", you win no prize. If you guessed anything else, you loose.
rc = Serial.read();
This function is reading one byte/character, NOT the entire string "200". And, it is certainly NOT reading the string "200" and making an int of it
The simplest solution to your problem is to stop having Python convert the value to string.
What do you suppose the str() and encode() bits are doing? If you guessed that they are converting the value 200 to the string "200", you win no prize. If you guessed anything else, you loose.
rc = Serial.read();
This function is reading one byte/character, NOT the entire string "200". And, it is certainly NOT reading the string "200" and making an int of it
The simplest solution to your problem is to stop having Python convert the value to string.
Thanks for the reply Paul. So I will probably have to just code like: serialCom.write(tau), right?
Crespo94:
Thanks for the reply Paul. So I will probably have to just code like: serialCom.write(tau), right?
That's one approach. It may, or may not, be the simplest, depending on what else the Python program is doing. Sending all binary data, as that change will do, or sending all ASCII data, as the original code did,is easier than mixing ASCII and binary data.
You are sending binary data. I see no point in comparing the value to endMarker. Nor, do I see any value in then storing the characters read in an array to be processed later. That is useful when you are sending ASCII data, where the "to be processed later" code converts the strings to ints or floats.
The code to read the data MUST match the code to send the data. You can't send ASCII data, as you were doing, and use binary methods to read it. You can't send binary data and use ASCII processes to read it.
Crespo94:
If it was correctly read, the red pulse should be in 200ms delayed in comparison to the peak in blue wave
I think you confused some things. The Serial interface bus can only transmit one byte at a time. This is why, when you want to send anything larger than one byte, you need to buffer the incoming data. You are doing this with this line:
receivedChars[ndx++] = rc;
This will "append" rc to the array of received characters. At some point you received all characters, but this will solely depend on what you are sending and how you are sending it. If you are sending the number 200, it might be enough to read only one byte from the serial stream and use it directly. If you are a message int the format #200* you know you have received everything, when you find a '*' to be received.
Now that received data has to be decoded somehow, but that is something only you know how to do.
In pyhton, write:
'200'.encode('utf-8')
This will send '2' '0' '0' down the serial line. In your receiver code, you count the bytes you have received and when the count hits 3 you add a '\0' to your received character array and give that to atoi.