Projekt z wykorzystaniem minutnika.

Masz problem z Arduino? Tutaj możesz szukać pomocy.
ODPOWIEDZ
szalalala
Młodszy majsterkowicz
Posty: 5
Rejestracja: 8 kwie 2014, 10:57

Projekt z wykorzystaniem minutnika.

Post autor: szalalala » 8 kwie 2014, 11:45

Cześć. Pracuje nad projektem opartym o Arduino Uno. W projekcie wykorzystuję płytkę przekaźnikową, wyświetlacz 2x16, silnik DC oraz przyciski. Zasada działania jest dosyć prosta, układ ma za zadanie sterować czasowo procesem uruchamianym przez przekaźniki. Wszystkie elementy mam już złożone w jeden układ, każdy z elementów przetestowany i sprawny. Pozostało mi oprogramowanie i tu napotkałem na problem z którym ciężko mi sobie poradzić.

Obsługa układu ma się sprowadzać do uruchomienia sterowania, odczekania 5 min (nagrzewanie lampy UV) następnie przy pomocy przycisków i wyświetlacza należy ustawić czas w zakresie od 1min-10min ze skokiem nie większym niż 10sec. Po ustawieniu czasu i naciśnięciu przycisku start na 1 sec uruchamiany jest silnik i następuje odliczanie ustawionego czasu (najlepiej widocznego na wyświetlaczu) na samym końcu silnik znowu działa przez 1sec i następuje powrót do ponownego ustawienia czasu. Pomysł zakłada jeszcze to że jest przycisk stop który pomija odliczanie i przeskakuje do końcowej pracy silnika i powrotu do ustawiania czasu.
Moja praca nad kodem sprowadza się na razie do:

Kod: Zaznacz cały

#include <ShiftLCD.h>               //biblioteka do LCD
ShiftLCD lcd(2, 4, 3);              //piny od LCD

int motorpin1 = 6;                  //wyjscia silnika pin 6
int motorpin2 = 7;                  //wyjscie silnika pin 7

int UV = 8;                         //przekaznik lampa UV
int Vacum = 9;                      //przekaznik pompa podcisnienia

void setup () {

  pinMode(motorpin1,OUTPUT);        
  pinMode(motorpin2,OUTPUT);        

  pinMode(UV, OUTPUT);              
  pinMode(Vacum, OUTPUT);
}

void praca(long time){
  digitalWrite(motorpin1,LOW);
  digitalWrite(motorpin2,HIGH);
  delay(1000);
  digitalWrite(motorpin1,HIGH);
  delay(time);
  digitalWrite(motorpin2,LOW);
  delay(1000);
  digitalWrite(motorpin1,LOW);
}

void loop () {
  digitalWrite(UV, LOW);
  digitalWrite(Vacum, LOW);
  praca(5000);
}

Kiedy zacząłem szukać informacji o wykorzystaniu czasu przy projektach na Arduino dowiedziałem się że lepiej nie używać delay, zamiast tego wykorzystać millis(). Kiedy szukałem gotowych rozwiązań znalazłem gotowy time counter jednak kod nie do końca jest dla mnie zrozumiały i na pewno zbyt obszerny dla mojego projektu. Zastosowanie samej pętli nie było by problemem jednak nie za bardzo wiem w jaki czytelny sposób ustawiać czas przy pomocy przycisków. Na początku próbowałem z potencjometrem jednak jest on zbyt mało precyzyjny. Obecnie szukam bibliotek które mogły by posiadać przydatne dla mnie funkcje do wykorzystania w kodzie projektu.

Bardzo prosze o komentarze osoby które mogą mi poradzić jakie rozwiązanie będzie najlepsze do wykonania mojego pomysłu.

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


zelek93
Majsterkowicz
Posty: 96
Rejestracja: 27 sie 2013, 02:01

Re: Projekt z wykorzystaniem minutnika.

Post autor: zelek93 » 8 kwie 2014, 12:12

Przede wszystkim nigdy nie podłaczaj NIGDY silnika do portów cyfrowych bezpośrednio. Użyj mostka H do obsługi silnika. Wydaje mi się ,że Twój problem rozwiąże funkcja przerwań czyt. attachInterrupt().

Pozdrawiam
szalalala
Młodszy majsterkowicz
Posty: 5
Rejestracja: 8 kwie 2014, 10:57

Re: Projekt z wykorzystaniem minutnika.

Post autor: szalalala » 8 kwie 2014, 12:23

Silnik jest podłączony przy pomocy mostka H. Kwestia przerwań nie jest dla mnie do końca jasna, ale nie wydaje mi się żeby przy wykorzystaniu przerwań udało mi się rozwiązać problem odliczania czasu. Chociażby dla tego że w czasie działania przerwań nie jest zliczany czas instrukcji millis().

Dzięki, Pozdrawiam.
zelek93
Majsterkowicz
Posty: 96
Rejestracja: 27 sie 2013, 02:01

Re: Projekt z wykorzystaniem minutnika.

Post autor: zelek93 » 8 kwie 2014, 17:28

Hmm, Arduino UNO obsługuje 2 przerwania tak więc:

Loop: odczyt z przycisku + i - do ustawienia czasu klikasz START i uruchamia się przerwanie 1.

Przerwanie 1: Funkcja włącza silnik na 1s, grzałkę na określony czas, następnie odlicza do zera od uprzednio ustawionej liczby w momencie gdy czas=0 uruchamia ponownie silnik na 1s

Przerwanie 2: Funkcja STOP kończąca wszystkie funkcje.

Pozdrawiam
Arturr300
Starszy majsterkowicz
Posty: 307
Rejestracja: 16 paź 2013, 17:24

Re: Projekt z wykorzystaniem minutnika.

Post autor: Arturr300 » 8 kwie 2014, 22:08

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

Re: Projekt z wykorzystaniem minutnika.

Post autor: wojtekizk » 9 kwie 2014, 10:48

Witam
no dobra... teraz ja swoje trzy grosze dorzucę :-) Właściwie dwie kwestie, jedna krótka i jedna długa :-)
Najpierw do kol. zelek93 :
Bardzo dobrze, że zwróciłeś koledze uwagę aby NIGDY nie zapominał o mostku H...
ale również ngdy, ale to NIGDY nie wykorzystuj przerwań w sposób jaki opisujesz powyżej. Przerwanie powinno wykonywać się najszybciej jak to możliwe i bez jakichkolwiek delay !!! Inaczej będziesz miał spore problemy :-)
Druga kwestia do szalalala :-)
Zainteresował mnie Twój post, z uwagi na problem wykorzystywania minutnika w aplikacjach tworzonych przez czytelników tego forum :-) Napisałem Ci gotowca, gdzie w mig zorientujesz się jak działa ów minutnik :-)
Jest tylko jeden problem - nie mam takiego LCD i nie korzystam z biblioteki ShiftLCD. ten kod testowałem na własnym LCD (w kodzie zaremowane linie). U Ciebie powinien także działać, gdyż obie biblioteki mają bliźniaczo podobną obsługę.
Do ustawiania czasu potrzeba 3 klawiszy, które umieściłem w kodzie. Dadałem także kilka niezbędnych zmiennych.
Przetestuj te moje wypociny... (zwróć uwagę na wykorzystywane piny, aby nie było konfliktów z Twoim projektem).

Kod: Zaznacz cały

// Twoja wersja LCD i konfiguracja pinów: 
// /*
#include <ShiftLCD.h>  // biblioteka do LCD
ShiftLCD lcd(2, 4, 3); // piny od LCD
int motorpin1 = 6;     // wyjscia silnika pin 6
int motorpin2 = 7;     // wyjscie silnika pin 7
int UV = 8;            // przekaznik lampa UV 8
int Vacum = 9;         // przekaznik pompa podcisnienia 9
#define pinUP 12       // klawisz +   pin 12
#define pinDOWN 11     // klawisz -   pin 11
#define pinOK 10       // klawisz OK  pin 10
// */
// moja wersja LCD i konfiguracja pinów:
/*
#include <LiquidCrystal.h>
LiquidCrystal lcd(8,9,4,5,6,7);
int motorpin1 = 11;    // wyjscia silnika pin 11
int motorpin2 = 12;    // wyjscie silnika pin 12
int UV = 13;           // przekaznik lampa UV  pin 13
int Vacum = 3;         // przekaznik pompa podcisnienia pin 3
#define pinUP 2        // klawisz +   pin 2
#define pinDOWN 1      // klawisz -   pin 1
#define pinOK 0        // klawisz OK  pin 0
*/
long start;            // zmienna okreslająca start procesu         
int czas;              // czas trwania procesu, w sekundach 
int minuty;            // bez komentarza
int sekundy;           // bez komentarza
// --- uniwersalna funkcja pokazująca aktualny czas procesu, czas jaki upłynął, itp.  ---
void pokazCzas(int c)  // c - aktualny czas procesu
{
  char buf[20]; memset(buf,0,sizeof(buf)); // zamiast pozycjonowania LCD proponuję to właśnie 
  minuty=c/60;sekundy=c%60;                // obliczamy mniuty i sekundy
  if(minuty>59){minuty=0;sekundy=0;}       // po przekroczeniu 60 minut liczymy od nowa
  snprintf(buf,sizeof(buf),"%02d:%02d",minuty,sekundy); // sprytna funkcja (radzę poczytać o niej :-)
  lcd.setCursor(6,1);lcd.print(buf); // kosmetyka LCD
}
// --- funkcja do ustawiania czasu trwania procesu -----------------
int ustaw(int c)     // c - defaultowy czas (na początek do ustawiania)
  {
  lcd.clear();
  lcd.setCursor(0,0);lcd.print("<  Ustaw Czas  >");
  pokazCzas(c);                     // pokazujemy czas procesu do ustawienia 
  while(digitalRead(pinOK!=LOW))  // trwa tak długo aż naciśniemy przycisk OK
    {
    if(digitalRead(pinUP)==LOW){delay(30);if(digitalRead(pinUP)==LOW){c+=10;if(c>1800)c=1800;pokazCzas(c);}}     // klawisz +
    if(digitalRead(pinDOWN)==LOW){delay(30);if(digitalRead(pinDOWN)==LOW){c-=10;if(c<0)c=0;pokazCzas(c);}} // klawisz -
    delay(150);                      // aby za szybko nie przeskakiwał czas gdy wciśniemy przycisk na dłużej
    }
  lcd.clear();lcd.setCursor(0,0);lcd.print(" Czas Ustawiony ");delay(2000); // kosmetyka
  return c;  // funkcja zwraca ustawiony czas
}
// --- funkcja do odliczania czasu (zapalnik zegarowy do bomby :-)---
void odliczanie(int ile)
{
  start=millis();                     // startujemy funkcją millis()
  int akt_czas=ile;                   // zmienna pomocnicza do żonglerki czasem
  while(akt_czas>0)                   // tak długo, aż odliczanie się nie skończy
    {
    akt_czas=czas-(millis()-start)/1000; // żonglerka czasem
    pokazCzas(akt_czas);                 // pokaz czasu jaki pozostał
    if(digitalRead(pinOK)==LOW)          // jeśli wciśniesz OK to natychmiastowe przerwanie procesu
      {
        akt_czas=0;pokazCzas(akt_czas);  // zerowanie czasu
        lcd.setCursor(0,1);lcd.print("Proces Przerwany");delay(2000); // kosmetyka
      }
    }
}
// --------------------------------------------------------------
void setup () {
  pinMode(pinUP,INPUT_PULLUP);    // klawisz +
  pinMode(pinDOWN,INPUT_PULLUP);  // klawisz -
  pinMode(pinOK,INPUT_PULLUP);    // klawisz OK
  pinMode(motorpin1,OUTPUT);        
  pinMode(motorpin2,OUTPUT);        
  pinMode(UV, OUTPUT);              
  pinMode(Vacum, OUTPUT);
  lcd.begin(16,2);                // wyświetlacz 16x2
  digitalWrite(UV, LOW);          // załączenie VU
  digitalWrite(Vacum, LOW);       // załączenie Vacum 
  lcd.clear();lcd.setCursor(0,0);lcd.print("   NAGRZEWANIE"); // kosmetyka
  czas=300;         // czas nagrzewania w sekundach 300 = 5 min.
  odliczanie(czas); // pokazujemy czas nagrzewania, jaki pozostał
  lcd.clear();      // kosmetyka
  }
// -----------------------------------------------------------
void loop () 
{
 czas=ustaw(300);                            // ustawiamy czas (domyślnie 5 minut)
  lcd.clear();lcd.print("Start Odliczania"); // kosmetyka
  digitalWrite(motorpin1,LOW);digitalWrite(motorpin2,HIGH); // Twoje motory ON
  delay(1000);digitalWrite(motorpin1,HIGH);                 
  odliczanie(czas);                          // start odliczania
  digitalWrite(motorpin2,LOW);delay(1000); digitalWrite(motorpin1,LOW); // motory OFF
  lcd.clear();lcd.print("  Koniec Cyklu");delay(3000);lcd.clear();      // kosmetyka
}
// ============================================================

Pozdrawiam
szalalala
Młodszy majsterkowicz
Posty: 5
Rejestracja: 8 kwie 2014, 10:57

Re: Projekt z wykorzystaniem minutnika.

Post autor: szalalala » 9 kwie 2014, 14:57

Dziękuje za pomoc. Nie spodziewałem się gotowego rozwiązania. Dokładnie przejrzę cały kod i dostosuje go do potrzeb swojego projektu.

Pozdrawiam
benio123
Młodszy majsterkowicz
Posty: 1
Rejestracja: 26 cze 2018, 15:01

Re: Projekt z wykorzystaniem minutnika.

Post autor: benio123 » 26 cze 2018, 15:17

Z tego "gotowca" od wojtekizk dużo się nauczyłem. Więcej niż z kilku poradników. Przerobiłem projekt na interesujący mnie prosty włącznik czasowy z sygnalizacją czasu zakończenia cyklu. Niestety mam problem. Układ od wojtekizk można nastawić maksymalnie na 30 minut i odlicza minuty/sekundy. Co zrobić, by odliczał godziny/minuty. Przynajmniej 8-12 godzin.
ODPOWIEDZ

Strony partnerskie: