Inkrementacja zmiennej

Masz problem, z którym nie możesz sobie poradzić? Pisz śmiało!
Awatar użytkownika
Marhef
Złota rączka
Posty: 1261
Rejestracja: 18 lis 2011, 02:18

Re: Inkrementacja zmiennej

Post autor: Marhef » 4 gru 2019, 14:54

stiven pisze:
3 gru 2019, 22:18
Zapisujesz coś do EEPROM a później po odczycie jest coś innego?
Gdzieś wyżej wspomniałem o możliwości zapisania do EEPROMu nastaw. Teraz nie mam za bardzo czasu, żeby się rozpisywać.
Ale w przykładach w arduino ide jest coś z pamięcią EEPROM. hazi18, spróbuj na ich podstawie coś napisać.
hazi18 pisze:
3 gru 2019, 18:40
prawdzałem oba przypadki pisane przez Was i po inkrementacji tylko zinkrementowało się o 0.1 i dalej nic.
Co znaczy, że dalej nic? Próbowałeś odczekać chwilę przed ponownym wciśnięciem przycisku?

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


hazi18
Młodszy majsterkowicz
Posty: 44
Rejestracja: 18 paź 2019, 20:36

Re: Inkrementacja zmiennej

Post autor: hazi18 » 4 gru 2019, 17:34

Nie, właśnie nie mam nic w kodzie co by zapisywało do EEPROM, teraz po wyłączeniu i właązeniu Arduino mam zadeklarowane 30 stopnie a nie to co ustawiłem przez wyłączeniem
hazi18 pisze: ↑
wczoraj, 18:40
prawdzałem oba przypadki pisane przez Was i po inkrementacji tylko zinkrementowało się o 0.1 i dalej nic.

Co znaczy, że dalej nic? Próbowałeś odczekać chwilę przed ponownym wciśnięciem przycisku?
Nie czekałem zbyt długo tylko kliknąłem, pojawiło mi się 30.1 potem klikam szybciej i nic, potem odczekałem z 1-2 sek i kliknąłem i też nic.
Awatar użytkownika
Marhef
Złota rączka
Posty: 1261
Rejestracja: 18 lis 2011, 02:18

Re: Inkrementacja zmiennej

Post autor: Marhef » 5 gru 2019, 12:55

Wrzuć kod, na jakim testujesz. Za każdym razem wrzucaj, jak masz problem. Bo w tym momencie nie wiem, do czego się odnieść.

A w sprawie zapisu do EEPROM... mogę coś podpowiedzieć.
Potrzebujesz użyć biblioteki EEPROM. Więc na górze musisz dopisać

Kod: Zaznacz cały

#include <EEPROM.h>
A w kodzie interesują Cię funkcje

Kod: Zaznacz cały

EEPROM.read(adres)
EEPROM.write(adres,wartosc)
I teraz się zastanów. Kiedy powinieneś odczytać wartość z pamięci EEPROM. I kiedy do tej pamięci zapisać.
stiven
Złota rączka
Posty: 1645
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Inkrementacja zmiennej

Post autor: stiven » 5 gru 2019, 14:36

Warto wspomnieć o tym, że EEPROM ma ograniczoną żywotność. Producent gwarantuje dla danej komórki pamięci, że do 100 000 cykli zapis-odczyt, dane będą na pewno prawidłowe, później już niekoniecznie. Jakby tak wrzucić bezpośrednio do pętli loop operację na komórce pamięci EEPROM, to to 100 000 może być już osiągnięte w mniej niż 10 sekund. Dlatego korzystając z EEPROM trzeba mieć tego świadomość.
A zmienne deklarowane w programie są zapisywane w pamięci RAM, no i wiadomo, po odłączeniu zasilania traci się zawartość RAM.
hazi18
Młodszy majsterkowicz
Posty: 44
Rejestracja: 18 paź 2019, 20:36

Re: Inkrementacja zmiennej

Post autor: hazi18 » 5 gru 2019, 18:58

@stiven
Warto wspomnieć o tym, że EEPROM ma ograniczoną żywotność. Producent gwarantuje dla danej komórki pamięci, że do 100 000 cykli zapis-odczyt, dane będą na pewno prawidłowe, później już niekoniecznie. Jakby tak wrzucić bezpośrednio do pętli loop operację na komórce pamięci EEPROM, to to 100 000 może być już osiągnięte w mniej niż 10 sekund. Dlatego korzystając z EEPROM trzeba mieć tego świadomość.
Wytłumacz mi jeszcze coś, jeśli EEPROM osiągnie 100 000 operacji to co potem? kość pamięci jest na tyle wysłużona, że należy zmienić urządzenie?
@Marhef
nie chciałem zaśmiecać co post kodem ale z miłą chęcia dodam po zmianach może komuś się przyda :)
co mam rozumieć pod pojęciem adres i wartość? Adresem będzie moja zmienna a? Czy raczej wartością będzie zmienna a do której jest przypisana wartość? Jeśli tak to co oznacza adres? Jakaś ścieżka?

Kod: Zaznacz cały

#include "DHT.h"
#include <TM1637Display.h>
#define DHTPIN 2
#define DHTTYPE DHT22
#include <EEPROM.h>
DHT dht(DHTPIN, DHTTYPE);
const int CLK = 4;
const int DIO = 5;
TM1637Display tm1637a(CLK, DIO);
int przekaznik=7;
int dioda=8;
int przycisk1 = 3;
int przycisk2 = 6;
unsigned long sekunda = 0;
unsigned long czas_pomiaru_temperatury = 0;
int stanLED = 0;
float a=30.0;
EEPROM.read(adres)
EEPROM.write(adres,wartosc)
void setup(void)
{
  pinMode(przekaznik,OUTPUT);
  digitalWrite(przekaznik,LOW);
  pinMode(dioda, OUTPUT);
  pinMode(przycisk1, INPUT_PULLUP);
  pinMode(przycisk2, INPUT_PULLUP);
  tm1637a.setBrightness(0x0a);
  Serial.begin(9600);
  dht.begin();

}

void loop(void)
{   float t = dht.readTemperature();

  if (millis() - czas_pomiaru_temperatury >= 1000UL)
  {
    czas_pomiaru_temperatury = millis();  
    Serial.print("Temperature: "); 
    Serial.print(a);
    Serial.println(" *C");
  }  
    
  if (t >= a)
  {
    digitalWrite(przekaznik,HIGH);
  }
  if (t <= (a-2.0))
  {
    digitalWrite(przekaznik,LOW);
  }
    
  if (digitalRead(przycisk1) == LOW)
  {
    a = a + 0.1;
    delay(250);
  }
    if (digitalRead(przycisk2) == LOW)
  {
    a = a - 0.1;
    delay(250);
  }

  tm1637a.showNumberDec(a); //Display the Variable value;

  if (millis() - sekunda >= 1000UL)
  {
    sekunda = millis();
    stanLED = !stanLED;     
    digitalWrite(dioda, stanLED);
  }  
}
stiven
Złota rączka
Posty: 1645
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Inkrementacja zmiennej

Post autor: stiven » 6 gru 2019, 02:03

Arduino Uno, czyli atmega328p posiada 1024 bajty pamięci EEPROM. Czyli można powiedzieć, że masz do dyspozycji 1024 komórki pamięci o wielkości 1 bajta, a każda komórka ma swój adres, od 0 do 1023. A skoro 1 komórka to 1 bajt, czyli 8 bitów, to w systemie dziesiętnym wartości zapisywane do pojedynczej komórki od 0 do 255. Większą liczbę nie można zapisać, przy odczycie będzie coś innego, jakaś wartość z tego przedziału 0-255. Większe wartości trzeba podzielić na większą ilość komórek. Na przykład zmienne typu int, to 2 bajty i na przykład można podzielić ją na 2 osobne bajty korzystając z operacji przesunięcia bitowego i zapisać do dwóch osobnych komórek, a potem przy odczycie odtworzyć pierwotną wartość. W internecie można znaleźć inne sposoby na to. Samo arduino ma też funkcje do zapisywania i odczytu zmiennych większych niż 1 bajt (EEPROM.put(), EEPROM.get()). https://www.arduino.cc/en/Reference/EEPROM
W funkcji EEPROM.write(adres,wartosc), adres to adres wybranej komórki od 0 do 1023, no a wartość, to to co zapisujemy do danej komórki.

Jeśli chodzi o tą żywotność, to dokładniej mają na nią wpływ operacje zapisu i kasowania. Odczyt nie powoduje żadnych konsekwencji. Pamięć EEPROM jest zbudowana z takiego materiału, który "niszczy" się trochę przy każdym zapisie i kasowaniu. Producent gwarantuje, że do 100 000 cykli zapisu/kasowania, zapisana wartość będzie trzymana przez 20 lat, czyli to co zostało zapisane, przy odczycie będzie to samo. Po 200 000 może być na przykład 10 lat, po 400 000 tydzień, a po 500 000 padnie całkiem. Ale tego nikt nie wie jak będzie, to tylko takie gdybanie. Każda komórka ma swoje 100 000 cykli liczone osobno. Ewentualne padnięte komórki EEPROM nie mają wpływu na inne moduły atmegi.
Awatar użytkownika
Marhef
Złota rączka
Posty: 1261
Rejestracja: 18 lis 2011, 02:18

Re: Inkrementacja zmiennej

Post autor: Marhef » 6 gru 2019, 10:31

hazi18 pisze:
5 gru 2019, 18:58
co mam rozumieć pod pojęciem adres i wartość? Adresem będzie moja zmienna a? Czy raczej wartością będzie zmienna a do której jest przypisana wartość? Jeśli tak to co oznacza adres? Jakaś ścieżka?
Sprawę EEPROMu myślę, że stiven już wyjaśnił. Dodam tylko, że chcesz tam zapisać wartość temperatury, która jest typu float, czyli jest zapisywana na 4 bajtach (32 bity). Więc nie możesz użyć funkcji read() i write() (przepraszam za wprowadzenie w błąd podając te funkcje, zgapiłem, że temperatura jest typu float). Tylko put() i get().
Patrząc na podany przez Ciebie kod... zacznij od podstaw. Wiesz, jak wywołać funkcje w kodzie programu? Do odczytu temperatury wywołujesz dobrze. Do obsługi wyświetlacza też dobrze. Ale próba użycia w ten sposób funkcji do obsługi EEPROMu... to zdecydowanie nie tak.
Poprawię trochę kod, zaznaczę, gdzie są zmiany.

Kod: Zaznacz cały

#include "DHT.h"
#include <TM1637Display.h>
#include <EEPROM.h> // przeniosłem wyżej. To tylko kosmetyka, ale staraj się dołączać biblioteki na początku programu
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
const int CLK = 4;
const int DIO = 5;
TM1637Display tm1637a(CLK, DIO);
int przekaznik=7;
int dioda=8;
int przycisk1 = 3;
int przycisk2 = 6;
unsigned long sekunda = 0;
unsigned long czas_pomiaru_temperatury = 0;
unsigned int blokada
int krok = 1;
int stanLED = 0;
float a=30.0;
float t;  // zmienną do odczytu temperatury też zadeklarujemy jako globalną - przyda się na później
//EEPROM.read(adres)  // tego zdecydowanie nie ma tu być
//EEPROM.write(adres,wartosc)  // tego też nie
void setup(void)
{
  pinMode(przekaznik,OUTPUT);
  digitalWrite(przekaznik,LOW);
  pinMode(dioda, OUTPUT);
  pinMode(przycisk1, INPUT_PULLUP);
  pinMode(przycisk2, INPUT_PULLUP);
  tm1637a.setBrightness(0x0a);
  Serial.begin(9600);
  dht.begin();
  t = dht.readTemperature(); // pierwszy raz odczytujemy temperaturę tu, żeby mieć wartość do warunków
}

void loop(void)
{  // float t = dht.readTemperature(); // tego ma tu nie być. Pomiar wykonujemy raz na sekundę, nie przy każdym obiegu pętli!

  if (millis() - czas_pomiaru_temperatury >= 1000UL)
  {
    t = dht.readTemperature();  // tu odczytujemy temperaturę, będzie co sekundę. Zmieniając wartość 1000UL na większą, zwiększy się odstęp czasu pomiędzy pomiarami
    czas_pomiaru_temperatury = millis();  
    Serial.print("Temperature: "); 
    Serial.print(a);
    Serial.println(" *C");
  }  
    
  if (t >= a)
  {
    digitalWrite(przekaznik,HIGH);
  }
  if (t <= (a-2.0))
  {
    digitalWrite(przekaznik,LOW);
  }
// obsługę przycisków spróbujemy po mojemu    
  if (digitalRead(przycisk1) == LOW && blokada == 0) 
  {
    blokada = 1;
    a = a + 0.1;
    licznik++;
    if (licznik == 7) krok = 10; 
    if (blokada > 65526 && krok == 10) blokada = 65526;
  } else if (blokada >0)
  {
    blokada+=krok;
  } else if (digitalRead(przycisk1) == HIGH)
  {
    krok = 1;
    licznik = 0;
  }

  tm1637a.showNumberDec(a); //Display the Variable value;

  if (millis() - sekunda >= 1000UL)
  {
    sekunda = millis();
    stanLED = !stanLED;     
    digitalWrite(dioda, stanLED);
  }  
}
Spróbuj ten kod. Dla jednego przycisku na razie. Jak zadziała, dodamy EEPROM
hazi18
Młodszy majsterkowicz
Posty: 44
Rejestracja: 18 paź 2019, 20:36

Re: Inkrementacja zmiennej

Post autor: hazi18 » 6 gru 2019, 18:23

Hej,
@Stiven dziękuję za wytłumaczenie :)
@Marhef nie działa inkrementacja, tylko dodało 0.1, nawet po dłuższym odczekaniu (ok 1 min) nic nie dodało po przyciśnięciu. To może zostańmy przy pierwotnej wersji a żeby zrobić tylko ten EEPROM :)
stiven
Złota rączka
Posty: 1645
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Inkrementacja zmiennej

Post autor: stiven » 7 gru 2019, 01:37

Słuchajcie, nie wiem jak to jest możliwe, teraz jak włączam program, to przepełnienie zmiennej typu byte mam po około dwóch sekundach dopiero, a zmiennej unsigned int zajmie kilka minut. Chyba dlatego to nie działa u @hazi18. Więc w tym programie, który podał @Marhef wystarczy zmienić typ zmiennej blokada z powrotem na byte i wrócić do poprzedniego warunku zabezpieczającego. Brakuje też deklaracji zmiennej licznik, ja ją zadeklarowałem też jako byte. I to działa mniej więcej dobrze do pewnego momentu. Jest tam na pewno jeden błąd i był też w tej poprzedniej wersji pod byte

Kod: Zaznacz cały

  if (blokada > 65526 && krok == 10) blokada = 65526;

Kod: Zaznacz cały

  if (blokada > 246 && krok == 10) blokada = 246;  // zabezpieczenie
To if w pierwszym ifie zabezpieczający warunek przepełnienia, on nigdy nie ma możliwości wykonać się, co powoduje po dłuższym przytrzymaniu przycisku, że program przestaje reagować na wciskanie przycisku. Trzeba ten if wyrzucić jako osobny else if. Dodatkowo warto dodać do ifa wykrywającego puszczenie przycisku zerowanie zmiennej blokada. Bez tego jak się szybko przyciska przycisk, to nie zawsze jest reakcja programu. Ale z jakiegoś powodu, kiedy to jest jako else if, to nie daje to efektu, chociaż powinno. Po usunięciu else już jest dobrze.
No ale tak patrząc na użyteczność całości w praktyce, to przydało by się to jeszcze zmodyfikować, żeby działało to płynniej, ale już to pominę, jeśli to będzie działać, to poprawienie będzie łatwe.

Kod: Zaznacz cały

  if (digitalRead(przycisk1) == LOW && blokada == 0) 
  {
    blokada = 1;
    a = a + 0.1;
    licznik++;
    if (licznik == 7) krok = 10; 
  } 
  else if (blokada > 246 && krok == 10) blokada = 246;  // zabezpieczenie
  else if (blokada > 0)
  {
    blokada+=krok;
  } 
  if (digitalRead(przycisk1) == HIGH)
  {
    krok = 1;
    licznik = 0;
    blokada = 0;
  }

Kod: Zaznacz cały

#include "DHT.h"
#include <TM1637Display.h>
#include <EEPROM.h> // przeniosłem wyżej. To tylko kosmetyka, ale staraj się dołączać biblioteki na początku programu
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
const int CLK = 4;
const int DIO = 5;
TM1637Display tm1637a(CLK, DIO);
int przekaznik=7;
int dioda=8;
int przycisk1 = 3;
int przycisk2 = 6;
unsigned long sekunda = 0;
unsigned long czas_pomiaru_temperatury = 0;
byte blokada;
byte licznik;
int krok = 1;
int stanLED = 0;
float a=30.0;
float t;  // zmienną do odczytu temperatury też zadeklarujemy jako globalną - przyda się na później
//EEPROM.read(adres)  // tego zdecydowanie nie ma tu być
//EEPROM.write(adres,wartosc)  // tego też nie
void setup(void)
{
  pinMode(przekaznik,OUTPUT);
  digitalWrite(przekaznik,LOW);
  pinMode(dioda, OUTPUT);
  pinMode(przycisk1, INPUT_PULLUP);
  pinMode(przycisk2, INPUT_PULLUP);
  tm1637a.setBrightness(0x0a);
  Serial.begin(9600);
  dht.begin();
  t = dht.readTemperature(); // pierwszy raz odczytujemy temperaturę tu, żeby mieć wartość do warunków
}

void loop(void)
{  // float t = dht.readTemperature(); // tego ma tu nie być. Pomiar wykonujemy raz na sekundę, nie przy każdym obiegu pętli!

  if (millis() - czas_pomiaru_temperatury >= 1000UL)
  {
    t = dht.readTemperature();  // tu odczytujemy temperaturę, będzie co sekundę. Zmieniając wartość 1000UL na większą, zwiększy się odstęp czasu pomiędzy pomiarami
    czas_pomiaru_temperatury = millis();  
    Serial.print("Temperature: "); 
    Serial.print(a);
    Serial.println(" *C");
  }  
    
  if (t >= a)
  {
    digitalWrite(przekaznik,HIGH);
  }
  if (t <= (a-2.0))
  {
    digitalWrite(przekaznik,LOW);
  }
// obsługę przycisków spróbujemy po mojemu    
  if (digitalRead(przycisk1) == LOW && blokada == 0) 
  {
    blokada = 1;
    a = a + 0.1;
    licznik++;
    if (licznik == 7) krok = 10; 
  } 
  else if (blokada > 246 && krok == 10) blokada = 246;  // zabezpieczenie
  else if (blokada > 0)
  {
    blokada+=krok;
  } 
  if (digitalRead(przycisk1) == HIGH)
  {
    krok = 1;
    licznik = 0;
    blokada = 0;
  }

  tm1637a.showNumberDec(a); //Display the Variable value;

  if (millis() - sekunda >= 1000UL)
  {
    sekunda = millis();
    stanLED = !stanLED;     
    digitalWrite(dioda, stanLED);
  }  
}

Jeśli chodzi o EEPROM. Odczyt to wiadomo, zrobiłbym w setup(). A zapis zrobiłbym po upłynięciu na przykład 10 sekund od ostatniego naciśnięcia któregoś z przycisków.
stiven
Złota rączka
Posty: 1645
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Inkrementacja zmiennej

Post autor: stiven » 7 gru 2019, 13:47

Wiem już skąd wzięły się tak diametralne różnice, ale nie rozumiem dlaczego tak się dzieje. Wcześniej jak testowałem działanie programów, wyświetlanie na serial miałem wewnątrz ifa, wczoraj zrobiłem poza ifem.

Kod: Zaznacz cały

byte blokada;
int krok = 1;
byte licznik;
byte przycisk1 = 5;

int zmienna = 0;

void setup(void)
{
  pinMode(przycisk1, INPUT_PULLUP);
  Serial.begin(9600);
}

void loop(void)
{     

  if (digitalRead(przycisk1) == LOW && blokada == 0) 
  {
    blokada = 1;
    zmienna++;
    licznik++;
    if (licznik == 7) krok = 10; 
    //Serial.print("zmienna:");
    //Serial.println(zmienna);    //tutaj miałem wcześniej wyświetlanie na serial
  } 
  else if (blokada > 246 && krok == 10) blokada = 246;  // zabezpieczenie
  else if (blokada > 0)
  {
    blokada+=krok;
    //Serial.print(blokada);      //to dodatkowe sprawdzanie wartości zmiennej blokada, które powoduje "naprawienie" działania programu
  } 
  
  if (digitalRead(przycisk1) == HIGH)
  {
    krok = 1;
    licznik = 0;
    blokada = 0;
  }
  Serial.print("zmienna:");
  Serial.println(zmienna);
   
}
Moim zdaniem ta dodatkowa linijka z serialem w ifie, powinna spowodować jeszcze dodatkowe opóźnienie w przepełnieniu zmiennej blokada, a tu powstaje jakaś anomalia, tak jakby ten pierwszy if był wykonywany cały czas przy wciśnięciu przycisku, jakby nie był brany pod uwagę warunek blokada == 0. A co jest ciekawe, jak dorzuciłem wyświetlanie wartości zmiennej blokada na serial, zostawiając w pierwszym ifie wyświetlanie wartości zmiennej inkrementowanej, to program się "naprawił" zaczął działać tak samo, jak mając tylko wyświetlanie na serial poza ifami.
Więc wcześniej wprowadziłem w błąd, że trzeba użyć większego typu dla zmiennej blokada, ale wynika to z jakiegoś dziwnego błędu w działaniu programu.
hazi18
Młodszy majsterkowicz
Posty: 44
Rejestracja: 18 paź 2019, 20:36

Re: Inkrementacja zmiennej

Post autor: hazi18 » 10 gru 2019, 18:45

Hej, sprawdziłem i nie do końca pokazywanie "zmienna" naprawia problem. "zmienna" owszem inkrementuje się ale nie temperatura, nadal jest 30 i nic więcej.
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
stiven
Złota rączka
Posty: 1645
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Inkrementacja zmiennej

Post autor: stiven » 11 gru 2019, 12:03

Ten ostatni program, to nie był dla Ciebie. Chciałem pokazać @Marhef, na jakim programie ja testuję sam algorytm obsługi przycisku i że moim zdaniem taka nieistotna zmiana powoduje całkiem inne działanie programu. Ty sprawdź działanie tego programu z mojego poprzedniego komentarza.

Kod: Zaznacz cały

#include "DHT.h"
#include <TM1637Display.h>
#include <EEPROM.h> // przeniosłem wyżej. To tylko kosmetyka, ale staraj się dołączać biblioteki na początku programu
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
const int CLK = 4;
const int DIO = 5;
TM1637Display tm1637a(CLK, DIO);
int przekaznik=7;
int dioda=8;
int przycisk1 = 3;
int przycisk2 = 6;
unsigned long sekunda = 0;
unsigned long czas_pomiaru_temperatury = 0;
byte blokada;
byte licznik;
int krok = 1;
int stanLED = 0;
float a=30.0;
float t;  // zmienną do odczytu temperatury też zadeklarujemy jako globalną - przyda się na później
//EEPROM.read(adres)  // tego zdecydowanie nie ma tu być
//EEPROM.write(adres,wartosc)  // tego też nie
void setup(void)
{
  pinMode(przekaznik,OUTPUT);
  digitalWrite(przekaznik,LOW);
  pinMode(dioda, OUTPUT);
  pinMode(przycisk1, INPUT_PULLUP);
  pinMode(przycisk2, INPUT_PULLUP);
  tm1637a.setBrightness(0x0a);
  Serial.begin(9600);
  dht.begin();
  t = dht.readTemperature(); // pierwszy raz odczytujemy temperaturę tu, żeby mieć wartość do warunków
}

void loop(void)
{  // float t = dht.readTemperature(); // tego ma tu nie być. Pomiar wykonujemy raz na sekundę, nie przy każdym obiegu pętli!

  if (millis() - czas_pomiaru_temperatury >= 1000UL)
  {
    t = dht.readTemperature();  // tu odczytujemy temperaturę, będzie co sekundę. Zmieniając wartość 1000UL na większą, zwiększy się odstęp czasu pomiędzy pomiarami
    czas_pomiaru_temperatury = millis();  
    Serial.print("Temperature: "); 
    Serial.print(a);
    Serial.println(" *C");
  }  
    
  if (t >= a)
  {
    digitalWrite(przekaznik,HIGH);
  }
  if (t <= (a-2.0))
  {
    digitalWrite(przekaznik,LOW);
  }
// obsługę przycisków spróbujemy po mojemu    
  if (digitalRead(przycisk1) == LOW && blokada == 0) 
  {
    blokada = 1;
    a = a + 0.1;
    licznik++;
    if (licznik == 7) krok = 10; 
  } 
  else if (blokada > 246 && krok == 10) blokada = 246;  // zabezpieczenie
  else if (blokada > 0)
  {
    blokada+=krok;
  } 
  if (digitalRead(przycisk1) == HIGH)
  {
    krok = 1;
    licznik = 0;
    blokada = 0;
  }

  tm1637a.showNumberDec(a); //Display the Variable value;

  if (millis() - sekunda >= 1000UL)
  {
    sekunda = millis();
    stanLED = !stanLED;     
    digitalWrite(dioda, stanLED);
  }  
}
Możesz też wgrać ten mój program, żeby sprawdzić jak to działa i porównać działanie przycisku w jednym i w drugim programie. Oba już nie modyfikuj w żaden sposób. W obu powinno być tak samo (poza tym, że u mnie jest ciągłe wyświetlanie na serial, a nie co sekundę), ten mój, to po prostu "wycięta" z Twojego programu sama obsługa przycisku, no i tylko dodane słówko "zmienna" przy wyświetlaniu inkrementowanej zmiennej, zamiast "Temperature: ", Twoja zmienna a, u mnie nazywa się zmienna, no ale to niczego nie zmienia, przynajmniej nie powinno. Ja nie wgrywam tego całego programu, bo nie mam na przykład Twojego wyświetlacza i tej biblioteki do niego.
Jeśli na przykład okaże się, że działanie przycisku będzie prawidłowe w moim programie, a w tym Twoim już nie, no to chyba będziesz musiał wrócić do obsługi przycisku, która u Ciebie działa. Arduino ide, to jest taki zbiór bibliotek tworzących "nakładkę" na język C, żeby łatwiej było programować, ale wygląda na to, że tworzy się tam jakiś konflikt i chociaż coś powinno działać w określony sposób, to jednak czasami w niektórych przypadkach działa inaczej.
hazi18
Młodszy majsterkowicz
Posty: 44
Rejestracja: 18 paź 2019, 20:36

Re: Inkrementacja zmiennej

Post autor: hazi18 » 11 gru 2019, 20:36

Hej,
Inkrementacja i dekrementacja działa u mnie, cieszę się bardzo i dziękuję za pomoc :) Tylko mam pytanie, jeśli "a" jest jako float ( tak samo jak "t") to dlaczego na wyświetlaczu mam liczbę całkowitą?
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
stiven
Złota rączka
Posty: 1645
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Inkrementacja zmiennej

Post autor: stiven » 12 gru 2019, 01:24

Poszukałem w internecie bibliotekę do obsługi tego wyświetlacza i jest ich kilka. W tych bibliotekach, które znalazłem, ta funkcja showNumberDec() jest właściwie do wyświetlania cyfry na konkretnym polu wyświetlaczu, to i tak ciekawe, że wyświetla liczbę na dwóch polach. No ale może to zależy od biblioteki. Podaj skąd ściągnąłeś swoją bibliotekę, to sprawdzę ją, może uda się zrobić, żeby wyświetlało z częścią po przecinku.
Awatar użytkownika
Marhef
Złota rączka
Posty: 1261
Rejestracja: 18 lis 2011, 02:18

Re: Inkrementacja zmiennej

Post autor: Marhef » 12 gru 2019, 15:20

Wstaw ostateczny kod, może się innym przydać.
Z tego, co wyczytałem w dokumentacji do Twojego wyświetlacza, funkcja showNumberDec() wyświetla liczbę całkowitą. Ale masz możliwość wstawienia kropki.
EDIT:
Użyj funkcji showNumberDecEx(a,32);
To funkcja z tej strony. W pliku TM1637Display.h masz dokładnie opisaną każdą dostępną w bibliotece funkcję. Doczytaj tam, dlaczego zapisałem takie wartości.
hazi18
Młodszy majsterkowicz
Posty: 44
Rejestracja: 18 paź 2019, 20:36

Re: Inkrementacja zmiennej

Post autor: hazi18 » 13 gru 2019, 15:04

@Stiven Bibliotek ściągnięta z Github
@Marhef, Hexadecymalnie wyszło 32 z tego co widzę :)
Poczytałem, pokombinowałem i kropkę mam ale nie potrafię przesunąć wartości do lewej strony, zeby po przecinku pokazywało mi liczbę dziesiętną.
użyłem

Kod: Zaznacz cały

void showNumberDec(int num, bool leading_zero = false, uint8_t length = 4, uint8_t pos = 0);
i dałem go przed void setup.

Podaje cały kod jak prosiłeś.

Kod: Zaznacz cały

#include "DHT.h"
#include <TM1637Display.h>
#include <EEPROM.h> // przeniosłem wyżej. To tylko kosmetyka, ale staraj się dołączać biblioteki na początku programu
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
const int CLK = 4;
const int DIO = 5;
TM1637Display tm1637a(CLK, DIO);
int przekaznik=7;
int dioda=8;
byte przycisk1 = 3;
int przycisk2 = 6;
unsigned long sekunda = 0;
unsigned long czas_pomiaru_temperatury = 0;
byte blokada;
int krok = 1;
byte licznik;
int zmienna = 0;
int stanLED = 0;
float a=30.0;
float t;  // zmienną do odczytu temperatury też zadeklarujemy jako globalną - przyda się na później
void setSegments(const uint8_t segments[], uint8_t length = 4, uint8_t pos = 2); //FAZA TESTÓW
void setup(void)
{
  pinMode(przekaznik,OUTPUT);
  digitalWrite(przekaznik,LOW);
  pinMode(dioda, OUTPUT);
  pinMode(przycisk1, INPUT_PULLUP);
  pinMode(przycisk2, INPUT_PULLUP);
  tm1637a.setBrightness(0x0a);
  Serial.begin(9600);
  dht.begin();
  t = dht.readTemperature(); // pierwszy raz odczytujemy temperaturę tu, żeby mieć wartość do warunków
}

void loop(void)
{ 
  if (millis() - czas_pomiaru_temperatury >= 1000UL)
  {
    t = dht.readTemperature();  // tu odczytujemy temperaturę, będzie co sekundę. Zmieniając wartość 1000UL na większą, zwiększy się odstęp czasu pomiędzy pomiarami
    czas_pomiaru_temperatury = millis();  
    Serial.print("Temperature: "); 
    Serial.print(a);
    Serial.println(" *C");
  }  
    
  if (t >= a)
  {
    digitalWrite(przekaznik,HIGH);
  }
  if (t <= (a-2.0))
  {
    digitalWrite(przekaznik,LOW);
  }
  //Przycisk inkrementujący
 if (digitalRead(przycisk1) == LOW && blokada == 0) 
  {
    blokada = 1;
    a = a + 0.1;
    licznik++;
    if (licznik == 7) krok = 10; 
  } 
  else if (blokada > 246 && krok == 10) blokada = 246;  // zabezpieczenie
  else if (blokada > 0)
  {
    blokada+=krok;
  } 
  if (digitalRead(przycisk1) == HIGH)
  {
    krok = 1;
    licznik = 0;
    blokada = 0;
  }
//Przycisk dekrementujący
  if (digitalRead(przycisk2) == LOW && blokada == 0) 
  {
    blokada = 1;
    a = a - 0.1;
    licznik++;
    if (licznik == 7) krok = 10; 
  } 
  else if (blokada > 246 && krok == 10) blokada = 246;  // zabezpieczenie
  else if (blokada > 0)
  {
    blokada+=krok;
  } 
  if (digitalRead(przycisk2) == HIGH)
  {
    krok = 1;
    licznik = 0;
    blokada = 0;
  }
  //Serial.print("zmienna:");
 // Serial.println(zmienna);
  delay(100);

  tm1637a.showNumberDecEx(a,16); //Display the Variable value; FAZA TESTÓW

  if (millis() - sekunda >= 1000UL)
  {
    sekunda = millis();
    stanLED = !stanLED;     
    digitalWrite(dioda, stanLED);
  }  
}
Czy jeśli działa inkrementacja i dekrementacja to możemy teraz zrobić tak aby EEPROM zapamiętywał zmienną?
stiven
Złota rączka
Posty: 1645
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Inkrementacja zmiennej

Post autor: stiven » 13 gru 2019, 23:59

Przed chwilą napisałem komentarz, ale usunąłem, bo bzdury tam napisałem.

Nigdzie w internecie nie mogę znaleźć wykorzystania tej funkcji do wyświetlania zmiennej float. Wygląda na to, że chyba nie ma takiej możliwości, musi to być liczba całkowita (co też wskazuje na to nazwa funkcji) i do niej ustawia się maskę do wyświetlenia kropki.

Można spróbować zrobić coś takiego.

Kod: Zaznacz cały

int a_int;	//dodatkowa zmienna int zadeklarowana przed setup(), chociaż ta akurat może być zadeklarowana w loop(), zamiast wcześniej

  a_int = a * 10;	//zamina wartości float na int, na przykład z 32,7 uzyskamy 327
  tm1637a.showNumberDecEx(a_int, 32); //Display the Variable value; FAZA TESTÓW
a możliwe, że nawet można to skrócić, nie deklarować dodatkowej zmiennej i zrobić tylko coś takiego:

Kod: Zaznacz cały

  tm1637a.showNumberDecEx(a * 10, 32); //Display the Variable value; FAZA TESTÓW
ewentualnie dodatkowo z rzutowaniem na int

Kod: Zaznacz cały

  tm1637a.showNumberDecEx(int(a * 10), 32); //Display the Variable value; FAZA TESTÓW




hazi18 pisze:
13 gru 2019, 15:04
@Stiven Bibliotek ściągnięta z Github
Na githubie są różne wersje bibliotek do tego wyświetlacza o takiej samej nazwie. Bardziej chodziło mi o link, no ale już wiemy, że to jest ta, która ma możliwość zapalania kropek, więc już nie trzeba.


hazi18 pisze:
13 gru 2019, 15:04
@Marhef, Hexadecymalnie wyszło 32 z tego co widzę :)
To 32, to jest akurat wartość dziesiętna binarnej 0b00100000, heksadecymalna byłaby 20 i w programie zapisałoby się to jako 0x20.




hazi18 pisze:
13 gru 2019, 15:04
Poczytałem, pokombinowałem i kropkę mam ale nie potrafię przesunąć wartości do lewej strony, zeby po przecinku pokazywało mi liczbę dziesiętną.
użyłem

Kod: Zaznacz cały

void showNumberDec(int num, bool leading_zero = false, uint8_t length = 4, uint8_t pos = 0);

i dałem go przed void setup.
Ta linijka nie jest w ogóle potrzebna w Twoim programie. Wszystko "dzieje się" w funkcji tm1637a.showNumberDecEx(), a tamta linijka tak naprawdę i tak jest dodawana do programu, bo załączasz bibliotekę. Każda załączona biblioteka jest jakby "wrzucana" w program w czasie kompilacji. A zauważ, że i tak dałeś deklarację funkcji showNumberDec(), a używamy teraz showNumberDecEx().




EDIT

Sprawdziłem u siebie jak działa program z dwoma przyciskami, dekrementującym i inkrementującym i to nie działa tak jak powinno. Te ify, które nie są jako else if (a z jakiegoś powodu nie mogą być, bo wtedy też program nie działa prawidłowo), trzeba zrobić jako jeden if.

Kod: Zaznacz cały

  if (digitalRead(przycisk1) == HIGH)
  {
    krok = 1;
    licznik = 0;
    blokada = 0;
  }

Kod: Zaznacz cały

  if (digitalRead(przycisk2) == HIGH)
  {
    krok = 1;
    licznik = 0;
    blokada = 0;
  }
zamienić na

Kod: Zaznacz cały

  if (digitalRead(przycisk1) == HIGH && digitalRead(przycisk2) == HIGH)
  {
    krok = 1;
    licznik = 0;
    blokada = 0;
  }
no chyba że pasuje Tobie jak tak szybko zmieniają się wartości przy naciśnięciu przycisku, ale wtedy cała ta idea licznika, kroku i blokady w ogóle nie działa jak są 2 osobne ify. Przy przyciskaniu danego przycisku, if od drugiego przycisku zmienia wartości tych trzech zmiennych, które są w ifie.

Jeśli chodzi o EEPROM, to ja zrobiłem coś takiego

Kod: Zaznacz cały

boolean eeprom = 0;		//zadeklarowane przed setup()
unsigned long t_eeprom;		//zadeklarowane przed setup()

  if (digitalRead(przycisk2) == HIGH && digitalRead(przycisk1) == HIGH)		//nowy wspólny if do obu przycisków zamiast dwóch osobnych wykrywający stan wysoki na wejściach od przycisków czyli wykrywanie puszczenia przycisków
  {
    if(licznik) 	//jeśli nastąpiło przyciśnięcie któregoś przycisku (poprzedni if będzie działać zawsze, jeśli nie jest wciśnięty żaden przycisk, a zmienna licznik większa od 0 będzie oznaczać, że rzeczywiście wcześniej nastąpiło przyciśnięcie któregoś przycisku {właściwie można dodać ten warunek do głównego ifa, a tu usunąć})
    {
      eeprom = 1;		//ustawienie zmiennej do późniejszego zapisu do EEPROM
      t_eeprom = millis();		//zapis czasu z millis() do zmiennej t_eeprom
    }
    krok = 1;
    licznik = 0;
    blokada = 0;
  }  
  
  if(eeprom && (millis() > (t_eeprom + 10000)))		//if wykona się jeśli zmienna eeprom ustawiona na 1 i minęło 10 sekund od puszczenia przycisku
  {
    eeprom = 0;		//zerowanie zmiennej eeprom
    Serial.println("tak"); 		//testowanie poprawności działania ifa, ma być to wyświetlone tylko 1 raz po 10 sekundach od ostatniego naciśnięcia przycisku
    /*tutaj funkcja zapisująca do EEPROM*/
  }
No i jeszcze do setup() dodać funkcję odczytu z EEPROM.

Funkcja odczytująca w setup() może wyglądać tak

Kod: Zaznacz cały

  EEPROM.get(0, a);		//odczyt wartości do zmiennej a z pamięci EEPROM zaczynająć od adresu 0
Funkcja zapisująca może wtedy wyglądać tak

Kod: Zaznacz cały

  EEPROM.put(0, a);		//zapis wartości ze zmiennej a do pamięci EEPROM zaczynająć od adresu 0
No i pamiętamy, że zapis do EEPROM musi być mocno ograniczony, czyli dodaj tę funkcję po wcześniejszym przetestowaniu poprawności działania ifa zapisującego.

Zmienna float zajmuje 4 bajty, czyli zaczynając od adresu 0, zapis będzie łącznie do 4 kolejnych komórek pamięci, więc zajęte będą komórki od 0 do 3.

Przy pierwszym uruchomieniu funkcja get odczyta wartość z EEPROM do zmiennej a, a jeszcze nie było wcześniejszego zapisu. Sprawdziłem u siebie co będzie odczytane. Wyświetlane jest nan, czyli brak wartości i potem nawet jak coś do tej zmiennej dodałem, to dalej było nan. Dlatego będziesz musiał raz dodać do setup() funkcję zapisu i zapisać tam tą wartość przypisaną do zmiennej a, wgrać program, a potem od razu usunąć ten zapis do EEPROM i wgrać program już bez zapisu w setup() a z odczytem.

No i jeszcze sprawa wersji Arduino IDE. Ja mam kilka wersji, stara wersja 1.0.5 nie posiada funkcji get() i put() dla pamięci EEPROM, no ale raczej posiadasz nowszą wersję.
hazi18
Młodszy majsterkowicz
Posty: 44
Rejestracja: 18 paź 2019, 20:36

Re: Inkrementacja zmiennej

Post autor: hazi18 » 14 gru 2019, 16:23

Hej

Kod: Zaznacz cały

 tm1637a.showNumberDecEx(a * 10, 32); //Display the Variable value; FAZA TESTÓW
to działa jak chcę :) dzięki.
co do hexadecymalnie to przepraszam, pomyliłem się, racja to są wartości dziesiętne :)
Jeśli chodzi o te przyciski to na wyświetlaczy widzę, że ładnie się to inkrementuje i dekrementuje, w dodatku przycisnę dłużej to samo leci :) U mnie nie widzę żadnych problemów z danymi na wyświetlaczu jak naciskam przycisk + lub -.
Jeśli zostawię ten mój kod to powiedz mi do którego ifa mam wkleić EEPROM?

Kod: Zaznacz cały

  //Przycisk inkrementujący
 if (digitalRead(przycisk1) == LOW && blokada == 0) 
  {
    blokada = 1;
    a = a + 0.1;
    licznik++;
    if (licznik == 7) krok = 10; 
  } 
  else if (blokada > 246 && krok == 10) blokada = 246;  // zabezpieczenie
  else if (blokada > 0)
  {
    blokada+=krok;
  } 
  if (digitalRead(przycisk1) == HIGH)
  {
    krok = 1;
    licznik = 0;
    blokada = 0;
  }
Się zastanawiam czy nie do if z HIGH bo jak jest HIGH to się zmieniają wartości i te zmienione powinno zapisać. Chyba że źle myślę
stiven
Złota rączka
Posty: 1645
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Inkrementacja zmiennej

Post autor: stiven » 14 gru 2019, 22:29

Skoro taki problem jest z tymi przyciskami, to zmodyfikowałem program i zrobiłem obsługę przycisków w takiej prostszej postaci i to działa tak jak u Ciebie teraz, ale nie ma żadnego delaya w programie (gdyby u Ciebie go usunąć, a do tego dążyliśmy to zmiana wartości jest za szybka). Moim zdaniem działa to teraz bardzo dobrze. Ewentualnie szybkość inkrementowania i dekrementowania przy naciśniętym przycisku możesz przyspieszyć albo zwolnić w linijkach z

Kod: Zaznacz cały

   blokada = blokada + 20;
Mniejsza wartość niż 20 zwolni, a większa przyspieszy.
Jeśli dasz więcej niż 25, to wtedy też byś musiał zmniejszyć wartość w linijkach

Kod: Zaznacz cały

  if(blokada > 240) blokada = 0;
tak, żeby ich suma nie przekraczała 255.

Dodałem też zmienne i warunki potrzebne do zapisu do EEPROM. Zakomentowałem linijki do zapisu i odczytu.

Kod: Zaznacz cały

#include "DHT.h"
#include <TM1637Display.h>
#include <EEPROM.h> // przeniosłem wyżej. To tylko kosmetyka, ale staraj się dołączać biblioteki na początku programu
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
const int CLK = 4;
const int DIO = 5;
TM1637Display tm1637a(CLK, DIO);
int przekaznik=7;
int dioda=8;
byte przycisk1 = 3;
int przycisk2 = 6;
unsigned long sekunda = 0;
unsigned long czas_pomiaru_temperatury = 0;
byte blokada;
int stanLED = 0;
float a=30.0;
float t;  // zmienną do odczytu temperatury też zadeklarujemy jako globalną - przyda się na później
boolean eeprom = 0;
unsigned long t_eeprom; 


void setup(void)
{
  pinMode(przekaznik,OUTPUT);
  digitalWrite(przekaznik,LOW);
  pinMode(dioda, OUTPUT);
  pinMode(przycisk1, INPUT_PULLUP);
  pinMode(przycisk2, INPUT_PULLUP);
  tm1637a.setBrightness(0x0a);
  Serial.begin(9600);
  dht.begin();
  t = dht.readTemperature(); // pierwszy raz odczytujemy temperaturę tu, żeby mieć wartość do warunków

  //EEPROM.put(0, a);  //tylko do jednorazowego uruchomienia
  //EEPROM.get(0, a);  //do zostawienia na stałe - zapis do EEPROM
}

void loop(void)
{ 
  if (millis() - czas_pomiaru_temperatury >= 1000UL)
  {
    t = dht.readTemperature();  // tu odczytujemy temperaturę, będzie co sekundę. Zmieniając wartość 1000UL na większą, zwiększy się odstęp czasu pomiędzy pomiarami
    czas_pomiaru_temperatury = millis();  
    Serial.print("Temperature: "); 
    Serial.print(a);
    Serial.println(" *C");
  }  
    
  if (t >= a)
  {
    digitalWrite(przekaznik,HIGH);
  }
  if (t <= (a-2.0))
  {
    digitalWrite(przekaznik,LOW);
  }

  //Przycisk inkrementujący
  if (digitalRead(przycisk1) == LOW && blokada == 0) 
  {
    blokada = 1;
    a = a + 0.1;

    eeprom = 1;
    t_eeprom = millis();
  }
  else if (blokada > 0)
  {
    blokada = blokada + 20;   //szybkość inkrementowania przy naciśniętym przycisku
    if(blokada > 240) blokada = 0; 
  } 

  //Przycisk dekrementujący
  if (digitalRead(przycisk2) == LOW && blokada == 0) 
  {
    blokada = 1;
    a = a - 0.1;

    eeprom = 1;
    t_eeprom = millis();
  } 
  else if (blokada > 0)
  {
    blokada = blokada + 20;   //szybkość dekrementowania przy naciśniętym przycisku
    if(blokada > 240) blokada = 0; 
  } 

  if(eeprom && (millis() > (t_eeprom + 10000)))    //if wykona się jeśli zmienna eeprom ustawiona na 1 i minęło 10 sekund od puszczenia przycisku
  {
    eeprom = 0;   //zerowanie zmiennej eeprom
    Serial.println("tak");    //testowanie poprawności działania ifa, ma być to wyświetlone tylko 1 raz po 10 sekundach od ostatniego naciśnięcia przycisku
    /*tutaj funkcja zapisująca do EEPROM*/
    //EEPROM.put(0, a);   //zapis do EEPROM
  }

  tm1637a.showNumberDecEx(a * 10,32); //Display the Variable value; FAZA TESTÓW

  if (millis() - sekunda >= 1000UL)
  {
    sekunda = millis();
    stanLED = !stanLED;     
    digitalWrite(dioda, stanLED);
  }  

}
stiven
Złota rączka
Posty: 1645
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Inkrementacja zmiennej

Post autor: stiven » 15 gru 2019, 12:25

I jak? Działają dobrze przyciski, czy jednak nie jest tak jak byś chciał?
hazi18
Młodszy majsterkowicz
Posty: 44
Rejestracja: 18 paź 2019, 20:36

Re: Inkrementacja zmiennej

Post autor: hazi18 » 16 gru 2019, 19:14

Hej,
@Stiven przyciski działają tak samo jak przedtem. Co do zapisu to po wyciągnięciu z prądu nie pamięta zmiany. Czekam ponad 10 sek po pokazaniu się TAK i wyciągam z prądu i nic. Chyba ze muszę dłużej odczekać? i raz mi się zdażyło, że po wyświetleniu tak odczekałem dłużej to z mojej ustawionej wartości nagle zrobiło się 30. Czy to wina zerowania EEPROM?

Kod: Zaznacz cały

 if(eeprom && (millis() > (t_eeprom + 10000)))    //if wykona się jeśli zmienna eeprom ustawiona na 1 i minęło 10 sekund od puszczenia przycisku
  {
    eeprom = 0;   //zerowanie zmiennej eeprom   <--------
    Serial.println("tak");    //testowanie poprawności działania ifa, ma być to wyświetlone tylko 1 raz po 10 sekundach od ostatniego naciśnięcia przycisku
    /*tutaj funkcja zapisująca do EEPROM*/
    EEPROM.put(0, a);   //zapis do EEPROM
  }
stiven
Złota rączka
Posty: 1645
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Inkrementacja zmiennej

Post autor: stiven » 17 gru 2019, 01:07

A w setup co masz? Może zostawiłeś zapis? Ma być tylko ta funkcja z get. Ta funkcja z put w setup miała być tylko raz wgrana, a potem od razu ją usunąć i wgrać program bez niej.
hazi18
Młodszy majsterkowicz
Posty: 44
Rejestracja: 18 paź 2019, 20:36

Re: Inkrementacja zmiennej

Post autor: hazi18 » 17 gru 2019, 18:30

Tak racja był ten zapis i faktycznie wcześniej było o tym pisane ale przy takiej literaturze umknęło mi to :) już to testuję :)
Działa :)
Coś mi wpadło do tej główki. Mam 1 wyświetlacz na który jest wyświetlana aktualna temperatura, ale podczas zmiany stałej jak będę klikał przyciskami nie będę widział czy ona się zmienia i o ile. Wpadłem na pomysł, że podczas kliknięcia na wyświetlaczu pojawiła by się zmienna której zmieniam wartość a po upływie 10 sek. na wyświetlaczu pojawia się aktualna temperatura. Więc czy do ifa jak dodam ze po naciśnięciu ma mi wyświetlić "a" a po upływie czasu 10sek. powrót do "t" będzie to dobrze? Napisałem tak i na wyświetlaczu pojawia się 0

Kod: Zaznacz cały

#include "DHT.h"
#include <TM1637Display.h>
#include <EEPROM.h> // przeniosłem wyżej. To tylko kosmetyka, ale staraj się dołączać biblioteki na początku programu
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
const int CLK = 4;
const int DIO = 5;
TM1637Display tm1637a(CLK, DIO);
int przekaznik=7;
int dioda=8;
byte przycisk1 = 3;
int przycisk2 = 6;
unsigned long sekunda = 0;
unsigned long czas_pomiaru_temperatury = 0;
byte blokada;
int stanLED = 0;
float a=30.0;
float t;  // zmienną do odczytu temperatury też zadeklarujemy jako globalną - przyda się na później
boolean eeprom = 0;
unsigned long t_eeprom; 


void setup(void)
{
  pinMode(przekaznik,OUTPUT);
  digitalWrite(przekaznik,LOW);
  pinMode(dioda, OUTPUT);
  pinMode(przycisk1, INPUT_PULLUP);
  pinMode(przycisk2, INPUT_PULLUP);
  tm1637a.setBrightness(0x0a);
  Serial.begin(9600);
  dht.begin();
  t = dht.readTemperature(); // pierwszy raz odczytujemy temperaturę tu, żeby mieć wartość do warunków

  //EEPROM.put(0, a);  //tylko do jednorazowego uruchomienia
  EEPROM.get(0, a);  //do zostawienia na stałe - zapis do EEPROM
}

void loop(void)
{ 
  if (millis() - czas_pomiaru_temperatury >= 1000UL)
  {
    t = dht.readTemperature();  // tu odczytujemy temperaturę, będzie co sekundę. Zmieniając wartość 1000UL na większą, zwiększy się odstęp czasu pomiędzy pomiarami
    czas_pomiaru_temperatury = millis();  
    Serial.print("Temperature: "); 
    Serial.print(a);
    Serial.println(" *C");
  }  
    
  if (t >= a)
  {
    digitalWrite(przekaznik,HIGH);
  }
  if (t <= (a-2.0))
  {
    digitalWrite(przekaznik,LOW);
  }

  //Przycisk inkrementujący
  if (digitalRead(przycisk1) == LOW && blokada == 0) 
  {
    blokada = 1;
    a = a + 0.1;

    eeprom = 1;
    t_eeprom = millis();
  }
  else if(eeprom && (millis() > (t_eeprom + 10000)))    //if wykona się jeśli zmienna eeprom ustawiona na 1 i minęło 10 sekund od puszczenia przycisku
  {
    tm1637a.showNumberDecEx(a * 10,32);
  }
  else if (blokada > 0)
  {
    blokada = blokada + 20;   //szybkość inkrementowania przy naciśniętym przycisku
    if(blokada > 240) blokada = 0; 
  } 

  //Przycisk dekrementujący
  if (digitalRead(przycisk2) == LOW && blokada == 0) 
  {
    blokada = 1;
    a = a - 0.1;

    eeprom = 1;
    t_eeprom = millis();
  } 
    else if(eeprom && (millis() > (t_eeprom + 10000)))    //if wykona się jeśli zmienna eeprom ustawiona na 1 i minęło 10 sekund od puszczenia przycisku
  {
    tm1637a.showNumberDecEx(a * 10,32);
  }
  else if (blokada > 0)
  {
    blokada = blokada + 20;   //szybkość dekrementowania przy naciśniętym przycisku
    if(blokada > 240) blokada = 0; 
  } 

  if(eeprom && (millis() > (t_eeprom + 10000)))    //if wykona się jeśli zmienna eeprom ustawiona na 1 i minęło 10 sekund od puszczenia przycisku
  {
    eeprom = 0;   //zerowanie zmiennej eeprom
    Serial.println("tak");    //testowanie poprawności działania ifa, ma być to wyświetlone tylko 1 raz po 10 sekundach od ostatniego naciśnięcia przycisku
    /*tutaj funkcja zapisująca do EEPROM*/
    EEPROM.put(0, a);   //zapis do EEPROM
  }

  tm1637a.showNumberDecEx(t * 10,32); //Display the Variable value;

  if (millis() - sekunda >= 1000UL)
  {
    sekunda = millis();
    stanLED = !stanLED;     
    digitalWrite(dioda, stanLED);
  }  

}
stiven
Złota rączka
Posty: 1645
Rejestracja: 13 maja 2014, 08:47
Lokalizacja: Zielona Góra

Re: Inkrementacja zmiennej

Post autor: stiven » 17 gru 2019, 19:31

Zmienna eeprom będzie miała przez 10 sekund wartość 1, to zobacz coś takiego.

Kod: Zaznacz cały

  if(eeprom) tm1637a.showNumberDecEx(a * 10,32);  //wyświetlanie od momentu naciśnięcia przycisku i przez 10 sekund po puszczeniu przycisku
  else tm1637a.showNumberDecEx(t * 10,32); 	//wyświetlanie w pozostałym czasie
Przy if i else nie trzeba dawać klamerek jak jest tylko jedna funkcja do wykonania, wtedy if/else ma zasięg do najbliższego średnika, tak to trochę przejrzyściej wygląda.

Kod: Zaznacz cały

#include "DHT.h"
#include <TM1637Display.h>
#include <EEPROM.h> // przeniosłem wyżej. To tylko kosmetyka, ale staraj się dołączać biblioteki na początku programu
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
const int CLK = 4;
const int DIO = 5;
TM1637Display tm1637a(CLK, DIO);
int przekaznik=7;
int dioda=8;
byte przycisk1 = 3;
int przycisk2 = 6;
unsigned long sekunda = 0;
unsigned long czas_pomiaru_temperatury = 0;
byte blokada;
int stanLED = 0;
float a=30.0;
float t;  // zmienną do odczytu temperatury też zadeklarujemy jako globalną - przyda się na później
boolean eeprom = 0;
unsigned long t_eeprom; 


void setup(void)
{
  pinMode(przekaznik,OUTPUT);
  digitalWrite(przekaznik,LOW);
  pinMode(dioda, OUTPUT);
  pinMode(przycisk1, INPUT_PULLUP);
  pinMode(przycisk2, INPUT_PULLUP);
  tm1637a.setBrightness(0x0a);
  Serial.begin(9600);
  dht.begin();
  t = dht.readTemperature(); // pierwszy raz odczytujemy temperaturę tu, żeby mieć wartość do warunków

  //EEPROM.put(0, a);  //tylko do jednorazowego uruchomienia
  EEPROM.get(0, a);  //do zostawienia na stałe - zapis do EEPROM
}

void loop(void)
{ 
  if (millis() - czas_pomiaru_temperatury >= 1000UL)
  {
    t = dht.readTemperature();  // tu odczytujemy temperaturę, będzie co sekundę. Zmieniając wartość 1000UL na większą, zwiększy się odstęp czasu pomiędzy pomiarami
    czas_pomiaru_temperatury = millis();  
    Serial.print("Temperature: "); 
    Serial.print(a);
    Serial.println(" *C");
  }  
    
  if (t >= a)
  {
    digitalWrite(przekaznik,HIGH);
  }
  if (t <= (a-2.0))
  {
    digitalWrite(przekaznik,LOW);
  }

  //Przycisk inkrementujący
  if (digitalRead(przycisk1) == LOW && blokada == 0) 
  {
    blokada = 1;
    a = a + 0.1;

    eeprom = 1;
    t_eeprom = millis();
  }
  else if (blokada > 0)
  {
    blokada = blokada + 20;   //szybkość inkrementowania przy naciśniętym przycisku
    if(blokada > 240) blokada = 0; 
  } 

  //Przycisk dekrementujący
  if (digitalRead(przycisk2) == LOW && blokada == 0) 
  {
    blokada = 1;
    a = a - 0.1;

    eeprom = 1;
    t_eeprom = millis();
  } 
  else if (blokada > 0)
  {
    blokada = blokada + 20;   //szybkość dekrementowania przy naciśniętym przycisku
    if(blokada > 240) blokada = 0; 
  } 

  if(eeprom && (millis() > (t_eeprom + 10000)))    //if wykona się jeśli zmienna eeprom ustawiona na 1 i minęło 10 sekund od puszczenia przycisku
  {
    eeprom = 0;   //zerowanie zmiennej eeprom
    Serial.println("tak");    //testowanie poprawności działania ifa, ma być to wyświetlone tylko 1 raz po 10 sekundach od ostatniego naciśnięcia przycisku
    /*tutaj funkcja zapisująca do EEPROM*/
    EEPROM.put(0, a);   //zapis do EEPROM
  }

  if(eeprom) tm1637a.showNumberDecEx(a * 10,32);  //wyświetlanie od momentu naciśnięcia przycisku i przez 10 sekund po puszczeniu przycisku
  else tm1637a.showNumberDecEx(t * 10,32); 	//wyświetlanie w pozostałym czasie

  if (millis() - sekunda >= 1000UL)
  {
    sekunda = millis();
    stanLED = !stanLED;     
    digitalWrite(dioda, stanLED);
  }  

}
hazi18
Młodszy majsterkowicz
Posty: 44
Rejestracja: 18 paź 2019, 20:36

Re: Inkrementacja zmiennej

Post autor: hazi18 » 17 gru 2019, 19:46

WOW działa, super dzięki :)
Teraz mam taki drugi projekt w głowie do którego potrzebuję funkcję, która zatrzyma program po osiągnięciu temperatury, możemy użyć ten sam program nad którym teraz pracowaliśmy. Szukałem informacji na temat zatrzymywania się programu po osiągnięciu danej temperatury, niestety opcje exit, break, pause, return 0, nie zadziałały. Chodzi mi o to, że po osiągnięciu ustalonej temperatury program "przestanie działać" czyli sprawdzać bieżącą temperaturę. Ja widząc, że temperatura została przekroczona idę i sprawdzam co było tego powodem (uszkodzony termostat :) ) wymieniam go i przyciskając przycisk chciałbym ponownie uruchomić działanie programu. Próbowałem z instrukcją goto jednak nie dawało to żadnego rezultatu, może dlatego, że to robiłem w loop?

Kod: Zaznacz cały

 if (millis() - czas_pomiaru_temperatury >= 1000UL)
    Serial.print("Temperature: "); 
    Serial.print(t);
    Serial.println(" *C");
  if (t>=a)  // wywołanie funkcji warunkowej
    {
    digitalWrite(przekaznik,HIGH);  // włączenie przekaźnika   
    }
      if (t<a) // wywołanie funkcji warunkowej
  {
    digitalWrite(przekaznik,LOW);  // wyłączenie przekaźnika, i tutaj powinno być coś co stopuje program, tzn, że spada temperatura ale nie uruchamia ponownie przekaźnika, bo teraz działa tak, że po spadku poniżej 36.5 ponownie się uruchamia przekaźnik.
  } 
    tm1637a.showNumberDecEx(t); //Display the Variable value;
      
 if (millis() - sekunda >= 1000UL)
  {
    sekunda = millis();
    stanLED = !stanLED;     
    digitalWrite(dioda, stanLED);
  }  
ODPOWIEDZ

Strony partnerskie: