Hey everyone!
I'm using an Arduino Uno to measure the frequency at which a pulse is generated. The pulse is generated by a hall effect switch which is connected to pin 2 as an interrupt, which initiates the ISR and calculates the frequency. In addition, the Arduino receives serial data which it uses to determine what piece of code to run.
The problem is that that every time I send serial data through the serial monitor, the Interrupt Service Routine is initiated even though no hall effect signal was generated. This screws up my measurements because the frequency is calculated in the ISR, so the false signal generates a false frequency. I also had difficulty reading the signal while using pin 3 as a PWM generate, which I fixed by using pin 5 instead.
I think it has something to do with pins 0 and 1 being Tx and Rx for serial communication (I'm connected via USB), and being on the same port an pin 2, but I'm not sure how to fix the problem.
String incomingByte; //Incoming serial byte
char firstChar; //First character of serial byte
//Volatile memory for changing in ISR
volatile long int currentTime, lastTime=micros();
volatile float delta, frequency;
volatile int count=0;
int debounceTime = 20000; //Debounce in micro-seconds
void setup() {
Serial.begin(9600);
pinMode(2,INPUT); //Initialize pin
attachInterrupt(digitalPinToInterrupt(2),hall_ISR,RISING); //Initialize ISR
pinMode(LED_BUILTIN,OUTPUT); //Debugging tool
}
void loop() {
if (Serial.available() > 0) { //Wait for serial data
incomingByte = Serial.readStringUntil('\n'); //Read available data
firstChar = incomingByte.charAt(0); //First character
//I'd like to differentiate between commands based on first character
switch(firstChar) {
case 's':
//code
break;
case 'b':
Serial.print("Frequency = ");
Serial.println(frequency);
break;
}
}
}
void hall_ISR(){ //Calculate frequency
if (micros()-lastTime>debounceTime){ //Debounce time in microseconds
count++;
delta=micros()-lastTime; //Time delta
lastTime=micros();
digitalWrite(LED_BUILTIN,!digitalRead(LED_BUILTIN)); //Debugging, will remove in final code
}
if (count==2){
frequency = 1000000.0/delta; // Hz = 1/s
}
if (count > 2){ //in case we missed a pulse
count =0;
}
}
The problem doesn't occur when I remove the 'if' statement from the ISR.
void hall_ISR(){ //Calculate frequency
digitalWrite(LED_BUILTIN,!digitalRead(LED_BUILTIN)); //Debugging, will remove in final code
if (count==2){
frequency = 1000000.0/delta; // Hz = 1/s
}
if (count > 2){ //in case we missed a pulse
count =0;
}
}
Any suggestions?
p.s. - I know that my ISR is too long and shouldn't have 'digitalWrite's. Once this problem is fixed I'm planning to minimize and for the calculation to take place in the main loop.