Arduino Polska Forum

Pełna wersja: działanie kodu w pro mini
Aktualnie przeglądasz uproszczoną wersję forum. Kliknij tutaj, by zobaczyć wersję z pełnym formatowaniem.
Witam, stworzyłem mały projekt sterownika do maszyny którego zadaniem jest sterownie ręczne poprzez przyciski oraz możliwość załączenia sterownika w tryb auto i wtedy sterownik sam bez mojej ingerencji steruje maszyną, całość zwieńczona LCD z inormacjami o stanie sterownika
Projekt zrobiłem na UNO 3, ale nie chce jej pakować do pudełka , tylko dać kod do Pro Mini i go zostawić. Niestety jest mały problem z kodem na Uno działał idealnie tak jak chciałem,ale na Pro Mini już robi bzdury.Nie wiem czemu tak się dzieje, czy to nie wina tych  INPUT_PULLUP ?
tak to wygląda :
Kod:
// od 3 do 8 podłączone 2 przekaźniki 5V 3 przyciki,i 2 krańcówki
#define kr1 12
#define kr2 13 //poodłączone dodatkowe rzeczy
#define przyciskL 8
#define startStop 7
#define przyciskP 6
#define przekaznik1 4 // przekaźnik1
#define przekaznik2 3 //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); //
 pinMode(kr2, INPUT_PULLUP); //  
 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();
 }
}
}
To nie wina INPUT_PULLUP. Nano, PRO MINI i UNO to te same procesory, programowo nie ma żadnej różnicy, możesz sobie wgrać bootloader od UNO do Nano lub Pro mini i będzie wykrywany jako UNO (w sensie nie wgrasz do NANO kodu jeśli w ustawieniach nie ustawisz płytki docelowej jako UNO). Ma to swoje dobre strony, w UNO bootloader zajmuje 1,5kb mniej i szybciej wgrywa kod.
Różnice między płytkami są widoczne w świecie makro. UNO ma więcej kondensatorów, w tym elektrolityczne. A Ty używasz przekaźników. Skąd je zasilasz? Jak z płytki to mogą powodować reset procka wysysając z płytki cały prąd.
Używam modułów przekaźników, są one zasilanie nie z płytki Pro Mini tylko z zasilacza jednak z tego samego zasilacza również płytka jest zasilana.Wgranie bootloadera od Uno do Pro mini mogłoby rozwiązać ten problem
Czym w ogóle objawiają się te bzdury? Co do pików zasilania dodaj do płytki kondensator ceramiczny 100n i  1000u elektrolityczny, bezpośrednio przy pinach zasilania procka, upewnij się, że zasilasz płytkę przez diodę. W razie szarpnięcia przekaźnika prąd nie wróci na przewody powodując 0 na resecie i reset procka. Czy  przekaźniki są przyczyną dziwnego zachowania łatwo sprawdzisz zamieniając je na ledy. Możesz też zasilić płytkę z osobnej ładowarki 5V, połączyć z płytką przekaźnika tylko GND.  Przy takiej konstrukcji programu dziwić może bardziej prawidłowe działanie na UNO. Napisz ten program bez delay, w szczególności w funkcji debounce. Ewentualnie tu jest do tego biblioteka: https://github.com/thomasfredericks/Boun...master.zip .
Do kontroli czasu działania czegoś użyj funkcji millis() i micros(), są przykłady w podstawach Arduino. Mnóstwo na tym forum.
A taki fragment:
Kod:
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);  
    }
na żadnym etapie nie ma sensu, to powinno trwać jakieś 1,5us (no, to Arduino, więc pewnie z 15us), nie do zobaczenia nawet na LED. Lepiej wypisać coś na port szeregowy w trybie testowania programu: "Krancowka nr 2 zadzialala". Wiele razy widziałem posty typu "przekaźniki i dziwne zachowanie Arduino".
Witam. Mimo ciagłego braku czasu na swoj projekt cos tam powoli dzialam. Podłaczyłem kondensatory jak radzisz, i doidy zamiast przekaźnikow , jednak cos jest nie tak ze sketchem,gdyz dalej nie dziala jak nalezy. Na Uno działa na promini nie chce. Nie bardzo wiem jak wywalic delay i wstawic milis, jeszcze nie ogarniam tego.
Są kursy na Forbot dla Arduino, jak już coś tam wiesz to początek sobie przejrzyj pierwsze lekcje, a najważniejszą z millis przerób na kilka sposobów. Warto przejrzeć wszystko, bo może ta o millis nie będzie najważniejsza dla Ciebie. Może płytka faktycznie jest uszkodzona - przetestuj ją na innych programach. W arduino jest mnóstwo przykładów, które działają prawidłowo. Jak zrobisz sobie 2 programy w życiu, to nic nie będziesz wiedział, po kilkudziesięciu, a lepiej po kilkuset, coś tam zaczniesz trybić - ważne by każdy starać się zrozumieć.
Stosowanie delay tak naprawdę ogranicza się gdy masz coś bardzo prostego w programie do przetestowania na szybko i tylko dla jednej rzeczy. Tylko miganie led – dajesz 1000ms, tylko sprawdzenie przycisku – dajesz 30. Jak już chcesz jedno i drugie to masz kolizję, bo dla leda tracisz 2000ms, a na przycisk trzeba zerknąć co co parę ms. Millis i delay stosujemy do kontroli czasu wykonywania poleceń. Jeszcze gorzej, jak nie stosujesz nic, a tak masz w pętli for powyżej. Dlatego mnie bardziej dziwi, że działa Ci to tak jak oczekujesz na UNO.
Zmieniłem diody na triaki z odseparowaniem za pomocą MOC3043. Podłączyłem wszystko pod UNO. Działa. Czy drżenie styków krańcówek i przyciskow da się wyeliminować sprzętowo a nie programowo np kondensator i rezystor? Gdzieś w trakcie kopania netu na coś takiego się natknąłem.
Wpisz w google "hardware debounce circuit", wyskoczą schematy w obrazach. Jak to działa nie wiem.
Ok dzięki.