Bike bättre med en LED kadens mätare (7 / 11 steg)
Steg 7: Koden
Denna kod läser när magneten passerar sensorn och håller en löpande genomsnittlig tid mellan pedalen passerar. Denna information används för att beräkna rotationer per minimalt.
För att produktionen till lysdioder, används en funktion för att beräkna ljusstyrkan i varje LED-baserade på rpm värdet. Detta skapar en smidig vissnande effekt mellan lysdioderna som värdena ändras.
Det bästa sättet att läsa från sensorn skulle ha varit med avbryter, men jag stötte på ett problem där värdena från sensorn inte var tillräckligt hög för att registrera dig med Arduino som digitala signaler. Så jag var tvungen att använda analog sensor värden.
Detta är inte den mest eleganta koden, men det fungerar och är för närvarande låst i en ruta på min cykel, så jag postar det som det är. Förslag och förändringar är välkomna.
#define ARRAY_SIZE 3 //The antal värden att hålla i den löpande genomsnittligt
#define TIMEOUT 1500 //Max tid utan input innan du stänger av lysdioder
#define FADE_INCREMENT.1 //Controls blekning hastigheten--justera med prova
#define LED_CONSTANT -20 //Used i ljusstyrka blekning ekvationen
RPM mål för varje LED:
#define RED_1_TARGET 45
#define YELLOW_1_TARGET 68
#define GREEN_TARGET 90
#define YELLOW_2_TARGET 113
#define RED_2_TARGET 135
/ ** PORT SETUP ** /
CONST int magnetSensor = A7; Ändra detta för din arduino
CONST int red1 = 12.
CONST int yellow1 = 10;
CONST int grön = 9.
CONST int yellow2 = 5;
CONST int red2 = 4;
CONST int ledPin = 11;
bool magnetonen = false;
bool prevMagOn = false;
bool primade = false;
bool arrayEmpty = false;
flyta gånger [ARRAY_SIZE]; matrisen kan innehålla värden för den löpande genomsnittligt
flyta startTime = millis();
int rpm = 0;
bool trampa = false;
int targetR1;
int targetY1;
int targetG;
int targetR2;
int targetY2;
float r1;
float y1;
float g;
float y2;
float r2;
lägga till ett nytt värde i arrayen, flytta resten tillbaka ett utrymme och ta bort den äldsta
void updateTimes(float newValue)
{
för (int jag = 0; jag < ARRAY_SIZE-1; i ++) {
gånger [i] = tider [i + 1];
}
gånger [ARRAY_SIZE-1] = newValue;
}
Returnerar ett medelvärde av alla värden i vektorn
int avgArray (float values[]) {
int totala = 0;
int räknas = ARRAY_SIZE;
för (int jag = 0; jag < ARRAY_SIZE; i ++) {
totalt = totalt + värden [i];
om (värden [i] == 0)
räknade--;
}
Return(total/counted);
}
för felsökning
void printValues() {
för (int jag = 0; jag < ARRAY_SIZE - 1; i ++) {
Serial.Print(Times[i]);
Serial.Print (",");
}
Serial.println (tiden [ARRAY_SIZE -1]).
}
Rensa matrisen
void clearTimes() {
för (int jag = 0; jag < ARRAY_SIZE; i ++)
gånger [i] = 0;
}
Kontrollera om matrisen är full
void checkFullArray() {
arrayEmpty = sant;
för (int jag = 0; jag < ARRAY_SIZE; i ++) {
om (gånger [i]! = 0)
arrayEmpty = false;
}
}
använda en funktion för att beräkna ljusstyrkan i en tanke ledde baserat på ett mål
int calculateLED (int target) {
om (rpm < = 0)
Return 0;
återvända int(LED_CONSTANT*abs(target-rpm)+255);
}
void setup() {
pinMode (red1, produktionen);
pinMode (yellow1, produktionen);
pinMode (grön, utgång);
pinMode (yellow2, produktionen);
pinMode (red2, produktionen);
Serial.BEGIN(9600);
}
void loop() {
Läsa från hall effekt sensorn (med analoga värden, tyvärr)
int magnetState = analogRead(magnetSensor);
Serial.println(magnetState);
om (magnetState > 60) {
magnetonen = false;
}
annat {
magnetonen = sant;
}
om (! magnetonen & & prevMagOn) {
primas = sant;
}
timeout
om (millis ()-startTime > TIMEOUT) {
clearTimes();
trampa = false;
}
om (magnetonen & &! prevMagOn & & primade) {//if magneten passerar sensorn en gång
flyta currentTime = millis();
flyta changeTime = (currentTime - startTime); spela in tiden efter sista pedalen
startTime = millis();
IF(pedaling) //if det har trampa sedan senaste timeout
updateTimes(changeTime); Lägg tiden till den löpande genomsnittliga matrisen
primas = false;
trampa = sant;
}
mest för felsökning, blinkar det inbyggda lampan varje gång magneten passerar sensorn
IF(magnetOn)
digitalWrite (ledPin, hög);
annat
digitalWrite (ledPin, låg);
prevMagOn = magnetonen;
checkFullArray();
float gap = avgArray(times);
IF(arrayEmpty) {
RPM = 0;
}
annat
RPM = 60000/gap; förvandla millisekundvärde gap till rpm
ljus den lägsta röda lampan när den första pedal stroke registreras, eftersom det inte finns tillräckligt med data för att beräkna rpm
om (trampa & & rpm == 0)
RPM = 40;
/ *** LED UTGÅNG *** /
beräkna värden
targetR1 = calculateLED(RED_1_TARGET);
targetY1 = calculateLED(YELLOW_1_TARGET);
targetG = calculateLED(GREEN_TARGET);
targetY2 = calculateLED(YELLOW_2_TARGET);
targetR2 = calculateLED(RED_2_TARGET);
Normalisera negativa värden till noll (dessa bör verkligen i en array...)
IF(targetR1 < 0)
targetR1 = 0;
IF(targetY1 < 0)
targetY1 = 0;
IF(targetG < 0)
targetG = 0;
IF(targetY2 < 0)
targetY2 = 0;
IF(targetR2 < 0)
targetR2 = 0;
blekna till värde
om (r1 < targetR1)
R1 += FADE_INCREMENT;
om (r1 > targetR1)
R1-= FADE_INCREMENT;
om (y1 < targetY1)
Y1 += FADE_INCREMENT;
om (y1 > targetY1)
Y1-= FADE_INCREMENT;
om (g < targetG)
g += FADE_INCREMENT;
om (g > targetG)
g-= FADE_INCREMENT;
om (y2 < targetY2)
Y2 += FADE_INCREMENT;
om (y2 > targetY2)
Y2-= FADE_INCREMENT;
om (r2 < targetR2)
R2 += FADE_INCREMENT;
om (r2 > targetR2)
R2-= FADE_INCREMENT;
utgång till lysdioder
analogWrite (red1, r1);
analogWrite (yellow1, y1);
analogWrite (grön, g);
analogWrite (yellow2, y2);
analogWrite (red2, r2);
}