Currently i have a project that forced me to make a program that receives several data from Serial Input using Interrupt in Arduino. I use Arduino as the receiver and ESP32 as the sender through Hardware Serial. The program i have written for Arduino is as posted at Serial Input Basics with a few changes as written below :
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars]; // temporary array for use when parsing
// variables to hold the parsed data
char messageFromPC[numChars] = {0};
unsigned long sendDataPrevMillis = 0;
int controlCondition = 0;
int droneCondition = 0;
int gasValue = 0;
int pitchValue = 0;
int rollValue = 0;
int yawValue = 0;
boolean newData = false;
void setup() {
attachInterrupt(digitalPinToInterrupt(1), handleInterrupt, RISING);
Serial.begin(57600);
}
void loop() {
Serial.print("Control Condition :");
Serial.print(controlCondition);
Serial.print(" Drone Condition :");
Serial.print(droneCondition);
Serial.print(" Roll:");
if(rollValue < 1500)Serial.print("<<<");
else if(rollValue > 1500)Serial.print(">>>");
else Serial.print("-+-");
Serial.print(rollValue);
Serial.print(" Pitch:");
if(pitchValue > 1500)Serial.print("^^^");
else if(pitchValue < 1500)Serial.print("vvv");
else Serial.print("-+-");
Serial.print(pitchValue);
Serial.print(" Gas:");
if(gasValue < 1500)Serial.print("vvv");
else if(gasValue > 1500)Serial.print("^^^");
else Serial.print("-+-");
Serial.print(gasValue);
Serial.print(" Yaw:");
if(yawValue < 1500)Serial.print("<<<");
else if(yawValue > 1500)Serial.print(">>>");
else Serial.print("-+-");
Serial.println(yawValue);
}
void handleInterrupt(){
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial.available() && newData == false) {
rc = Serial.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
if (newData == true) {
strcpy(tempChars, receivedChars);
char * strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(tempChars, ",");
controlCondition = atoi(strtokIndx);
strtokIndx = strtok(NULL, ",");
droneCondition = atoi(strtokIndx);
strtokIndx = strtok(NULL, ",");
gasValue = atoi(strtokIndx);
strtokIndx = strtok(NULL, ",");
pitchValue = atoi(strtokIndx);
strtokIndx = strtok(NULL, ",");
rollValue = atoi(strtokIndx);
strtokIndx = strtok(NULL, ",");
yawValue = atoi(strtokIndx);
newData = false;
}
}
The data will be sent from ESP32 to change the values of controlCondition
, droneCondition
, gasValue
, pitchValue
, rollValue
, and yawValue
.
I have tried it and the Interrupt cannot be triggered. The Interrupt should be triggered whenever the controlCondition
, droneCondition
, gasValue
, pitchValue
, rollValue
, or yawValue
change its value. Any idea what should I do? or is there something wrong with my code?
Note that the code that i showed in the void loop()
is just an example code. The real code is more complex with so many calculations involved. The variables that I mentioned are the important variables for the calculations.
attachInterrupt(digitalPinToInterrupt(1), handleInterrupt, RISING)
: which Arduino because pin 1 on say a Uno is not set up for edge triggered external interrupts. The usual method for handling serial is in the loop() using Serial.available() to check if there is any data to process. Why are you attempting to do this in an interrupt service routine? Are you planning blocking code in the loop() or what?while (Serial.available())
... if the arduino speed was scaled to human speed, then a serial character would arrive once a week