Problem z biblioteką MenuBackend i RTC

Masz problem, z którym nie możesz sobie poradzić? Pisz śmiało!
ODPOWIEDZ
bpachel
Młodszy majsterkowicz
Posty: 32
Rejestracja: 2 sty 2014, 22:02

Problem z biblioteką MenuBackend i RTC

Post autor: bpachel » 12 lut 2014, 19:04

Witam
Chciałem prosić was o pomoc ponieważ pomyślałem że zrobie sobie zegarek z wyświetlaniem temperatury i wilgotności( na ds18b20 i dht11) postanowiłem wykorzystać bibliotekę MenuBackend lecz mam problem ponieważ czas wyświetlany na wyświetlaczu nie jest aktualizowany. Z temperaturą jeszcze nie sprawdzałem ale pewnie będzie to samo.
chodzi mi dokładnie o część w funkcjii void menuUseEvent(MenuUseEvent used)

Kod: Zaznacz cały

#include <MenuBackend.h>               
#include <LiquidCrystal.h>
#include <Wire.h>  
 #include "RTClib.h"  
 RTC_DS1307 RTC;  
// --- definiujemy dla LCD własne znaki strzałek: dół, lewo, prawo, gora-dół i powrót ---
uint8_t arrowUpDown[8] = {0x4,0xe,0x15,0x4,0x15,0xe,0x4}; 
uint8_t arrowDown[8]  = {0x4,0x4,0x4,04,0x15,0xe,0x4}; 
uint8_t arrowRight[8] = {0x0,0x4,0x2,0x1f,0x2,0x4,0x0}; 
uint8_t arrowLeft[8] = {0x0,0x4,0x8,0x1f,0x8,0x4,0x0};
uint8_t arrowBack[8] = {0x1,0x1,0x5,0x9,0x1f,0x8,0x4};
LiquidCrystal lcd(5, 6, 7, 8, 9, 10);
volatile int zm =-1; // to dla kontroli zmiany stanu klawiatury
volatile int x=-1; // zmienna pomocnicza
volatile int stan_Analog; // wartość na wejściu Analogowym dla klawiaturki analogowej
char *linia1;    // pierwsza linia wyświetlanego tekstu na LCD                  
char *linia2;
/*
    CZAS
      Pokaz Czas
      Ustaw Czas
    TEMPERATURA
      Pokój
      Pole
*/
MenuBackend menu = MenuBackend(menuUseEvent,menuChangeEvent);
  MenuItem P1 = MenuItem("     CZAS",1);
    
  
  MenuItem P2 = MenuItem(" TEMPERATURA",1);
    MenuItem P21 = MenuItem("    Pokoj",2);
    MenuItem P22 = MenuItem("     Pole",2);

void menuSetup()
{
  menu.getRoot().add(P1);
  
  P1.addRight(P2);
  P2.add(P21);
    P21.add(P22);P21.addLeft(P2);
    P22.addLeft(P1);P22.add(P21);
  
  P2.addRight(P1);
}

void menuUseEvent(MenuUseEvent used)

{
  Serial.print("wybrano:  "); Serial.println(used.item.getName());
  
  if (used.item.getName() =="     CZAS")
  {
    DateTime now = RTC.now();  
  lcd.setCursor(2, 0);
  lcd.print(now.year(), DEC);
  lcd.setCursor(6,0);  
  lcd.print(".");
  lcd.setCursor(7,0);  
  lcd.print(now.month(), DEC);
  lcd.setCursor(9,0);  
  lcd.print(".");
  lcd.setCursor(10,0);  
  lcd.print(now.day(), DEC);  
  lcd.setCursor(3, 1);  
  lcd.print(now.hour(), DEC);  
  lcd.print(':');  
  lcd.print(now.minute(), DEC);  
  lcd.print(':');  
  lcd.print(now.second(), DEC);  
  int akcja=-1;delay(1000);/ zmienna pomocnicza, sterująca dla petli while
                                           // jesli nie puścisz klawisza OK w ciągu 1 sek. to powrót do menu    
        while(akcja!=4)                   // ta pętla trwa tak długo aż wciśniesz klawisz OK
  {
    zm=-1;
    akcja=czytaj_1(0); // odczyt stanu klawiatury - funkcja czytaj_1 lub czytaj_2 lub czytaj_3
                                            // opis poniżej przy 3 różnych definicjach funkcji czytaj
                              // ruszamy do pracy tylko wtedy gdy zmienił sie stan klawiatury
    if(zm!=akcja)
    {
      if(akcja==4) // jeśli wciśnieto OK
      {
        lcd.setCursor(1,1);lcd.print("              ");
        lcd.setCursor(0,0);lcd.print("*     MENU     *");delay(2500);
        lcd.setCursor(1,0);lcd.print("              ");// czyścimy linie odtwarzamy poprzedni stan na LCD
        lcd.setCursor(1,0);lcd.print(linia1);
      }
      
    }
  } zm=akcja;// aktualizacja zmiennej zm, po to aby reagować tylko na zmiany stanu klawiatury
         // tu WAŻNY MOMENT - kończy się pętla while i zwracamy sterowanie do głównej pętli loop()
  }
// a tutaj obsługa pozostałych opcji
}

void menuChangeEvent(MenuChangeEvent changed)
{
  int c=changed.to.getShortkey();                         // pobieramy shortkey (1,2,3, lub4)
  lcd.clear();                                            // bez komentarza 
  lcd.setCursor(0,0); 
  if(c==1)                                                // jeśli to menu głowne (shortkey=1) to:
    {
    lcd.write(3);                                         // strzałka w lewo
    strcpy(linia1,changed.to.getName());                  // tworzymy napis w pierwszej linii
    lcd.print(linia1);                                    // wyświetlamy ją
    lcd.setCursor(15,0);lcd.write(4);                     // strzałka w prawo
    lcd.setCursor(0,1);lcd.write(5);                      // strzałka w dół
    lcd.setCursor(15,1);lcd.write(5);                     // strzałka w dół
    }
    if(c==2)                                              // jeśli to podmenu dla dziecka - (shortkey=2) to:
    {
    lcd.print("*");                                       // rysujemy gwiazdkę
    strcpy(linia2,changed.to.getName());                  // tworzymy napis w pierwszej linii
    lcd.print(linia1);                                    // wyświetlamy ją
    lcd.setCursor(15,0);lcd.print("*");                   // gwiazdka 
    lcd.setCursor(0,1);lcd.write(6);                      // druga linia i strzałka powrotu (arrowBack)
    lcd.print(changed.to.getName());                      // wyświetlamy nazwe "dziecka"
    lcd.setCursor(15,1);lcd.write(7);                     // strzałka góra-dół
    }
    if(c==3)                                              // jeśli dziecko  ma dziecko - (shortkey =3) to:
    {
    lcd.print("*");                                       // gwiazdka
    strcpy(linia2,changed.to.getName());                  // kopiujemy akt. nazwe opcji menu do zmiennej linia2
    lcd.print(linia1);                                    // i wyświetlamy pierwszą linię
    lcd.setCursor(15,0);lcd.print("*");                   // gwiazdka
    lcd.setCursor(0,1);lcd.write(6);                      // druga linia i strzałka arrowBack
    lcd.print(changed.to.getName());                      // wyświetlamy wnuka w drugiej linii
    lcd.setCursor(15,1);lcd.write(4);                     // strzałka w prawo bo są wnuki
    }
    
    if(c==4)                                              // jeśli to wnuk  (shortkey =4) to:
    {
    lcd.print("*");                                       // gwaizdka
    lcd.print(linia2);                                    // w pierwszej linii wyświetlamy dziecko ( czyli rodzica wnuka) 
    lcd.setCursor(15,0);lcd.print("*");                   // gwaizdka
    lcd.setCursor(0,1);lcd.write(6);                      // druga linia i strzałka arrowBack
    lcd.print(changed.to.getName());                      // wyświetlamy wnuka
    lcd.setCursor(15,1);lcd.write(7);                     // strzałka góra-dół 
    }
}
volatile int czytaj_1(int analog)
{
   int stan_Analog = analogRead(analog);delay(30);//Serial.println(stan_Analog); 
   if (stan_Analog < 50) return -1; // dla wartosci poza zakresem
   if (stan_Analog < 185)   return 0;  // w prawo  
   if (stan_Analog < 215)  return 1;  // do gĂłry 
   if (stan_Analog < 275)  return 2;  // w dół 
   if (stan_Analog < 360)  return 3;  // w lewo  
   if (stan_Analog < 550)  return 4;  // OK 
   return -1;                         // nic nie wcisnieto
}

  void setup()
{
  linia1=new char[16];  // zainicjowanie dynamicznego wskaźnika do tekstu 
  linia2=new char[16];
  Serial.begin(9600);   // inicjacja Seriala, głównie do testów 
  lcd.begin(16, 2);     // inicjacja LCD
  lcd.createChar(3,arrowLeft);    // tworzymy w pamięci LCD 5 własnych znaków dla strzałek
  lcd.createChar(4,arrowRight);
  lcd.createChar(5,arrowDown);
  lcd.createChar(6,arrowBack);
  lcd.createChar(7,arrowUpDown);
  pinMode(0,OUTPUT);digitalWrite(0,LOW);
  menuSetup();          // funkcja klasy MenuBackend - tu tak naprawdę tworzymy nasze menu 
  menu.moveDown();
  Wire.begin();  
  RTC.begin();
  //RTC.adjust(DateTime(__DATE__, __TIME__));
}

void loop()
{
  x=czytaj_1(0);delay(30);
  if(zm!=x)                               // jesli była zmiana stanu to :
    {
      switch(x)                           // sprawdzamy co nacisnieto 
      {
      case 0: menu.moveRight();break;     // jesli naciśnięto klawisz w Prawo to przesuń menu w prawo
      case 1: menu.moveUp();break;        // menu do góry
      case 2: menu.moveDown();break;      // menu w dół
      case 3: menu.moveLeft();break;      // menu w lewo
      case 4: menu.use();break;           // wciśnięto OK więc skok do funkcji menuUseEvent(MenuUseEvend used)
                                          // to w tej funkcji właśnie obsługujemy nasze Menu, tu sprawdzamy
                                          // jaką opcję wybrano i tutaj tworzymy kod do obslugi zdarzenia.
      }
    } zm=x; 
}
    
Jeszcze nie wiem też jak wyeliminować małe błedy jeśli godzina lub data mają jedną cyfrę i zero np. dzisiejsza data 2014.02.12 mi wyświetla się 2014.2A.12

Z góry dziękuje za pomoc

Co miesiąc do wygrania nagrody o wartości ponad 1600 zł!


Awatar użytkownika
wojtekizk
Starszy majsterkowicz
Posty: 311
Rejestracja: 19 lis 2013, 10:54
Lokalizacja: Bydgoszcz

Re: Problem z biblioteką MenuBackend i RTC

Post autor: wojtekizk » 13 lut 2014, 12:36

Witam... cóż jesteś pewien że sama płytka z RTC działa prawidłowo? Chodzi o to czy jeśli napiszesz prosty programik do samego RTC to zmienia się czas?

Kod: Zaznacz cały

#include <Wire.h>
#include"RTClib.h"
 
RTC_DS1307 RTC;
 
void setup()
{
   Serial.begin(9600);
   Wire.begin();
   RTC.begin();
 
   if(!RTC.isrunning())
   {
      Serial.println("RTC jeszcze sie nie podniosl !!!");
      // podnosimy wiec sami raz jeszcze recznie 
      RTC.adjust(DateTime(__DATE__,__TIME__));
   }
}
 
void loop()
{
   DateTime now=RTC.now();
   Serial.println(now.second()); // na przykład 
   delay(1000);
}
u Ciebie widzę, że linię :
RTC.adjust(DateTime(__DATE__,__TIME__));
masz zaremowaną ... sprawdź to proszę.
.. co do wyświetlania na LCD musisz użyć prostego tricku. Zmienną typu uint8_t musisz zamienić na char , potem odczytać jej długość, tz. czy ma jeden czy 2 znaki . potem jeśli ma jeden to dodajesz do początku '0' i dopiero potem takie char-y wyświetlasz w polach miesiąc, dzień, minuta czy sekunda. Opisy jak balansować z konwersją typów w C++ znajdziesz na pewno w każdym podręczniku. Możesz także użyć operacji matematycznych, choćby dla liczb 2 cyfrowych liczbą dziesiątek z x uzyskasz dzieląc x/10 a liczbę jednostek dzieląc modulo x%10. Po takiej operacji masz już odp. cyfry i potem przypisujesz je do char.
Pozdrawiam
bpachel
Młodszy majsterkowicz
Posty: 32
Rejestracja: 2 sty 2014, 22:02

Re: Problem z biblioteką MenuBackend i RTC

Post autor: bpachel » 13 lut 2014, 14:43

Samo RTC działa nawet jak ma wyświetlać czas na wyświetlaczu. Tylko jak chce żeby działał z tą biblioteką to mi czasu już nie odświeża.
Awatar użytkownika
wojtekizk
Starszy majsterkowicz
Posty: 311
Rejestracja: 19 lis 2013, 10:54
Lokalizacja: Bydgoszcz

Re: Problem z biblioteką MenuBackend i RTC

Post autor: wojtekizk » 13 lut 2014, 18:49

OK... chyba wiem gdzie problem... zaczyna się w funkcji menuUseEvent(MenuUseEvent used) od tego miejsca:

Kod: Zaznacz cały

 while(akcja!=4) 
to właśnie w tej pętli powinieneś umieszczać cały kod wyświetlania czasu... a robisz to powyżej... czyli tylko raz, potem przekazujesz sterowanie do "teoretycznie niekończącej się pętli while", bo kończy się dopiero wtedy, kiedy wciśniesz OK. W Twoim działającym programiku całe wyświetlanie czasu wrzuciłeś do funkcji czas() ... i to rozwiązanie jest bardzo ładne i praktyczne... zrób to tutaj - całe wyświetlanie czasu wrzuć do funkcji i potem wywołuj ją w pętli:
while(akcja!=4) ... Powinno być wtedy dobrze... co do wyświetlania pojedynczych jednocyfrowych składników daty to poczytaj sobie o funkcji o której sam zapomniałem :-)
ta fajna funkcja to: snprintf(buf, sizeof(buf), "ciąg farmatujący zmienne ", zmienne);
pomóc?
Przykład : najpierw :

Kod: Zaznacz cały

char buf[50]; // zmienna globalna 49-cio znakowa z zapasem na inne składniki daty, tu na razie tylko godzina :-)
snprintf(buf, sizeof(buf), " %02d:%02d:%02d ",now.hour(), now.minute(), now.second());
a potem w lcd wyświetlasz buf ... prawda że fajne :-)
Pozdrawiam
ps. mała poprawka zmienna buf chyba powinna być najpierw wyczyszczona... jak się nie mylę funkcją memset :-)
memset( buf, 0 , sizeof(buf));
... no i oczywiście chyba potrzebne będzie także :
#include <stdio.h>
#include <string.h>
bpachel
Młodszy majsterkowicz
Posty: 32
Rejestracja: 2 sty 2014, 22:02

Re: Problem z biblioteką MenuBackend i RTC

Post autor: bpachel » 14 lut 2014, 12:06

dzięki już sprawdzam czy działa :)
bpachel
Młodszy majsterkowicz
Posty: 32
Rejestracja: 2 sty 2014, 22:02

Re: Problem z biblioteką MenuBackend i RTC

Post autor: bpachel » 14 lut 2014, 12:29

nigdzie nie mogę znaleźć tych bibliotek
bpachel
Młodszy majsterkowicz
Posty: 32
Rejestracja: 2 sty 2014, 22:02

Re: Problem z biblioteką MenuBackend i RTC

Post autor: bpachel » 14 lut 2014, 13:23

coś mi nie przepuszcza tych funkjii
Awatar użytkownika
wojtekizk
Starszy majsterkowicz
Posty: 311
Rejestracja: 19 lis 2013, 10:54
Lokalizacja: Bydgoszcz

Re: Problem z biblioteką MenuBackend i RTC

Post autor: wojtekizk » 14 lut 2014, 13:37

Witam
pisz proszę nieco jaśniej...jakich funkcji, co nie przepuszcza - kompilator, konsolidator i jakich bibliotek nie możesz znaleźć...
te dwie:
#include <stdio.h>
#include <string.h>
...najprawdopodobniej od wersji IDE 1.0.5 nie są już potrzebne wcale... wcześniej trzeba było je includować...
Jeżeli kompilator wywala błąd o o nieznanej nazwie snprintf()...ble..ble..ble to trzeba je dodać...jeśli nie ma błędu to jest OKI

Kod: Zaznacz cały

// poniższy testowy kod kompiluje się bezbłędnie
int k=3;
char buf[50];
// -------------------------------------------------
void setup()
{
  Serial.begin(9600);
  memset(buf,0,sizeof(buf));
  snprintf(buf, sizeof(buf), " %02d ",k);
}
// -------------------------------------------------
void loop()
{
  Serial.println(buf);delay(1000);
}
// =================================================
bpachel
Młodszy majsterkowicz
Posty: 32
Rejestracja: 2 sty 2014, 22:02

Re: Problem z biblioteką MenuBackend i RTC

Post autor: bpachel » 14 lut 2014, 13:57

dobra teraz pozmieniałem trochę i program się załadował ale chyba coś źle umieściłem bo godzina mi się teraz nie odświeża

Kod: Zaznacz cały

#include <MenuBackend.h>               
#include <LiquidCrystal.h>
#include <Wire.h>  
#include "DHT.h"
#include <OneWire.h>
#include <DallasTemperature.h>
 #include "RTClib.h"  
 #define DHTPIN 4
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
 RTC_DS1307 RTC;  
 char buf[50];




uint8_t arrowUpDown[8] = {0x4,0xe,0x15,0x4,0x15,0xe,0x4};
uint8_t arrowDown[8]  = {0x4,0x4,0x4,04,0x15,0xe,0x4};
uint8_t arrowRight[8] = {0x0,0x4,0x2,0x1f,0x2,0x4,0x0};
uint8_t arrowLeft[8] = {0x0,0x4,0x8,0x1f,0x8,0x4,0x0};
uint8_t arrowBack[8] = {0x1,0x1,0x5,0x9,0x1f,0x8,0x4};
LiquidCrystal lcd(5, 6, 7, 8, 9, 10);
volatile int zm =-1;
volatile int x=-1;
volatile int stan_Analog;
char *linia1;                      
char *linia2;
/*
    CZAS
      Pokaz Czas
      Ustaw Czas
    TEMPERATURA
      Pokój
      Pole
*/
MenuBackend menu = MenuBackend(menuUseEvent,menuChangeEvent);
  MenuItem P1 = MenuItem("     CZAS",1);
    MenuItem P11 = MenuItem("  Pokaz Czas",2);
    MenuItem P12 = MenuItem("  Ustaw Czas",2);
    
  
  MenuItem P2 = MenuItem(" TEMPERATURA",1);
    MenuItem P21 = MenuItem("    Pokoj",2);
    MenuItem P22 = MenuItem("     Pole",2);

void menuSetup()
{
  menu.getRoot().add(P1);
  P1.add(P11);
  P11.add(P12);P11.addLeft(P1);
  P12.addLeft(P1);P12.add(P11);
  
  P1.addRight(P2);
  P2.add(P21);
    P21.add(P22);P21.addLeft(P2);
    P22.addLeft(P2);P22.add(P21);
  
  P2.addRight(P1);
}

void menuUseEvent(MenuUseEvent used)

{
  Serial.print("wybrano:  "); Serial.println(used.item.getName());
  
  if(used.item.getName() =="     Pole")
  {
    int akcja=-1;delay(1000);
    while(akcja!=4)
  {
    zm=-1;
    akcja=czytaj_1(0);
    pole();
    if(zm!=akcja)
    {
      if(akcja==4)
      {
        lcd.setCursor(1,1);lcd.print("              ");
        lcd.setCursor(0,0);lcd.print("*     MENU     *");delay(2500);
        lcd.setCursor(1,0);lcd.print("              ");
        lcd.setCursor(1,0);lcd.print(linia1);
        lcd.setCursor(1,1);lcd.print(linia2);

      }
      
    }
  } zm=akcja;
  }
  
  if(used.item.getName() =="    Pokoj")
  {
    int akcja=-1;delay(1000);
    while(akcja!=4)
  {
    zm=-1;
    akcja=czytaj_1(0);
    pokoj();
    if(zm!=akcja)
    {
      if(akcja==4)
      {
        lcd.setCursor(1,1);lcd.print("              ");
        lcd.setCursor(0,0);lcd.print("*     MENU     *");delay(2500);
        lcd.setCursor(1,0);lcd.print("              ");
        lcd.setCursor(1,0);lcd.print(linia1);
        lcd.setCursor(1,1);lcd.print(linia2);

      }
      
    }
  } zm=akcja;
  }
  if (used.item.getName() =="  Pokaz Czas")
  { 
  int akcja=-1;delay(1000);
  while(akcja!=4)
  {
    zm=-1;
    akcja=czytaj_1(0);
    czas();
    if(zm!=akcja)
    {
      if(akcja==4)
      {
        lcd.setCursor(1,1);lcd.print("              ");
        lcd.setCursor(0,0);lcd.print("*     MENU     *");delay(2500);
        lcd.setCursor(1,0);lcd.print("              ");
        lcd.setCursor(1,0);lcd.print(linia1);
        lcd.setCursor(1,1);lcd.print(linia2);

      }
      
    }
  } zm=akcja;
  }
}

void menuChangeEvent(MenuChangeEvent changed)
{
  int c=changed.to.getShortkey();                         // pobieramy shortkey (1,2,3, lub4)
  lcd.clear();                                            // bez komentarza 
  lcd.setCursor(0,0); 
  if(c==1)                                                // jeśli to menu głowne (shortkey=1) to:
    {
    lcd.write(3);                                         // strzałka w lewo
    strcpy(linia1,changed.to.getName());                  // tworzymy napis w pierwszej linii
    lcd.print(linia1);                                    // wyświetlamy ją
    lcd.setCursor(15,0);lcd.write(4);                     // strzałka w prawo
    lcd.setCursor(0,1);lcd.write(5);                      // strzałka w dół
    lcd.setCursor(15,1);lcd.write(5);                     // strzałka w dół
    }
    if(c==2)                                              // jeśli to podmenu dla dziecka - (shortkey=2) to:
    {
    lcd.print("*");                                       // rysujemy gwiazdkę
    strcpy(linia2,changed.to.getName());                  // tworzymy napis w pierwszej linii
    lcd.print(linia1);                                    // wyświetlamy ją
    lcd.setCursor(15,0);lcd.print("*");                   // gwiazdka 
    lcd.setCursor(0,1);lcd.write(6);                      // druga linia i strzałka powrotu (arrowBack)
    lcd.print(changed.to.getName());                      // wyświetlamy nazwe "dziecka"
    lcd.setCursor(15,1);lcd.write(7);                     // strzałka góra-dół
    }
    if(c==3)                                              // jeśli dziecko  ma dziecko - (shortkey =3) to:
    {
    lcd.print("*");                                       // gwiazdka
    strcpy(linia2,changed.to.getName());                  // kopiujemy akt. nazwe opcji menu do zmiennej linia2
    lcd.print(linia1);                                    // i wyświetlamy pierwszą linię
    lcd.setCursor(15,0);lcd.print("*");                   // gwiazdka
    lcd.setCursor(0,1);lcd.write(6);                      // druga linia i strzałka arrowBack
    lcd.print(changed.to.getName());                      // wyświetlamy wnuka w drugiej linii
    lcd.setCursor(15,1);lcd.write(4);                     // strzałka w prawo bo są wnuki
    }
    
    if(c==4)                                              // jeśli to wnuk  (shortkey =4) to:
    {
    lcd.print("*");                                       // gwaizdka
    lcd.print(linia2);                                    // w pierwszej linii wyświetlamy dziecko ( czyli rodzica wnuka) 
    lcd.setCursor(15,0);lcd.print("*");                   // gwaizdka
    lcd.setCursor(0,1);lcd.write(6);                      // druga linia i strzałka arrowBack
    lcd.print(changed.to.getName());                      // wyświetlamy wnuka
    lcd.setCursor(15,1);lcd.write(7);                     // strzałka góra-dół 
    }
}
volatile int czytaj_1(int analog)
{
   int stan_Analog = analogRead(analog);delay(30);//Serial.println(stan_Analog); 
   if (stan_Analog < 50) return -1; // dla wartosci poza zakresem
   if (stan_Analog < 185)   return 0;  // w prawo  
   if (stan_Analog < 215)  return 1;  // do gĂłry 
   if (stan_Analog < 275)  return 2;  // w dół 
   if (stan_Analog < 360)  return 3;  // w lewo  
   if (stan_Analog < 550)  return 4;  // OK 
   return -1;                         // nic nie wcisnieto
}

  void setup()
{
  linia1=new char[16];  // zainicjowanie dynamicznego wskaźnika do tekstu 
  linia2=new char[16];
  Serial.begin(9600);   // inicjacja Seriala, głównie do testów 
  lcd.begin(16, 2);     // inicjacja LCD
  lcd.createChar(3,arrowLeft);    // tworzymy w pamięci LCD 5 własnych znaków dla strzałek
  lcd.createChar(4,arrowRight);
  lcd.createChar(5,arrowDown);
  lcd.createChar(6,arrowBack);
  lcd.createChar(7,arrowUpDown);
  pinMode(0,OUTPUT);digitalWrite(0,LOW);
  menuSetup();          // funkcja klasy MenuBackend - tu tak naprawdę tworzymy nasze menu 
  menu.moveDown();
  Wire.begin();  
  RTC.begin();
  RTC.adjust(DateTime(__DATE__, __TIME__));
  DateTime now = RTC.now();
  memset( buf, 0 , sizeof(buf));
  snprintf(buf, sizeof(buf), " %02d:%02d:%02d ",now.hour(), now.minute(), now.second());
}

void czas()
{
  lcd.setCursor(1,0);lcd.print("              ");
  lcd.setCursor(1,1);lcd.print("              ");  
  lcd.setCursor(2, 0);
  DateTime now = RTC.now();
  lcd.print(now.year(), DEC);
  lcd.setCursor(6,0);  
  lcd.print(".");
  lcd.setCursor(7,0);  
  lcd.print(now.month(), DEC);
  lcd.setCursor(9,0);  
  lcd.print(".");
  lcd.setCursor(10,0);  
  lcd.print(now.day(), DEC);  
  lcd.setCursor(3, 1); 
  lcd.print(buf);  
  delay(10);
}

void pole()
{
  if (sensors.getTempCByIndex(0) < 10)
  {
  lcd.setCursor(7,1);lcd.print("   ");
  }
  else{lcd.setCursor(7,1);lcd.print("  ");}
  sensors.requestTemperatures();
  lcd.setCursor(1, 0);
  lcd.print("Temperatura na");
  lcd.setCursor(1, 1);
  lcd.print("zewn.: ");
  lcd.setCursor(9, 1);
  lcd.print(sensors.getTempCByIndex(0),2);
  
}


void pokoj()
{
  float h = dht.readHumidity(); 
  float t = dht.readTemperature();
  float temp = t - 1.0;
    lcd.setCursor(1,0);lcd.print("              ");
    lcd.setCursor(1,1);lcd.print("              ");
    lcd.setCursor(1, 0);
    lcd.print("Temp.:");
    lcd.setCursor(7, 0);
    lcd.print(temp, 1);
    lcd.setCursor(11,0);
    lcd.print(" C");
    lcd.setCursor(1, 1);
    lcd.print("Wilgot.:");
    lcd.setCursor(9, 1);
    lcd.print(h, 1);
    lcd.setCursor(13,1);
    lcd.print("%");
}

void loop()
{
  x=czytaj_1(0);delay(30);
  if(zm!=x)                               // jesli była zmiana stanu to :
    {
      switch(x)                           // sprawdzamy co nacisnieto 
      {
      case 0: menu.moveRight();break;     // jesli naciśnięto klawisz w Prawo to przesuń menu w prawo
      case 1: menu.moveUp();break;        // menu do góry
      case 2: menu.moveDown();break;      // menu w dół
      case 3: menu.moveLeft();break;      // menu w lewo
      case 4: menu.use();break;           // wciśnięto OK więc skok do funkcji menuUseEvent(MenuUseEvend used)
                                          // to w tej funkcji właśnie obsługujemy nasze Menu, tu sprawdzamy
                                          // jaką opcję wybrano i tutaj tworzymy kod do obslugi zdarzenia.
      }
    } zm=x; 
}
    
Awatar użytkownika
wojtekizk
Starszy majsterkowicz
Posty: 311
Rejestracja: 19 lis 2013, 10:54
Lokalizacja: Bydgoszcz

Re: Problem z biblioteką MenuBackend i RTC

Post autor: wojtekizk » 14 lut 2014, 14:14

dobra... czegoś tu nie kumam... a wcześniej odświeżała Ci się godzina...bo wydaje mi się, że właśnie to było powodem Twojej ...hmm... flustracji :-)
Proponuję dodać jakąś czujkę np. na serialu aby przekonać się czy wszystko w pętli while posuwa się jak trzeba, czyli:

Kod: Zaznacz cały

while(akcja!=4)
  {
    zm=-1;
    akcja=czytaj_1(0);
    Serial.println("przed funkcja czas");delay(30); // czujka przed
    czas();
    Serial.println("po funkcji czas");delay(30);    // czujka po
    if(zm!=akcja)
    {
      if(akcja==4)
      {
        lcd.setCursor(1,1);lcd.print("              ");
        lcd.setCursor(0,0);lcd.print("*     MENU     *");delay(2500);
        lcd.setCursor(1,0);lcd.print("              ");
        lcd.setCursor(1,0);lcd.print(linia1);
        lcd.setCursor(1,1);lcd.print(linia2);

      }
      
    }
  } zm=akcja;
sprawdź na serialu co Ci wywala i sam się zorientujesz o co biega :-)
Pozdrawiam... będę wieczorkiem dopiero
bpachel
Młodszy majsterkowicz
Posty: 32
Rejestracja: 2 sty 2014, 22:02

Re: Problem z biblioteką MenuBackend i RTC

Post autor: bpachel » 14 lut 2014, 14:24

jak dodałem funkcję czas do pętli while to godzina się odświeżała a potem jak dopisałem z tym snprintf() i coś tam jeszcze to już się nie odświeża
bpachel
Młodszy majsterkowicz
Posty: 32
Rejestracja: 2 sty 2014, 22:02

Re: Problem z biblioteką MenuBackend i RTC

Post autor: bpachel » 14 lut 2014, 14:38

sprawdziłam i funkcja czas działa ale to chyba chodzi o to że coś źle zrobiłem w funkcji czas. ponieważ jak ma mi wyświetlić ten buf to wyświetla mi tą samą godzinę (nawet jak zakończę tą funkcję ok i wejdę jeszcze raz)
Awatar użytkownika
wojtekizk
Starszy majsterkowicz
Posty: 311
Rejestracja: 19 lis 2013, 10:54
Lokalizacja: Bydgoszcz

Re: Problem z biblioteką MenuBackend i RTC

Post autor: wojtekizk » 14 lut 2014, 14:39

dobra...ale mam dosłownie chwilkę tylko...
- po pierwsze w Twojej funkcji czas widzę tylko wyświetlanie daty... a gdzie godzina???, więc dopiero jutro byś zobaczył czy Ci się odświerza :-)
- po drugie dałeś snprintf() do setupa a powinieneś do czasu
- po trzecie masz wyświetlać w lcd zmienną buf i już bez kombinacji z ust. kursora, bo właśnie te dziwne znaki formatujące robią to za Ciebie... pokumaj trochę sam to się zorientujesz o co biega...
w razie czego zajrzę tu jeszcze wieczorkiem :-)
bpachel
Młodszy majsterkowicz
Posty: 32
Rejestracja: 2 sty 2014, 22:02

Re: Problem z biblioteką MenuBackend i RTC

Post autor: bpachel » 14 lut 2014, 14:45

myślałem że to buf jest za wyświetlanie godziny
bpachel
Młodszy majsterkowicz
Posty: 32
Rejestracja: 2 sty 2014, 22:02

Re: Problem z biblioteką MenuBackend i RTC

Post autor: bpachel » 14 lut 2014, 15:10

dzięki za pomoc. wygląda tak jak chciałem ale w kodzie jest chyba coś źle bo musiałem zostawić to setCursor i stworzyć buf2.

Kod: Zaznacz cały

#include <MenuBackend.h>               
#include <LiquidCrystal.h>
#include <Wire.h>  
#include "DHT.h"
#include <OneWire.h>
#include <DallasTemperature.h>
 #include "RTClib.h"  
 #define DHTPIN 4
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
 RTC_DS1307 RTC;  
 char buf[50];
 char buf2[50];
#include <stdio.h>
#include <string.h>



uint8_t arrowUpDown[8] = {0x4,0xe,0x15,0x4,0x15,0xe,0x4};
uint8_t arrowDown[8]  = {0x4,0x4,0x4,04,0x15,0xe,0x4};
uint8_t arrowRight[8] = {0x0,0x4,0x2,0x1f,0x2,0x4,0x0};
uint8_t arrowLeft[8] = {0x0,0x4,0x8,0x1f,0x8,0x4,0x0};
uint8_t arrowBack[8] = {0x1,0x1,0x5,0x9,0x1f,0x8,0x4};
LiquidCrystal lcd(5, 6, 7, 8, 9, 10);
volatile int zm =-1;
volatile int x=-1;
volatile int stan_Analog;
char *linia1;                      
char *linia2;
/*
    CZAS
      Pokaz Czas
      Ustaw Czas
    TEMPERATURA
      Pokój
      Pole
*/
MenuBackend menu = MenuBackend(menuUseEvent,menuChangeEvent);
  MenuItem P1 = MenuItem("     CZAS",1);
    MenuItem P11 = MenuItem("  Pokaz Czas",2);
    MenuItem P12 = MenuItem("  Ustaw Czas",2);
    
  
  MenuItem P2 = MenuItem(" TEMPERATURA",1);
    MenuItem P21 = MenuItem("    Pokoj",2);
    MenuItem P22 = MenuItem("     Pole",2);

void menuSetup()
{
  menu.getRoot().add(P1);
  P1.add(P11);
  P11.add(P12);P11.addLeft(P1);
  P12.addLeft(P1);P12.add(P11);
  
  P1.addRight(P2);
  P2.add(P21);
    P21.add(P22);P21.addLeft(P2);
    P22.addLeft(P2);P22.add(P21);
  
  P2.addRight(P1);
}

void menuUseEvent(MenuUseEvent used)

{
  Serial.print("wybrano:  "); Serial.println(used.item.getName());
  
  if(used.item.getName() =="     Pole")
  {
    int akcja=-1;delay(1000);
    while(akcja!=4)
  {
    zm=-1;
    akcja=czytaj_1(0);
    pole();
    if(zm!=akcja)
    {
      if(akcja==4)
      {
        lcd.setCursor(1,1);lcd.print("              ");
        lcd.setCursor(0,0);lcd.print("*     MENU     *");delay(2500);
        lcd.setCursor(1,0);lcd.print("              ");
        lcd.setCursor(1,0);lcd.print(linia1);
        lcd.setCursor(1,1);lcd.print(linia2);

      }
      
    }
  } zm=akcja;
  }
  
  if(used.item.getName() =="    Pokoj")
  {
    int akcja=-1;delay(1000);
    while(akcja!=4)
  {
    zm=-1;
    akcja=czytaj_1(0);
    pokoj();
    if(zm!=akcja)
    {
      if(akcja==4)
      {
        lcd.setCursor(1,1);lcd.print("              ");
        lcd.setCursor(0,0);lcd.print("*     MENU     *");delay(2500);
        lcd.setCursor(1,0);lcd.print("              ");
        lcd.setCursor(1,0);lcd.print(linia1);
        lcd.setCursor(1,1);lcd.print(linia2);

      }
      
    }
  } zm=akcja;
  }
  if (used.item.getName() =="  Pokaz Czas")
  { 
  int akcja=-1;delay(1000);
  while(akcja!=4)
  {
    zm=-1;
    akcja=czytaj_1(0);
    czas();
    if(zm!=akcja)
    {
      if(akcja==4)
      {
        lcd.setCursor(1,1);lcd.print("              ");
        lcd.setCursor(0,0);lcd.print("*     MENU     *");delay(2500);
        lcd.setCursor(1,0);lcd.print("              ");
        lcd.setCursor(1,0);lcd.print(linia1);
        lcd.setCursor(1,1);lcd.print(linia2);

      }
      
    }
  } zm=akcja;
  }
}

void menuChangeEvent(MenuChangeEvent changed)
{
  int c=changed.to.getShortkey();                         // pobieramy shortkey (1,2,3, lub4)
  lcd.clear();                                            // bez komentarza 
  lcd.setCursor(0,0); 
  if(c==1)                                                // jeśli to menu głowne (shortkey=1) to:
    {
    lcd.write(3);                                         // strzałka w lewo
    strcpy(linia1,changed.to.getName());                  // tworzymy napis w pierwszej linii
    lcd.print(linia1);                                    // wyświetlamy ją
    lcd.setCursor(15,0);lcd.write(4);                     // strzałka w prawo
    lcd.setCursor(0,1);lcd.write(5);                      // strzałka w dół
    lcd.setCursor(15,1);lcd.write(5);                     // strzałka w dół
    }
    if(c==2)                                              // jeśli to podmenu dla dziecka - (shortkey=2) to:
    {
    lcd.print("*");                                       // rysujemy gwiazdkę
    strcpy(linia2,changed.to.getName());                  // tworzymy napis w pierwszej linii
    lcd.print(linia1);                                    // wyświetlamy ją
    lcd.setCursor(15,0);lcd.print("*");                   // gwiazdka 
    lcd.setCursor(0,1);lcd.write(6);                      // druga linia i strzałka powrotu (arrowBack)
    lcd.print(changed.to.getName());                      // wyświetlamy nazwe "dziecka"
    lcd.setCursor(15,1);lcd.write(7);                     // strzałka góra-dół
    }
    if(c==3)                                              // jeśli dziecko  ma dziecko - (shortkey =3) to:
    {
    lcd.print("*");                                       // gwiazdka
    strcpy(linia2,changed.to.getName());                  // kopiujemy akt. nazwe opcji menu do zmiennej linia2
    lcd.print(linia1);                                    // i wyświetlamy pierwszą linię
    lcd.setCursor(15,0);lcd.print("*");                   // gwiazdka
    lcd.setCursor(0,1);lcd.write(6);                      // druga linia i strzałka arrowBack
    lcd.print(changed.to.getName());                      // wyświetlamy wnuka w drugiej linii
    lcd.setCursor(15,1);lcd.write(4);                     // strzałka w prawo bo są wnuki
    }
    
    if(c==4)                                              // jeśli to wnuk  (shortkey =4) to:
    {
    lcd.print("*");                                       // gwaizdka
    lcd.print(linia2);                                    // w pierwszej linii wyświetlamy dziecko ( czyli rodzica wnuka) 
    lcd.setCursor(15,0);lcd.print("*");                   // gwaizdka
    lcd.setCursor(0,1);lcd.write(6);                      // druga linia i strzałka arrowBack
    lcd.print(changed.to.getName());                      // wyświetlamy wnuka
    lcd.setCursor(15,1);lcd.write(7);                     // strzałka góra-dół 
    }
}
volatile int czytaj_1(int analog)
{
   int stan_Analog = analogRead(analog);delay(30);//Serial.println(stan_Analog); 
   if (stan_Analog < 50) return -1; // dla wartosci poza zakresem
   if (stan_Analog < 185)   return 0;  // w prawo  
   if (stan_Analog < 215)  return 1;  // do gĂłry 
   if (stan_Analog < 275)  return 2;  // w dół 
   if (stan_Analog < 360)  return 3;  // w lewo  
   if (stan_Analog < 550)  return 4;  // OK 
   return -1;                         // nic nie wcisnieto
}

  void setup()
{
  linia1=new char[16];  // zainicjowanie dynamicznego wskaźnika do tekstu 
  linia2=new char[16];
  Serial.begin(9600);   // inicjacja Seriala, głównie do testów 
  lcd.begin(16, 2);     // inicjacja LCD
  lcd.createChar(3,arrowLeft);    // tworzymy w pamięci LCD 5 własnych znaków dla strzałek
  lcd.createChar(4,arrowRight);
  lcd.createChar(5,arrowDown);
  lcd.createChar(6,arrowBack);
  lcd.createChar(7,arrowUpDown);
  pinMode(0,OUTPUT);digitalWrite(0,LOW);
  menuSetup();          // funkcja klasy MenuBackend - tu tak naprawdę tworzymy nasze menu 
  menu.moveDown();
  Wire.begin();  
  RTC.begin();
  RTC.adjust(DateTime(__DATE__, __TIME__));
  memset( buf, 0 , sizeof(buf));
  memset( buf2, 0 , sizeof(buf2));
}

void czas()
{
  lcd.setCursor(1,0);lcd.print("              ");
  lcd.setCursor(1,1);lcd.print("              ");
  DateTime now = RTC.now(); 
  snprintf(buf, sizeof(buf), "  %02d:%02d:%02d ",now.year(), now.month(), now.day()); 
  snprintf(buf2, sizeof(buf2), "   %02d:%02d:%02d ",now.hour(), now.minute(), now.second()); 
  lcd.setCursor(1,0);
  lcd.print(buf);
  lcd.setCursor(1, 1); 
  lcd.print(buf2);
  delay(10);
}

void pole()
{
  if (sensors.getTempCByIndex(0) < 10)
  {
  lcd.setCursor(7,1);lcd.print("   ");
  }
  else{lcd.setCursor(7,1);lcd.print("  ");}
  sensors.requestTemperatures();
  lcd.setCursor(1, 0);
  lcd.print("Temperatura na");
  lcd.setCursor(1, 1);
  lcd.print("zewn.: ");
  lcd.setCursor(9, 1);
  lcd.print(sensors.getTempCByIndex(0),2);
  
}


void pokoj()
{
  float h = dht.readHumidity(); 
  float t = dht.readTemperature();
  float temp = t - 1.0;
    lcd.setCursor(1,0);lcd.print("              ");
    lcd.setCursor(1,1);lcd.print("              ");
    lcd.setCursor(1, 0);
    lcd.print("Temp.:");
    lcd.setCursor(7, 0);
    lcd.print(temp, 1);
    lcd.setCursor(11,0);
    lcd.print(" C");
    lcd.setCursor(1, 1);
    lcd.print("Wilgot.:");
    lcd.setCursor(9, 1);
    lcd.print(h, 1);
    lcd.setCursor(13,1);
    lcd.print("%");
}

void loop()
{
  x=czytaj_1(0);delay(30);
  if(zm!=x)                               // jesli była zmiana stanu to :
    {
      switch(x)                           // sprawdzamy co nacisnieto 
      {
      case 0: menu.moveRight();break;     // jesli naciśnięto klawisz w Prawo to przesuń menu w prawo
      case 1: menu.moveUp();break;        // menu do góry
      case 2: menu.moveDown();break;      // menu w dół
      case 3: menu.moveLeft();break;      // menu w lewo
      case 4: menu.use();break;           // wciśnięto OK więc skok do funkcji menuUseEvent(MenuUseEvend used)
                                          // to w tej funkcji właśnie obsługujemy nasze Menu, tu sprawdzamy
                                          // jaką opcję wybrano i tutaj tworzymy kod do obslugi zdarzenia.
      }
    } zm=x; 
}
    
Awatar użytkownika
wojtekizk
Starszy majsterkowicz
Posty: 311
Rejestracja: 19 lis 2013, 10:54
Lokalizacja: Bydgoszcz

Re: Problem z biblioteką MenuBackend i RTC

Post autor: wojtekizk » 14 lut 2014, 17:19

Super... nareszcie wszystko jest OKI... ale wrzucę tu swoje trzy grosze, jako "ojciec" tego sukcesu :-)
- teoretycznie powinieneś memset(buf,0,sizeof(buf)); używać przed każdą zmianą zawartości bufora. W tym konkretnym przypadku to bez znaczenia ponieważ dane masz tak zorganizowane, że zawsze długość zmiennej buf jest taka sama, więc po prostu ją nadpisujesz... ale gdyby w jakimś innym programie zmienna buf miała by różną ilość znaków to mogło by dojść do niepełnego nadpisania. Dla przykładu gdyby buf="Ala ma pieska" a chwile potem zmieniłbyś na buf="Ola na kota" to po nadpisaniu miałbyś "Ola ma kotaka"... mam nadzieję że wiesz o co biega.
- te dziwne znaki formatujące wypadało by zmienić w buf na: "%02d.%02d.%02d" ... czyli na kropki pomiędzy składnikami daty, bo właśnie po to się używa tych znaków, można także tak: "ROK=%02d Mies=%02d Dzien=%02d" :-)
Również mogłeś to wszystko zapisać w jednej zmiennej buf:
snprintf(buf, sizeof(buf), " %02d.%02d.%02d %02d:%02d:%02d",now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second());
... ale potrzebowałbyś 20 znakowego LCD, bo na 16 znakowym nie zmieściły by się sekundy :-)

Gratuluję uporu i wytrwałości
Pozdrawiam
bpachel
Młodszy majsterkowicz
Posty: 32
Rejestracja: 2 sty 2014, 22:02

Re: Problem z biblioteką MenuBackend i RTC

Post autor: bpachel » 14 lut 2014, 17:35

Dzięki za rady, co do daty to nie zauważyłem nawet ale już zmieniam. Niestety znalazłem pewien błąd który normalnie nie powinien występować a mianowicie po odłączeniu i ponownym załączeniu zasilania godzina zmienia się na taką która była aktualnie podzczas ładowania programu(nie sprawdzałem ale z datą pewnie jest to samo).
Awatar użytkownika
wojtekizk
Starszy majsterkowicz
Posty: 311
Rejestracja: 19 lis 2013, 10:54
Lokalizacja: Bydgoszcz

Re: Problem z biblioteką MenuBackend i RTC

Post autor: wojtekizk » 14 lut 2014, 18:46

Hey... kurcze w tym temacie Ci chyba nie pomogę, ponieważ posiadam w swoich zasobach tylko moduł RTC na DS1302, który w przeciwieństwie do RTC DS1307 jest inaczej zbudowany i ma zupełnie inną komunikację. Ja w swoim module mam możliwość zapisu aktualnej daty i robi się to jednorazowo, moduł ma własną baterię i po starcie co jakiś czas, średnio raz na kilka miesięcy wymaga leciutkiej korekcji. Po ponownym załączeniu ARDUINO tylko czyta aktualny czas z modułu i jest OK. Podejrzewam jednak że i Twój moduł RTB DS 1307 ma jakąś funkcję do zapisu parametru akt. daty i potem tylko się to czyta. Trzeba zerknąć do biblioteki RTClib tam musi być odpowiedź, jak to zrobić. Jak znajdę czas to pogrzebię... musi być gdzieś funkcja do ustawiania daty po starcie modułu. Robi się to tylko raz. Poszukaj w plikach biblioteki.
Awatar użytkownika
wojtekizk
Starszy majsterkowicz
Posty: 311
Rejestracja: 19 lis 2013, 10:54
Lokalizacja: Bydgoszcz

Re: Problem z biblioteką MenuBackend i RTC

Post autor: wojtekizk » 14 lut 2014, 18:59

chyba już wiem o co biega...
wykonaj taki kod:

Kod: Zaznacz cały

void setup()
{
Serial.begin(9600);
Serial.println(__DATE__);
Serial.println(__TIME__);
}
void loop()
{
}
... cały dowcip musi być tutaj:

Kod: Zaznacz cały

if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  } 
... czyli jeśli nie zainicjowano modułu to inicjujesz go aktualną datą i czasem.
spróbuj zaremować linię z RTC ponieważ ARDUINO odłączone potem od kompa nie ma możliwości odczytu systemowej __DATE__ i __TIME___ więc pewnie czyta co ma w swoich rejestrach... czyli ost. śmieci
bpachel
Młodszy majsterkowicz
Posty: 32
Rejestracja: 2 sty 2014, 22:02

Re: Problem z biblioteką MenuBackend i RTC

Post autor: bpachel » 14 lut 2014, 19:40

poprzednio robiłem tak że wgrywałem program z tą linijką a potem drugi raz bez nie a teraz przestałem bo myślałem że to nie musi być zaremowanę. Dziękuje ci bardzo za pomoc.
ODPOWIEDZ

Strony partnerskie: