Skocz do zawartości
Wprost123

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

Pomocna odpowiedź

Pierwsza sprawa to niewykorzystanych case w środku nie piszesz bo nie musisz jeśli nic nie robią, najzwyczajniej je pomijasz.
Druga sprawa to owszem, żeby to wszystko miało ręce i nogi czyli było zrobione jak przysłowiowa książka pisze to faktycznie, należało by użyć pięciu czujników jak wyżej opisał kolega szymonw, chociaż nie do końca tak musi być bo wyobraź sobie sytuację że wchodzisz od którejś strony na schody czyli aktywujesz któryś czujnik to raczej nie wrócisz a pójdziesz do końca schodów tak więc wedle tej teorii powinieneś aktywować ten drugi czujnik. Więc można zastosować tylko dwie bariery podczerwieni plus czujnik zmierzchu.

Druga sprawa, po co w ten sposób robisz sobie pod górkę ?
 

if(digitalRead(2)==LOW)                        //jeśli wciśnięty przycisk 1 to
{stanPrzycisku1=1;
}
 
  if(stanPrzycisku1==1){ 
    newTime = millis();                    //do zmiennej newTime wpisujesz czas z millis
    if (newTime - oldTime >= 300)

Napisz od razu:

if(digitalRead(2)==LOW)                        //jeśli wciśnięty przycisk 1 to
{newTime = millis();                    //do zmiennej newTime wpisujesz czas z millis
 if (newTime - oldTime >= 300)

Nie są Ci potrzebne linie z poleceniami stanPrzycisku = 1; oraz if (stanPrzycisku == 1). Jeżeli potrzebny Ci dalej ten stanPrzycisku = 1; to wpisz to sobie zaraz po wejściu do warunku if (digitalRead(2) == LOW)

Teraz żeby nie było za łatwo to nie podam Ci wszystkiego na tacy bo się niczego nie nauczysz. Podpowiem że aby ustawić czas pomiędzy świeceniem a rozpoczęciem wygaszania to robisz sobie dwa switche. w poniższy sposób:

void cosTam()
{
  byte zmienna = 0;
  unsigned long oldTime;
  unsigned long newTime;
  long czas = 0;

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

  switch (zmienna)
  {
  case 1: //włączasz led1
    break;
  case 2: //włączasz led2
    break;
  case 3: //włączasz led3 itd
    break;
  }

  byte zmienna2 = 0;
  do                                              //cała ta pętla wstrzyma Ci cały program póki nie zostanie spełniony warunek za wyrażeniem while
  {                                               //ale wstrzymuje inteligentnie i tylko raz po uruchomieniu czujki
    long zmiennaOdczytana = digitalRead(A0);      //odczytujesz wartość z portu A0
    czas = map(zmiennaOdczytana, 0, 1023, 0, 10); //zamienia zmienną z przedziału od 0 do 1023 na zmienną od 0 do 10 (sekund)
    newTime = millis();
    if (newTime - oldTime >= 1000) //znowu odliczasz sobie 1sek
    {
      oldTime = newTime;
      zmienna2++; //co 1sek zwiększasz wartość zmiennej 2
    }
  } while (zmienna2 < czas); //a pętla trwa póki zmienna2 nie osiągnie wartości zmapowanej zmiennej czas
  
  switch (zmienna)
  {
  case 4: //wyłączasz led1
    break;
  case 5: //wyłączasz led2
    break;
  case 6: //wyłaczasz led3
    break;
  }
}

 

Tak naprawdę jest to tylko i wyłącznie przykład z racji iż cały ten fragment kodu jest napisany w pewien sposób źle. Nie bierze pod uwagę żadnego zerowania zmiennych, sprawdzania czasów itp. Jest to tylko przykład pokazania jak można stosować switch...case.

Nad pętlą for pomyślę innym razem.

6 minut temu, Wprost123 napisał:

Proszę o podpowiedź co zepsułem, że teraz po naciśnięciu przycisku 1 (lub 2) rozświetla mi się tylko pierwsza dioda. Żeby zapaliła się kolejna, to muszę kolejny raz nacisnąć przycisk.

Mówiłem że to co piszę jest tylko przykładem. Nie będzie działać poprawnie ponieważ zadziała tylko raz. Jeśli będziesz trzymał przycisk cały czas to będą rozświetlać się kolejne diody. Pomyśl dlaczego ?

Udostępnij ten post


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

Druga sprawa, po co w ten sposób robisz sobie pod górkę ?
 


if(digitalRead(2)==LOW)                        //jeśli wciśnięty przycisk 1 to
{stanPrzycisku1=1;
}
 
  if(stanPrzycisku1==1){ 
    newTime = millis();                    //do zmiennej newTime wpisujesz czas z millis
    if (newTime - oldTime >= 300)

Napisałem tak, ponieważ przycisk naciskam tylko na chwilę, więc warunek (2)=LOW szybko przestanie być prawdziwy i wystarczy na rozświetlenie jednej diody. Gdy zapiszę to jako stan przycisku, to będzie on trzymany aż do końca sekwencji rozświetlania.  Gdy "zmiennaP1" osiągnie maksymalną wartość, czyli przejdą wszystkie kroki, to wtedy zeruję wartość przycisku. 

if(zmiennaP1 < iloscKrokow)            //jeśli zmienna mniejsza niż zakładana ilość krooków to
        {
          zmiennaP1++;                    //można zwiększyć wartość zmiennej -    
        }else
        {
          zmiennaP1 = 0;                    //jeśli "zmienna" zwiększy swoją wartość powyżej ilości kroków to wyzeruj + Wyzeruj zapamiętany stan przycisku
             stanPrzycisku1=0;

 

Udostępnij ten post


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

Napisałem tak, ponieważ przycisk naciskam tylko na chwilę, więc warunek (2)=LOW szybko przestanie być prawdziwy i wystarczy na rozświetlenie jednej diody. Gdy zapiszę to jako stan przycisku, to będzie on trzymany aż do końca sekwencji rozświetlania.  Gdy "zmiennaP1" osiągnie maksymalną wartość, czyli przejdą wszystkie kroki, to wtedy zeruję wartość przycisku.

Takie rzeczy można zrobić inaczej, ale co kto woli. Jeśli będzie Ci działać to możesz robić jak chcesz. Nikt nie będzie Ci narzucał jak pisać swoje programy. Ważne by działały zgodnie z tym co sobie założyłeś. Dobrej praktyki nabędziesz z czasem.

Co do pętli for.. masz poniżej. Mniej więcej widział bym to tak. Kompilator nie zgłasza żadnego błędu więc stylistycznie raczej jest ok.

void cosTam()
{
  unsigned long oldTime1;
  unsigned long newTime1;
  byte zmienna1 = 0;
  byte liczbaDiod = 7;
  for (int i = 0; i < liczbaDiod; i = i)
  {
    newTime = millis();
    if (newTime1 - oldTime1 >= 1000)
    {
      oldTime = newTime;
      zmienna1++;
      i++;
    }

    switch (zmienna)
    {
    case 1:
      break;
    case 2:
      break;
    }

    byte zmienna2 = 0;
    long wartosc = digitalRead(A0);
    byte czas;
    czas = map(wartosc, 0, 1023, 0, 10);
    do
    {
      newTime = millis();
      if (newTime1 - oldTime1 >= 1000)
      {
        oldTime = newTime;
        zmienna2++;
      }
    } while (zmienna2 < czas);

    switch (zmienna)
    {
    case 3:
      break;
    case 4:
      break;
    }
  }
}

 

Nie wiem tylko jak zadziała fragment:

for (int i = 0; i < liczbaDiod; i = i)

ponieważ jak pisałem wyżej, kompilator nie zgłasza błędu w tym przypadku, ale to nie jest prawidłowe sformułowanie warunku for. Prawidłowe wygląda tak:

for (int i = 0; i < liczbaDiod; i++)

Ale ta prawidłowa pętla for wykona się w mgnieniu oka a ja chciałem dodać możliwość zwiększania wartości zmiennej "i" co 1sek, więc do zmiennej "i" wpisuję wartość "i" a samą zmienną "i" zwiększam w warunku co sekundę.

 

Jeszcze raz na koniec napiszę. Cały mój kod niekoniecznie musi działać a wręcz prawdopodobnie nie będzie działał prawidłowo bo pisanie kodu bez sprawdzania to nie pisanie. Trzeba co jakiś czas kod przetestować. W teorii działa jak trzeba bo kompilator nie zgłasza problemów a jak zgłasza to piszę tak by nie zgłaszał. Ale bez załadowania tego do procesora i bez sprawdzenia jak działa dany fragment na tzw żywym organizmie czyli w projekcie docelowym, lub chociaż w złożonym na jakieś płytce prototypowej to nie pisanie kodu.

 

Ja zawsze robię tak że myślę nad układem, projektuję taki układ w EasyEda, często wprowadzam do takiego układu poprawki przez nawet kilka tygodni (chyba że coś chcę mieć bardzo szybko). Jeżeli uznam że układ jest gotowy to myślę nad tym jak ma działać. Co ma się znaleźć w pętli głównej, co najczęściej się powtarza i gdzie z pętli mam się odwoływać. Program dzielę na funkcje i testuję fragment po fragmencie, nigdy całość. Jeśli każdy fragment z osobna będzie mi działał prawidłowo to całość też zadziała jak trzeba.

 

Mała podpowiedź, jeżeli coś ma się wykonać wiele razy po zadziałaniu jakiegoś czynnika to trzeba takie coś zamknąć w jakiejś pętli.

Edytowano przez matrix0606

Udostępnij ten post


Link to post
Share on other sites

Dla sportu narysowałem program do podświetlania schodów.Program został stworzony w Realizerze a symulacja jest w załączniku .

Total used bits              : 67
Total used events            : 0
Total used unsigned bytes    : 6
Total used signed bytes      : 0
Total used unsigned integers : 4
Total used signed integers   : 0
Total used longs             : 0


Memory overview:
----------------------------------------------------------------------

Total used RAM               : 27 byte (0080H,0087H->00A0H)
Total used ROM               : 1045 byte (E000H->E414H) of FFDFH

-----------------------------------------------------------------

Best case loop time  : 141 usec
Worst case loop time : 171 usec

 

bandicam 2020-10-27 18-33-21-592.rar

Udostępnij ten post


Link to post
Share on other sites

@matrix0606 Zrobiłem tak ja poniżej. Niestety po uruchomieniu programu i naciśnięciu przycisku zapala się tylko jedna dioda i cały czas w kółko wyświetla mi się linijka z ustawionym czasem podtrzymania (dodałem sobie taki Serial.print, żeby widzieć gdzie jest program). Proszę o podpowiedź co zrobiłem źle. 

Myślę, że błąd jest w tym, jak wstawiłem kod odpowiedzialny za podtrzymanie świecenia, ale nie potrafię tego poprawić i program zamiast liczyć kolejne odstępy czasu do zapalania diod, to od razu przeskakuje do pętli  z while. Dopiero gdy pętla while się przepełni- tzn. zmienna2 osiągnie np. wartość 5 (jak na potencjometrze) to program zaczyna rozświetlać diody, a powinien to robić na początku, po wciśnięciu przycisku.

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

  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 setup(){
pinMode(led1,OUTPUT);
pinMode(led2,OUTPUT);
pinMode(led3,OUTPUT);
pinMode(led4,OUTPUT);
pinMode(led5,OUTPUT);
pinMode(led6,OUTPUT);
pinMode(led7,OUTPUT);
  
pinMode(2,INPUT_PULLUP); //przycisk 1
pinMode(3,INPUT_PULLUP); // przycisk 2
   
Serial.begin(9600);

}

void loop()
{
				
if(digitalRead(2)==LOW)						//jeśli odczytany stan czujki = 0 to
{stanPrzycisku1=1;
}
 
  if(stanPrzycisku1==1){ 
    newTime = millis();					//do zmiennej newTime wpisujesz czas z millis
    if (newTime - oldTime >= 300)		//jeśli nowy czas - stary czas jest >= 1000 czyli mniej więcej 1sek to
    {
      oldTime = newTime;				//stary czas = nowy czas
      Serial.print("nowy czas ");
      Serial.println(oldTime);
      
		if(zmiennaP1 < iloscKrokow)			//jeśli zmienna mniejsza niż zakładana ilość kroków to
        {
          zmiennaP1++;					//można zwiększyć wartość zmiennaP1
      Serial.print("zmienna P1 ");
      Serial.println(zmiennaP1);
        
        
        }else
        {
          zmiennaP1 = 0;					//jeśli "zmiennaP1" zwiększy swoją wartość powyżej ilości kroków to wyzeruj jej wartość
       	  stanPrzycisku1=0;
        }
      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;
      }
      
     
  do                                              //cała ta pętla wstrzyma Ci cały program póki nie zostanie spełniony warunek za wyrażeniem while
  {                                               //ale wstrzymuje inteligentnie i tylko raz po uruchomieniu czujki
    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();
    Serial.print("t podtrzym ");
    Serial.println(czasPodtrzymania);
    if (newTimePodtrzymania - oldTimePodtrzymania >= 1000) // oidliczaj po 1s
    {
      oldTimePodtrzymania = newTimePodtrzymania;
      zmienna2++; //co 1sek zwiększasz wartość zmiennej2
    Serial.print("zmienna2 ");
    Serial.println(zmienna2);
    
    }
  } while (zmienna2 < czasPodtrzymania); //a pętla trwa póki zmienna2 nie osiągnie wartości zmapowanej zmiennej czasPodtrzymania
    
  switch (zmiennaP1)  //kontynuacja switchów z wcześniejszej części
  {
  case 8:
   digitalWrite(led1, LOW); //wyłączasz led1
    break;
  case 5: //wyłączasz led2
    digitalWrite(led2, LOW);
    break;
  case 6: //wyłaczasz led3
   digitalWrite(led3, LOW);
    break;
  
  
     }
    }
  }
}
  

 

Udostępnij ten post


Link to post
Share on other sites

Ciężko się rozkminia Twój kod bo wszystko jest w jednym ciągu.
Poniżej podzieliłem kod na pętlę główną, i trzy funkcje. Funkcja ledsOn która zapala diody, funkcja ledsOff która je gasi i funkcja czasCzekania którą na razie się nie zajmuj.
W pętlę główną wpisz swój kod który będzie reagował na przyciski, resztę pomogę Ci dopisać.

 

#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()
{
}

void ledsOn()
{
  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;
  }
}

void ledsOff()
{
  switch (zmiennaP1) //kontynuacja switchów z wcześniejszej części
  {
  case 8:
    digitalWrite(led1, LOW); //wyłączasz led1
    break;
  case 5: //wyłączasz led2
    digitalWrite(led2, LOW);
    break;
  case 6: //wyłaczasz led3
    digitalWrite(led3, LOW);
    break;
  }
}

void czasCzekania()
{
  do                                                          //cała ta pętla wstrzyma Ci cały program póki nie zostanie spełniony warunek za wyrażeniem while
  {                                                           //ale wstrzymuje inteligentnie i tylko raz po uruchomieniu czujki
    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) // oidliczaj po 1s
    {
      oldTimePodtrzymania = newTimePodtrzymania;
      zmienna2++; //co 1sek zwiększasz wartość zmiennej2
      //Serial.print("zmienna2 ");
      //Serial.println(zmienna2);
    }
  } while (zmienna2 < czasPodtrzymania); //a pętla trwa póki zmienna2 nie osiągnie wartości zmapowanej zmiennej czasPodtrzymania
}

 

Udostępnij ten post


Link to post
Share on other sites

Kontroler użyty w moim projekcie to ST7flite39.O który kod Ci chodzi.Jeśli o plik źródłowy to musisz mieć program Realizer .Jeśli o plik wsadowy to S19 też nie ma problemu ,jeśli o ASM to też  nie ma problemu.Ale jeśli masz konwerter z ASM > C to sobie poradzisz.Najprościej jest zastosować ST7flite39,który kupisz w Kamami lub TME ale potrzebny jest programator!

Nowy folder.rar

Udostępnij ten post


Link to post
Share on other sites

Napiszę tak jak ja to widzę.
Tak jak wspomniał szymonw, zakładamy  że wchodzisz na piętro. Aktywujesz czujkę na parterze, więc ledy na schodach zapalają się od dołu. Ale gdy wchodzisz juz na piętro, aktywujesz czujkę na górze, przez co czas świecenia się resetuje i będą gasły od góry w dół, tak jakby ktoś schodził.
Można zablokować drugą czujkę po aktywowaniu pierwszej, ale co wtedy kiedy będziesz się mijać z kimś na chodach.

A co do samego kodu to trzeba go oprzeć na funkcji millis() i wydaje mi się ze wystarczy kilka instrukcji warunkowych if. Ale to jeszcze sam napisze kod i dam znać.

Udostępnij ten post


Link to post
Share on other sites

@szymonw 

12 godzin temu, szymonw napisał:

Ale jeśli masz konwerter z ASM > C to sobie poradzisz.Najprościej jest zastosować ST7flite39,który kupisz w Kamami lub TME ale potrzebny jest programator!

Nowy folder.rar 4 kB · 2 downloads

To dziękuję za poświęcony czas, ale jednak nie podziałam. Na początek z uwagi na to, że jestem zielony, skupię się na "prostszym" pisaniu pod Arduino. 

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Zrobiłem jak poniżej. Niestety coś jest źle, bo muszę naciskać kolejny raz przycisk żeby zapaliła się kolejna dioda.

#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 stanPrzycisku1=0;   //0-puszczony, 1-wciśnięty
  byte stanPrzycisku2=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 do case-ów
  byte zmiennaP2 = 0;  // zmienna dla przycisku 2 do case-ów
  byte stanDiod=0;  // 0- Wszystkie diody zgaszone 1- Wszystkie diody świecą

  void ledsOnZdoluDoGory();  //f. rozświetlająca diody Z dołu do góry
  void ledsOffZdoluDoGory(); // f. gasząca diody z dołu do góry

  void ledsOnZgoryDoDolu();  // f. rozświetlająca diody przy schodzeniu
  void ledsOffZgoruDoDolu(); // f. gasząca diody przy schodzeniu
  void czasCzekania();      // f. podtrzymania świecenia diod

  

  // zmienne dot. czasu podtrzymania świecenia
  int odczytanaWartosc=0;
  int zmienna2= 0;  //zmienna ilosci seknud które mineły w podtrzymaniu
  int czasPodtrzymania=0;




    
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)==LOW)&&(stanDiod==0)) //jeśli przycisk 1 wciśnięty i diody zgaszone  to uruchom funcję rozświetlania w GÓRĘ
{stanPrzycisku1=1;
 ledsOnZdoluDoGory();
}
 

}
 
 void ledsOnZdoluDoGory(){ 
 
  if(stanPrzycisku1==1){ 
    newTime = millis();					//do zmiennej newTime wpisujesz czas z millis
    if (newTime - oldTime >= 300)		//jeśli nowy czas - stary czas jest >= 1000 czyli mniej więcej 1sek to
    {
      oldTime = newTime;				//stary czas = nowy czas
      Serial.print("nowy czas ");
      Serial.println(oldTime);
      
		if(zmiennaP1 < iloscKrokow)			//jeśli zmienna mniejsza niż zakładana ilość diod to
        {
          zmiennaP1++;					//można zwiększyć wartość zmiennej - kawałek kodu odpowiadający za zwiększanie zmiennej "zmienna"
      Serial.print("zmienna P1 ");
      Serial.println(zmiennaP1);
        
        
        }else
        {
          zmiennaP1 = 0;			//jeśli "zmiennaP1" zwiększy swoją wartość powyżej ilości ktoków to wyzeruj jej wartość + wyzeruj stan przycisku 1
       	  stanPrzycisku1=0;
        }
      switch (zmiennaP1)					//dzięki temu że minęla 1sek możemy wybrać co się stanie
      {
      case 1:							//jeśli minęła 1 sek włączasz led1
        digitalWrite(led1, HIGH);
        break;
      case 2:							//odliczasz kolejne 2 sek 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);
        stanDiod=1;                    //Gdy wszystkie diody się zaświecą to stanDiod=1 (gdy zgasną =0)
        break;
      }
    }   
  }
 }
      
  

Nie wiem jak to zrobić, żeby do funkcji "ledsOnZdoluDogory" zapamiętane zostało to, że przycisk został wciśnięty.

Edytowano przez Wprost123

Udostępnij ten post


Link to post
Share on other sites
int ledState = HIGH;
int Sensor1 = 0;		//Stan sensora
int Loop = 0;
int Delay = 1000;		//Czas miedzy kolejnymi diodami
int Pin;
int OnLong = 10;		//Czas swiecenia wszystkich diod pomnozone przez Delay
unsigned long OldTime = 0;

void setup()
{
	pinMode(2, INPUT);
	pinMode(9, OUTPUT);
	pinMode(10, OUTPUT);
	pinMode(11, OUTPUT);
	pinMode(12, OUTPUT);
	pinMode(13, OUTPUT);
}

void loop()
{
	unsigned long NewTime = millis();
	Sensor1 = digitalRead(2);
  
  	if(Sensor1==HIGH)		//Aktywowanie czujki
  	{
  		Pin = 9;
    	Loop = 1;
    	ledState=HIGH;
    	do{}while(digitalRead(2)==HIGH);		//dopoki czujka ma stan wysoki nie zalaczy schodow (cos naprzyklad ja zaslania)
  	}
  
  	if((Loop==1) && (NewTime - OldTime >= Delay))
  	{
    	OldTime = NewTime;
    	if(Pin<14)
    	{
      		Serial.println(Pin);//TEST DZIALANIA
    		digitalWrite(Pin,ledState);
      		if(Pin==13 && ledState==LOW) Loop=0;
    	}
    
    if(Pin<=13+OnLong)Pin++;
    else if(ledState==HIGH)
    {
      	Pin=9;
      	if(ledState==HIGH)ledState=LOW;
    }
}
  

Jest to kod na bieganie po schodach tylko w górę.
Schodzenie już powinieneś dać radę zrobić sam analizując na bazie tego kodu.
Jeśli będziesz miał pytania to wal śmiało 🍻

Udostępnij ten post


Link to post
Share on other sites

Możesz spróbować też tak:

#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)
    {
      ledsOn();
    }
    if (stanPrzycisku2 == 1)
    {
      ledsOff();
    }
  }
}

void ledsOn()
{
  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()
{
  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;
    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
}

tylko to nie bierze pod uwagę tego co mówił kolega Paazak -> TYM POŚCIE <-

Udostępnij ten post


Link to post
Share on other sites

No tak jak pisałem, jest to fragment kodu dający efekt świetlny przy wchodzeniu przy każdym ruchu przy czujce na dole

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

@matrix0606 Dziękuję.

Zmieniłem trochę miejsce w którym było pobieranie i zapisywanie czasu newTime i OldTime, ponieważ z rozwiązaniu zaproponowanym przez Ciebie, zmiennaP1 rosła od razu po włączeniu programu i gdy nacisnąłem przycisk po jakimś czasie, to diody startowały np od trzeciej.

Pytanie, jak teraz zrobić wyjście z pętli while (gdy zmienna2 wzrośnie powyżej zmiennej czasPodtrzymania) z funkcji czasCzekania do funkcji ledsOff. Tak, jak to zapisałem to niestety nie działa.  Dochodzi tylko do "kejsa" 9" czyli gaśnie pierwsza dioda i dalej nic. 

 

#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;
  }


    if (stanPrzycisku1 == 1)
    {
      ledsOn();
    }
    if (stanPrzycisku2 == 1)
    {
      ledsOn();
    }
  }


void ledsOn(){
 newTime = millis();
  if (newTime - oldTime >= 300)
  {
    oldTime = newTime;
    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();
  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;
    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 >= 500) // 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
ledsOff();
zmienna2=0;
}

 

@Pazaak Dzięki, narazie chciałbym doprowadzić do dobrego działania rozwiązanie zaproponowane przez Kolegę matrix0606. Później będę pewnie próbował rozwinąć program tak, żeby działał na PIR-ach (czyli min dodanie sytuacji że ktoś idzie z dołu i trzeba górny PIR na chwilę zablokować, żeby on nie rozświetlił "po swojemu" czyli w dół i przede wszystkim dodawanie/ zwiększanie czasu podtrzymania gdy podczas sekwencji na schody wejdzie kolejna osoba)  a potem może spróbuję ugryźć temat w inny sposób, np. zaproponowany przez Ciebie. 

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