• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Poprawa kodu
#1
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.

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) {}                                                       
}
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości