KamilKolesnik Napisano Styczeń 20, 2022 Udostępnij Napisano Styczeń 20, 2022 (edytowany) Hej, To moje początki z Arduino więc z góry przepraszam jeżeli mój problem jest banalny. Chciałbym zbudować program który będzie liczyć ile razy np: w ciągu doby fotorezystor zostanie zasłonięty i prześle impuls np: do diody led Umiem napisać program który zaświeci diodą led podczas zasłonięcia fotorezystora. Chcę umieścić diodę led naprzeciwko fotorezystora, dioda będzie oświetlać fotorezystor. Chęć liczyć ile razy w ciągu danego czasu przejedzie przedmiot między diodą a fotorezystorem. Odległość między diodą a fotorezystorem będzie wykosić 3 - 5 cm Natomiast nie mam pojęcia jak zabrać się za napisanie części liczącej ilość zaciemnień fotorezystora Czy ktoś może coś podpowiedzieć? Będę wdzięczny za każdą podpowiedź Edytowano Styczeń 20, 2022 przez KamilKolesnik doprecyzowanie Cytuj Link do komentarza Share on other sites More sharing options...
H1M4W4R1 Styczeń 20, 2022 Udostępnij Styczeń 20, 2022 A nie lepiej zastosować diodę IR z odbiornikiem zamiast fotorezystora i LED? Ale to już moja fanaberia... By to zrobić najwygodniej jest puścić sygnał z fotorezystora (albo odbiornika IR) poprzez jakiś komparator porównujący w/w sygnał do wartości napięcia ustawianej potencjometrem, który w określonym momencie zmieni stan na wysoki / niski (jak przedmiot będzie nad diodą) i na przeciwny jak go nie będzie. Wtedy sprowadza się to do porównania stanu logicznego 😉 Podobnie jak jest zrobiony ten moduł: https://sklep.avt.pl/czujnik-odbiciowy-ir-detektor-przeszkod-na-lm393-arduino.html Ale zwykle mam tendencję do komplikowania prostych rzeczy. Równie dobrze możesz to zrobić na ADC (sprawdzasz jaką wartość odczytuje ADC z dzielnika napięcia fotorezystor + rezystor kiedy jest przeszkoda i kiedy jej nie ma, a potem robisz ifa w programie 😉) Cytuj Link do komentarza Share on other sites More sharing options...
StefanekP Styczeń 20, 2022 Udostępnij Styczeń 20, 2022 Ja bym zrobił trzy zmienne-jedną przechowującą obecną wartość odczytu z ADC, drugą wartość odczytu przed chwilą i trzecią, przechowującą liczbę zliczeń. Na początku każdego obiegu pętli aktualizujesz zmienną przechowującą aktualną wartość, a na końcu- tą, przechowującą poprzednią wartość. W momencie, kiedy różnica dwóch pierwszych zmiennych jest duża (natężenie światla się zmieni), dodajesz do wyniku 1. Przpraszam, jeśli coś namieszałem. Cytuj Link do komentarza Share on other sites More sharing options...
H1M4W4R1 Styczeń 21, 2022 Udostępnij Styczeń 21, 2022 (edytowany) 10 godzin temu, StefanekP napisał: W momencie, kiedy różnica dwóch pierwszych zmiennych jest duża (natężenie światla się zmieni) Takie określenie powodowałoby, że zliczenia występowałyby podwójnie, bo prowadzi do konkluzji, że if(abs(adc[1] - adc[0]) > treshold) count++; Więc zliczanie powinno następować w momencie, gdy napięcie znacząco spadnie, tylko musisz wziąć też pod uwagę kwestię, że napięcie może spadać przez dłuższą chwilę (przez pojemności na płytce), przez co częste odczyty mogą powodować błędy. Tak samo jak za rzadkie odczyty przy małych obiektach... Więc konkludując... #define ADC_PIN A0 #define TRESHOLD 127 int count; bool isObjectOverPhotoresistor; bool wasObjectOverPhotoresistor; void onObjectDetected() { count++; } void loop() { if(analogRead(ADC_PIN) > TRESHOLD) isObjectOverPhotoresistor = false; else isObjectOverPhotoresistor = true; if(wasObjectOverPhotoresistor != isObjectOverPhotoresistor) { if(isObjectOverPhotoresistor) onObjectDetected(); wasObjectOverPhotoresistor = isObjectOverPhotoresistor; } // Tutaj można dodać jakiś delay() } Jedyny problem jaki może wystąpić to efekt przycisku, dlatego przy dzielniku napięcia warto by zastosować jakiś mikroskopijny kondensator rzędu kilku - kilkunastu pikoF, chyba, że jest to płytka stykowa, wtedy można to pominąć 😉 Alternatywnie zamiast kondensatora delay na kilkanaście milisekund powinien dać radę skompensować błędy odczytu. Pisane na kolanie o 6 rano... Edytowano Styczeń 21, 2022 przez H1M4W4R1 1 Cytuj Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Produkcja i montaż PCB - wybierz sprawdzone PCBWay! • Darmowe płytki dla studentów i projektów non-profit • Tylko 5$ za 10 prototypów PCB w 24 godziny • Usługa projektowania PCB na zlecenie • Montaż PCB od 30$ + bezpłatna dostawa i szablony • Darmowe narzędzie do podglądu plików Gerber Zobacz również » Film z fabryki PCBWay
ethanak Styczeń 21, 2022 Udostępnij Styczeń 21, 2022 42 minuty temu, H1M4W4R1 napisał: częste odczyty mogą powodować błędy Dzisiejszy post sponsoruje słowo "histereza" 2 Cytuj Link do komentarza Share on other sites More sharing options...
KamilKolesnik Styczeń 21, 2022 Autor tematu Udostępnij Styczeń 21, 2022 Dziękuje bardzo za pomoc. Żeby było wiadomo o co dokładnie chodzi wstawiam foto mojego wstępnego układu Tutaj pierwotny kod: - oczywiście brakuje sekwencji liczącej - zaraz będę nad nią pracować int odczyt = 0; // Zmienna do przechowywania odczytu ADC void setup() { pinMode(8,OUTPUT); // kofiguracja wyjsc diody sygnalizujacej zakrycie fotorezystora // dioda na stałe oświetlająca fotorezystor pinMode(2, OUTPUT); // konf wyjscia digitalWrite(2, HIGH); // zawsze włączona } void loop() { // kod liczenia // kod do fotorezystora odczyt = analogRead(A5);//Odczyt wartosci z ADC if (odczyt < 100) { digitalWrite(8, HIGH); } else { digitalWrite(8, LOW); } delay(50); Cytuj Link do komentarza Share on other sites More sharing options...
StefanekP Styczeń 21, 2022 Udostępnij Styczeń 21, 2022 Myślę że może lepiej od fotorezystora sprawdziłby się czujnik przerwania wiązki IR. Tutaj jest do niego fajna instrukcja. Cytuj Link do komentarza Share on other sites More sharing options...
KamilKolesnik Styczeń 21, 2022 Autor tematu Udostępnij Styczeń 21, 2022 13 minut temu, StefanekP napisał: Myślę że może lepiej od fotorezystora sprawdziłby się czujnik przerwania wiązki IR. Tutaj jest do niego fajna instrukcja. Hej, Na pewno lepiej - został zamówiony i ma przyjść w przyszłym tygodniu. A na tą chwile musi mi wystarczyć to co mam w domu 😛 1 Cytuj Link do komentarza Share on other sites More sharing options...
KamilKolesnik Styczeń 21, 2022 Autor tematu Udostępnij Styczeń 21, 2022 Ok - uruchomiłem UART dodałem zmienną do liczenia ale zlicza nie tak jak bym chciał ;/ to znaczy liczy cały czas gdy fotorezystor jest zasłoniety a chciałbym aby liczyło zasłonięcie tylko raz Aktualny kod: int odczyt = 0; // Zmienna do przechowywania odczytu ADC int licznik = 0; // zmienna do liczenia void setup() { Serial.begin(9600); // inicjalizacja UART pinMode(8,OUTPUT); // kofiguracja wyjsc diody sygnalizujacej zakrycie fotorezystora // dioda na stałe oświetlająca fotorezystor pinMode(2, OUTPUT); // konf wyjscia digitalWrite(2, HIGH); // zawsze włączona } void loop() { // kod do fotorezystora odczyt = analogRead(A5);//Odczyt wartosci z ADC if (odczyt < 100) { digitalWrite(8, HIGH); // jezeli foto. zakryty zapal diode Serial.println(licznik); licznik = licznik + 1; // Chciałbym aby liczyło tylko 1 raz jedno zakrycie czujnika } else { digitalWrite(8, LOW); } delay(50); } problem jest w sformułowaniu: licznik = licznik + 1; ale jak to napisać aby tylko raz mi liczyło ;/ Cytuj Link do komentarza Share on other sites More sharing options...
H1M4W4R1 Styczeń 21, 2022 Udostępnij Styczeń 21, 2022 16 minut temu, KamilKolesnik napisał: problem jest w sformułowaniu: licznik = licznik + 1; ale jak to napisać aby tylko raz mi liczyło ;/ Problem jest w Twoim myśleniu 😉 Wróć do mojego wcześniejszego posta, a powinno się wyjaśnić czemu źle liczy. Cytuj Link do komentarza Share on other sites More sharing options...
ethanak Styczeń 21, 2022 Udostępnij Styczeń 21, 2022 (edytowany) 18 minut temu, KamilKolesnik napisał: problem jest w sformułowaniu Nie - problem jest w błędnym założeniu. Twój program reaguje na stan fotorezystora (zakryty/odkryty). A powinien zareagować na zdarzenie (fotorezystor właśnie został zakryty). Podpowiedź: "został zakryty" czyli jest zakryty, a przed chwilą nie był. (o tajemniczym słowie histereza porozmawiamy jak już to zrobisz) Edytowano Styczeń 21, 2022 przez ethanak Cytuj Link do komentarza Share on other sites More sharing options...
KamilKolesnik Styczeń 21, 2022 Autor tematu Udostępnij Styczeń 21, 2022 Przerobiłem kod po przeczytaniu kodu H1M4W4R1 i wyszło mi to: int StanSensora = 0; // Zmienna do przechowywania odczytu ADC int OstatniStan = 0; // zmienna przechowująca ostatni stan void setup() { Serial.begin(9600); // inicjalizacja UART pinMode(8,OUTPUT); // dioda sygnalizująca zdarzenie // dioda oświetlajaca fotorezystor pinMode(2, OUTPUT); // konf wyjscia digitalWrite(2, HIGH); // zawsze włączona } void loop() { StanSensora = analogRead(A5); // odczyt wartosci z ADC if (StanSensora <100) { digitalWrite(8, HIGH); // jeżeli fotorezystor zakryty zapal diode kontrolną StanSensora = OstatniStan + 1; Serial.println(OstatniStan); } else { digitalWrite(8, LOW); } delay(50); } Jest jeszcze coś nie tak - w UART pokazuje mi cały czas ciąg "0" Cytuj Link do komentarza Share on other sites More sharing options...
StefanekP Styczeń 21, 2022 Udostępnij Styczeń 21, 2022 Bo wysyłasz przez UART wartość zmiennej OstatniStan, której wartości w żadnym miejscu nie zmieniasz, więc jest cały czas równa 0. Cytuj Link do komentarza Share on other sites More sharing options...
farmaceuta Styczeń 21, 2022 Udostępnij Styczeń 21, 2022 Dalej zle...juz wszyscy Ci powiedzieli...masz wykryc stan RAZ i poczekac az stan znow bedzie wiekszy od 100 i wtedy znowu czekasz az stan bedzie mniejszy niz 100 i zwiekszasz licznik o 1.. Cytuj Link do komentarza Share on other sites More sharing options...
KamilKolesnik Styczeń 21, 2022 Autor tematu Udostępnij Styczeń 21, 2022 (edytowany) 37 minut temu, farmaceuta napisał: Dalej zle...juz wszyscy Ci powiedzieli...masz wykryc stan RAZ i poczekac az stan znow bedzie wiekszy od 100 i wtedy znowu czekasz az stan bedzie mniejszy niz 100 i zwiekszasz licznik o 1.. Ok hmmm int StanSensora = 0; // Zmienna do przechowywania odczytu ADC int OstatniStan = 0; // zmienna przechowująca ostatni stan int NowyStan = 0; int licznik = 0; void setup() { Serial.begin(9600); // inicjalizacja UART pinMode(8,OUTPUT); // dioda sygnalizująca zdarzenie // dioda oświetlajaca fotorezystor pinMode(2, OUTPUT); // konf wyjscia digitalWrite(2, HIGH); // zawsze włączona } void loop() { StanSensora = analogRead(A5); // odczyt wartosci z ADC if (StanSensora <100) { StanSensora = OstatniStan +1; digitalWrite(8, HIGH); // jeżeli fotorezystor zakryty zapal diode kontrolną } else { if (StanSensora>100) { OstatniStan = NowyStan; NowyStan = licznik +1; Serial.println(licznik); digitalWrite(8, LOW); } delay(50); } } Czy kombinuje w dobrą stronę? Czy powinienem zacząć od nowa i starać się napisać podobnie do kodu H1M4W4R1? Edytowano Styczeń 21, 2022 przez KamilKolesnik poprawa Cytuj Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
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!