The problem is, the current updates frequently than the rpm. Is there a way where I can update them at the same time? Maybe, display them both on the void loop() or get even the past value of rpm so the current and rpm change simultaneously?
Here's the code:
#include <TimerOne.h>
int curPin = 19;
unsigned int counter = 0;
void blink(){
counter++;
}
void timerIsr(){
Timer1.detachInterrupt(); //disable the timer1
Serial.print(counter,DEC); Serial.println(" rpm");
counter=0;
Timer1.attachInterrupt( timerIsr ); //enable the timer1
}
//----------
void setup(){
Serial.begin(9600);
Timer1.initialize(60000000); // set a timer of length 1sec
attachInterrupt(0, blink, RISING); //INT0
Timer1.attachInterrupt( timerIsr ); // attach the service routine here
}
void loop(){
Serial.print(readCurrent(curPin)); Serial.println(" A");
}
float readCurrent(int pin){
float average = 0;
for(int i = 0; i < 1000; i++) {
average = average + (.0264 * analogRead(pin) -13.51);
delay(1);
}
average = average / 1000;
if(average < 0){
average = average * (-1);
}
return average;
}
Using Serial inside an ISR is not good, and I'm surprised it works at all
Added
int finalCounter
I'm cheating a bit, you really need a flag and a variable, but I'm using -1 to indicate data not available yet, as I assume that 0 may be a valid number
if you only want to display the current when you display the rpm, move the
Serial.print(readCurrent(curPin)); Serial.println(" A");
inside the if {}
int finalCounter=-1;
void timerIsr(){
// Timer1.detachInterrupt(); //disable the timer1
// Serial.print(counter,DEC); Serial.println(" rpm");
finalCounter=counter;
counter=0;
//Timer1.attachInterrupt( timerIsr ); //enable the timer1
}
//----------
void setup(){
Serial.begin(9600);
Timer1.initialize(60000000); // set a timer of length 1sec
attachInterrupt(0, blink, RISING); //INT0
Timer1.attachInterrupt( timerIsr ); // attach the service routine here
}
void loop(){
Serial.print(readCurrent(curPin)); Serial.println(" A");
if (finalCounter!=-1)
{
Serial.print(counter,DEC); Serial.println(" rpm");
finalCounter=-1;
}
}
arduinoTime:
The problem is, the current updates frequently than the rpm. Is there a way where I can update them at the same time? Maybe, display them both on the void loop() or get even the past value of rpm so the current and rpm change simultaneously?
when timerISR runs, just store the value to a global variable instead of printing.
then print it in the loop() function:
#include <TimerOne.h>
int curPin = 19;
unsigned int counter = 0;
unsigned int lastCount;
void blink(){
counter++;
}
void timerIsr(){
Timer1.detachInterrupt(); //disable the timer1
lastCount = counter;
counter=0;
Timer1.attachInterrupt( timerIsr ); //enable the timer1
}
//----------
void setup(){
Serial.begin(9600);
Timer1.initialize(60000000); // set a timer of length 1sec
attachInterrupt(0, blink, RISING); //INT0
Timer1.attachInterrupt( timerIsr ); // attach the service routine here
}
void loop(){
Serial.print(readCurrent(curPin)); Serial.println(" A");
Serial.print(counter,DEC); Serial.println(" rpm");
}
float readCurrent(int pin){
float average = 0;
for(int i = 0; i < 1000; i++) {
average = average + (.0264 * analogRead(pin) -13.51);
delay(1);
}
average = average / 1000;
if(average < 0){
average = average * (-1);
}
return average;
}
I have not analized your code in detail. AFAIK serial.print and interrupts do not mix properly (I had problems using interrupts from an encoder and motorizing results -simultaneously through the serial monitor).
@Robin2 gave you a great recommendation and some demonstration code with which you could easily add another sensor and detect the RPM of two spinning wheels:
BulldogLowell: @Robin2 gave you a great recommendation and some demonstration code with which you could easily add another sensor and detect the RPM of two spinning wheels:
two interrupts, two sensors.
Sir BuldogLowell, how can I measure the rpm in the 'SeveralThingsAtTheSameTimeRev1.ino'?
The code i found on grove.com has a command attachInterrupt(0, blink, RISING)--the RISING means trigger when the pin goes from low to high--should I count the updateLed_A_State() change from LOW to HIGH? How?
you can reduce the sampling time and calculate the RPM accordingly.
int pinOne = 2; //interrupt Zero on pin2
int pinTwo = 3; //interrupt One on pin3
int wheelOneCount = 0;
int wheelTwoCount = 0;
unsigned long startTime;
unsigned long oneMinute = 60000UL; //sample over a period of one minute
//
void setup()
{
Serial.begin(9600);
attachInterrupt(0, countWheelOne, RISING); // when sensor voltage rises
attachInterrupt(1, countWheelTwo, RISING);
startTime = millis();
}
void loop()
{
if (millis() - startTime >= oneMinute)
{
int rpmOne = wheelOneCount;
int rpmTwo = wheelTwoCount;
Serial.print(F("Wheel One RPM: "));
Serial.println(rpmOne);
Serial.print(F("Wheel Two RPM: "));
Serial.println(rpmTwo);
wheelOneCount = 0;
wheelTwoCount = 0;
startTime = millis();
}
}
//
void countWheelOne()
{
wheelOneCount++;
}
//
void countWheelTwo()
{
wheelTwoCount++;
}
Thank you Sir Buldoglowell but can I do it without attachInterrupt()? I want to read the blade rpm of 5 fans.
You said I can use 'SeveralThingsAtTheSameTimeRev1.ino' but I don't know what to count