• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Sterownik świateł drogowych plus tryb "party"
#1
Witam, 
Zaczynam dopiero przygodę z arduino i proszę o wyrozumiałość. Wszystkiego uczę się z internetu i składam programowe klocki w jeden projekt: Sterownik świateł drogowych, czyli 3 diody (czerwona, żółta, zielona). Dodatkowo PIN na input (guzik), który pozwala przełączyć w tryb "party", czyli wszystkie światła włączają się w losowych odstępach czasu na losowy okres czasu.
Coś mam nie tak w programie gdyż kiedy zmienię stan guzika z trybu "party" na tryb świateł drogowych często program nie idzie pokolei wg schematu: czerwona, czerwona i żółta, zielona, żółta, czerwona, czerwona i żółta, itd... tylko z diody żółtej potrafi przejść na czerwoną i zieloną równocześnie... 
Może to coś oczywistego a ja tego nie widzę? Jakieś śmieci w pamięci? Proszę o pomoc dobrzy ludzie Smile

P.S. 
Zrobiłem przejścia świateł drogowych na delay, nie przeszkadza mi to, że guzik będzie czytany dopiero po zmienie światła. Wiem, że można to robić jakoś na mills, ale przerosło mnie to.
Kod:
#define numberOfLEDs 3
long nextFlash[3];
int ledPin[] = { 8, 9, 10}; // LED pins to use.
int ledState[3];
int guzik = 0;

int red_time = 4000; //4000
int yellow_time = 2000; //2000
int green_time = 4000; //4000
void setup() {
 pinMode(8, OUTPUT); //Konfiguracja pinu 8 jako wyjście RED
 pinMode(9, OUTPUT); //Konfiguracja pinu 9 jako wyjście YELLOW
 pinMode(10, OUTPUT); //Konfiguracja pinu 10 jako wyjście GREEN
 pinMode(11, INPUT); //Konfiguracja pinu 11 jako guzik



}
void loop()
{
 guzik = digitalRead(11);  // read input value
 if (guzik == LOW)
   {
     traffic();
   }
   else losowe();
}


void guzik_on()
{
   guzik = digitalRead(11);  // read input value
 if (guzik == LOW)
   {
     traffic();
   }
}

void guzik_off()
{
   guzik = digitalRead(11);  // read input value
 if (guzik == HIGH)
   {
     losowe();
   }
}





 
void traffic() {
 digitalWrite(8, HIGH); //Włączenie diody RED
 delay(red_time);
 guzik_off();
 digitalWrite(9, HIGH); //Włączenie diody YELLOW
 delay(yellow_time);
 guzik_off();
 digitalWrite(8, LOW); //Wyłączenie diody RED
 digitalWrite(9, LOW); //Wyłączenie diody YELLOW
 digitalWrite(10, HIGH); //Włączenie diody GREEN
 delay(green_time);
 guzik_off();
 digitalWrite(10, LOW); //Wyłączenie diody GREEN
 digitalWrite(9, HIGH); //Włączenie diody YELLOW
 delay(2000);
 guzik_off();
 digitalWrite(9, LOW); //Wyłączenie diody YELLOW
}

void losowe()
{

 for (int i = 0; i < numberOfLEDs; i++) {
   pinMode(ledPin[i], OUTPUT);
   ledState[i] = LOW;
   digitalWrite(ledPin[i], LOW); // all LEDs off
   nextFlash[i] = millis() + random(20, 300);
 }

 while (true) {
   for (int i = 0; i < numberOfLEDs; i++) {
     if (millis() > nextFlash[i]) {
       if (ledState[i] == LOW) ledState[i] = HIGH; else ledState[i] = LOW;
       digitalWrite(ledPin[i], ledState[i]);
       nextFlash[i] = millis() + random(20, 300) ; // next toggle random time
       guzik_on();
     }
   }
 }
}
 
Odpowiedź
#2
hmmm,

tak sobie czytam ten kod i pierwsze co przychodzi mi na myśl to:

1) Czy masz rezystory pull down do guzika? Zawsze należy o nich pamiętać żeby pin nie "wisiał luźno w powietrzu" a mikrokontroler wiedział że LOW to faktycznie LOW a nie jakiś stan nieustalony.

2) Nie widzę też nic związanego z debounce a wystarczyło by dodać:

Kod:
void guzik_on()
{
  guzik = digitalRead(11);  // read input value
if (guzik == LOW)
delay(100);
  {
    traffic();
  }
}

void guzik_off()
{
  guzik = digitalRead(11);  // read input value
if (guzik == HIGH)
delay(100)
  {
    losowe();
  }
}


Na tę chwilę to tyle 

Wiem że istnieją inne możliwości debounce ale zawsze lepiej zacząć do łatwiejszych Tongue

Tak mi jeszcze przyszło do głowy że przy każdej zmianie stanów guzika możesz "Czyścić" wyjśćia

Kod:
void guzik_on()
{
  guzik = digitalRead(11);  // read input value
if (guzik == LOW)
delay(100);
  {
     digitalWrite(8, LOW); //Wyłączenie diody RED
     digitalWrite(9, LOW); //Wyłączenie diody YELLOW
     digitalWrite(10, LOW); //Włączenie diody GREEN
    traffic();
  }
}

void guzik_off()
{
  guzik = digitalRead(11);  // read input value
if (guzik == HIGH)
delay(100)
  {
     digitalWrite(8, LOW); //Wyłączenie diody RED
     digitalWrite(9, LOW); //Wyłączenie diody YELLOW
     digitalWrite(10, LOW); //Włączenie diody GREEN
    losowe();
  }
}
 
Odpowiedź
#3
(22-09-2015, 17:40)shalvan napisał(a): tak sobie czytam ten kod i pierwsze co przychodzi mi na myśl to:

1) Czy masz rezystory pull down do guzika? Zawsze należy o nich pamiętać żeby pin nie "wisiał luźno w powietrzu" a mikrokontroler wiedział że LOW to faktycznie LOW a nie jakiś stan nieustalony.

2) Nie widzę też nic związanego z debounce a wystarczyło by dodać:

Kod:
void guzik_on()
{
  guzik = digitalRead(11);  // read input value
if (guzik == LOW)
delay(100);
  {
    traffic();
  }
}

void guzik_off()
{
  guzik = digitalRead(11);  // read input value
if (guzik == HIGH)
delay(100)
  {
    losowe();
  }
}


Na tę chwilę to tyle 

Wiem że istnieją inne możliwości debounce ale zawsze lepiej zacząć do łatwiejszych Tongue

Tak mi jeszcze przyszło do głowy że przy każdej zmianie stanów guzika możesz "Czyścić" wyjśćia

Kod:
void guzik_on()
{
  guzik = digitalRead(11);  // read input value
if (guzik == LOW)
delay(100);
  {
     digitalWrite(8, LOW); //Wyłączenie diody RED
     digitalWrite(9, LOW); //Wyłączenie diody YELLOW
     digitalWrite(10, LOW); //Włączenie diody GREEN
    traffic();
  }
}

void guzik_off()
{
  guzik = digitalRead(11);  // read input value
if (guzik == HIGH)
delay(100)
  {
     digitalWrite(8, LOW); //Wyłączenie diody RED
     digitalWrite(9, LOW); //Wyłączenie diody YELLOW
     digitalWrite(10, LOW); //Włączenie diody GREEN
    losowe();
  }
}

zle gadasz ja mam sposub programowy i nie czeba nic dodawac

Kod:
#define numberOfLEDs 3
long nextFlash[3];
int ledPin[] = { 8, 9, 10}; // LED pins to use.
int ledState[3];
int guzik = 0;

int red_time = 4000; //4000
int yellow_time = 2000; //2000
int green_time = 4000; //4000
void setup() {
pinMode(8, OUTPUT); //Konfiguracja pinu 8 jako wyjście RED
pinMode(9, OUTPUT); //Konfiguracja pinu 9 jako wyjście YELLOW
pinMode(10, OUTPUT); //Konfiguracja pinu 10 jako wyjście GREEN
pinMode(11, INPUT); //Konfiguracja pinu 11 jako guzik
pinMode(11, OUTPUT);
digitalWrite(8, LOW);



}
void loop()
{
guzik = digitalRead(11);  // read input value
if (guzik == LOW)
   {
     traffic();
   }
   else losowe();
}


void guzik_on()
{
   guzik = digitalRead(11);  // read input value
if (guzik == LOW)
   {
     traffic();
   }
}

void guzik_off()
{
   guzik = digitalRead(11);  // read input value
if (guzik == HIGH)
   {
     losowe();
   }
}






void traffic() {
digitalWrite(8, HIGH); //Włączenie diody RED
delay(red_time);
guzik_off();
digitalWrite(9, HIGH); //Włączenie diody YELLOW
delay(yellow_time);
guzik_off();
digitalWrite(8, LOW); //Wyłączenie diody RED
digitalWrite(9, LOW); //Wyłączenie diody YELLOW
digitalWrite(10, HIGH); //Włączenie diody GREEN
delay(green_time);
guzik_off();
digitalWrite(10, LOW); //Wyłączenie diody GREEN
digitalWrite(9, HIGH); //Włączenie diody YELLOW
delay(2000);
guzik_off();
digitalWrite(9, LOW); //Wyłączenie diody YELLOW
}

void losowe()
{

for (int i = 0; i < numberOfLEDs; i++) {
   pinMode(ledPin[i], OUTPUT);
   ledState[i] = LOW;
   digitalWrite(ledPin[i], LOW); // all LEDs off
   nextFlash[i] = millis() + random(20, 300);
}

while (true) {
   for (int i = 0; i < numberOfLEDs; i++) {
     if (millis() > nextFlash[i]) {
       if (ledState[i] == LOW) ledState[i] = HIGH; else ledState[i] = LOW;
       digitalWrite(ledPin[i], ledState[i]);
       nextFlash[i] = millis() + random(20, 300) ; // next toggle random time
       guzik_on();
     }
   }
}
}
to kod z poprawionym drganiem zestyków sprawdzę jak ci to działa a ty opisz dokładnie jak chciałeś by to działało.
 
Odpowiedź
#4
podrugie nie pisz tak
Kod:
digitalWrite(9, HIGH); //Włączenie diody YELLOW
delay(yellow_time);
guzik_off();
digitalWrite(8, LOW); //Wyłączenie diody RED
digitalWrite(9, LOW); //Wyłączenie diody YELLOW
digitalWrite(10, HIGH); //Włączenie diody GREEN
delay(green_time);
guzik_off();
digitalWrite(10, LOW); //Wyłączenie diody GREEN
digitalWrite(9, HIGH); //Włączenie diody YELLOW
do jak zrobisz kod na 20 kartek a4 i będziesz chciał zmienić jeden pin to 2 godziny będziesz to robił masz tu poprawiony kod podmieni miny na swoje i sprawdź u mnie dział ale nie wiem czy tak ci to się wyobrażało
Kod:
#define numberOfLEDs 3
long nextFlash[3];
int ledPin[] = { 42, 43, 44}; // LED pins to use.
int ledState[3];
int guzik=1;
const int button = 48;
int red_time = 4000; //4000
int yellow_time = 2000; //2000
int green_time = 4000; //4000
void setup() {
pinMode(42, OUTPUT); //Konfiguracja pinu 8 jako wyjście RED
pinMode(43, OUTPUT); //Konfiguracja pinu 9 jako wyjście YELLOW
pinMode(44, OUTPUT); //Konfiguracja pinu 10 jako wyjście GREEN
pinMode(48, INPUT); //Konfiguracja pinu 11 jako guzik
pinMode(48, OUTPUT);




}
void loop()
{
guzik = digitalRead(button);  // read input value
if (guzik == LOW)
   {
     traffic();
   }
   else losowe();
}


void guzik_on()
{
   guzik = digitalRead(button);  // read input value
if (guzik == LOW)
   {
     traffic();
   }
}

void guzik_off()
{
   guzik = digitalRead(button);  // read input value
if (guzik == HIGH)
   {
     losowe();
   }
}






void traffic() {
digitalWrite(ledPin[0], HIGH); //Włączenie diody RED
delay(red_time);
guzik_off();
digitalWrite(ledPin[1], HIGH); //Włączenie diody YELLOW
delay(yellow_time);
guzik_off();
digitalWrite(ledPin[0], LOW); //Wyłączenie diody RED
digitalWrite(ledPin[1], LOW); //Wyłączenie diody YELLOW
digitalWrite(ledPin[2], HIGH); //Włączenie diody GREEN
delay(green_time);
guzik_off();
digitalWrite(ledPin[2], LOW); //Wyłączenie diody GREEN
digitalWrite(ledPin[1], HIGH); //Włączenie diody YELLOW
delay(2000);
guzik_off();
digitalWrite(ledPin[1], LOW); //Wyłączenie diody YELLOW
}

void losowe()
{

for (int i = 0; i < numberOfLEDs; i++) {
   pinMode(ledPin[i], OUTPUT);
   ledState[i] = LOW;
   digitalWrite(ledPin[i], LOW); // all LEDs off
   nextFlash[i] = millis() + random(20, 300);
}

while (true) {
   for (int i = 0; i < numberOfLEDs; i++) {
     if (millis() > nextFlash[i]) {
       if (ledState[i] == LOW) ledState[i] = HIGH; else ledState[i] = LOW;
       digitalWrite(ledPin[i], ledState[i]);
       nextFlash[i] = millis() + random(20, 300) ; // next toggle random time
       guzik_on();
     }
   }
}
}
 
Odpowiedź
#5
Dziękuję Wam za wszystkie cenne podpowiedzi.

@shalvan - Tak mam rezystor w przełączniku. Wiem, że nie może wisieć w powietrzu bo może sobie coś losowo wybierać.

@adix - dziękuję za ładny kod. Masz rację, że tak łatwiej potem zmieniać wszystko. Z Twoim kodem po powrocie z trybu "party" miałem to samo: po żółtej diodzie zapalały się nie wiem dlaczego, zielona i czerwona równocześnie...

Na koniec zastosowałem połączenie kodu @adix i @shalvan używając "czyszczenia wyjść" Shalvana i zadziałało tak jak chciałem!!!

Jeszcze raz Wam dziękuję Shalvan i Adix za poświęcony mi czas. 

Oto ostateczny kod:

Kod:
#define numberOfLEDs 3
long nextFlash[3];
int ledPin[] = { 8, 9, 10}; // LED pins to use.
int ledState[3];
int guzik=1;
const int button = 11;
int red_time = 4000; //4000
int yellow_time = 2000; //2000
int green_time = 4000; //4000
void setup() {
pinMode(8, OUTPUT); //Konfiguracja pinu 8 jako wyjście RED
pinMode(9, OUTPUT); //Konfiguracja pinu 9 jako wyjście YELLOW
pinMode(10, OUTPUT); //Konfiguracja pinu 10 jako wyjście GREEN
pinMode(11, INPUT); //Konfiguracja pinu 11 jako guzik




}
void loop()
{
guzik = digitalRead(button);  // read input value
if (guzik == LOW)
  {
    traffic();
  }
  else losowe();
}


void guzik_on()
{
  guzik = digitalRead(button);  // read input value
if (guzik == LOW)
  {
    digitalWrite(8, LOW); //Wyłączenie diody RED
    digitalWrite(9, LOW); //Wyłączenie diody YELLOW
    digitalWrite(10, LOW); //Włączenie diody GREEN
    traffic();
  }
}

void guzik_off()
{
  guzik = digitalRead(button);  // read input value
if (guzik == HIGH)
  {
    digitalWrite(8, LOW); //Wyłączenie diody RED
    digitalWrite(9, LOW); //Wyłączenie diody YELLOW
    digitalWrite(10, LOW); //Włączenie diody GREEN
    losowe();
  }
}






void traffic() {
digitalWrite(ledPin[0], HIGH); //Włączenie diody RED
delay(red_time);
guzik_off();
digitalWrite(ledPin[1], HIGH); //Włączenie diody YELLOW
delay(yellow_time);
guzik_off();
digitalWrite(ledPin[0], LOW); //Wyłączenie diody RED
digitalWrite(ledPin[1], LOW); //Wyłączenie diody YELLOW
digitalWrite(ledPin[2], HIGH); //Włączenie diody GREEN
delay(green_time);
guzik_off();
digitalWrite(ledPin[2], LOW); //Wyłączenie diody GREEN
digitalWrite(ledPin[1], HIGH); //Włączenie diody YELLOW
delay(2000);
guzik_off();
digitalWrite(ledPin[1], LOW); //Wyłączenie diody YELLOW
}

void losowe()
{

for (int i = 0; i < numberOfLEDs; i++) {
  pinMode(ledPin[i], OUTPUT);
  ledState[i] = LOW;
  digitalWrite(ledPin[i], LOW); // all LEDs off
  nextFlash[i] = millis() + random(20, 300);
}

while (true) {
  for (int i = 0; i < numberOfLEDs; i++) {
    if (millis() > nextFlash[i]) {
      if (ledState[i] == LOW) ledState[i] = HIGH; else ledState[i] = LOW;
      digitalWrite(ledPin[i], ledState[i]);
      nextFlash[i] = millis() + random(20, 300) ; // next toggle random time
      guzik_on();
    }
  }
}
}
 
Odpowiedź
#6
Kod:
pinMode(8, OUTPUT); //Konfiguracja pinu 8 jako wyjście RED
pinMode(9, OUTPUT); //Konfiguracja pinu 9 jako wyjście YELLOW
pinMode(10, OUTPUT); //Konfiguracja pinu 10 jako wyjście GREEN
pinMode(11, INPUT); //Konfiguracja pinu 11 jako guzik
pinMode(11,OUTPUT); //Konfiguracja pinu 11 jako guzik
digitalWrite(11, HIGH);//LOW wzaleznosci czy wyzwalsz 0 czy 1
dzieki uzyciu takiej kobinacji mozesz usunac rezysto bo on jest zbedny
 
Odpowiedź
#7
(23-09-2015, 17:03)adix napisał(a):
Kod:
pinMode(8, OUTPUT); //Konfiguracja pinu 8 jako wyjście RED
pinMode(9, OUTPUT); //Konfiguracja pinu 9 jako wyjście YELLOW
pinMode(10, OUTPUT); //Konfiguracja pinu 10 jako wyjście GREEN
pinMode(11, INPUT); //Konfiguracja pinu 11 jako guzik
pinMode(11,OUTPUT); //Konfiguracja pinu 11 jako guzik
digitalWrite(11, HIGH);//LOW wzaleznosci czy wyzwalsz 0 czy 1
dzieki uzyciu takiej kobinacji mozesz usunac rezysto bo on jest zbedny
To też sprytne. Czyli deklaruję PIN 11 jako INPUT i OUTPUT?
 
Odpowiedź
#8
tak ale musisz pamiętać digitalWrite(11, HIGH) bo to jest podciagniecie
 
Odpowiedź
#9
(24-09-2015, 18:16)adix napisał(a): tak ale musisz pamiętać digitalWrite(11, HIGH) bo to jest podciagniecie

Wystarczy użyć INPUT_PULLUP jest to podciągnięcie wewnętrznego rezystora na procku przy funkcji odczytu pinu ustawiając go zawsze na stan wysoki .

Kod:
digitalRead(11, INPUT_PULLUP)
Ważne aby robić co się lubi albo lubić co się robi .
Arduino UNO, TINY, PRO MINI
Pomoc nagradzamy punktami reputacji Wink
 
Odpowiedź
#10
O tym nie widzialem

Wysłane z mojego ME371MG przy użyciu Tapatalka
[Obrazek: banerelektronika.jpg]



Jeśli pomogłem podziękuj punktem reputacji Wink
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości