-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathTachometer.ino
112 lines (101 loc) · 3.01 KB
/
Tachometer.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/**
* Copyright (C) 2024, Bruce MacKinnon
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* NOT FOR COMMERCIAL USE WITHOUT PERMISSION.
*/
#include <fix_fft.h>
#define FFT_SIZE 64
#define FFT_SIZE_BITS 6
unsigned long samplesPerSecond = 256;
unsigned long microsBetweenSamples = 1000000UL / samplesPerSecond;
unsigned long lastSample = micros();
unsigned long lastCycle = 0;
unsigned long msBetweenCycles = 500;
int samplePtr = 0;
char dataR[FFT_SIZE];
char dataI[FFT_SIZE];
void setup() {
Serial.begin(9600);
delay(100);
Serial.println("Tachometer");
/*
float step = 2.0 * 3.14159 / 64.0;
for (int i = 0; i < 64; i++) {
float rad = step * (float)i;
// Sample centered around 512 (0->1023)
float sample = 512.0 + cos(rad * 63.0) * (float)511.0;
// Shift down so that we are centerd around zero (-127->127)
dataR[i] = ((sample - 512.0) / 512.0) * 128.0;
dataI[i] = 0;
Serial.print(i);
Serial.print(" ");
Serial.println((int)dataR[i]);
}
Serial.println("FFT");
fix_fft(dataR,dataI,6,0);
for (int i = 0; i < 32; i++) {
float real = dataR[i];
float imag = dataI[i];
float mag = sqrt(real * real + imag * imag);
Serial.print(i);
Serial.print(" ");
Serial.println(mag);
}
*/
}
int mode = 0;
void loop() {
if (mode == 0) {
if (millis() - lastCycle > msBetweenCycles) {
lastCycle = millis();
mode = 1;
samplePtr = 0;
}
}
else if (mode == 1) {
unsigned long now = micros();
if (now - lastSample > microsBetweenSamples) {
lastSample = now;
// Sample centered around 512 (0->1023)
float sample = analogRead(0);
// Shift down so that we are centerd around zero (-127->127)
dataR[samplePtr] = ((sample - 512.0) / 512.0) * 127.0;
dataI[samplePtr] = 0;
// Advance the counter
samplePtr++;
// Full window?
if (samplePtr == FFT_SIZE) {
fix_fft(dataR,dataI,FFT_SIZE_BITS,0);
// Find the biggest bucket
float maxMag = 0;
float maxMagBucket = 0;
for (int i = 0; i < FFT_SIZE / 2; i++) {
float real = dataR[i];
float imag = dataI[i];
float mag = sqrt(real * real + imag * imag);
if (mag > maxMag) {
maxMag = mag;
maxMagBucket = i;
}
}
Serial.print(maxMagBucket);
Serial.print(" ");
Serial.println(maxMag);
mode = 0;
}
}
}
}