Skocz do zawartości

Arduino UNO program zliczający impulsy ściemnienia na fotorezystorze


kamkol1

Pomocna odpowiedź

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.

obraz.thumb.png.e9a32b81790482349ba023c68284f3fd.png

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 przez KamilKolesnik
doprecyzowanie
Link do komentarza
Share on other sites

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 😉)

Link do komentarza
Share on other sites

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.

 

Link do komentarza
Share on other sites

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 przez H1M4W4R1
  • Lubię! 1
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

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

Dziękuje bardzo za pomoc.

Żeby było wiadomo o co dokładnie chodzi wstawiam foto mojego wstępnego układu

obraz.thumb.png.9791a0b8139f7d00b029a1552f644ea5.png

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);

 

Link do komentarza
Share on other sites

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 ;/

 

Link do komentarza
Share on other sites

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.

Link do komentarza
Share on other sites

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 przez ethanak
Link do komentarza
Share on other sites

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"

Link do komentarza
Share on other sites

(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 przez KamilKolesnik
poprawa
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.