• 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
Problem z ir
#21
Masz w Arduino 20 pinów IO, są płytki gdzie masz >100, można napisać tyle funkcji dla tych płytek ile starcza wyobraźni, umiejętności, pamięci RAM i FLASH - taki problem tylko, wejdź na forbot, nettigo, jakiś kanał youtube, ksiażka, przerób kurs Arduino, naucz się millis.
Dopóki korzystasz z jednej funkcji urządzenia, czy jak to nazywasz masz wgrany jeden program, to można nie używać millis czy innych timerów programowych/sprzętowych, ale jak zadań do zrobienia jest więcej to trzeba zaplanować jak często każde trzeba wywołać, tak by każde miało szansę zadziałać zgodnie z oczekiwaniami.
Zresztą jest to proste, wystarczy nauczyć się, że nie zatrzymujesz programu, tylko pomijasz przez określony czas wykonywanie danych czynności. Do tego służą podstawowe polecenia C - if, else, <>=, dzielenie modulo.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#22
Ok jak pójdę na nocki do pracy to poczytam o tym millis a czy mógłbym mieć taką prośbę żeby ktoś dla wzoru, przykładu pokazał mi taki program żeby jednocześnie działały dwa czujniki ruchu hc-sr501 oraz żebym mial dwa wyjścia sterowane ir. Będę bardzo wdzięczny
 
Odpowiedź
#23
Np. tutaj masz millis ładnie opisane:
https://www.seeedstudio.com/blog/2021/05...rtos-more/
 
Odpowiedź
#24
Kod:
#define ledPin 13
#define ledPin1 12

volatile uint16_t timer1 =0;
volatile uint16_t timer2 =0;

void setupTimer1() {
  noInterrupts();
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1 = 0;
  OCR1A = 249;
  TCCR1B |= (1 << WGM12);
  TCCR1B |= (1 << CS11) | (1 << CS10);
  TIMSK1 |= (1 << OCIE1A);
  interrupts();
}

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(ledPin1, OUTPUT);
  setupTimer1();
}

void loop() {

  if(timer1 >=1000){
    timer1=0;
    digitalWrite(ledPin, digitalRead(ledPin) ^ 1);
   }

   if(timer2 >=500){
      timer2=0;
     digitalWrite(ledPin1, digitalRead(ledPin1) ^ 1);
   }
}

ISR(TIMER1_COMPA_vect) {
  timer1++;
  timer2++;
}
Od milllis lepsze są własne timery programowe,  Nie dość że  program bardziej przejrzysty to timer programowy można zresetować w dowolnym momencie.  Nie opłaca się uczyć millis lepiej iść w timery. Tym bardziej że w internecie są dostępne kalkulatory  wystarczy wpisać dane jakie chcemy a program sam nam skonfiguruje timera sprzętowego.

https://www.arduinoslovakia.eu/applicati...calculator

Program jest bardzo prosty
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#25
(24-02-2024, 20:57)Jarewa0606 napisał(a): Od milllis lepsze są własne timery programowe, 

Można je też wykorzystać bardziej wszechstronnie - mają wiele funkcji i można na jednym timerze zrealizować wiele funkcji np. OCR (generowanie przebiegów) i ICR (odbiór pilota) jednocześnie. Można też trzeba rozważyć czy w sumie to całe arduino jest jeszcze do czegoś potrzebne, bo zastąpienie np. funkcji GPIO (digitalWrite) przez obsługę bezpośrednio rejestrów jest jeszcze prostsze. Jeśli zostajemy pod kontrolą arduino to trzeba brać pod uwagę to, co jest napisale w opisie funkcji millis:

Cytat:
  • millis() is incremented (for 16 MHz AVR chips and some others) every 1.024 milliseconds, then incrementing by 2 (rather than 1) every 41 or 42 ticks, to pull it back into synch; thus some millis() values are skipped. For accurate timing over short intervals, consider using micros().
  • millis() will wrap around to 0 after about 49 days (micros in about 71 minutes).
  • Reconfiguration of the microcontroller’s timers may result in inaccurate millis() readings. The "Arduino AVR Boards" and "Arduino megaAVR Boards" cores use Timer0 to generate millis(). The "Arduino ARM (32-bits) Boards" and "Arduino SAMD (32-bits ARM Cortex-M0+) Boards" cores use the SysTick timer.
 
Odpowiedź
#26
Timery sprzętowe są OK, ale jest ich tylko 3, po to jest dane millis w Arduino, zresztą i w STM czy w ESP też jest gotowa biblioteka dająca taki tiker systemowy, to po to by go używać, a nie kombinować jak koń pod górę. Jak nic innego się nie planuje z nimi robić to OK. Millis zadziała jednak nie tylko na UNO, jak ktoś za chwilę oprócz zaświecenia światła będzie chciał mieć możliwość wysłania powiadomienia, że światło się zaświeciło to zmienia przez WIFI, to musi już zmienić te timery AVR na ESP, a to już nie jest takie proste. Z millis w ESP dodaje się tylko funkcje obsługi WIFI , wysłanie komunikatu, reszta zostaje bez zmian.
Millis to właśnie timer programowy, bazuje na sprzętowym 0. Jego dokładność jest w zupełności wystarczająca. Nie nadaje się by mierzyć nim wprost te okresy powyżej 54 dni, ale by odmierzać sekundy, podzielić ją na 100 części i porozkładać w czasie zadania jest w porządku. Nic się po 54 dniach złego nie dzieje, jeśli pamiętamy by operować na liczbach bez znaku, wtedy przechodzimy gładko przez tę granicę i zachowujemy ciągłość działania w czasie.
W takim programie gdzie masz dwa kody IR i dwa PIR millis w sumie nie jest potrzebne, przynajmniej dopóki nie będziesz miał jakiś konkretnych wymagań wobec programu. Prosty algorytm jest jednak kulawy i zmusza do machania rękami od czasu do czasu.
Typowa czujka ruchu ma dwa potencjometry, jednym ustawiasz czułość wykrywania ruchu, drugim długość aktywacji, możesz to wprost podłączyć do żarówki i masz świecenie przez określony czas po wykryciu ruchu, po czym wyłącza żarówkę i oczekuje na ruch, machniesz ręką to znowu załączy. Można to wprost przenieść do Arduino, wykrywa stan na pinie, to załącz, nie wykrywa to wyłącz. W programie można to jednak zrobić inaczej, potencjometr ustawiasz na minimum, potem np. jeśli słońce jest nad horyzontem, czyli od zmroku do świtu to jak wykryje ruch zignoruj, else ustaw timer świecenia na 10 minut. Program sobie działa dalej, w innej części kodu jeśli timer świecenia jest >0 to świec. W tym pierwszym ciągle wykrywa ruch, ale nic z tym nie rób, algorytm czeka aż przestanie i ponownie wykryje ruch, jeśli tak się stanie to mamy ponowne wykrycie ruchu i znowu ustawiamy timer na 10 minut, lub w prostej wersji po prostu ustawia 10 dopóki wykrywa impuls, wtedy czas świecenia jest liczony od końca impulsu z PIR..
Drugi code IR to w sumie prosto, dodajesz po prostu w switch case kolejny case.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
#27
Różnica też głównie jest taka że jest oszczędność pamięci. Np. w programie użyłem dwie zmienne 16bit przy millis musiał bym użyć 2 zmienne 32bit (a nawet mógł bym użyć zmiennej 8bit i ustawić timer co 100ms lub 10ms). To że timery użyłem do odliczania zmiennych wcale nie oznacza że nie mogą czegoś innego robić może generować PWM i jednocześnie obsługiwać timery programowe możliwości są spore.

A w uno nie ma za bardzo czym szastać z pamięcią kiedy programy są bardziej złożone.
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#28
To tak jak z delay, wszyscy wiedzą, że nie należy stosować w programie, po czym otwiera się przykład czegokolwiek napisane przez PRO programistę i w loop delay(1000). Wszystko zależy od kontekstu, czasami wystarczy UNO, delay jest OK, można wykorzystać millis, a czasami lepiej napisać program w assamblerze analizując każdy cykl zegara i bajt pamięci - co nie znaczy, że od tego trzeba zaczynać przygodę z Arduino, bo po to w szczególności zostało wymyślone, by użytkownika odsunąć od grzebania w rejestrach.
Miło być decenianym https://buycoffee.to/kaczakat
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości