Hi,
For a school project we had to make a Frequency counter (hardware and software).
It works great! but today I dicided that I want to put all the hardware on a PCB.
I quickly ran out of space so I dicided to swap the arduino nano with an arduino pro micro.
But now the sketch does not read the frequency anymore... it doesnt even read a change off the state off the pin.
(hardware is still working fine, i tested it by just connecting the nano to the pcb with jumper cables)
am I missing something?
Is the pro micro not capable to read a frequency up to 1000Hz? (it should be!)
I am using pin D5 to recieve the signal on.
For not getting confused with another board here is a link from where I got mine.
board used in IDE: arduino micro
code: (Sorry that the language in the declarations is different, I had to "explain" the code to the teacher)
#define signalPin 5 // De pin waarop het signaal binnenkomt
// Dit zijn 3 waarden die je zelf kan aanpassen om een beter resultaat te krijgen
#define MAX_COUNT 50 // Het aantal getallen waarvan het gemidelden moet worden
#define LOWER_LEFTOUT 25 // het aantal getallen dat aan de lagere kant moet worden wegelaten (na het sorteren)
#define UPPER_LEFTOUT 10 // het aantal getallen dat aan de hogere kant moet worden wegelaten (na het sorteren)
#define INTERVAL 1000 // om de hoeveel tijd een meting moet gedaan worden (0 is mogelijk maar raad ik niet aan)
#include "U8glib.h" // het libary voor het oled display
U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE);
void setup() {
pinMode(signalPin, INPUT); // sigalPin wordt in de INPUT mode gezet
if ( u8g.getMode() == U8G_MODE_R3G3B2 ) { // een aantal instellingen voor het display
u8g.setColorIndex(255); // white
}
else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
u8g.setColorIndex(3); // max intensity
}
else if ( u8g.getMode() == U8G_MODE_BW ) {
u8g.setColorIndex(1); // pixel on
}
else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
u8g.setHiColorByRGB(255, 255, 255);
}
u8g.firstPage();
do {
u8g.setFont(u8g_font_fur11);
u8g.drawStr(0, 20, "Booting:");
} while ( u8g.nextPage() );
delay(1000);
}
void loop() {
CheckForLowPulse(); // deze functie kijkt of er een Pulse is en zorgt ervoor dat deze in Hz op het display wordt getoont
}
void CheckForLowPulse() {
static unsigned long startTime = 0; // de tijd aan het begin van de pulse wordt hier in opgeslagen
static unsigned long endTime = 0; // de tijd aan het einde van de pulse wordt hier in opgeslagen
static bool state = LOW; // state waarin de signalPin bevind wordt hier in opgeslagen
static bool lastState = LOW; // vorige state waarin de signalPin zich bevond wordt hier in opgeslagen
static int counter = 1; // deze variable houdt bij hoeveel frequenties al zijn opgeslagen
float freqArray[MAX_COUNT]; // deze Array slaagt alle frequenties (totdat het gemidelde is berekend)
state = digitalRead(signalPin); // slaag de status van signalPin op in state
if (lastState != state) { // het mag aleen het onderstaande stukje programa uivoeren als er net een verandering in status op singalPin is
unsigned long currentTime = micros();
startTime = endTime; // endTime is éénderzijds de eindtijd van de pulse maar de tijd van de vorig verandering in status
endTime = currentTime; // startTime neemt endTime over en daarna krijgt eindTime terug de tijd op dat moment
if (state == HIGH) { // je wilt niet dat de tijd altijd wordt opgenomen, maar aleen als de Pin HIGH is (LOW kan ook)
freqArray[counter] = calcFreq(endTime, startTime); // de endTime en startTime worden in de functie calcFreq gestoken en deze berkend op zijn beurd de frequentie
counter++; // dit was één frequentie die wert ingelezen, nu gaat dit opnieuw beginnen totdat de counter een bepaald getal bereikt
}
lastState = state; // lastState krijgt de waarde van state
}
if (counter > MAX_COUNT) { // simpel gezecht gaat dit stukje code de Array sorteren
float holder = 0; // dit maakt het makelijk om de peak waarden er uit te nemen
for (int x = 0; x < MAX_COUNT; x++) {
for (int y = 0; y < MAX_COUNT - 1; y++) {
if (freqArray[y] > freqArray[y + 1]) {
holder = freqArray[y + 1];
freqArray[y + 1] = freqArray[y];
freqArray[y] = holder;
}
}
}
unsigned long totalFreq = 0;
for (int i = LOWER_LEFTOUT; i < MAX_COUNT - UPPER_LEFTOUT; i++) { // hier wordt de hele array opgetelt in één variable
totalFreq += freqArray[i]; // maar er wordt ook gezord dat het aantal waarden uit LOWER_LEFTOUT en UPPER_LEFTOUT uit de berekening worden gehouden
freqArray[i] = 0; // en de Array wordt leeg gemaakt (niet verplicht nodig, overschrijven zou ook kunnen)
}
float freq = totalFreq / (MAX_COUNT - LOWER_LEFTOUT - UPPER_LEFTOUT); // berekening gemidelde, maar het mag niet van het totaal dat gegeven zijn want er moet rekening gehouden worden met LOWER_LEFTOUT en UPPER_LEFTOUT
oled_print(freq); // deze functie print de megegeven waarden van freq
counter = 1; // counter reset
delay(INTERVAL); // wacht ...
}
}
void oled_print(int frequency) { // dit is hoe je met het U8glib waarden en strings print
u8g.firstPage();
do {
u8g.setFont(u8g_font_fur11);
u8g.drawStr(0, 20, "Frequency:");
u8g.setPrintPos(75, 20);
u8g.print(frequency);
u8g.drawStr(110, 20, "Hz");
u8g.drawBox(0, 29, 128, 2);
} while ( u8g.nextPage() );
}
float calcFreq(unsigned long endTIME, unsigned long startTIME) { // dit is de berekening om van een halve periode naar de frequentie te gaan
float periodTimeMicros = endTIME - startTIME;
float periodTime = periodTimeMicros / 500000;
unsigned int frequency = (1 / periodTime);
return frequency;
}
here is a schematic of the hardware (opamp, etc.) for those interested.
Isaak