03-02-2021, 23:26
Witam wszystkich użytkowników.
Tworzę od jakiegoś czasu układ, który ma docelowo realizować funkcje licznika rowerowego z paroma dodatkowymi funkcjami. Jedną z nich jest pomiar sumy podjazdów na trasie. Posiada czujnik ciśnienia, który odpowiada za pomiar wysokości na poziomem morza. Na ten moment ma w kodzie funkcje, która realizuje tylko wyznaczanie różnicy między początkowym punktem a najwyższym pokonanym na trasie. Chciałbym przerobić to tak aby program zliczał wszystkie metry pokonywane w górę z pominięciem tych w dół. Z góry dziękuje za pomoc.
Tworzę od jakiegoś czasu układ, który ma docelowo realizować funkcje licznika rowerowego z paroma dodatkowymi funkcjami. Jedną z nich jest pomiar sumy podjazdów na trasie. Posiada czujnik ciśnienia, który odpowiada za pomiar wysokości na poziomem morza. Na ten moment ma w kodzie funkcje, która realizuje tylko wyznaczanie różnicy między początkowym punktem a najwyższym pokonanym na trasie. Chciałbym przerobić to tak aby program zliczał wszystkie metry pokonywane w górę z pominięciem tych w dół. Z góry dziękuje za pomoc.
Kod:
#include <LiquidCrystal.h>
#include <Wire.h>
#include <LPS331.h>
#define reed 2 //pin z kontaktronem
#define reed2 3 //pin z kontaktronem
#define BUTTONS_DELAY 200
LPS331 ps;
float altStart, altMax, altMin, altDiff;
int reedVal;
int maxDebounceTicks = 100;
int currentDebounceTicks;
int time = 0;
unsigned long t = 0;
unsigned long v_n = 0;
float v_ave = 0.00;
float v_sum = 0.00;
float diameter = 20;
float velocity = 0.00;
float distance = 0.00;
float weight = 70;
float energy = 0;
int reedVal2;
int maxDebounceTicks2 = 100;
int currentDebounceTicks2;
int time2 = 0;
float velocity2 = 0.00;
bool treningStarted = false;
unsigned long treningTime = 0;
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
enum stateOfButtons {RIGHT, UP, DOWN, LEFT, SELECT, NONE};
int menuPosition = 0;
int menuDepth = 0;
String menuDesc[] = {"Kmh + Dystans", "Kadencja", "Przewyzszenie", "Wydatek + czas", "Srednica kola", "Waga"};
byte menuCursor[8] = {
B01000, // *
B00100, // *
B00010, // *
B00001, // *
B00010, // *
B00100, // *
B01000, // *
B00000 //
};
void setup() {
Wire.begin();
if (!ps.init()){while (1);}
ps.enableDefault();
delay(500);
float pressure = ps.readPressureMillibars();
altStart = altMax = altMin = ps.pressureToAltitudeMeters(pressure);
lcd.begin(16, 2);
lcd.createChar(0, menuCursor);
currentDebounceTicks = maxDebounceTicks;
currentDebounceTicks2 = maxDebounceTicks2;
pinMode(reed, INPUT_PULLUP);
pinMode(reed2, INPUT_PULLUP);
cli();
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // set entire TCCR1B register to 0
TCNT1 = 0; // initialize counter value to 0;
OCR1A = 1999; // set timer count for 1khz increments // = (16*10^6) / (1000*8) - 1
TCCR1B |= (1 << WGM12); // turn on CTC mode
TCCR1B |= (1 << CS11); // Set CS11 bit for 8 prescaler
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
sei();
}
void loop() {
lpsHandling();
clickedBtnHanlding(read_LCD_buttons());
displayText();
}
void lpsHandling(){
//float temperature = ps.readTemperatureC();
float pressure = ps.readPressureMillibars();
float altitude = ps.pressureToAltitudeMeters(pressure);
if(altitude > altMax) altMax = altitude;
altDiff = altMax - altStart;
}
void decreaseTicks1(){
if (currentDebounceTicks > 0) //jesli ilosc tickow wieksza od zera
currentDebounceTicks -= 1; //to zmniejsz o 1
}
void decreaseTicks2(){
if (currentDebounceTicks2 > 0) //jesli ilosc tickow wieksza od zera
currentDebounceTicks2 -= 1; //to zmniejsz o 1
}
ISR(TIMER1_COMPA_vect) {
reedVal = digitalRead(reed); //odczytaj wartosc
if (reedVal==0) { //jesli odczytano wartosc 0
if (currentDebounceTicks == 0) { //jesli odliczono odpowiednia ilosc tickow
float radius = diameter / 2 / 100 / 1000; //przeliczenie srednicy w cm na promien w km
float circumference = 2 * 3.14 * radius; //obliczenie obwodu
velocity = circumference/(float(time)/1000/3600); //oblicz predkosc km/h
v_sum += velocity;
v_n++;
v_ave = v_sum / v_n;
t += maxDebounceTicks;
treningStarted = true;
energy = weight*float(t)/1000.0*(0.6345*v_ave*v_ave+0.7563*v_ave+36.725)/(3600);
time = 0; //zeruj aktualny czas
currentDebounceTicks = maxDebounceTicks; //ustaw ilosc tickow na max
distance = distance + circumference; //zwieksz dystans o obwod kola
}
else //jesli nie odliczono jeszcze odpowiedniej ilosci tickow
decreaseTicks1(); //to zmniejszIloscTickow
}
else //jesli odczytano wartosc 0
decreaseTicks1(); //to zmniejszIloscTickow
if (time > 2000) {velocity = 0;} //jesli przez 2s nic sie nie dzialo to ustaw predkosc na 0
else time += 1; //w innym przypadku zwieksz czas
if(time > 30000) {treningStarted = false; treningTime = 0;}
if(treningStarted) treningTime++;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
reedVal2 = digitalRead(reed2); //odczytaj wartosc
if (reedVal2==0) { //jesli odczytano wartosc 0
if (currentDebounceTicks2 == 0) { //jesli odliczono odpowiednia ilosc tickow
velocity2 = 1/(float(time2)/1000/60); //oblicz kadencje obr/min
time2 = 0; //zeruj aktualny czas
currentDebounceTicks2 = maxDebounceTicks2; //ustaw ilosc tickow na max
}
else //jesli nie odliczono jeszcze odpowiedniej ilosci tickow
decreaseTicks2(); //to zmniejszIloscTickow
}
else //jesli odczytano wartosc 0
decreaseTicks2(); //to zmniejszIloscTickow
if (time2 > 20000) {velocity2 = 0;} //jesli przez 20s nic sie nie dzialo to ustaw predkosc na 0
else time2 += 1; //w innym przypadku zwieksz czas
}
void displayText(){
for (int x = 0; x < 2; x++) { // Erases current cursor
lcd.setCursor(0, x);
lcd.print(" ");
}
if(menuDepth == 0){
int row = menuPosition%2;
lcd.setCursor(0, row);
lcd.write(byte(0));
int menuNo = menuPosition/2;
lcd.setCursor(1, 0);
lcd.print(menuDesc[menuNo*2]);
lcd.setCursor(1, 1);
lcd.print(menuDesc[menuNo*2+1]);
}
else if(menuDepth == 1){
if(menuPosition == 0){
lcd.setCursor(1, 0);
lcd.print("v = ");
lcd.print(int(velocity));
lcd.print(" km/h ");
lcd.setCursor(1, 1);
lcd.print("s = ");
if (distance > 1) {lcd.print(distance);lcd.print(" km ");}
else {lcd.print(int(distance * 1000));lcd.print(" m ");}
}
else if(menuPosition == 1){
lcd.setCursor(1, 0);
lcd.print("Kadencja");
lcd.setCursor(1, 1);
lcd.print(int(velocity2));
lcd.print(" obr/min ");
}
else if(menuPosition == 2){
lcd.setCursor(1, 0);
lcd.print("Przewyzszenie:");
lcd.setCursor(1, 1);
lcd.print(altDiff, 2);
lcd.print(" m ");
}
else if(menuPosition == 3){
lcd.setCursor(1, 0);
lcd.print("Wydat: ");
lcd.print(energy, 2);
lcd.print(" kcal");
lcd.setCursor(1, 1);
lcd.print("Czas: ");
lcd.print((int)(treningTime/1000));
lcd.print(" s ");
}
else if(menuPosition == 4){
lcd.setCursor(1, 0);
lcd.print("Srednica kola: ");
lcd.setCursor(1, 1);
lcd.print(diameter, 0);
lcd.print(" cm ");
}
else if(menuPosition == 5){
lcd.setCursor(1, 0);
lcd.print("Waga: ");
lcd.setCursor(1, 1);
lcd.print(weight, 0);
lcd.print(" kg ");
}
}
}
stateOfButtons read_LCD_buttons(){
int adc_key_in = analogRead(0); //odczytaj wartosc z portu A0
if (adc_key_in < 50) return RIGHT; //jesli wykryto przycisk RIGHT
if (adc_key_in < 250) return UP; //jesli wykryto przycisk UP
if (adc_key_in < 450) return DOWN; //jesli wykryto przycisk DOWN
if (adc_key_in < 650) return LEFT; //jesli wykryto przycisk LEF
if (adc_key_in < 850) return SELECT; //jesli wykryto przycisk SELECT
return NONE; //kiedy wszystkie inne przypadki zawiodą zwróc NONE
}
void clickedBtnHanlding(stateOfButtons btnState){
int menuPositions = sizeof(menuDesc) / sizeof(String);
if(btnState == RIGHT) {delay(BUTTONS_DELAY); lcd.clear(); if(menuDepth < 1) menuDepth++;}
if(btnState == LEFT) {delay(BUTTONS_DELAY); lcd.clear(); if(menuDepth > 0) menuDepth--;}
if(btnState == UP){
delay(BUTTONS_DELAY);
lcd.clear();
if(menuDepth == 0 && menuPosition > 0) menuPosition--;
if(menuDepth == 1 && menuPosition == 4 && diameter < 100) diameter++;
if(menuDepth == 1 && menuPosition == 5 && weight < 150) weight++;
}
if(btnState == DOWN){
delay(BUTTONS_DELAY);
lcd.clear();
if(menuDepth == 0 && menuPosition < menuPositions-1) menuPosition++;
if(menuDepth == 1 && menuPosition == 4 && diameter > 1) diameter--;
if(menuDepth == 1 && menuPosition == 5 && weight > 20) weight--;
}
if(btnState == SELECT) {}
}