Skocz do zawartości
Komentator

Kurs Arduino II - #9 - wielozadaniowość, opóźnienia z millis()

Pomocna odpowiedź

Prosiłbym o poradę co dalej. Skończyłem pierwszy poziom elektroniki i oba poziomy arduino. Chciałbym spróbować z Raspberry, ale zastanawiam sie czy nie lepiej bedzie bardziej najpierw rozwinąć umiejętności związane z arduino lub elektronika bądź zacząć naukę lutowania?  Byłbym wdzięczny za każda pomoc.

Udostępnij ten post


Link to post
Share on other sites

@Madaulpe, witam na forum 😉 Widzę, że to Twoje pierwsze kroki na Forbocie, oto najważniejsze informacje na start:

  • Chcesz przywitać się z innymi członkami naszej społeczności? Skorzystaj z tematu powitania użytkowników.
  • Opis najciekawszych funkcji, które ułatwiają korzystanie z forum znajdziesz w temacie instrukcja korzystania z forum - co warto wiedzieć?
  • Poszczególne posty możesz oceniać (pozytywnie i negatywnie) za pomocą reakcji - ikona serca w prawym dolnym rogu każdej wiadomości.
Dnia 23.11.2018 o 13:03, Madaulpe napisał:

Poradziłem sobie z tym pisząc drugą funkcje która różni się tymi parametrami i wszystko działa. Nie chcę jednak tworzyć nowych funkcji dla każdej następnej diody. Próbuję zastosować tablice ale nie bardzo mi to wychodzi i już trochę zwątpiłem czy idę w odpowiednim kierunku.

To dość zawiły temat, bo nie ma uniwersalnej metody, aby delay zamienić elegancko jedną funkcją na millis. Oczywiście można się pokusić o szukanie jakiegoś sztucznego rozwiązania, które świetnie sprawdzi się w tym przypadku, ale to jest program typowo edukacyjny, który "tylko" miga diodami. W praktyce programy tak nie wyglądają i wtedy użyteczność wypracowywanej tutaj (uniwersalnej) metody może okazać się mało użyteczna. Na szczęście korzystamy z Arduino, a jak wiadomo do tej platformy znaleźć można biblioteki od wszystkiego. To tylko przykładowe biblioteki, które mogą być pomocne przy tworzeniu programów z opóźnieniami. Sprawdź, czy któraś będzie pomocna w Twoim przypadku:

4 godziny temu, D3binski napisał:

 @Treker, ogromne podziękowania i ukłony w Twoją stronę. Świetnie się bawiłem już od pierwszego poziomu kursu.

@D3binski, dziękuję miło słyszeć, że kursy są pomocne 😉

47 minut temu, D3binski napisał:

Prosiłbym o poradę co dalej. Skończyłem pierwszy poziom elektroniki i oba poziomy arduino. Chciałbym spróbować z Raspberry, ale zastanawiam sie czy nie lepiej bedzie bardziej najpierw rozwinąć umiejętności związane z arduino lub elektronika bądź zacząć naukę lutowania?  Byłbym wdzięczny za każda pomoc.

Możliwości masz wiele 😉 Jeśli wciągnąłeś się w temat to polecałbym kurs elektroniki poziom II i kurs lutowania, bo te tematy są znacznie ciekawsze od kursu elektroniki poziom I, który masz już za sobą. Podczas drugiego poziomu kursu elektroniki jest omówione sporo tematów, które są przydatne przy Arduino. Jeśli chcesz iść dalej w kierunku programowania Arduino to masz jeszcze trzeci kurs z tej serii (dotyczący budowy robotów). Zawsze fajnie jest zbudować coś co może jeździć po biurku 😉 Kurs Raspberry Pi jest według mnie "niezależny" od tych, które tu wspomniałem i możesz śmiało przeplatać te tematy.

PS akurat do jutra (poniedziałek, 26.11.2018) włącznie trwa promocja, w której m.in. taniej można zamówić zestaw do kursu budowy robotów i kursu Raspberry Pi. Może z czegoś skorzystasz: Rabaty na zestawy do kursów elektroniki, Arduino oraz RPi

Udostępnij ten post


Link to post
Share on other sites

Udało mi się uzyskać to o czym myślałem. Wszystko działa. Czy można w tym jeszcze coś poprawić?

unsigned long curren_T = 0;
unsigned long prv_T[2];
int stanLED[2];

void setup() {}

void loop() {
  curren_T = millis();
  LED_BLINK (50, 500, 2, 0); //czas LED OFF / czas LED ON / pin /nr komórki
  LED_BLINK (500, 500, 3, 1); //czas LED OFF / czas LED ON / pin /nr komórki
}

//------------------  FUNKCJA 1  -----------------------
void LED_BLINK(unsigned long interval, unsigned long blink_T, int pin, int n) {
  pinMode(pin, OUTPUT);

  if (stanLED[n] == LOW) {
    if (curren_T - prv_T[n] >= interval) {
      stanLED[n] = HIGH;
      digitalWrite(pin, stanLED[n]);
      prv_T[n] = curren_T;
    }
  }
  else {
    if (curren_T - prv_T[n] >= blink_T) {
      stanLED[n] = LOW;
      digitalWrite(pin, stanLED[n]);
      prv_T[n] = curren_T;
    }
  }
}

 

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

@Madaulpe, ciekawe rozwiązanie 🙂 Może warto dodać jeszcze stałą (lub definicję), która będzie określała liczbę LEDów? Będziesz mógł wykorzystać tę informację przy deklaracji tablic.

Udostępnij ten post


Link to post
Share on other sites

@konik960, witam na forum 😉 Widzę, że to Twoje pierwsze kroki na Forbocie, oto najważniejsze informacje na start:

  • Chcesz przywitać się z innymi członkami naszej społeczności? Skorzystaj z tematu powitania użytkowników.
  • Opis najciekawszych funkcji, które ułatwiają korzystanie z forum znajdziesz w temacie instrukcja korzystania z forum - co warto wiedzieć?
  • Poszczególne posty możesz oceniać (pozytywnie i negatywnie) za pomocą reakcji - ikona serca w prawym dolnym rogu każdej wiadomości.

14 godzin temu, konik960 napisał:

Super lekcja, dziękuję za pomoc w zrozumieniu.

Dziękuję za miłe słowa, cieszę się, że kurs jest pomocny 🙂 Przy okazji gratuluję ostatniego posta napisanego na Forbocie w 2018 roku 🎆

Udostępnij ten post


Link to post
Share on other sites

FORBOT jest kopalnią wiedzy! Co równie istotne artykuły i kursy są komplementarne z merytorycznymi, inteligentnymi dyskusjami. Do tego kursu obowiązkowo powinna być podlinkowana ta:

 Słowa uznania dla WSZYSTKICH jej uczestników, powiem tylko że czytałem/analizowałem kody i uczyłem się może wolniej niż SOYER ale też z frajdą. THX.

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites
4 godziny temu, wmaker napisał:

FORBOT jest kopalnią wiedzy! Co równie istotne artykuły i kursy są komplementarne z merytorycznymi, inteligentnymi dyskusjami.

Bardzo milo słyszeć, cieszę się, że kursy są pomocne 🙂

Udostępnij ten post


Link to post
Share on other sites

Witam czy jest ktoś w stanie mi wytłumaczyć w jaki sposób przerobić program z tej części tak aby migać jedną diodą tylko dwoma różnymi czasami przykładowo załączyć na sekundę i wyłączyć na dwie

Udostępnij ten post


Link to post
Share on other sites

@Bolto witam na forum!

8 godzin temu, Bolto napisał:

Witam czy jest ktoś w stanie mi wytłumaczyć w jaki sposób przerobić program z tej części tak aby migać jedną diodą tylko dwoma różnymi czasami przykładowo załączyć na sekundę i wyłączyć na dwie

Pewnie - chętnie pomożemy 😉 Pokaż jakieś swoje próby to nakierujemy Cie na poprawne rozwiązanie tego problemu.

Udostępnij ten post


Link to post
Share on other sites
#define LED1 3


int stanLED1 = LOW;
int stanLED2 = HIGH;

unsigned long aktualnyCzas = 0;
unsigned long zapamietanyCzasLED1 = 0;
unsigned long zapamietanyCzasLED2 = 0;

void setup(){
  Serial.begin(9600);
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
}

void loop(){
 
  aktualnyCzas = millis();    //Pobierz liczbe milisekund od startu
  
  if (aktualnyCzas - zapamietanyCzasLED1 >= 1000UL) {    //Jeśli różnica wynosi ponad 1 sekund
    zapamietanyCzasLED1 = aktualnyCzas;    //Zapamietaj aktualny czas
    stanLED1 = !stanLED1;      //Zmieniamy stan diody na przeciwny
    digitalWrite(LED1, stanLED1);    //ustawiamy nowy stan na diodzie
  }
  else if (aktualnyCzas - zapamietanyCzasLED2 >= 3000UL) {   //Jeśli różnica wynosi ponad 0,5 sekundy
    zapamietanyCzasLED2 = aktualnyCzas;   //Zapamietaj aktualny czas
    stanLED2 = !stanLED2;              //Zmieniamy stan diody na przeciwny
    digitalWrite(LED1, stanLED2);          //ustawiamy nowy stan na diodzie
  }
}

Tak to się prezentuje niestety obawiam się że słabo opanowałem materiał z tej części i zrobiłem straszną głupotę więc proszę o wyrozumiałość  z góry dziękuję i pozdrawiam.

Udostępnij ten post


Link to post
Share on other sites

Masz dwie drogi:

  1. Możesz mieć dwa warunki, które będą wyzwalane co określony (różny) czas: jeden będzie włączał, a drugi będzie wyłączał diodę.
  2. Możesz też mieć jeden warunek wyzwalany co sekundę oraz dodatkową zmienną, która będzie pamiętała ile czasu minęło. Jeśli zmienna będzie miała wartość 1 lub 2 to znaczy, że dioda ma być włączona, jeśli wartość zmiennej będzie wynosiła 3 to gasimy diodę i zerujemy zmienną (tak w dużym uproszczeniu).

Jak rozumiem to w tej chwili próbujesz pójść w kierunku pierwszej z metod? Jeśli jeden warunek ma zawsze włączać, a drugi ma zawsze wyłączać diodę to zastanów się czy ta negacja i zapamiętywanie stanów jest Ci w ogóle potrzebne 😉

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

 

#define LED1 A3
unsigned long aktualnyCzas=0;
unsigned long zapamietanyCzasLED1=0;
unsigned long zapamietanyCzasLED2=0;
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4); 
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 13
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
int swiatlo=0;
int podswietlenie=0;
int wilg=0;
int wilgproc=0;
void setup() {
lcd.init();
lcd.init();
lcd.backlight();
Serial.begin(9600);
pinMode(A3, OUTPUT);
lcd.clear();
} 
  

void loop() {
  sensors.requestTemperatures();
wilg=analogRead(A6);
wilgproc = map(wilg,105,545,100,0);
swiatlo=analogRead(A0);
lcd.setCursor(2,0);
lcd.print("Wilgotnosc Gleby:");
lcd.setCursor(9,1);
lcd.print(wilgproc);
lcd.setCursor(12,1);
lcd.print("%");
lcd.setCursor(0,2);
lcd.print("Temperatura Pokoju:");
lcd.setCursor(6,3);
lcd.print(sensors.getTempCByIndex(0),1);
lcd.setCursor(10,3);
lcd.print("st.C");

delay(1000);

if (swiatlo < 4) { 
lcd.noBacklight();   
} else {   
lcd.backlight();   
}
  aktualnyCzas = millis();
 if(wilgproc <= 30){ 

 if (aktualnyCzas - zapamietanyCzasLED1 >= 30000UL) {
    zapamietanyCzasLED1 = aktualnyCzas;
  digitalWrite(LED1, HIGH);
 } else if(aktualnyCzas - zapamietanyCzasLED2 >= 10000UL) {
       zapamietanyCzasLED2 = aktualnyCzas;
       digitalWrite(LED1, LOW);
  
 }


  
  }
  }

Napisałem coś takiego działa to tak że po 30 sekundach od włączenia programu( jeśli warunek jest spełniony) załącza się zasilanie na sekundę a ja chciałbym żeby po spełnieniu warunku wilgproc <=30 załączyła się dioda na 30 sekund i była wyłączona przez 10 pytanie brzmi co robię nie tak

Edytowano przez Bolto

Udostępnij ten post


Link to post
Share on other sites

@Bolto mam wrażenie, że trochę sobie tutaj namieszałeś (łącząc za dużo rzeczy i błędnym formatowaniem kodu). Zacznij może od samego programu, który miga diodą zgodnie z założonym schematem i później dodaj dopiero pozostałe warunki - tak będzie łatwiej. Zerknij też na program z tego poradnika: https://www.baldengineer.com/millis-ind-on-off-times.html Jest tam bardzo fajna implementacja migania diodą z różnymi czasami stanów on/off.

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!

Gość
Napisz odpowiedź...

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