Skocz do zawartości
Wprost123

Proste podświetlanie schodów na Arduino. Prośba o pomoc w stworzeniu programu

Pomocna odpowiedź

Podtrzymanie czasu u mnie się znajduje, można to wykorzystać.

A co do sytuacji kilku osób to mnie natchnęło po nocy. Tzn, jakby zmienić efekt świetlny na taki - od góry i dołu lewy zapałają się do środka. Tak jakby dwa mosty sie ze soba łączyly. Wtedy nie wazne ktora czujka będzie aktywowana, efekt świetlny ten sam.

Ale to juz takie luźne myśli.

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

To zrób inaczej. Nie dziel tego na dwie funkcje, tylko wpisz wszystko w jedną. Czyli mniej więcej tak jak niżej. Cała funkcja ledsOnUp będzie włączać i wyłączać diody do góry, a druga funkcja "ledsOnDown" będzie je zapalać w dół. Niech to wszystko zadziała i będziemy się martwić dalej.

 

#include <Arduino.h>

#define led1 4
#define led2 5
#define led3 6
#define led4 7
#define led5 8
#define led6 9
#define led7 10
#define przycisk1 2
#define przycisk2 3

unsigned long oldTime = 0; //zmienna starego czasu między rozświetlaniem diod
unsigned long newTime = 0;
unsigned long oldTimePodtrzymania = 0; //zmienna starego czasu podtrzymania świecenia
unsigned long newTimePodtrzymania = 0;

//byte iloscKrokow = 17; // il. diod x 4 bo co 2 case-y się zapalają + podtrzymanie np 4 okresy i gaszenie
byte zmiennaP1 = 0; //zmienna dla przycisku 1
byte zmiennaP2 = 0; //zmienna dla przycisku 2

byte stanPrzycisku1 = 0; //0-puszczony, 1-wciśnięty
byte stanPrzycisku2 = 0;

int odczytanaWartosc = 0;
byte zmienna2 = 0; //zmienna ilosci seknud które mineły w podtrzymaniu
int czasPodtrzymania = 0;

void ledsOn();
void ledsOff();
void czasCzekania();

void setup()
{
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(led7, OUTPUT);

  pinMode(przycisk1, INPUT_PULLUP); //przycisk 1
  pinMode(przycisk2, INPUT_PULLUP); // przycisk 2

  Serial.begin(9600);
}

void loop()
{
  if (digitalRead(przycisk1) == 0)
  {
    stanPrzycisku1 = 1;
  }
  if (digitalRead(przycisk2) == 0)
  {
    stanPrzycisku2 = 1;
  }

  newTime = millis();
  if (newTime - oldTime >= 1000)
  {
    oldTime = newTime;
    zmiennaP1++;

    if (stanPrzycisku1 == 1)
    {
      ledsOnUp();
    }
    if (stanPrzycisku2 == 1)
    {
      ledsOnDown();
    }
  }
}

void ledsOnUp()
{
  switch (zmiennaP1) //dzięki temu że minęla 1sek możemy wybrać co się stanie
  {
  case 1: //jeśli minęły 1sek włączasz led1
    digitalWrite(led1, HIGH);
    break;
  case 2: //odliczasz kolejną 1sek i włączasz led2
    digitalWrite(led2, HIGH);
    break;
  case 3:
    digitalWrite(led3, HIGH); //itd
    break;
  case 4:
    digitalWrite(led4, HIGH);
    break;
  case 5:
    digitalWrite(led5, HIGH);
    break;
  case 6:
    digitalWrite(led6, HIGH);
    break;
  case 7:
    digitalWrite(led7, HIGH);
    break;
  case 8:
    czasCzekania(); //zamiast tego mozna zastosować delay jak pisałem wyżej.
    stanPrzycisku1 = 0;
    break;
  case 9:
    digitalWrite(led1, LOW); //wyłączasz led1
    break;
  case 10: //wyłączasz led2
    digitalWrite(led2, LOW);
    break;
  case 11: //wyłaczasz led3
    digitalWrite(led3, LOW);
    break;
  case 12:
    digitalWrite(led4, LOW);
    break;
  case 13:
    digitalWrite(led5, LOW);
    break;
  case 14:
    digitalWrite(led6, LOW);
    break;
  case 15:
    digitalWrite(led7, LOW);
    stanPrzycisku2 = 0;
    zmiennaP1 = 0;
    break;
  }
}

void ledsOnDown()
{
}

void czasCzekania()
{    //jako że program nie jest wymagający to tutaj również można użyć delay'a bo i tak program jest wstrzymany
  do //cała ta pętla wstrzyma Ci cały program póki nie zostanie spełniony warunek za wyrażeniem while
  {
    odczytanaWartosc = analogRead(A0);                        //odczytujesz wartość z portu A0
    czasPodtrzymania = map(odczytanaWartosc, 0, 1023, 0, 10); //zamienia zmienną z przedziału od 0 do 1023 na zmienną od 0 do 10 (sekund)
    newTimePodtrzymania = millis();
    if (newTimePodtrzymania - oldTimePodtrzymania >= 1000) // odliczaj po 1s
    {
      oldTimePodtrzymania = newTimePodtrzymania;
      zmienna2++; //co 1sek zwiększasz wartość zmiennej2
    }
  } while (zmienna2 < czasPodtrzymania); //a pętla trwa póki zmienna2 nie osiągnie wartości zmapowanej zmiennej czasPodtrzymania
}

 

Edytowano przez matrix0606

Udostępnij ten post


Link to post
Share on other sites

@matrix0606 @matrix0606 

Czy Kolega ma pomysł dlaczego wg. kodu który zamieściłem, program dochodził tylko do case 9, czyli wygaszenia pierwszej diody i dalej już zmiennaP1 nie rośnie a co z tym idzie, kolejne diody nie gasną? 

Gdy wrzuciłem funkcję ledsOff na początek- tzn.  do pętli loop, jeszcze przed kod który sprawdza stan przycisków, to tam wartości zmiennejP1 i- kejsów rosły prawidłowo (ale to wykonywało się przed  funkcją ledsOn). 

 

Udostępnij ten post


Link to post
Share on other sites
(edytowany)
40 minut temu, Wprost123 napisał:

@matrix0606 @matrix0606 

Czy Kolega ma pomysł dlaczego wg. kodu który zamieściłem, program dochodził tylko do case 9, czyli wygaszenia pierwszej diody i dalej już zmiennaP1 nie rośnie a co z tym idzie, kolejne diody nie gasną? 

Ponieważ nigdzie nie masz odwołania do funkcji "ledsOff" ? Popatrz na kod, gdzie masz skok do tej funkcji ? Bo ja nigdzie nie widzę. Spróbuj takiego kodu:

 

#include <Arduino.h>

#define led1 4
#define led2 5
#define led3 6
#define led4 7
#define led5 8
#define led6 9
#define led7 10
#define przycisk1 2
#define przycisk2 3

unsigned long oldTime = 0; //zmienna starego czasu między rozświetlaniem diod
unsigned long newTime = 0;
unsigned long oldTimePodtrzymania = 0; //zmienna starego czasu podtrzymania świecenia
unsigned long newTimePodtrzymania = 0;

//byte iloscKrokow = 17; // il. diod x 4 bo co 2 case-y się zapalają + podtrzymanie np 4 okresy i gaszenie
byte zmiennaP1 = 0; //zmienna dla przycisku 1
byte zmiennaP2 = 0; //zmienna dla przycisku 2

byte stanPrzycisku1 = 0; //0-puszczony, 1-wciśnięty
byte stanPrzycisku2 = 0;

int odczytanaWartosc = 0;
byte zmienna2 = 0; //zmienna ilosci seknud które mineły w podtrzymaniu
int czasPodtrzymania = 0;

void ledsOnUp();
void ledsOnDown();
void czasCzekania();

void setup()
{
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(led7, OUTPUT);

  pinMode(przycisk1, INPUT_PULLUP); //przycisk 1
  pinMode(przycisk2, INPUT_PULLUP); // przycisk 2

  Serial.begin(9600);
}

void loop()
{
  if (digitalRead(przycisk1) == 0)
  {
    stanPrzycisku1 = 1;
  }
  if (digitalRead(przycisk2) == 0)
  {
    stanPrzycisku2 = 1;
  }

  newTime = millis();
  if (newTime - oldTime >= 1000)
  {
    oldTime = newTime;

    if (stanPrzycisku1 == 1)
    {
      zmiennaP1++;
      ledsOnUp();
    }
    if (stanPrzycisku2 == 1)
    {
      zmiennaP2++;
      ledsOnDown();
    }
  }
}

void ledsOnUp()
{
  switch (zmiennaP1)
  {
  case 1:
    digitalWrite(led1, HIGH);
    break;
  case 2:
    digitalWrite(led2, HIGH);
    break;
  case 3:
    digitalWrite(led3, HIGH);
    break;
  case 4:
    digitalWrite(led4, HIGH);
    break;
  case 5:
    digitalWrite(led5, HIGH);
    break;
  case 6:
    digitalWrite(led6, HIGH);
    break;
  case 7:
    digitalWrite(led7, HIGH);
    break;
  case 8:
    czasCzekania();
    break;
  case 9:
    digitalWrite(led1, LOW);
    break;
  case 10:
    digitalWrite(led2, LOW);
    break;
  case 11:
    digitalWrite(led3, LOW);
    break;
  case 12:
    digitalWrite(led4, LOW);
    break;
  case 13:
    digitalWrite(led5, LOW);
    break;
  case 14:
    digitalWrite(led6, LOW);
    break;
  case 15:
    digitalWrite(led7, LOW);
    stanPrzycisku1 = 0;
    zmiennaP1 = 0;
    break;
  }
}

void ledsOnDown()
{
  switch (zmiennaP2)
  {
  case 1:
    digitalWrite(led7, HIGH);
    break;
  case 2:
    digitalWrite(led6, HIGH);
    break;
  case 3:
    digitalWrite(led4, HIGH); //itd
    break;
  case 4:
    digitalWrite(led4, HIGH);
    break;
  case 5:
    digitalWrite(led3, HIGH);
    break;
  case 6:
    digitalWrite(led2, HIGH);
    break;
  case 7:
    digitalWrite(led1, HIGH);
    break;
  case 8:
    czasCzekania();
    break;
  case 9:
    digitalWrite(led7, LOW);
    break;
  case 10:
    digitalWrite(led6, LOW);
    break;
  case 11:
    digitalWrite(led5, LOW);
    break;
  case 12:
    digitalWrite(led4, LOW);
    break;
  case 13:
    digitalWrite(led3, LOW);
    break;
  case 14:
    digitalWrite(led2, LOW);
    break;
  case 15:
    digitalWrite(led1, LOW);
    stanPrzycisku2 = 0;
    zmiennaP2 = 0;
    break;
  }
}

void czasCzekania()
{    //jako że program nie jest wymagający to tutaj również można użyć delay'a bo i tak program jest wstrzymany
  do //cała ta pętla wstrzyma Ci cały program póki nie zostanie spełniony warunek za wyrażeniem while
  {
    odczytanaWartosc = analogRead(A0);                        //odczytujesz wartość z portu A0
    czasPodtrzymania = map(odczytanaWartosc, 0, 1023, 0, 10); //zamienia zmienną z przedziału od 0 do 1023 na zmienną od 0 do 10 (sekund)
    newTimePodtrzymania = millis();
    if (newTimePodtrzymania - oldTimePodtrzymania >= 1000) // odliczaj po 1s
    {
      oldTimePodtrzymania = newTimePodtrzymania;
      zmienna2++; //co 1sek zwiększasz wartość zmiennej2
    }
  } while (zmienna2 < czasPodtrzymania); //a pętla trwa póki zmienna2 nie osiągnie wartości zmapowanej zmiennej czasPodtrzymania
}

 

Edytowano przez matrix0606

Udostępnij ten post


Link to post
Share on other sites
46 minut temu, matrix0606 napisał:

 Popatrz na kod, gdzie masz skok do tej funkcji ?

 } while (zmienna2 < czasPodtrzymania); //a pętla trwa póki zmienna2 nie osiągnie wartości zmapowanej zmiennej czasPodtrzymania
ledsOff();
zmienna2=0;
}

Na końcu była taki fragment. Ale chyba nie jest to dobry sposób na wyjście z while i wejście do ledsOff. Pytanie, jak takie wyjście powinno wyglądać? Może wtedy ruszy poprawnie.

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Takie umiejscowienie wywołania funkcji "ledsOff"

} while (zmienna2 < czasPodtrzymania); //a pętla trwa póki zmienna2 nie osiągnie wartości zmapowanej zmiennej czasPodtrzymania
ledsOff();
zmienna2=0;
}

właśnie spowodowało jej jednokrotne wywołanie. I nic więcej się nie wydarzyło. Po wywołaniu funkcji "czasCZekania" na końcu tejże funkcji wywołałeś tylko raz funkcję "ledsOff" i więcej jej nie wywołałeś. Do tego wyzerowałeś zmienną2 i pozamiatane.

Edytowano przez matrix0606

Udostępnij ten post


Link to post
Share on other sites
5 minut temu, matrix0606 napisał:

właśnie spowodowało jej jednokrotne wywołanie. I nic więcej się nie wydarzyło. Po wywołaniu funkcji "czasCZekania" na końcu tejże funkcji wywołałeś tylko raz funkcję "ledsOff" i więcej jej nie wywołałeś. Do tego wyzerowałeś zmienną2 i pozamiatane.

Więc jak wywołać ledsOff poprawnie-żeby wykonała się cała? 

Zerowanie zmiennej2, przeniosłem teraz na koniec funkcji ledsOff, do ostatniego kejsa. 

  case 15:
    digitalWrite(led7, LOW);
    stanPrzycisku2 = 0;
    zmiennaP1 = 0;
    zmienna2=0; // zerowanie zmiennej zliczającej w czasie podtrzymania
    break;

 

Udostępnij ten post


Link to post
Share on other sites

Teraz nie ma mnie w domu, ale jak wrócę za 2h to spróbuje dodać do pętli loop coś w stylu

If((stanPrzycisku1==0) && (zmiennaP1>8) {

ledsOff();

}

A w case 7 dodam zerowanie stanu przycisku1

Czy ma to sens? 

 

Udostępnij ten post


Link to post
Share on other sites
(edytowany)
13 minut temu, Wprost123 napisał:

Teraz nie ma mnie w domu, ale jak wrócę za 2h to spróbuje dodać do pętli loop coś w stylu

If((stanPrzycisku1==0) && (zmiennaP1>8) {

ledsOff();

}

A w case 7 dodam zerowanie stanu przycisku1

Czy ma to sens? 

 

Tak było w poprzedniej wersji mojego programu ale teraz napisałem to co wyżej z racji że trzeba włączać i wyłączać ledy z dołu do góry ale i z góry do dołu. Coś czuję że na stykówce podepnę kilka ledów i to oprogramuję.

Edytowano przez matrix0606

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Zmieniłem lekko kod. 

W pętli loop dodałem warunek   

if(stanPrzycisku1==0 and zmienna2 >= czasPodtrzymania){
    ledsOff();

Żeby ten warunek nie był spełniony na starcie, to początkową wartość czasPodtrzymania ustawiłem na 1. Jeśli dobrze myślę, to nie ma to znaczenia, bo w funkcji "czasCzekania" itak ta zmienna jest pobierana z potencjometru i zastępuje tę pierwotną??

Teraz program działa- tzn. diody się rozpalają, czekają jakiś czas a potem gasną (Na symulatorze 😉 )

Jutro będę próbował zmodyfikować kod tak, że gdy w fazie podtrzymania lub gaszenia  ktoś znów naciśnie przycisk- czyli będzie szła kolejna osoba i żeby schody nie zaczęły jej nagle gasnąć, to naciska kolejny raz przycisk, to wtedy czas podtrzymania powinien zostać zresetowany i liczony od początku (jeśli były już w fazie podtrzymania) lub  schody powinny się znów zacząć podświetlać  (jeśli już wygasały).

#define led1 4
#define led2 5
#define led3 6
#define led4 7
#define led5 8
#define led6 9
#define led7 10
#define przycisk1 2
#define przycisk2 3

unsigned long oldTime= 0; //zmienna starego czasu między rozświetlaniem diod
unsigned long newTime = 0;

  
unsigned long oldTimePodtrzymania = 0; //zmienna starego czasu podtrzymania świecenia
unsigned long newTimePodtrzymania = 0;

//byte iloscKrokow = 17; // il. diod x 4 bo co 2 case-y się zapalają + podtrzymanie np 4 okresy i gaszenie
byte zmiennaP1 = 0; //zmienna dla przycisku 1
byte zmiennaP2 = 0; //zmienna dla przycisku 2

byte stanPrzycisku1 = 0; //0-puszczony, 1-wciśnięty
byte stanPrzycisku2 = 0;

int odczytanaWartosc = 0;
byte zmienna2 = 0; //zmienna ilosci seknud które mineły w podtrzymaniu
int czasPodtrzymania = 1; // NIE zero żeby warunek w loop if(stanPrzycisku1==0 and zmienna2 >= czasPodtrzymania Nie był od razu spełniony na starcie

void ledsOnDoGory();
void ledsOffNaDol();
void czasCzekania();

void setup()
{ 
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(led7, OUTPUT);

  pinMode(przycisk1, INPUT_PULLUP); //przycisk 1
  pinMode(przycisk2, INPUT_PULLUP); // przycisk 2

  Serial.begin(9600);
}

void loop()
{  
  
  if (digitalRead(przycisk1) == 0)
  {
    stanPrzycisku1 = 1;
  }
  if (digitalRead(przycisk2) == 0)
  {
    stanPrzycisku2 = 1;
  }


    if (stanPrzycisku1 == 1)
    {
      ledsOn();    
    }
  
    if (stanPrzycisku2 == 1)
    {
      ledsOn();
    }
  if(stanPrzycisku1==0 and zmienna2 >= czasPodtrzymania){
    ledsOff();
  }
    
  }


void ledsOn(){
 newTime = millis();
  if (newTime - oldTime >= 200)
  {
    oldTime = newTime;
    zmiennaP1++;
    Serial.print("zmiennaP1 z ledsOn ");
    Serial.println(zmiennaP1);
  }
  switch (zmiennaP1) //dzięki temu że minęla 1sek możemy wybrać co się stanie
  {
  case 1: //jeśli minęły 1sek włączasz led1
    digitalWrite(led1, HIGH);
    break;
  case 2: //odliczasz kolejną 1sek i włączasz led2
    digitalWrite(led2, HIGH);
    break;
  case 3:
    digitalWrite(led3, HIGH); //itd
    break;
  case 4:
    digitalWrite(led4, HIGH);
    break;
  case 5:
    digitalWrite(led5, HIGH);
    break;
  case 6:
    digitalWrite(led6, HIGH);
    break;
  case 7:
    digitalWrite(led7, HIGH);
    
    break;
  case 8:
    czasCzekania(); //zamiast tego mozna zastosować delay jak pisałem wyżej.
    stanPrzycisku1 = 0;
    break;
  }
}

void ledsOff(){
newTime = millis();
  Serial.print("newTime z ledsOff ");
    Serial.println(newTime);
  if (newTime - oldTime >= 300)
  {
    oldTime = newTime;
    zmiennaP1++;
    Serial.print("wart zmiennaP1 z ledsOff ");
    Serial.println(zmiennaP1);
  }
  
  switch (zmiennaP1) //kontynuacja switchów z wcześniejszej części
  {
  case 9:
    digitalWrite(led1, LOW); //wyłączasz led1
    break;
  case 10: //wyłączasz led2
    digitalWrite(led2, LOW);
    break;
  case 11: //wyłaczasz led3
    digitalWrite(led3, LOW);
    break;
  case 12:
    digitalWrite(led4, LOW);
    break;
  case 13:
    digitalWrite(led5, LOW);
    break;
  case 14:
    digitalWrite(led6, LOW);
    break;
  case 15:
    digitalWrite(led7, LOW);
    stanPrzycisku2 = 0;
    zmiennaP1 = 0;
    zmienna2=0;
    break;
  }
}

void czasCzekania()
{    //jako że program nie jest wymagający to tutaj również można użyć delay'a bo i tak program jest wstrzymany
  do //cała ta pętla wstrzyma Ci cały program póki nie zostanie spełniony warunek za wyrażeniem while
  {
    odczytanaWartosc = analogRead(A0);                        //odczytujesz wartość z portu A0
    czasPodtrzymania = map(odczytanaWartosc, 0, 1023, 0, 10); //zamienia zmienną z przedziału od 0 do 1023 na zmienną od 0 do 10 (sekund)
    Serial.print("t podtrzym ");
    Serial.println(czasPodtrzymania);
    
    newTimePodtrzymania = millis();
    if (newTimePodtrzymania - oldTimePodtrzymania >= 200) // odliczaj po 1s
    {
      oldTimePodtrzymania = newTimePodtrzymania;
      zmienna2++; //co 1sek zwiększasz wartość zmiennej2
    Serial.print("zmienna2 akt. wart. ");
    Serial.println(zmienna2);
      
    }
  } while (zmienna2 <= czasPodtrzymania); //a pętla trwa póki zmienna2 nie osiągnie wartości zmapowanej zmiennej czasPodtrzymania
   //dodajemy 1 do zmienna2 żeby była większa niż czasPodtrzymania-potrzebne do warunku w loop na włączenie f ledsOff
 
}

 

Edytowano przez Wprost123

Udostępnij ten post


Link to post
Share on other sites

Ja cały czas myślałem że Ty tego nie symulujesz tylko testujesz na żywym organizmie. Ja nigdy nie testuję w symulatorze bo od testowania do realnego działania to daleko.
W takim przypadku to wy gonimy swój własny ogon. Symulator coś tam pokaże ale to nie to samo co nawet najprostsze zestawienie układu powiedzmy na płytce stykowej.

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Myślałem, że symulator pokaże to w miarę wiernie, z różnicą w czasie działania , ale że kolejność i reakcja na przyciski będzie "prawdziwa".  W przyszłym tygodniu będę już próbował na rzeczywistym Arduino.  Tymczasem, będę próbował zrealizować wspomniane wyżej funkcje, dla sytuacji gdy kolejna osoba wchodzi na schody i naciska przycisk.

Jak narazie bez skutków. Nie wiem, jak odpowiednio "obwarunkować" tę sytuacje ponownego wciśnięcia przycisku. 

Edytowano przez Wprost123

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Dodałem taki kod w funkcji loop.

 
   if((stanPrzycisku1==1)&& (zmiennaP1>8)){  // Jeśli kolejne naciśnięcie przycisku, a czas podtrzym, jeszcze nie minął to rozświetl od początku
    zmiennaP1=0;
     zmienna2=0;
     ledsOn();
  }
  

Dzięki temu gdy program dojdzie już do rozpoczęcia wygaszania a będzie kolejne wciśniecie przycisku, to rozświetetlanie zacznie się od początku. 

Nie wiem jak zrobić, żeby sekwencja zaczęła się od początku gdy ktoś wciśnie przycisk w czasie gdy funkcja czasCzekania już się uruchomi. Warunek if((stanPrzycisku1==1)&& (zmiennaP1>7))   się nie sprawdza, bo gdy program wejdzie już do kejsa 8, to wykonuje się cała funkcja czasCzekania i taki warunek mi jej (funkcji czasCzekania) nie przerwie.

Chciałbym osiągnąć taką sytuację w programie:

1.jeśli jesteśmy w ledsOn-> jeśli naciśnięto przycisk-> zwiększ zmienną czasPodtrzymania np. o 5 ponad to, co zostanie odczytane z potencjometru

2.jeśli jesteśmy w czasCzekania-> jeśli naciśnięto przycisk-> zresetuj zliczoną do tej pory wartość zmienna2 do zera i zacznij liczyć ponownie

3.jeśli jesteśmy w ledsOff-> jeśli naciśnięto przycisk -> uruchom funkcję ledsOn, czyli rozświetlaj od nowa.

 

Punkt 1 i 2 chciałem zrealizować dodają dodając zmienną dodatkowePodtrzymanie, która na początku ma wartość 0 ale przyjmowała by wartość 5 w sytuacji gdy przycisk został naciśnięty kolejny raz. Dodałem w tym celu kolejny warunek w funkcji ledsOn tak, że jeśli zaświeciły się min 2 diody, i kolejny raz wciśnięto przycisk, to ta zmienna przyjmie wartość 5

zmieniłem też trochę funkcję czasCzekania dodając czasPodtrzymania=czasPodtrzymania+dodatkowePodtrzymanie;

 

 

// DODANY FRAGMENT W LEDSON
void ledsOn(){
   if((stanPrzycisku1==1)&&(digitalRead(przycisk1)==0)&&(zmiennaP1>2)&&(zmiennaP1<=7)){ // Jeśli jesteśmy w rozświetlaniu i zapaliły się więcej niż 2 diody to kolejne naciśnięcie przycisku zwiększa podtrzymanie o 5 
    dodatkowePodtrzymanie=5;
  }


//  ZMIANA W FUNCJI czasCzekania
  void czasCzekania()
{    
  do 
  {
    odczytanaWartosc = analogRead(A0);                        //odczytujesz wartość z portu A0
    czasPodtrzymania = map(odczytanaWartosc, 0, 1023, 0, 10); 

    czasPodtrzymania=czasPodtrzymania+dodatkowePodtrzymanie; // Jeśli kolejne naciśnięcie przycisku w czasie ledsOn, to zwiększ czasPodtrzymania
     
    newTimePodtrzymania = millis();
    if (newTimePodtrzymania - oldTimePodtrzymania >= 200) // odliczaj po 1s
    {
      oldTimePodtrzymania = newTimePodtrzymania;
      zmienna2++; //co 1sek zwiększasz wartość zmiennej2
    Serial.print("zmienna2 akt. wart. ");
    Serial.println(zmienna2);
      
    }
  } while (zmienna2 <= czasPodtrzymania); 
   
 
}

Po kilku pierwszych próbach okazało się nie działa dobrze 😞 Czasami gdy prog. jest w funkcji czasCzekania i nacisnę przycisk, to zmienna zmienna2 się nie resetuje.

Pytanie z czego może to wynikać? Czy naciskam przycisk w złym momencie- tzn. gdy program jest zajęty odliczaniem newTimePodtrzymania - oldTimePodtrzymania >= 200 ?? (tak na pewno byłoby gdyby to było na delay, ale tutaj jest na millis)  Czy może czymś innym? 

Edytowano przez Wprost123

Udostępnij ten post


Link to post
Share on other sites
12 godzin temu, Wprost123 napisał:

Jak narazie bez skutków. Nie wiem, jak odpowiednio "obwarunkować" tę sytuacje ponownego wciśnięcia przycisku. 

To co chcesz zrealizować to jedno z prostszych zadań. Dzisiaj mam wolne to złożę układ na stykówce i napiszę cały program.

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Próbowałem punkt 2 (gdy jesteśmy w f. czasCzekania)  zrobić z użyciem przerwania,  w ten sposób że naciśnięcie przycisku powoduje naliczenie  zmiennej ileRazy i gdy jest ona (zmienna ileRazy) większa od 1 wyzerowania zmiennej zmienna2

 

// w definiowaniu zmiennych
volatile int ileRazy = 0; //ilość naciśnięć przycisku 
attachInterrupt(digitalPinToInterrupt(przycisk1), resetZmienna2, FALLING); // Przerwanie reagujące na zbocze malejące
  
//Funkcja licząca nacisnięcia,  do resetowania zmiennej2
void resetZmienna2()
{
  ileRazy++;
  Serial.print("ile razy ");
  Serial.println(ileRazy);
}


void czasCzekania()
{    
  do 
  {
   
  
    
    odczytanaWartosc = analogRead(A0);                        //odczytujesz wartość z portu A0
    czasPodtrzymania = map(odczytanaWartosc, 0, 1023, 0, 10); //zamienia zmienną z przedziału od 0 do 1023 na zmienną od 0 do 10 (sekund)
  Serial.print("t podtrzym z potenc. ");
  Serial.println(czasPodtrzymania); 
    czasPodtrzymania=czasPodtrzymania+dodatkowePodtrzymanie;
   
    
    Serial.print("t podtrzym+ dodatk ");
    Serial.println(czasPodtrzymania);
    
  
    
    newTimePodtrzymania = millis();
    if (newTimePodtrzymania - oldTimePodtrzymania >= 800) // odliczaj po 1s
    {
      oldTimePodtrzymania = newTimePodtrzymania;
      zmienna2++; //co 1sek zwiększasz wartość zmiennej2
      
 //DODANY FRAGMENT  Jeśli razy nacisnięto przycisk. Jeśli więcej niż 1 to zresetuj zmienn2
      if(ileRazy>=1){  
      zmienna2=0;
      ileRazy=0;
    }
    
      
    Serial.print("ZMIENNA 2 akt. wart. ");
    Serial.println(zmienna2);
      
    }
  } while (zmienna2 <= czasPodtrzymania); //a pętla trwa póki zmienna2 nie osiągnie wartości zmapowanej zmiennej czasPodtrzymania
   
 
}

 

Gdyby Kolega wgrał na początek mój dotychczasowy program na Arduino i potestował jak to działa, to byłbym wdzięczny.😀 Ja będę mógł sprawdzać na rzeczywistym  Arduino dopiero w przyszłym tygodniu.

#define led1 4
#define led2 5
#define led3 6
#define led4 7
#define led5 8
#define led6 9
#define led7 10
#define przycisk1 2
#define przycisk2 3

unsigned long oldTime= 0; //zmienna starego czasu między rozświetlaniem diod
unsigned long newTime = 0;

  
unsigned long oldTimePodtrzymania = 0; //zmienna starego czasu podtrzymania świecenia
unsigned long newTimePodtrzymania = 0;

byte zmiennaP1 = 0; //zmienna dla przycisku 1 - ilość case-ów 
byte zmiennaP2 = 0; //zmienna dla przycisku 2- ilość case-ów

byte stanPrzycisku1 = 0; //0-puszczony, 1-wciśnięty
byte stanPrzycisku2 = 0;

int odczytanaWartosc = 0;
byte zmienna2 = 0; //zmienna ilosci seknud które mineły w podtrzymaniu
int czasPodtrzymania = 1; // NIE zero żeby warunek w loop if(stanPrzycisku1==0 and zmienna2 >= czasPodtrzymania Nie był od razu spełniony na starcie
int dodatkowePodtrzymanie=0; //zmienna zwiększająca odczytaną wart. czasPodtrzymania. Jeśli jesteśmy w ledsOn i naciśnięto przycisk to przedłuża czas podtrzym.

volatile int ileRazy = 0; //ilość naciśnięć przycisku 

void ledsOnDoGory();
void ledsOffNaDol();
void czasCzekania();

void setup()
{ 
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  pinMode(led7, OUTPUT);

  pinMode(przycisk1, INPUT_PULLUP); //przycisk 1
  pinMode(przycisk2, INPUT_PULLUP); // przycisk 2

attachInterrupt(digitalPinToInterrupt(przycisk1), resetZmienna2, FALLING); // Przerwanie reagujące na zbocze malejące
  
  
  Serial.begin(9600);
}

void loop()
{  
  
  
  if (digitalRead(przycisk1) == 0)
  {
    stanPrzycisku1 = 1;
  }
  if (digitalRead(przycisk2) == 0)
  {
    stanPrzycisku2 = 1;
  }


    if (stanPrzycisku1 == 1)
    {
      ledsOn();    
    }
  
    if (stanPrzycisku2 == 1)
    {
      ledsOn();
    }
  if(stanPrzycisku1==0 and zmienna2 >= czasPodtrzymania){  // wejście do f gaszenia
    ledsOff();
  }
  
   if((stanPrzycisku1==1)&& (zmiennaP1>8)){  // Jeśli kolejne naciśnięcie przycisku, a jesteśmy w gaszeniu to rozświetl od początku
    zmiennaP1=0;
    zmienna2=0;
     ledsOn();
  }
 
  }


void ledsOn(){
   if((stanPrzycisku1==1)&&(digitalRead(przycisk1)==0)&&(zmiennaP1>2)&&(zmiennaP1<=7)){ // Jeśli jesteśmy w rozświetlaniu i zapaliły się więcej niż 2 diody to kolejne naciśnięcie przycisku zwiększa podtrzymanie o 5 jedn
    dodatkowePodtrzymanie=3;
  }
  
 newTime = millis();
  if (newTime - oldTime >= 1000)
  {
    oldTime = newTime;
    zmiennaP1++;
    Serial.print("zmiennaP1 z ledsOn ");
    Serial.println(zmiennaP1);
  }
  switch (zmiennaP1) //dzięki temu że minęla 1sek możemy wybrać co się stanie
  {
  case 1: //jeśli minęły 1sek włączasz led1
    digitalWrite(led1, HIGH);
    break;
  case 2: //odliczasz kolejną 1sek i włączasz led2
    digitalWrite(led2, HIGH);
    break;
  case 3:
    digitalWrite(led3, HIGH); //itd
    break;
  case 4:
    digitalWrite(led4, HIGH);
    break;
  case 5:
    digitalWrite(led5, HIGH);
    break;
  case 6:
    digitalWrite(led6, HIGH);
    break;
  case 7:
    digitalWrite(led7, HIGH);
    
    break;
  case 8:
    czasCzekania(); //zamiast tego mozna zastosować delay jak pisałem wyżej.
    stanPrzycisku1 = 0;
    break;
  }
}

void ledsOff(){
newTime = millis();
  Serial.print("newTime z ledsOff ");
    Serial.println(newTime);
  if (newTime - oldTime >= 1000)
  {
    oldTime = newTime;
    zmiennaP1++;
    Serial.print("wart zmiennaP1 z ledsOff ");
    Serial.println(zmiennaP1);
  }
  
  switch (zmiennaP1) //kontynuacja switchów z wcześniejszej części
  {
  case 9:
    digitalWrite(led1, LOW); //wyłączasz led1
    break;
  case 10: //wyłączasz led2
    digitalWrite(led2, LOW);
    break;
  case 11: //wyłaczasz led3
    digitalWrite(led3, LOW);
    break;
  case 12:
    digitalWrite(led4, LOW);
    break;
  case 13:
    digitalWrite(led5, LOW);
    break;
  case 14:
    digitalWrite(led6, LOW);
    break;
  case 15:
    digitalWrite(led7, LOW);
    stanPrzycisku2 = 0;
    zmiennaP1 = 0;
    zmienna2=0;
    break;
  }
}

void czasCzekania()
{    //jako że program nie jest wymagający to tutaj również można użyć delay'a bo i tak program jest wstrzymany
  do //cała ta pętla wstrzyma Ci cały program póki nie zostanie spełniony warunek za wyrażeniem while
  {
   
  
    
    odczytanaWartosc = analogRead(A0);                        //odczytujesz wartość z portu A0
    czasPodtrzymania = map(odczytanaWartosc, 0, 1023, 0, 10); //zamienia zmienną z przedziału od 0 do 1023 na zmienną od 0 do 10 (sekund)
  Serial.print("t podtrzym z potenc. ");
  Serial.println(czasPodtrzymania); 
    czasPodtrzymania=czasPodtrzymania+dodatkowePodtrzymanie;
   
    
    Serial.print("t podtrzym+ dodatk ");
    Serial.println(czasPodtrzymania);
    
  
    
    newTimePodtrzymania = millis();
    if (newTimePodtrzymania - oldTimePodtrzymania >= 1000) // odliczaj po 1s
    {
      oldTimePodtrzymania = newTimePodtrzymania;
      zmienna2++; //co 1sek zwiększasz wartość zmiennej2
 
      if(ileRazy>=1){  //Jeśli naciśnięto  kolejny raz przycisk to reset zmienna2
      zmienna2=0;
      ileRazy=0;
    }
    
      
    Serial.print("ZMIENNA 2 akt. wart. ");
    Serial.println(zmienna2);
      
    }
  } while (zmienna2 <= czasPodtrzymania); //a pętla trwa póki zmienna2 nie osiągnie wartości zmapowanej zmiennej czasPodtrzymania
   
 
}

void resetZmienna2()
{
  ileRazy++;
  Serial.print("ile razy ");
  Serial.println(ileRazy);
}
  

 

Edytowano przez Wprost123

Udostępnij ten post


Link to post
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...