Hello,
This is my first post but I have already done some research in this forum, but I didn’t find out how to solve this problem yet.
I built this code for a tachometer:
int analogPin = 3;
unsigned long t1=0;
unsigned long t0=0;
unsigned long interval=0;
int digitalPin = 2;
volatile int cnt = 0;
void setup()
{
Serial.begin(9600) ;
attachInterrupt(digitalPinToInterrupt(digitalPin), IRQ, RISING);
t0=millis();
}
void loop() {
t1=millis();
interval = t1-t0;
if(interval >= 1000){
Serial.print(t1);
Serial.print(" , ");
Serial.print(interval);
Serial.print(" , ");
Serial.println(cnt);
cnt=0;
t0=millis();
}
}
void IRQ()
{
cnt++;
}
The frequency is displayed in [Hz] for better troubleshooting. The usage range would be from 16 Hz to 180 Hz.
Also, I built the circuit attached, based on this topic in order to test the code. AC sine wave is conditioned to a 0 to 5V DC voltage in order to trigger Arduino Uno digital pin 2. The sine wave is generated by a computer soundcard output that is controlled by a program from this site. . The value of the sine wave is 1.7V RMS.
Apparently the circuit is OK because I put an oscilloscope and it is generating an square wave signal, 0 to 5V DC, and the frequency is accurate.
However, when I run the code in Arduino, the frequency calculation is not accurate at low frequencies.
This is the result from 1000Hz generated: accurate
Sample time [ms] interval [ms] frequency [Hz]
1 1000 1000 1009
2 2000 1000 1008
3 3000 1000 1006
4 4000 1000 1008
5 5000 1000 1006
6 6000 1000 1007
7 7000 1000 1006
8 8000 1000 1007
9 9000 1000 1008
10 10000 1000 1006
This is the result from 30Hz generated: average of 61.6Hz, far away from accuracy
Sample time [ms] interval [ms] frequency [Hz]
1 1000 1000 57
2 2000 1000 72
3 3000 1000 60
4 4000 1000 60
5 5000 1000 66
6 6000 1000 59
7 7000 1000 56
8 8000 1000 68
9 9000 1000 58
10 10000 1000 60
This is the result from 20Hz generated: average of 79.3Hz, far away from accuracy
Sample time [ms] interval [ms] frequency [Hz]
1 1000 1000 81
2 2000 1000 84
3 3000 1000 73
4 4000 1000 74
5 5000 1000 82
6 6000 1000 73
7 7000 1000 74
8 8000 1000 79
9 9000 1000 79
10 10000 1000 94
In order to understand what is going on, I ran the code below.
int analogPin = 3;
unsigned long t1;
float val =0;
int pin = 2;
volatile int Time =0;
volatile int lastTime =0;
volatile int deltaTime=0;
volatile uint8_t cnt = 0;
void setup()
{
Serial.begin(115200) ;
attachInterrupt(digitalPinToInterrupt(pin), IRQ, RISING);
}
void loop() {
t1=micros();
val = (5.1/1023)*analogRead(analogPin);
if(cnt>0)
Serial.print(t1);
Serial.print(" , ");
Serial.print(cnt);
Serial.print(" , ");
Serial.println(val);
}
void IRQ()
{
cnt++;
Time = micros();
deltaTime = Time-lastTime;
lastTime = Time;
}
Thus, I pick up the digital count from digital pin 2 and compare with “analogRead” from analog pin 3.
The table below summarize the results for 30Hz from signal generator.
Sample Sample Time [us] Sample period [us] Count Analog Read value [V]
1 4688140 1872 172 0.2
2 4690012 1868 172 0.22
3 4691880 1872 172 0.22
4 4693752 1868 172 0.21
5 4695620 1872 172 0.19
6 4697492 1868 173 0.22
7 4699360 1872 173 5
8 4701232 1868 173 5
9 4703100 1872 173 4.99
10 4704972 1868 173 4.99
11 4706840 1872 173 4.99
12 4708712 1868 173 5.01
13 4710580 1876 173 5.01
14 4712456 1864 173 4.99
15 4714320 1872 173 4.99
16 4716192 1868 173 4.99
17 4718060 1872 173 1.58
18 4719932 1868 173 0.19
19 4721800 1872 173 0.21
20 4723672 1868 173 0.22
21 4725540 1872 173 0.22
22 4727412 1868 173 0.21
23 4729280 1872 173 0.19
24 4731152 1868 177 4.26
25 4733020 1872 177 5.01
26 4734892 1868 177 4.99
27 4736760 1872 177 4.99
28 4738632 1868 177 5
29 4740500 1872 177 4.98
30 4742372 1868 177 4.98
31 4744240 1872 177 4.99
32 4746112 1868 177 4.98
33 4747980 1872 177 4.99
34 4749852 1868 177 4.99
35 4751720 1872 178 0.19
36 4753592 1876 178 0.2
37 4755468 1864 178 0.21
38 4757332 1868 178 0.22
39 4759200 1872 178 0.22
40 4761072 1868 178 0.2
41 4762940 1872 178 0.18
42 4764812 1868 179 5.01
43 4766680 1872 179 5
44 4768552 1868 179 4.99
45 4770420 1872 179 4.98
46 4772292 1868 179 4.99
47 4774160 1872 179 4.99
48 4776032 1868 179 4.97
49 4777900 1872 179 4.97
50 4779772 1868 179 4.98
From the results, it appears to be counting more than once when there is only 1 rising of the edge. That’s where I am stuck.
Does anyone knows why it is counting more than should be? Any solution for that? I have already tried to switch from “RISING” to “FALLING” with no success.
Thanks in advance.
Best reagards
vrsensorcircuit.pdf (17.5 KB)