Skocz do zawartości

Kurs Arduino - #4 - Przetwornik ADC


Pomocna odpowiedź

Moje rozwiązanie do zadania 4.4:

int foto = 0;
int pot = 0;
void setup() {
  pinMode(11, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  foto = analogRead(A0);
  pot = analogRead(A5);

  if (foto < pot) {
    digitalWrite(11, HIGH);
    Serial.println(foto);
    while(foto < pot) {
        foto = analogRead(A0);
        pot = analogRead(A5);
        delay(50);
      }
  } else {
    digitalWrite(11, LOW);
  }
  delay(50);
}

 

  • Lubię! 1
Link to post
Share on other sites

@luksonski witam na forum 🙂 

Fajnie że wrzucasz swoje rozwiązanie, widzę, że sprytnie to wymyśliłeś. Ale mam jedną uwagę, albo nawet dwie.

  • Pierwsza prostsza sprawa - nie używaj w kodzie A0 A5 4 i innych tzw. magicznych wartości. Nie ma tragedii bo domyślilem się co robi A0 po nazwie zmiennej do której zapisujesz pomiar, ale na przyszłość używaj etykiet z dyrektywy #define.
  • Druga to jak popatrzysz na kod, to jest powtórzenie odczytu analogRead. A może daloby się umieścić to tylko w jednym miejscu? Oczywiście będzie to wymagać dodatkowej zmiennej trzymającej stan.

Przejrzyj temat o obsłudze przycisków, wiem że nie jest przycisk ale zachowuje się tak samo - coś zmienia stan. 

  • Lubię! 1
Link to post
Share on other sites

Cześć Wszystkim !

zabrałem się za zadanie 4.4 i póki co chciałbym żeby program pokazywał mi zmienną "odczytaneDane" jeszcze bez konwersji na wartości napięcia, ale...

Mam problem z pętlą while().

Gdy zasłaniam dłonią fotorezystor dioda się zapala i podaje zmienną "odczytaneDane" ale  gdy odsłaniam fotorezystor, czyli teoretycznie mój warunek dla pętli while(odczytanaWartosc < prog) przestaje być spełniony, program nie chce wyjść z pętli.

zastanawia mnie dlaczego pętla while nie reaguje na niespełnienie warunku? 

proszę o pomoc i wyjaśnienie

poniżej szkic:

int odczytanaWartosc = 0; //Zmienna do przechowywania odczytu ADC
int prog = 0; //Próg włączenia światła - ustawiany potencjometrem
void setup() {
  pinMode(8, OUTPUT); //Konfiguracja wyjść pod diodę LED
  Serial.begin(9600);
}

void loop() {
  odczytanaWartosc = analogRead(A5);//Odczytanie wartości z ADC
  prog = analogRead(A4);//Odczytanie wartości z ADC  
  
  if (odczytanaWartosc < prog) { //Czy jest ciemniej od ustawionego progu?
     digitalWrite(8, HIGH);//Włączenie diody    
     Serial.println(odczytanaWartosc);
     while(odczytanaWartosc < prog){
      delay(50);
     }
    } else {
     digitalWrite(8, LOW);//Wyłączenie diody      
  }
  
  delay(50);
}

 

Link to post
Share on other sites
(edytowany)
while(odczytanaWartosc < prog)
	{
  		delay(50); 
	}

Program wchodzi w pętle kiedy warunek jest spełniony, ale sama pętla to tylko delay(50). Tym samym program wykonują ciągle opóźnienie i nic więcej. Musisz w tej pętli odczytać zmienną odczytanaWartosc, aby wyjść z tej pętli.

while(odczytanaWartosc < prog)
	{
  		delay(50);
  		odczytanaWartosc = analogRead(A5);
	}

Ogólnie ten warunek IF jest niepotrzebny w tym wypadku, jeśli robisz to przy użyciu WHILE - bo właściwie to powtarzasz to samo. Wystarczy np.:

while (odczytanaWartosc < prog)
	{
		digitalWrite(8, HIGH);	//Włączenie diody    
		Serial.println(odczytanaWartosc);
		delay(50);
		odczytanaWartosc = analogRead(A5);	//Sprawdzamy czy wychodzimy z pętli WHILE
		prog = analogRead(A4);	//Przy okazji można dodać sprawdzenie czy próg nie został zmieniony
	}
digitalWrite(8, LOW);	//Wyłączenie diody

Same odczyty możesz zrobić w osobnej funkcji np.:

void odczyty()
	{
		odczytanaWartosc = analogRead(A5);	
		prog = analogRead(A4);
	}

void loop()
	{
		odczyty(); // teraz w dowolnym miejscu programu mozesz powolac sie na ta funkcje
	}

 

Edytowano przez Shary
  • Pomogłeś! 1
Link to post
Share on other sites
(edytowany)

@Shary wielkie dzięki za pomoc! coś mi się rozjaśniło 🙂

Trochę mnie przyblokowało podpatrzenie komendy z fragmentu lekcji nr3, 

tam był taki szkic:

void setup(){
  Serial.begin(9600); //Uruchamiamy transmisję
  
  pinMode(8, OUTPUT); //Wyjście diody czerwonej
  pinMode(9, OUTPUT); //Wyjście diody zielonej
  pinMode(10, INPUT_PULLUP); //Przycisk
  
  digitalWrite(8, LOW); //Wyłączenie obu diod
  digitalWrite(9, LOW);
}
 
void loop() {
  
  if (digitalRead(10) == LOW) { //Jeśli przycisk jest wciśnięty
    digitalWrite(9, HIGH); //Włączenie diody zielonej
    digitalWrite(8, LOW); //Wyłączenie diody czerwonej
  } else { //Jeśli przycisk nie jest wciśnięty
    digitalWrite(9, LOW); //Wyłączenie diody zielonej
    digitalWrite(8, HIGH); //Włączenie diody czerwonej
    Serial.println("Uwaga! Alarm! Okno nie jest zamkniete!");
    
    while (digitalRead(10) == HIGH) {
      //Zatrzymujemy się w pustej pętli do ponownego zamknięcia okna
      delay(25); //W pętli wprowadzamy małe opóźnienie 25ms, aby niwelować zakłócenia
    }
 
  }
}

Próbowałem zrobić analogie. Myślałem że skoro w powyższej pętli while() program wychodzi z pętli gdy  switch przechodzi na stan LOW, to w moim szkicu do zadania 4.4 będzie podobnie, tzn. Wychodzę z pętli gdy odsłaniam rękę (odczytanaWartosc>prog). 

Rozumiem Twoją propozycję i bardzo dziękuję za nią, ale też pojawia mi się pytanie czemu ten powyższy szkic nie musiał mieć "niczego w środku" pętli while a potrafił przeczytać Warunek do pętli i wyjść z niej gdy switch przeszedł w stan LOW, a ja w swoim zadaniu 4.4 musze wpisać do swojej pętli while linjkę kodu: odczytanaWartosc=analogRead(A5); bo gdy tego nie zrobię zapętlam się w nieskończoność i nie wychodzę z pętli.

Edytowano przez dastawowy
Link to post
Share on other sites
(edytowany)

dobre pytanie, zwróć uwagę na konstrukcję obu pętli:

while (digitalRead(10) == HIGH) // robimy odczyt w warunku, czyli pętla się wykonuję póki D10 ma stan HIGH
  
if (odczytanaWartosc < prog) lub while (odczytanaWartosc < prog) //w obu przypadkach sprawdzamy zmienną (czyli co zawiera zmienna)

w pierwszym wariancie dokonujemy bezpośrednio odczytu z D10, w drugim (Twoim dokonujemy odczytu wartości zmiennej (dwóch zmiennych dokładnie). Zmienna, ma to do siebie, że sama nie zmieni wartości. Musisz na niej wykonać operację. Dlatego w Twojej pętli dokonałem odczytu w "środku" pętli, co zmieni wartość samej zmiennej jeśli odczyt ulegnie zmianie.

Oczywiście analogicznie możesz zrobić warunek taki:

while (analogRead(A5) < analogRead(A4))

I to będzie działać. Jednak z punktu widzenia bardziej skomplikowanych programów, łatwiej jest edytować zmienne niż cały kod.

Edytowano przez Shary
  • Pomogłeś! 1
Link to post
Share on other sites

Cześć 🙂

mam pytanie do zadania 4.5. (gra)

jakiej funkcji należy użyć by arduino odczytał zmienne typu int które chcę wprowadzić za pośrednictwem terminala?

metodą prób i błędów wiem  że:

odebraneDane = Serial.readStringUntil('\n');

powyższy kod nie odbierze String i nie przekonwertuje tego na INT (użyłem go w pierwszej kolejności na podstawie wiedzy wyniesionej z lekcji nr 3, ale teraz już wiem że to tak nie działa 😉 )

Najbliżej było z:

odebraneDane = Serial.parseInt();

jednak tutaj mam problem z tym że gdy wpisze do terminala poprawną liczbę (dioda zapali mi się na zielono) to po chwili i tak zapala mi się na pomarańczowo.

Zanim okażę się że mam jakieś błędy w szkicu, chciałbym w ogóle dowiedzieć się czy dobrze kombinuje z tym zadaniem, jeśli chodzi o odbiór danych za pośrednictwem terminala. szkic jest w powijakach więc póki co nie wklejam..

Pozdrawiam

Link to post
Share on other sites
(edytowany)

Sprawdź pętlą IF czy serial jest aktywny, odczytaj STRING do końca lini, a następni STRING zmień na INT, coś w tej deseń:

if(Serial.available() > 0) 
	{ 
       odczyt_z_konsoli = Serial.readStringUntil('\n');  
       liczba = odczyt_z_konsoli.toInt();
	}

https://www.arduino.cc/reference/pl/language/variables/data-types/string/functions/toint/

Powinno działać. Tu masz dokumentację toInt();

Edytowano przez Shary
  • Pomogłeś! 1
Link to post
Share on other sites

@Shary jesteś wielki! 🙂 dzięki serdeczne, mała wskazówka a bardzo pomogła.

To moja propozycja zadania 4.5

String odczyt = ""; // Liczba którą wysyłam za pośrednictwem terminala
int wyslana = 0; // zmienna użyta do konwersji ze String na Int
int odczytana = 0; // Liczba którą odczytuję z ADC
int szansa = 0; // zmiena do liczenia ile pozostało szans

void setup() {
  Serial.begin(9600);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(2, INPUT_PULLUP);

digitalWrite(8, LOW);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
}

void loop() {
  if(digitalRead(2)==LOW)
  {
    Serial.println("podaj liczbę");
    delay(1000);
    szansa=0;
  }
   if(Serial.available() > 0) //czy wpisałem jakas liczbe?
     {
     odczyt = Serial.readStringUntil('\n'); //jesli tak to wpisz do zmiennej
     wyslana = odczyt.toInt();
     odczytana = analogRead(A4);
     if((wyslana >= odczytana - 50) && (wyslana <= odczytana + 50)) // czy moja liczba spelnia oba warunki?
     {
       Serial.println("wygrana");
       digitalWrite(10, HIGH);
       delay(1000);
       digitalWrite(10, LOW);
       delay(1000);
       szansa=0;
     } 
     else if ((wyslana != odczytana) && (szansa <= 2)) //czy moja liczba spełnia warunki?
     {
       digitalWrite(9, HIGH);
       delay(1000);
       digitalWrite(9, LOW);
       delay(1000);
       szansa=szansa+1;
     }
     if (szansa >= 3) 
     {
      Serial.println("przegrana");
      digitalWrite(8, HIGH);
      delay(1000);
      digitalWrite(8, LOW);
      delay(1000);
      Serial.println("zresetuj grę");
      }
     if(szansa==1)
     {
       Serial.println("zostały 2 szanse");
     }
     if(szansa==2)
     {
       Serial.println("została 1 szansa");
     }
    }
}
 

 

  • Lubię! 1
Link to post
Share on other sites

4.5 

#define czerwona 6
#define zolta 7
#define zielona 8
#define przycisk 3

boolean wygrana = false;
int odczyt = 0;
String traf = "";
int traf1 = 0;
int prob = 2;
boolean odnowa = false;

void setup() {
  
Serial.begin (9600);
 
 pinMode(czerwona,OUTPUT);
 pinMode(zolta, OUTPUT);
 pinMode(zielona, OUTPUT);
 pinMode(przycisk, INPUT_PULLUP);

}

void loop() {

    if(odnowa == true){
      digitalWrite(czerwona, LOW);
      digitalWrite(zielona, LOW);
      digitalWrite(zolta, LOW);
      wygrana = false;
      prob = 2;
    }

  
if(digitalRead(przycisk)==LOW){
      odczyt = analogRead(A4);
      Serial.println ("Podaj liczbę:");
      delay(200);
      
      while(Serial.available()==0){};
      
      if(Serial.available() >0){
        traf = Serial.readStringUntil ('\n');
        traf1 = traf.toInt();
         }
 
         if(odczyt - traf1 <= 50 && odczyt - traf1 >= -50){
          digitalWrite(zielona, HIGH);
          odnowa = true;
          delay(2000);
          } else {
             digitalWrite(zolta, HIGH);
             if(wygrana == false){
              
               while(prob > 0){
       
         
              Serial.println ("Masz jeszcze: ");
              Serial.println (prob);
              Serial.println (" prob");
              prob = prob -1;
              delay(200);
              
               while(Serial.available()==0){};
               
                  if(Serial.available() >0){
                    traf = Serial.readStringUntil ('\n');
                     traf1 = traf.toInt();
          
                      if(odczyt - traf1 <= 50 && odczyt - traf1 >= -50){
                       digitalWrite(zielona, HIGH);
                       digitalWrite(zolta, LOW);
                       wygrana = true;
                       odnowa = true;
                      delay(2000);
                 }
               }  
              }
                          if(wygrana ==false){
                             digitalWrite(zolta, LOW);
                             digitalWrite(czerwona, HIGH);
                             odnowa = true;
                             delay(2000);
         }
       }
    }
  }
 }
 

 

4.6

#define Lzielona  2
#define Lczerwona 3
#define zolta 4
#define Pczerwona 5
#define Pzielona 6

int a =0;
int b = 0;

void setup() {
  Serial.begin(9600);

  pinMode(Lzielona, OUTPUT);
  pinMode(Lczerwona, OUTPUT);
  pinMode(zolta, OUTPUT);
  pinMode(Pczerwona, OUTPUT);
  pinMode(Pzielona, OUTPUT);
}

void loop() {
  digitalWrite(Lzielona, LOW);
  digitalWrite(Lczerwona, LOW);
  digitalWrite(zolta, LOW);
  digitalWrite(Pczerwona, LOW);
  digitalWrite(Pzielona, LOW);
  
  a = analogRead(A5);
  b = analogRead(A4);

  a= map(a, 0, 1023, 1, 5);
  b = map(b, 0, 1023, 1,5);

  Serial.println(a);
  Serial.println(b);

   if(a==b)
    {
      digitalWrite(Lzielona, LOW);
      digitalWrite(Lczerwona, LOW);
      digitalWrite(zolta, HIGH);
      digitalWrite(Pczerwona, LOW);
      digitalWrite(Pzielona, LOW);
    }else if (a-b >=3)
    {
      digitalWrite(Lzielona, HIGH);
      digitalWrite(Lczerwona, LOW);
      digitalWrite(zolta, LOW);
      digitalWrite(Pczerwona, LOW);
      digitalWrite(Pzielona, LOW);
    } else if( a-b == 2 || a-b == 1)
    {
      digitalWrite(Lzielona, LOW);
      digitalWrite(Lczerwona, HIGH);
      digitalWrite(zolta, LOW);
      digitalWrite(Pczerwona, LOW);
      digitalWrite(Pzielona, LOW);
    }else if( b-a >=3)
    {
      digitalWrite(Lzielona, LOW);
      digitalWrite(Lczerwona, LOW);
      digitalWrite(zolta, LOW);
      digitalWrite(Pczerwona, LOW);
      digitalWrite(Pzielona, HIGH);
    }else if( b-a ==2 || b-a ==1)
      {
      digitalWrite(Lzielona, LOW);
      digitalWrite(Lczerwona, LOW);
      digitalWrite(zolta, LOW);
      digitalWrite(Pczerwona, HIGH);
      digitalWrite(Pzielona, LOW);
      }

 delay(100);
}

Może niezbyt optymalne rozwiązania, ale działają 🙂

  • Lubię! 2
Link to post
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

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

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.