Skocz do zawartości

Obsługa modułu z dwoma przekaźnikami


Zbyszko125

Pomocna odpowiedź

Trochę mnie to gryzło więc odchudziłem znacznie ten program - zostawiłem 2 diody które udają przekaźniki i jednocześnie są sygnalizajcą załączenia krańcówki, kod wydaje mi się, że jest czytelniejszy:

#define kr1 0
#define kr2 13
#define przyciskL A0
#define startStop A1
#define przyciskP A2
#define przekaznik1 2 //dioda jako przekaźnik2
#define przekaznik2 1 //dioda jako przekaźnik2

#include <Wire.h>  
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

boolean kierunek = false;  //false {LEWO}; true {PRAWO}
boolean tryb = true; //false {tryb AUTOMAT}; true {tryb RECZNY}


void setup() {
 lcd.begin(16,2);

 pinMode(przekaznik1, OUTPUT);
 pinMode(przekaznik2, OUTPUT);
 digitalWrite(przekaznik1, HIGH); //wyłączenie "przekaźników" - 
 digitalWrite(przekaznik2, HIGH);



 pinMode(kr1, INPUT); // przyciski podłączone przez zewnętrzny rezystor
 pinMode(kr2, INPUT); // podciągający do 5V, gdy wciśnięte - stan NISKI
 pinMode(przyciskL, INPUT);
 pinMode(startStop, INPUT);
 pinMode(przyciskP, INPUT); 
}

void wylacznikKrancowyP() {
 if (digitalRead(kr1) == LOW) {
   delay(100); //debounce
   if (digitalRead(kr1) == LOW) {
     for (int i = 1; i < 10; i++) {      //sygnalizacja zadziałania wyłącznika krańcowego
       digitalWrite(przekaznik2, HIGH);  //w rzeczywistym programie byłoby to bez sensu
       delay(100);
       digitalWrite(przekaznik2, LOW);
       delay(100);
     }
     kierunek = false;
     digitalWrite(przekaznik2, HIGH); //WYLACZ PRZEKAZNIK 2
     digitalWrite(przekaznik1, LOW); //włącz przekaźnik 1
   }
 }
}
void wylacznikKrancowyL() {
 if (digitalRead(kr2) == LOW) {
   delay(100); //debounce
   if (digitalRead(kr2) == LOW) {
      for (int i = 1; i < 10; i++) {      //sygnalizacja zadziałania wyłącznika krańcowego
       digitalWrite(przekaznik1, HIGH);  //w rzeczywistym programie byłoby to bez sensu
       delay(100);
       digitalWrite(przekaznik1, LOW);
       delay(100);
     }     
     delay(2000);
     kierunek = true;
     digitalWrite(przekaznik2, LOW); //WYLACZ PRZEKAZNIK 2
     digitalWrite(przekaznik1, HIGH); //włącz przekaźnik 1
   }
 }
}
void trybAutomatycznyLCD() {
 lcd.setCursor(0, 0);
 lcd.print("[AUTOMAT]");
}
void kierunekLewoLCD() {
 lcd.setCursor(0, 1);
 lcd.print("[LEWO     ]");
}
void trybRecznyLCD() {
 lcd.setCursor(0, 0);
 lcd.print("[ RECZNY]");
}
void kierunekPrawoLCD() {
 lcd.setCursor(0, 1);
 lcd.print("[    PRAWO]");
}

void przekaznikiStopLCD() {
 lcd.setCursor(0, 1);
 lcd.print("[         ]");
}
void wlaczPrzekaznik1() {
 digitalWrite(przekaznik1, LOW);  
 digitalWrite(przekaznik2, HIGH);
}
void wlaczPrzekaznik2() {
 digitalWrite(przekaznik1, HIGH);
 digitalWrite(przekaznik2, LOW);
}
void przekaznikiStop() {
 digitalWrite(przekaznik1, HIGH);
 digitalWrite(przekaznik2, HIGH);
}

void loop() {
 if (digitalRead(startStop) == LOW) {
   delay(100);
   if (digitalRead(startStop) == LOW) {
     if (tryb == true) {         //jeżeli przed wcisnieciem, był tryb ręczny
       tryb = false;     //przełącz na automat
       kierunek = false; //w automacie ruszaj w lewo
       trybAutomatycznyLCD();
     } else {
       tryb = true;
       trybRecznyLCD();
     }
   }
   delay(500);
 }

wylacznikKrancowyL(); //sprawdzenie, czy wylacznik krancowy nie jest wlaczony
wylacznikKrancowyP();

if (tryb == false && kierunek == false) {
 trybAutomatycznyLCD();
 kierunekLewoLCD();
 wlaczPrzekaznik1();  
} else if (tryb == false && kierunek == true) {
 trybAutomatycznyLCD();
 kierunekPrawoLCD();
 wlaczPrzekaznik2();
} else if (tryb == true) {
 if (digitalRead(przyciskL) == LOW && digitalRead(przyciskP) == HIGH) {
 trybRecznyLCD();
 kierunekLewoLCD();
 wlaczPrzekaznik1();  
 } else if (digitalRead(przyciskL) == HIGH && digitalRead(przyciskP) == LOW) {
 trybRecznyLCD();
 kierunekPrawoLCD();
 wlaczPrzekaznik2();   
 } else {
 trybRecznyLCD();
 przekaznikiStopLCD();
 przekaznikiStop();
 }
}
}

Link do komentarza
Share on other sites

Nie mówię nie. Ale kolega miał problem z logiką swojego programu, więc trzymam kciuki, by chociaż odrobinę ten przykład pomógł mu ruszyć do przodu.

delay(2000); - może za długi i będzie poczucie bezwładności, ale zakładam, że Zbyszko125 nie będzie strzelał ze swojego urządzenia. 🙂

Link do komentarza
Share on other sites

Gość es2
delay(2000); - może za długi i będzie poczucie bezwładności, ale zakładam, że Zbyszko125 nie będzie strzelał ze swojego urządzenia. 🙂

Może tam być i 100ms, reakcja na stop powinna być natychmiastowa.

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

Poniekąd słusznie - niestety zaoferowałem swoją pomoc mając na biurku jedynie diody (więc nie do końca pisałem to na układ typu silnik, czyli taki jaki autor ma w warsztacie(?) ).

Czy kod mogę poprawić jutro? Bo o 4 muszę wstać. Jak już będzie zaakceptowany, to przepiszę go 100x.

Dobranoc.

Link do komentarza
Share on other sites

Gość es2
Poniekąd słusznie - niestety zaoferowałem swoją pomoc mając na biurku jedynie diody (więc nie do końca pisałem to na układ typu silnik, czyli taki jaki autor ma w warsztacie(?) ).

Ja aż tyle nie mogę zaoferować. Nie mam tyle czasu aby zmontować jakiś zestaw nawet z ledami. Mogę pomóc tylko patrząc na kod dlatego jeśli napisze kod, trzeba go sprawdzić w praktyce.

Na STM32 mógłbym pomóc, bo na warsztacie mam między innymi KA-NUCLEO_F411, shield LCD2x16, na NUCLEO jest dioda RGB. Przyciski i krańcówki zasymulowałbym sobie z terminala.

Link do komentarza
Share on other sites

Witam.

Sory ale trochę mniej mam czasu na prace przy projekcie ("młyn" w pracy)

Na dokładkę wysypal mi się system na komputerze, na którym to robię. ( żona nie pozwala mi używać do tego jej komputera).

Kolega Zero chyba wstrzelił się w dziesiątkę z tym projektem,kolega es2 również sądząc po analizie kodu, niestety na chwilę obecną nie mam możliwości testu kodów na swoim projekcie z powodu j/w.

W trybie ręcznym klawisze lewo prawo po naciśnięciu ich przesuwają korpus maszyny w odpowiednią stronę. I tu mi się nasuwa kolejny znak zapytania co gdy zostaną wciśnięte obydwa jednocześnie? Zadziałanie obydwóch przekaźników jednocześnie zrobi zwarcie i będzie "bum"

Jeszcze raz dzięki za zainteresowanie, jak tylko uporam się z kompem po testuje i tez wrzucę filmik z działania układu.Pozdrawiam

Link do komentarza
Share on other sites

es2, słusznie dał mi po uszach, bo ja myślałem o diodach a nie o maszynie.

Zbyszko125, Co do obawy o przyciski, to w przypadku, gdy lewo i prawo są wciśnięte jednocześnie to diody/przekaźniki nie działają, co powinien załatwić ostatni else (wcześniejsze warunki wykonują się, gdy jeden przycisk jest wciśnięty a drugi nie).

Generalnie jest to luźna implementacja logiki twojego problemu, więc nie przekładałnym jej 1:1 do Twojego programu.

Dziś mam już inne pomysły, kto wie może pokuszę się o trzecie rozwiązanie. Znów dostanę po uszach i znów się czegoś nauczę. 🙂

Ale to najwcześniej w weekend.

  • Lubię! 1
Link do komentarza
Share on other sites

Zawinołem żonie laptopa i wgrałem sketch kolegi Zerohttp://youtube.com/watch?v=4R8I6SsMQcg po małej modyfikacji kodu działa tak jak oczekiwałem.

#define kr1 0 
#define kr2 13 
#define przyciskL 8 
#define startStop 7 
#define przyciskP 6
#define przekaznik1 2 //przekaźnik1
#define przekaznik2 1 //przekaźnik2 

#include <Wire.h>  
#include <LiquidCrystal_I2C.h> 
LiquidCrystal_I2C lcd(0x27,16,2);  

boolean kierunek = false;  //false {LEWO}; true {PRAWO} 
boolean tryb = true; //false {tryb AUTOMAT}; true {tryb RECZNY} 


void setup() { 
 lcd.init(); 

 pinMode(przekaznik1, OUTPUT); 
 pinMode(przekaznik2, OUTPUT); 
 digitalWrite(przekaznik1, HIGH); //wyłączenie "przekaźników" - 
 digitalWrite(przekaznik2, HIGH); 



 pinMode(kr1, INPUT_PULLUP); // przyciski przez rezystor
 pinMode(kr2, INPUT_PULLUP); // podciągający //wbudowany w płytkę arduino
 pinMode(przyciskL, INPUT_PULLUP); 
 pinMode(startStop, INPUT_PULLUP); 
 pinMode(przyciskP, INPUT_PULLUP); 
} 

void wylacznikKrancowyP() { 
 if (digitalRead(kr1) == LOW) { 
   delay(100); //debounce 
   if (digitalRead(kr1) == LOW) { 
     for (int i = 1; i < 10; i++) {      //sygnalizacja zadziałania wyłącznika krańcowego 
       digitalWrite(przekaznik2, HIGH);  //w rzeczywistym programie byłoby to bez sensu  
       digitalWrite(przekaznik2, LOW);  
     } 

     kierunek = false; 
     digitalWrite(przekaznik2, HIGH); //WYLACZ PRZEKAZNIK 2 
   delay(500);
     digitalWrite(przekaznik1, LOW); //włącz przekaźnik 1 
   } 
 } 
} 
void wylacznikKrancowyL() { 
 if (digitalRead(kr2) == LOW) { 
   delay(100); //debounce 
   if (digitalRead(kr2) == LOW) { 
      for (int i = 1; i < 10; i++) {      //sygnalizacja zadziałania wyłącznika krańcowego 
       digitalWrite(przekaznik1, HIGH);  //w rzeczywistym programie byłoby to bez sensu
       digitalWrite(przekaznik1, LOW); 

     }      

     kierunek = true; 
       digitalWrite(przekaznik1, HIGH); //wyłącz przekaźnik 1
       delay(500);
        digitalWrite(przekaznik2, LOW); //WLACZ PRZEKAZNIK 2 

   } 
 } 
} 
void trybAutomatycznyLCD() { 
 lcd.setCursor(0, 0); 
 lcd.print("    AUTOMAT "); 
} 
void kierunekLewoLCD() { 
 lcd.setCursor(0, 1); 
 lcd.print("[LEWO          ]"); 
} 
void trybRecznyLCD() { 
 lcd.setCursor(0, 0); 
 lcd.print("    RECZNY "); 
} 
void kierunekPrawoLCD() { 
 lcd.setCursor(0, 1); 
 lcd.print("[         PRAWO]"); 
} 

void przekaznikiStopLCD() { 
 lcd.setCursor(0, 1); 
 lcd.print("[              ]"); 
} 
void wlaczPrzekaznik1() { 
 digitalWrite(przekaznik1, LOW);  
 digitalWrite(przekaznik2, HIGH); 
} 
void wlaczPrzekaznik2() { 
 digitalWrite(przekaznik1, HIGH); 
 digitalWrite(przekaznik2, LOW); 
} 
void przekaznikiStop() { 
 digitalWrite(przekaznik1, HIGH); 
 digitalWrite(przekaznik2, HIGH); 
} 

void loop() { 
 if (digitalRead(startStop) == LOW) { 
   delay(100); 
   if (digitalRead(startStop) == LOW) { 
     if (tryb == true) {         //jeżeli przed wcisnieciem, był tryb ręczny 
       tryb = false;     //przełącz na automat 
       kierunek = false; //w automacie ruszaj w lewo 
       trybAutomatycznyLCD(); 
     } else { 
       tryb = true; 
       trybRecznyLCD(); 
     } 
   } 
   delay(200); 
 } 

wylacznikKrancowyL(); //sprawdzenie, czy wylacznik krancowy nie jest wlaczony 
wylacznikKrancowyP(); 

if (tryb == false && kierunek == false) { 
 trybAutomatycznyLCD(); 
 kierunekLewoLCD(); 
 wlaczPrzekaznik1();  
} else if (tryb == false && kierunek == true) { 
 trybAutomatycznyLCD(); 
 kierunekPrawoLCD(); 
 wlaczPrzekaznik2(); 
} else if (tryb == true) { 
 if (digitalRead(przyciskL) == LOW && digitalRead(przyciskP) == HIGH) { 
 trybRecznyLCD(); 
 kierunekLewoLCD(); 
 wlaczPrzekaznik1();  
 } else if (digitalRead(przyciskL) == HIGH && digitalRead(przyciskP) == LOW) { 
 trybRecznyLCD(); 
 kierunekPrawoLCD(); 
 wlaczPrzekaznik2();    
 } else { 
 trybRecznyLCD(); 
 przekaznikiStopLCD(); 
 przekaznikiStop(); 
 } 
} 
} 

Jeszcze małe poprawki i kolejne testy.

Przyciski lewo /prawo zastąpie włącznikiem ON/OFF/ON monostabilnym, start chwilowym.

Link do komentarza
Share on other sites

No to cieszę się, że udało się ten kod zastosować.

Pogoda w ten weekend nie zachęca do siedzenia, przy biurku, więc ja zrobiłem sobie wolne. :]

Patrząc na ten kod z perspektywy, zastanawiam się, nad tym fragmentem (w sumie to pierdoła)

delay(100); //debounce

Czy powinien być tak długi? Teoretycznie drgania styków to 20(?)-30(?) ms? Piszę teoretycznie, bo nie mam oscyloskopu, więc nigdy ich nie widziałem "na żywo". :|

Link do komentarza
Share on other sites

Gość es2
delay(100); //debounce

Czy powinien być tak długi? Teoretycznie drgania styków to 20(?)-30(?) ms? Piszę teoretycznie, bo nie mam oscyloskopu, więc nigdy ich nie widziałem "na żywo". :|

Do likwidacji drżenia styków, dla Arduino sa stosowne biblioteki. Linki można znaleźć tu http://www.avt.4ra.pl/viewtopic.php?pid=29#p29

Po co więc kombinować z delay?

Link do komentarza
Share on other sites

Witam po dłuższej przerwie. W końcu udało mi się dopracować cały projekt i powoli zaczynam go finalizować, szkice obudowy,mocowanie krańcówek. Jednak ciągły brak czasu nie pozwala na to.

Dziś udało mi sie poświęcić trochę czasu i przenieść na Pro Mini, a tu niespodzianka, wszystko się zawaliło, kod głupieje tzn styczniki i przyciski, LCD nic nie wyświetla. LCD mam podłączony przez I2C na Pro Mini pin A5 to SCL A4 to SDA i lipa. Na Uno chodzi elegancko, a na Pro Mini nie.Nie mam pojęcia co jest tego powodem,przekopałem pół netu i nic nie znalazłem. Zasilanie przekaźników zrobiłem nie z płytki tylko z zasilacza, co prawda z tego samego źródła zasilam płytkę ale to nie ma chyba znaczenia. A już miałem się zabierać za PCB i resztę a tu ......

Link do komentarza
Share on other sites

Pro Mini wymaga rezystorów podciągających (też się kiedyś na to nabrałem).

Podłącz A4 i A5 do Vcc poprzez rezystory 4.7k i wyświetlacz automagicznie ruszy.

Link do komentarza
Share on other sites

Gość es2
Pro Mini wymaga rezystorów podciągających (też się kiedyś na to nabrałem).

Podłącz A4 i A5 do Vcc poprzez rezystory 4.7k i wyświetlacz automagicznie ruszy.

Uzupełnię odpowiedź. WSZYSTKIE znane mi płytki Arduino wymagają rezystorów podciągających. Dlaczego? Dopowiedz można znaleźć pod linkiem https://www.nxp.com/docs/en/user-guide/UM10204.pdf

Na Forbocie temat rezystorów podciągających potraktowany jest po macoszemu https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=4&ved=0ahUKEwix5fXymZbbAhWiDpoKHTtpCzoQFghEMAM&url=https%3A%2F%2Fwww.forbot.pl%2Fforum%2Fdownload.php%3Fid%3D1335&usg=AOvVaw272DoIPv-ggqR_3Lb38EJf

podobnie jak w Wiki https://pl.wikipedia.org/wiki/I%C2%B2C

Tak więc Panowie, jeśli pracuje sie ze sprzętem, trzeba sprzętu i wiedzy. Oscyloskop, Analizator logiczny, to podstawa.

Bez not katalogowych sie nie obejdzie.

Podłącz A4 i A5 do Vcc poprzez rezystory 4.7k i wyświetlacz automagicznie ruszy.

Kiedy 4,7k wystarczy, a kiedy nie? Jaka może byc minimalna a jaka maksymalna wartość rezystorów podciągających? Na wszystkie te pytania odpowiedź jest w nocie NXP, dla przypomnienia https://www.nxp.com/docs/en/user-guide/UM10204.pdf

Proszę też poczytać oo statusie 0xF8 układu TWI. Na tym, nie tylko Arduino potrafi sie wykrzaczyć. Pół biedy gdy jest włączony watchdog. Niestety, praktycznie każdy znany mi program na Arduino nie używa watchdoga.

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • 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.