• 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
Led i ekspander PCF8574
#1
Witam, mam taki problem z  napisaniem kodu który umożliwiłby sterowanie diodami led z pilota.
Mam przykładowo kilka kodów sterowania ledami, chciałbym zrobić tak, aby np po wciśnięciu na pilocie "1" uruchamiał się program nr 1 oczywiście w nieskończonej pętli, a po wciśnięciu przycisku "2" wykonywał sie ten 2 kod. Próbowałem na switch case ale wykonuje mi sie to tylko raz, pętle for i while również sie nie sprawdziły... 
Może ma ktoś z was pomysł jak by to zrobić.


Pozdrawiam Wink

Wrzucam przykład.


Załączone pliki
.txt   prog.txt (Rozmiar: 2.35 KB / Pobrań: 7)
 
Odpowiedź
#2
Nie załączaj plików, tylko wklej kod, bo ludzie nie mają czasu na pobieranie i kombinowanie z tymi plikami.

Kod:
#include <PCF8574.h>
#include <Wire.h>
#include <IRremote.h>  //biblioteka
#define irPin 8 //pin Arduino, do którego został podłšczony odbiornik IR
#define LED1 2

IRrecv irrecv(irPin);
decode_results results;

PCF8574 expander0;
PCF8574 expander1;
PCF8574 expander2;

void setup() {

 Serial.begin(9600);
 irrecv.enableIRIn(); // uruchamia odbiornik podczerwieni
 
pinMode(LED1,OUTPUT);
expander0.begin(0x20);
expander0.pinMode(0,OUTPUT);
expander0.pinMode(1,OUTPUT);
expander0.pinMode(2,OUTPUT);
expander0.pinMode(3,OUTPUT);
expander0.pinMode(4,OUTPUT);
expander0.pinMode(5,OUTPUT);
expander0.pinMode(6,OUTPUT);
expander0.pinMode(7,OUTPUT);
 
expander1.begin(0x21);
expander1.pinMode(0,OUTPUT);
expander1.pinMode(1,OUTPUT);
expander1.pinMode(2,OUTPUT);
expander1.pinMode(3,OUTPUT);
expander1.pinMode(4,OUTPUT);
expander1.pinMode(5,OUTPUT);
expander1.pinMode(6,OUTPUT);
expander1.pinMode(7,OUTPUT);

expander2.begin(0x22);
expander2.pinMode(0,OUTPUT);
expander2.pinMode(1,OUTPUT);
expander2.pinMode(2,OUTPUT);
expander2.pinMode(3,OUTPUT);
expander2.pinMode(4,OUTPUT);
expander2.pinMode(5,OUTPUT);
expander2.pinMode(6,OUTPUT);
expander2.pinMode(7,OUTPUT);
}

void loop() {
 // 1 program
   digitalWrite(LED1,HIGH);
 expander0.set();
 expander1.set();
 expander2.set();
   if (irrecv.decode(&results)) {
     
   if(results.value==0x9716BE3F)
     {
     
    digitalWrite(LED1,LOW);
    delay(50);
 digitalWrite(LED1,HIGH);
delay(50);
 expander0.digitalWrite(0, LOW);
 delay(50);
 expander0.digitalWrite(0, HIGH);
 delay(50);
 expander0.digitalWrite(1, LOW);
 delay(50);
 expander0.digitalWrite(1, HIGH);
 delay(50);
 expander0.digitalWrite(2, LOW);
 delay(50);
 expander0.digitalWrite(2, HIGH);

     }
     irrecv.resume();
 //program2

  if(results.value==0x3D9AE3F7)
  {
 digitalWrite(LED1,LOW);
 delay (50);
 digitalWrite(LED1,HIGH);
 delay(50);
 expander2.digitalWrite(7, LOW);
 delay(50);
 expander2.digitalWrite(7, HIGH);
 delay(50);
 expander2.digitalWrite(6, LOW);
 delay(50);
 expander2.digitalWrite(6, HIGH);
 delay(50);
 expander2.digitalWrite(5, LOW);
 delay(50);
 expander2.digitalWrite(5, HIGH);
 delay(50);
 expander2.digitalWrite(4, LOW);
 delay(50);
 expander2.digitalWrite(4, HIGH);
 delay(50);

  }
irrecv.resume();
 

}


Funkcja loop nie jest zakończona klamrą, więc ci się program nie skompiluje, ale to pewnie przeoczenie przy kopiowaniu do pliku tekstowego (tak jak by nie można było wrzucić pliku .ino).
Gdyby ludzie komentowali swoje "dzieła", to nie mieli by problemu z analizą błędów.
Po prostu piszesz przy każdej linijce kodu, co on ma zrobić i wiesz co się dzieje, że nic się nie dzieje.

Na przykład:


Kod:
if (irrecv.decode(&results)) {

Oznacza to, że jeśli mój odbiornik otrzyma coś z nadajnika....

i tym czymś będzie to:
Kod:
if(results.value==0x9716BE3F)

to wykonaj coś tam i przejdź do następnej instrukcji.
Jeśli nie jest tym co wyżej, to nie wykonuj kodu w klamrach, tylko przejdź po prostu do następnej instrukcji.

Następną instrukcją jest:
Kod:
irrecv.resume();

Ni mniej ni więcej, tylko resetuje odbiornik i przygotowuje go do odbioru następnej dawki danych.
Oznacza to, że results.value==0x00000000 i dalsza część kodu ci się nie wykona, ponieważ:
Kod:
if(results.value==0x3D9AE3F7)
nie jest prawdą, więc przechodzimy do następnej instrukcji:
(No i tu powinno być else if, nie będę tłumaczył, zajżyj do poradników)

Kod:
irrecv.resume();
czyli patrz wyżej.

Następnie pętla główna wykona się jeszcze raz.
Kod:
   digitalWrite(LED1,HIGH);
 expander0.set();
 expander1.set();
 expander2.set();
expanderX.set(); wyłącza wszystkie diody, więc jeśli coś wcześniej zadziałało, to pewnie nawet nie zdążyłeś zauważyć.

Ja bym wywalił
Kod:
 expander0.set();
 expander1.set();
 expander2.set();

do funkcji setup();
a tą funkcję:
Kod:
irrecv.resume();

wywalić i zostawić tylko po ostatnim ifie.
Coś w tym stylu:
Kod:
#include <PCF8574.h>
#include <Wire.h>
#include <IRremote.h>  //biblioteka
#define irPin 8 //pin Arduino, do którego został podłšczony odbiornik IR
#define LED1 2

IRrecv irrecv(irPin);
decode_results results;

PCF8574 expander0;
PCF8574 expander1;
PCF8574 expander2;

void setup() {

 Serial.begin(9600);
 irrecv.enableIRIn(); // uruchamia odbiornik podczerwieni
 
pinMode(LED1,OUTPUT);
expander0.begin(0x20);
expander0.pinMode(0,OUTPUT);
expander0.pinMode(1,OUTPUT);
expander0.pinMode(2,OUTPUT);
expander0.pinMode(3,OUTPUT);
expander0.pinMode(4,OUTPUT);
expander0.pinMode(5,OUTPUT);
expander0.pinMode(6,OUTPUT);
expander0.pinMode(7,OUTPUT);
 
expander1.begin(0x21);
expander1.pinMode(0,OUTPUT);
expander1.pinMode(1,OUTPUT);
expander1.pinMode(2,OUTPUT);
expander1.pinMode(3,OUTPUT);
expander1.pinMode(4,OUTPUT);
expander1.pinMode(5,OUTPUT);
expander1.pinMode(6,OUTPUT);
expander1.pinMode(7,OUTPUT);

expander2.begin(0x22);
expander2.pinMode(0,OUTPUT);
expander2.pinMode(1,OUTPUT);
expander2.pinMode(2,OUTPUT);
expander2.pinMode(3,OUTPUT);
expander2.pinMode(4,OUTPUT);
expander2.pinMode(5,OUTPUT);
expander2.pinMode(6,OUTPUT);
expander2.pinMode(7,OUTPUT);

 expander0.set();
 expander1.set();
 expander2.set();

}

void loop() {
 // 1 program
   digitalWrite(LED1,HIGH);

   if (irrecv.decode(&results)) {
     
        if(results.value==0x9716BE3F)    {
     
            digitalWrite(LED1,LOW);
            delay(50);
            digitalWrite(LED1,HIGH);
            delay(50);
            expander0.digitalWrite(0, LOW);
            delay(50);
            expander0.digitalWrite(0, HIGH);
            delay(50);
            expander0.digitalWrite(1, LOW);
            delay(50);
            expander0.digitalWrite(1, HIGH);
            delay(50);
            expander0.digitalWrite(2, LOW);
            delay(50);
            expander0.digitalWrite(2, HIGH);

        }
   
 //program2

                 else if(results.value==0x3D9AE3F7)    {
            digitalWrite(LED1,LOW);
            delay (50);
            digitalWrite(LED1,HIGH);
            delay(50);
            expander2.digitalWrite(7, LOW);
            delay(50);
            expander2.digitalWrite(7, HIGH);
            delay(50);
            expander2.digitalWrite(6, LOW);
            delay(50);
            expander2.digitalWrite(6, HIGH);
            delay(50);
            expander2.digitalWrite(5, LOW);
            delay(50);
            expander2.digitalWrite(5, HIGH);
            delay(50);
            expander2.digitalWrite(4, LOW);
            delay(50);
            expander2.digitalWrite(4, HIGH);
            delay(50);

        }
    irrecv.resume();
 
    }
}

A najlepiej to powywalał bym to do zewnętrznych funkcji, a w pętli głównej tylko wywoływał je odpowiednimi instrukcjami. Wtedy program jest przejrzysty i łatwiejszy do ogarnięcia.
Kod:
#include <PCF8574.h>
#include <Wire.h>
#include <IRremote.h>  //biblioteka
#define irPin 8 //pin Arduino, do którego został podłšczony odbiornik IR
#define LED1 2

IRrecv irrecv(irPin);
decode_results results;

PCF8574 expander0;
PCF8574 expander1;
PCF8574 expander2;

void program1(); //deklaracje funkcji
void program2();

void setup() {

 Serial.begin(9600);
 irrecv.enableIRIn(); // uruchamia odbiornik podczerwieni
 
pinMode(LED1,OUTPUT);
expander0.begin(0x20);
expander0.pinMode(0,OUTPUT);
expander0.pinMode(1,OUTPUT);
expander0.pinMode(2,OUTPUT);
expander0.pinMode(3,OUTPUT);
expander0.pinMode(4,OUTPUT);
expander0.pinMode(5,OUTPUT);
expander0.pinMode(6,OUTPUT);
expander0.pinMode(7,OUTPUT);
 
expander1.begin(0x21);
expander1.pinMode(0,OUTPUT);
expander1.pinMode(1,OUTPUT);
expander1.pinMode(2,OUTPUT);
expander1.pinMode(3,OUTPUT);
expander1.pinMode(4,OUTPUT);
expander1.pinMode(5,OUTPUT);
expander1.pinMode(6,OUTPUT);
expander1.pinMode(7,OUTPUT);

expander2.begin(0x22);
expander2.pinMode(0,OUTPUT);
expander2.pinMode(1,OUTPUT);
expander2.pinMode(2,OUTPUT);
expander2.pinMode(3,OUTPUT);
expander2.pinMode(4,OUTPUT);
expander2.pinMode(5,OUTPUT);
expander2.pinMode(6,OUTPUT);
expander2.pinMode(7,OUTPUT);

 expander0.set();
 expander1.set();
 expander2.set();

}

void loop() {

   digitalWrite(LED1,HIGH);

   if (irrecv.decode(&results)) {
         if(results.value==0x9716BE3F) program1();
       else if(results.value==0x3D9AE3F7) program2();    
        irrecv.resume();
     }
}

void program1()    {
     
            digitalWrite(LED1,LOW);
            delay(50);
            digitalWrite(LED1,HIGH);
            delay(50);
            expander0.digitalWrite(0, LOW);
            delay(50);
            expander0.digitalWrite(0, HIGH);
            delay(50);
            expander0.digitalWrite(1, LOW);
            delay(50);
            expander0.digitalWrite(1, HIGH);
            delay(50);
            expander0.digitalWrite(2, LOW);
            delay(50);
            expander0.digitalWrite(2, HIGH);

        }
        
void program2()    {
            digitalWrite(LED1,LOW);
            delay (50);
            digitalWrite(LED1,HIGH);
            delay(50);
            expander2.digitalWrite(7, LOW);
            delay(50);
            expander2.digitalWrite(7, HIGH);
            delay(50);
            expander2.digitalWrite(6, LOW);
            delay(50);
            expander2.digitalWrite(6, HIGH);
            delay(50);
            expander2.digitalWrite(5, LOW);
            delay(50);
            expander2.digitalWrite(5, HIGH);
            delay(50);
            expander2.digitalWrite(4, LOW);
            delay(50);
            expander2.digitalWrite(4, HIGH);
            delay(50);

        }
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#3
To wszystko jest dla mnie zrozumiałem co napisałeś.




void loop() {
if (irrecv.decode(&results)) //odbieranie danych przez odbirnika
  {
    if(results.value==0x9716BE3F)program1();
     if(results.value==0x3D9AE3F7) program2(); 
     if(results.value==0x6182021B) program3(); 
             irrecv.resume(); //resetowanuie odbiornika
     }
}

void program1() 
{
   expander2.digitalWrite(5, LOW);
expander1.digitalWrite(6, LOW);
expander0.digitalWrite(7, LOW);
 expander0.digitalWrite(0, LOW);
delay(50);
expander1.digitalWrite(7, LOW);
expander1.digitalWrite(0, LOW);
expander0.digitalWrite(1, LOW); 
delay(50);
}
void program2()
 {
  digitalWrite(LED1,LOW);
  expander2.digitalWrite(7, LOW);
  expander2.digitalWrite(6, LOW);
  expander2.digitalWrite(5, LOW);
  delay (100);

  expander2.digitalWrite(4, LOW);
  expander2.digitalWrite(3, LOW);
  expander2.digitalWrite(2, LOW);
  expander2.digitalWrite(1, LOW); 
  expander2.digitalWrite(0, LOW);
  expander1.digitalWrite(7, LOW);
  expander1.digitalWrite(6, LOW);
  delay(100);
}
 void program3() 
{ digitalWrite(LED1,LOW); 
     delay(50);
  digitalWrite(LED1,HIGH);
 delay(50);
  expander0.digitalWrite(0, LOW);
  delay(50);
  expander0.digitalWrite(0, HIGH);
  delay(50);
  expander0.digitalWrite(1, LOW);
  delay(50);
  expander0.digitalWrite(1, HIGH);
  delay(50);
  expander0.digitalWrite(2, LOW);
  delay(50);
}
 
kody w void programX wykonują sie raz, a jak zrobić by wykonywały sie nieskończenie wiele raz?
 
Odpowiedź
#4
No program po wykonaniu funkcji programX(); wraca do głównej pętli i nasłuchuje informacji z odbiornika.
Jeśli chcesz aby funkcja była zapętlona, należy ją umieścić w pętli.
Pętla powinna mieć możliwość przerwania i powrotu do funkcji loop();
Czyli można to zrobić w pętli WHILE.
Dopóki nic nie odbieram z odbiornika IRrecv, wykonuj daną sekwencję.
W przeciwnym razie BREAK.
Albo na przerwaniach zewnętrznych, ale to musiał byś przeprojektować cały kod.
Przepraszam, ale jestem w pracy i mogę się tym zająć dopiero wieczorem.
Pozdrawiam.
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#5
Jak zrobie tak:

if (irrecv.decode(&results)) //odbieranie danych przez odbirnika
  {
    while(results.value==0x9716BE3F)program1();
     while(results.value==0x3D9AE3F7) program2(); 
     while(results.value==0x6182021B) program3(); 
     while(results.value==0x8C22657B) program4(); 
             irrecv.resume(); //resetowanuie odbiornika
}

to z kolei nie można przełączyć na inny program....
 
Odpowiedź
#6
Pętla WHILE ma taką konstrukcję, że dopóki warunek w nawiasach jest spełniony, to będzie ona wykonywać instrukcję, lub blok instrukcji umieszczonych w klamrach.
To znaczy, w twoim kodzie, dopóki results.value==0x9716BE3F
wykonuj funkcję prgram1();
Czyli suma summarum, te funkcje nie muszą wykonać się ani razu, bo jeśli warunek nie jest spełniony, to program przeskakuje do następnej instrukcji.

Mi chodziło o to, że jak już przeskoczysz z bloku

Kod:
if (irrecv.decode(&results)) //odbieranie danych przez odbirnika
 {
   if(results.value==0x9716BE3F)program1();
    if(results.value==0x3D9AE3F7) program2();
    if(results.value==0x6182021B) program3();
            irrecv.resume(); //resetowanuie odbiornika
    }
}

 do funkcji, powiedzmy program1(); to możesz ją sobie zapętlić dopóki nie naciśniesz klawisza na pilocie.
Mniej więcej coś takiego:

Kod:
void program1() 
{
 while(irrecv.decode(!results))
  {
      expander2.digitalWrite(5, LOW);
     expander1.digitalWrite(6, LOW);
     expander0.digitalWrite(7, LOW);
      expander0.digitalWrite(0, LOW);
     delay(50);
     expander1.digitalWrite(7, LOW);
     expander1.digitalWrite(0, LOW);
     expander0.digitalWrite(1, LOW);
     delay(50);}
  }

   break;

}

Nie wiem czy negacja results zadziała, bo nie znam tej biblioteki, ale widać na tym przykładzie sens mojego wywodu. 
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#7
(01-06-2017, 19:32)Robson Kerman napisał(a):
Kod:
void program1() 
{
 while(irrecv.decode(!results))
  {
      expander2.digitalWrite(5, LOW);
     expander1.digitalWrite(6, LOW);
     expander0.digitalWrite(7, LOW);
      expander0.digitalWrite(0, LOW);
     delay(50);
     expander1.digitalWrite(7, LOW);
     expander1.digitalWrite(0, LOW);
     expander0.digitalWrite(1, LOW);
     delay(50);}
  }

   break;

}
Niestety w takiej konfiguracji to nie działa,
wyrzuca błąd expected unqualified-id before 'break'a 
a jak przerzuce break zaraz za pętle to mamy ten sam efekt czyli wykona tez sie raz 

void program1() 
{
 while(irrecv.decode(!results))
  {
      expander2.digitalWrite(5, LOW);
     expander1.digitalWrite(6, LOW);
     expander0.digitalWrite(7, LOW);
      expander0.digitalWrite(0, LOW);
     delay(50);
     expander1.digitalWrite(7, LOW);
     expander1.digitalWrite(0, LOW);
     expander0.digitalWrite(1, LOW);
     delay(50);
break;
}

}

 
Odpowiedź
#8
Tak jak myślałem że nie ogarniam tej biblioteki.
Trochę się z nią zapoznałem i powiem, że nie jest napisana prostym językiem.
Po zresetowaniu, results.value tak łatwo się nie poddaje i resetuje się po następnym przebiegu pętli.
No i tamta negacja to moja porażka, to by nigdy nie poszło.

Wstaw więc do funkcji program1(); ten kod. Sprawdzone, działa.
Kod:
void program1()    {
         
           
           while(1){
              expander2.digitalWrite(5, LOW);
              expander1.digitalWrite(6, LOW);
              expander0.digitalWrite(7, LOW);
              expander0.digitalWrite(0, LOW);
              delay(50);
              expander1.digitalWrite(7, LOW);
              expander1.digitalWrite(0, LOW);
              expander0.digitalWrite(1, LOW);
              delay(50);
       

              if (irrecv.decode(&results)) {
                irrecv.resume();
                if(results.value==0x9716BE3F) ;
                else  break;
                 }
               }
     
       }

Analogicznie zrób to samo dla następnych funkcji.

Funkcja pracuje w pętli nieskończonej. Wychodzi się z niej po naciśnięciu jakiegokolwiek przycisku na pilocie.
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#9
Działa! 


Dzięki za pomoc kolego!  Cool

Pozdrawiam.
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości