Skocz do zawartości

Arduino problem z obsługą przycisku


Frodus

Pomocna odpowiedź

Panowie. Piszę sobie sterownik (a dokładniej to kopiuje przykłady) i dostosowuję do własnych potrzeb.

Chcę stworzyć sterownik kontroli temperatury (4 czujniki DS18b20) obecnie to kombinuje aby zadziałało to tak jak ja chce na 1 czujniku, resztę dodam gdy osiągnę zamierzony efekt.

(na potrzeby testów górną temperaturę alarmową ustawiłem na 30stopni.

Chcę aby po przekroczeniu 30stopni zapaliła mi się dioda LED oraz rysunek dzwonka na wyświetlaczu (do tej pory wszystko działa tak jak oczekuję)

W momencie gdy temperatura spanie poniżej tych 30 stopni ,chcę aby dioda zgasła i na wyświetlaczu pozostał nadal rysunek dzwonka (również działało tak jak planowałem), natomiast problem zaczął się gdy dodałem BUTTON w celu wymazania znaku dzownka.

Kombinowałem na różne sposoby i nie uzyskałem efektu jaki jest mi potrzebny.

Dodam że cyfrowy pin 0 jest podłączony do GND przez rezystor 10k, oraz cyfrowy pin 0 poprzez Button podłączony do +5V

#include <LiquidCrystal_I2C.h>                   // inicjalizacja biblioteki
#include <DallasTemperature.h>                   // inicjalizacja biblioteki
#include <OneWire.h>                             // inicjalizacja biblioteki
#include <Wire.h>                                // inicjalizacja biblioteki

#define ONE_WIRE_BUS 10                          // zdefiniowanie pinu 10 jako magistrale OneWire

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // inicjalizacja wyswietlacza LCD po lini I2C
int backLight = 3;                                             // zdefiniowanie pinu podswietlenia LCD

char hiSetPoint = 30;

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);


DeviceAddress czujnik_bojler = {0x28, 0xFF, 0x86, 0x36, 0x73, 0x15, 0x1, 0x18};     // adres czujnika temperatury bojlera

void setup()
{
 pinMode(0, INPUT);

 char alarmBojler;
 sensors.setHighAlarmTemp(czujnik_bojler, hiSetPoint);
 alarmBojler = sensors.getHighAlarmTemp(czujnik_bojler);
 sensors.setHighAlarmTemp(czujnik_bojler, 30);
 sensors.setLowAlarmTemp(czujnik_bojler, 5);

 sensors.begin();                                 // wlaczenie komunikacji z czujnikami(sensorami)
 sensors.setResolution(czujnik_bojler, 11);      // rozdzielczość pomiaru (dokładność) 11=0,1

 pinMode(backLight, OUTPUT);                     // pin (3) backLight jako wyjscie
 digitalWrite(backLight, LOW);                  // ustaw stan wysoki na pinie (3) backLight

 lcd.begin(20, 4);                          // ustawienie parametrow wyswietlacza LCD
 lcd.clear();                               // czyszczenie wyswietlacza LCD
}

void printTemperature(DeviceAddress deviceAddress)
{
 float tempC = sensors.getTempC(deviceAddress);
 if (tempC == -127.00) 
 {
   lcd.print("----");
 } 
 else 
 {
   lcd.print(tempC, 1); //ile miejsc po przecinku
 }
}

void loop() {

 byte znak_stopnia[8] = {B00111, B00101, B00111, B00000, B00000, B00000, B00000, B00000};      // definiowanie znaku dla wyswietlacza LCD
 lcd.createChar(0, znak_stopnia);                                                                      // utworz znak
 byte znak_alarmu[8] = {B00000, B00100, B01110, B01110, B01110, B11111, B00100, B00000};               // definiowanie znaku dla wyswietlacza LCD
 lcd.createChar(1, znak_alarmu);                                                                       // utworz znak

 delay(1000);                               // czekaj 1000ms (odswiezaj wskazania czujnikow co 1 sekunde
 sensors.requestTemperatures();             // odczytaj temperature z czujnikow


 //----------BOJLER---------//
 lcd.setCursor(0, 1);
 lcd.print("BOJLER :");
 lcd.setCursor(13, 1);
 printTemperature(czujnik_bojler);            // wyswietl wynik temperatury z czujnik_bojler
 lcd.print((char)0);
 lcd.print("C");


 if (sensors.hasAlarm(czujnik_bojler))
 {
   lcd.setCursor(11, 1);
   lcd.print((char)1);
   digitalWrite(13, HIGH);
 }
 else
 {
   digitalWrite(13, LOW);
 }

  if (digitalRead(0) == HIGH)
  {
     lcd.setCursor(11, 1);
     lcd.print(" ");    // wyswietlenie pustego miejsca - skasowanie znaku alarmu
   }
}
Link do komentarza
Share on other sites

Jeśli użyję digitalRead ... == LOW, nie ma znaku wcale

natomiast w przypadku == HIGH pojawia sie wraz zapalaniem diody LED, znika po jej wygaszeniu.

Wieczorem gdy będe mial płytkę po ręka spróbuje podciągnąć przycisk do + zasilania

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Problem nie leży w tym czy przycisk zwiera do masy i ma podciąg do plusa czy zwiera do plusa a ma opornik do masy.

Twój kłopot polega na tym, że nie zastanowiłeś się jak to ma działać i nie odróżniasz zdarzeń od stanów. Przyjrzyj się temu od strony wyjść czyli diody LED i dzwonka:

- Dioda LED ma świecić się zawsze gdy temperatura jest większa niż zadany próg. To wydaje się proste, bo wystarczy w głównej pętli pomiarowej sprawdzać warunek i zapalać diodkę lub ją gasić i to Ci działa - nic dziwnego. Diodka jest zapalana bezpośrednio stanem temperatury.

- Dzwonek na LCD ma zapalać się gdy temperatura przekroczy próg, potem świecić niezależnie od stanu temperatury i gasnąć gdy wciśniesz przycisk. To oznacza, że nie masz bezpośredniego stanu temperatury w którym możesz jednoznacznie stwierdzić, że dzwonek ma być. Dzwonek musi być sterowany zdarzeniami. Zdarzeniem zapalającym jest przekroczenie temperatury a gaszącym wciśnięcie przycisku. Oczywiście do zapamiętywania zdarzeń potrzebujesz nowej zmiennej. W kodzie może to wyglądać tak:

int dzwonek = 0;

if (temperatura >= prog)
   dzwonek = 1;
if (przycisk_wcisniety())
  dzwonek = 0;
if (dzwonek)
   pokaz_dzwonek_na_LCD();
else
   pokaz_spacje_w_miejscu_dzwonka();

Znaczenia funkcji przycisk_wcisniety() i pokaz_dzwonek_na_LCD() są chyba oczywiste. Jeżeli taki kod umieścisz w pętli głównej gdzie dokonujesz pomiarów i wyświetlasz wyniki, zmienna dzwonek będzie odzwierciedlała pożądany stan dzwonka na LCD.

W powyższym kodzie gaszenie ma większy priorytet niż zapalanie bo test gaszenia dzwonka jest wykonywany po teście zapalenia więc przycisk będzie gasił dzwonek nawet w sytuacji gdy temperatura jest przekroczona. Jeżeli zamienisz kolejność dwóch pierwszych if-ów, dzwonek będzie będzie widoczny w czasie przekroczenia progu nawet w czasie wciśnięcia przycisku. Przemyśl to.

Cały ostatni if możesz zamienić na wywołanie innej funkcji np. pokaz_dzwonek(dzwonek) która po prostu dostanie żądany stan i w zależności od niego pokaże na LCD symbol lub spację.

  • Pomogłeś! 1
Link do komentarza
Share on other sites

Witam wszystkich na forum.

Nie napisałeś z jakiego Arduino korzystasz. W większości płytek (np UNO) piny 0 i 1 są podpięte do kości odpowiedzialnej za komunikację USB. Może to wprowadza u Ciebie zakłócenia? Poza tym pozbawiasz się możliwości obserwacji stanów pracy przez monitor szeregowy. Przepnij przycisk na inny pin i sprawdź czy to nie pomoże. Poza tym radziłbym Ci jednak podciągać do plusa a zwierać do masy.

Uporządkuj też kod, bo np. dublujesz ustawianie progu alarmu raz zmienną, a za moment podając bezpośrednio 30, definicję własnych znaków przenieś do funkcji funkcji setup(), sprawdź komentarze itp. Łatwiej wtedy będzie wyłapać ewentualny problem.

I jeszcze jedno. Stan przycisku sprawdzasz co sekundę. Może lepiej częściej?

Pozdrawiam

  • Pomogłeś! 1
Link do komentarza
Share on other sites

Dziękuję Panowie! Działa tak jak było w założeniach 🙂

Jamik, zwieranie do GND i podciągnięcie do + pomogło.

Zmiana w programie jak doradził kolega Marek1007 też rozszerzyła moje spojrzenie na to i dała trochę do przemyśleń.

Jeszcze raz dziękuję 🙂

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.