Skocz do zawartości

Kurs Arduino - #4 - Przetwornik ADC


Pomocna odpowiedź

43 minuty temu, Screwdriv napisał:

no i dobrze pokazuje. na wyjściu ma 3 V a że nic nie jest podpięte to i się nic nie zmienia. 

@Screwdriv, nie to, niedobrze. Przypadek, w którym nic nie jest podłączone i otrzymujemy równiutką, stabilną wartość jest raczej niemożliwy - zawsze z powietrza złapiemy jakieś zakłócenia.

@radekwrc nie ma za bardzo co tutaj testować, jeśli jest tak jak piszesz to znaczy, że raczej uszkodził się przetwornik ADC, ale to bardzo dziwne. Do tej pory chyba nikomu się to jeszcze nie udało (nie kojarzę takich zgłoszeń na forum). Podłączałeś do płytki coś co mogło ją uszkodzić? Może położyłeś Arduino na czymś i od spodu zrobiło się zwarcie?

Link do komentarza
Share on other sites

@Screwdriv no właśnie, jeśli u Ciebie wartości jakoś skaczą to jest to poprawne zachowanie - jak wetkniesz w dany pin Arduino jakiś przewód (nawet taki do płytki stykowej) i zostawisz go luźnego w powietrzu to wahania powinny być jeszcze większe. Jeśli wartość jest stabilna i zawsze równa dokładnie 3V to raczej jest to jakieś uszkodzenie 😞

Link do komentarza
Share on other sites

Cześć Wam po raz kolejny!

Świetna cześć kursu i w końcu jedno z zadań domowych stanowi (przynajmniej dla mnie) niewielkie, ale jednak, wyzwanie. Chodzi mi o zadanie 4.5. Wymusza ono moim zdaniem trochę zmianę myślenia i podejścia w stosunku do programowania "tradycyjnego". Trzeba mieć cały czas w głowie, że wszystkie te polecenia wykonują się w nieskończonej pętli i trzeba odpowiednio dobrać inne pętle, które pozwolą nam pozornie zatrzymać działanie programu w wymaganym momencie. Przyznam, że musiałem w pewnym momencie spojrzeć na kody innych użytkowników żeby zauważyć moje błędne myślenie w pewnych miejscach. Tak czy siak, udało się - łącznie z zaimplementowaniem małego oszustwa.

Tak czy siak kody do: 

4.4: 

int odczytanaWartosc = 0; //zmienna odczytana przez ADC fotorezystor
int prog = 0; //prog wlaczenia swiatla ustawioniany potencjometrem
#define LED 5


void setup()
{
    pinMode(LED, OUTPUT); //konfiguracja wyjscia
    Serial.begin(9600);

}

void loop()
{
    odczytanaWartosc = analogRead(A5); //odczytanie wartosci z fotorezystora
    prog = analogRead(A4); //odczytanie wartosci z potencjometru

    if (odczytanaWartosc > prog)
    { //czy jest jasniej od ustawionego progu?
        digitalWrite(LED, LOW); //wylaczenie diody
        Serial.println("swiatlo wylaczone"); //wyslanie info o wylaczeniu swiatla)
        while (odczytanaWartosc > prog)
        { //petla umozliwiajaca info tylko raz
            odczytanaWartosc = analogRead(A5);
            prog = analogRead(A4);
            delay(50);
        }
    }
    else
    {
        digitalWrite(LED, HIGH);
        Serial.println("swiatlo wlaczone");
        while (odczytanaWartosc < prog)
        {
            odczytanaWartosc = analogRead(A5);
            prog = analogRead(A4);
            delay(50);
        }
    }
    delay(50);
}

 

Oraz 4.5: 

#define przycisk 3
#define zielona 4
#define zolta 5
#define czerwona 6
#define potencjometr A4

int odczytanaWartosc = 0; //zmienna z ADC
byte proby = 2; //ilosc prob
String podana_wartosc = ""; //zmienna z podana wartoscia
int int_podana_wartosc = 0;
boolean poczatek = true; // stan programu
int roznica = 0; //roznica podanej wartosci i odczytu z ADC

void setup()
{
    pinMode(przycisk, INPUT_PULLUP); // zdefiniowanie wyjsc
    pinMode(zielona, OUTPUT);
    pinMode(zolta, OUTPUT);
    pinMode(czerwona, OUTPUT);

    Serial.begin(9600); //otwarcie komunikacji z PC

}

void loop()
{
    if (poczatek == true)
    { // jesli wartunek na poczatek prawidziwy to
        proby = 2; //zadania odpowiedniej ilosci prob
        digitalWrite(zielona, LOW); // ustalenie stanu poczatkowego LEDow
        digitalWrite(zolta, LOW);
        digitalWrite(czerwona, LOW);
        Serial.println("Ustaw potencjometr i wcisnij przycisk!");
        while (!Serial)
        { //oczekiwanie na otwarcie monitora portu
            delay(25);
        }
        while (digitalRead(przycisk) == LOW)
        { //oczekiewanie na zwolnienie przycisku po restarcie gry
            delay(25);
        }
        while (digitalRead(przycisk) == HIGH)
        { //oczekiewanie na wciśnięcie przycisku
            delay(25);
        }
        odczytanaWartosc = analogRead(potencjometr); //odczytanie wartosci z potencjometru
        Serial.println("Podaj liczbę z zakresu 0 - 1023!");
    }

    while (Serial.available() == 0)
    { //oczekiwanie na wpisanie liczby
        delay(25);
    }

    podana_wartosc = Serial.readStringUntil('\n'); //odczytanie wartości wpisanej z klawiatury
    int_podana_wartosc = podana_wartosc.toInt(); //zamiana tekstu na liczbę
    roznica = abs(odczytanaWartosc - int_podana_wartosc); //wyliczenie wartości bezwzględnej z różnicy

    if (int_podana_wartosc == 1410)
    {// jesli podano specjalną liczbę, używamy oszustwa
        Serial.println("Brawo oszuście! Prawidłowa odpowiedź to: " + String(odczytanaWartosc));
        poczatek = false;
        Serial.println("Spróbuj teraz, na pewno się uda!");
    } else

    if (roznica <= 50)
    { //jesli miesciemy sie w warunku
        digitalWrite(zielona, HIGH);
        digitalWrite(zolta, LOW); // wygaszenie żółtej w przypadku gdy zgadniemy za drugim lub trzecim razem
        Serial.println("Udalo Ci się!");
        Serial.println("Pomyliłeś się o: " + String(roznica));
        Serial.println("Jesli chcesz zagrac ponownie wcisnij przycisk!");
        while (digitalRead(przycisk) == HIGH)
        { //oczekiwanie na wcisniecie przycisku
            delay(25);
        }
        poczatek = true;
    }
    else
    {
        if (proby > 0 && int_podana_wartosc != 1410 )
        { //jesli ilosc prob wieksza od 0 
            digitalWrite(zolta, HIGH);
            poczatek = false; 
            Serial.println("Niestety nie udał się się!");
            Serial.println("Pozostało Ci: " + String(proby) + " prob!");
            proby--;
            Serial.println("Podaj kolejną liczbę!");
            while (Serial.available() == 0)
            { //oczekiwanie na podanie kolejnej liczby
                delay(25);
            }
        } else
        { //jesli ilosc prob jest rowna zero
            digitalWrite(czerwona, HIGH);
            digitalWrite(zolta, LOW);
            Serial.println("Znów się nie udało :(");
            Serial.println("Wykorzystaleś wszystkie próby!");
            Serial.println("Prawidłową odpowiedzią było: " + String(odczytanaWartosc));
            Serial.println("Jesli chcesz zacząć od nowa wcisnij przycisk");
            while (digitalRead(przycisk) == HIGH)
            { //oczekiwanie na wcisniecie przycisku
                delay(25);
            }
            poczatek = true;

        }
    }
}

 

Edytowano przez BHBmacieg
  • 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

Witam

To jeśli to faktycznie jest normalne, że na A5 nawet bez podłączenia kabelka, Arduino twierdzi że jest jakieś napięcie ok. 3V, tzn. że płytka jest ok.  To dlatego nie mogłem poradzić sobie z zadaniem 4.5, ponieważ napisałem taki warunek, że jak na A5 pojawi się jakaś wartość, np. większa niż 100, (a u mnie wyjście z potencjometru idzie do przycisku, a za przyciskiem do A5) to ma wyświetlić się napis "podaj wartość 0 - 1023". To dlatego ten napis ciągle się wyświetlał 99999... razy, skoro na A5 szczytuje sobie wartości ok. 600. Muszę wymyślić inny sposób, na  razie nie chcę patrzeć jak zrobili to inni:)

Ważne że płytka działa !

 

Link do komentarza
Share on other sites

Witam

Dlaczego program blokuje się przy "while (proby < 3)?"

 

//#define diodazielona 8
//#define diodazolta 9
//#define diodaczerwona 10
//#define przycisk A5

String liczbastring = "";
int odczytanaWartosc = 0;
int liczba = 0;
int roznica = 0;
int proby = 0;
//boolean petle = true; 


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

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

}

void loop() {
  Serial.println("Ustaw potencjometr i wciśnij przycisk");
  odczytanaWartosc = analogRead(A5);
  Serial.println(odczytanaWartosc);
    while (odczytanaWartosc >= 0)
  {
   delay(25);
  
                                                                                                                                                                                                                                                                                                                                                                                     
  if (digitalRead(11) == LOW)
  {
   Serial.println("Podaj liczbe od 20 do 1023:");
  
   while (Serial.available() == 0)
   {
    delay(25);
   while (proby < 3)
   {
    delay(25);
   }
    {
  liczbastring = Serial.readStringUntil('\n');
  liczba = liczbastring.toInt();
  Serial.println(liczba);
    
   roznica = liczba - odczytanaWartosc;
   if (roznica <= 50 && roznica >= -50)
   {
  Serial.println("wygrałes");
  digitalWrite(8, HIGH);
  delay(10000);
  digitalWrite(8,LOW);
  }
    else                       
   {
                            //if(proby < 2)
      proby = proby + 1;
      Serial.println("błędna odpowiedz, spróbuj jeszcze raz");
      digitalWrite(9, HIGH);
                             //petle = true;
    }
   }
      {
        Serial.println("przegrałeś");
        digitalWrite(10, HIGH);
      }
    
    
  }
  }
}
}

 

Mam jeszcze taki drugi wariant, ale nie wiem jak "przeskoczyć" z void setup do void loop

 

//#define diodazielona 8
//#define diodazolta 9
//#define diodaczerwona 10
//#define przycisk A5

String liczbastring = "";
int odczytanaWartosc = 0;
int liczba = 0;
int roznica = 0;
boolean zakres = false; 


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

  digitalWrite(8, LOW);
  digitalWrite(9, LOW);
  digitalWrite(10, LOW);
  
  Serial.println("Ustaw potencjometr i wciśnij przycisk");
  odczytanaWartosc = analogRead(A5);
    Serial.println(odczytanaWartosc);
                                                                                                                                                                                                                                                                                                                                                                
   if (digitalRead(11) == LOW)
  {
   Serial.println("Podaj liczbe od 20 do 1023:");
     }
   
}
  

   

void loop() {
  
  while (Serial.available() == 0)
{
    delay(25);
   }
{
  liczbastring = Serial.readStringUntil('\n');
  liczba = liczbastring.toInt();
  Serial.println(liczba);
}  
   roznica = liczba - odczytanaWartosc;
   if (roznica <= 50 && roznica >= -50)
   {
  Serial.println("wygrałes");
  digitalWrite(8, HIGH);
       }
else
   {
      Serial.println("błędna odpowiedz, spróbuj jeszcze raz");
      digitalWrite(9, HIGH);
      Serial.println("Podaj liczbe od 20 do 1023:");
    }
  }

 

Link do komentarza
Share on other sites

@radekwrc mógłbyś napisać co dokładniej masz na myśli pisząc, że się blokuje? Jakiego efektu się spodziewałeś, a jaki uzyskałeś?

Postaraj się trochę zadbać o formatowanie programu, bo ciężko go analizować 😞 Trudno się połapać w takim zapisie:

    }
   }
      {
        Serial.println("przegrałeś");
        digitalWrite(10, HIGH);
      }
    
    
  }
  }
}
}

 

Link do komentarza
Share on other sites

Mam taki problem z  pętlami while, szczególnie z while (proby < 3) 

Jak zapiszę to w ten sposób:

 while (proby < 3)
   {
    delay(25);
   }

Program dojdzie do momentu delay i nie reaguje już na to że wpisuję wartość np. 300 i klikam "wyślij".

Jeśli usunę po delay nawias, to po wciśnięciu przycisku na płytce stykowej, wyskoczy :

Podaj liczbe od 20 do 1023:
0
błędna odpowiedz, spróbuj jeszcze raz
0
błędna odpowiedz, spróbuj jeszcze raz
0
błędna odpowiedz, spróbuj jeszcze raz
przegrałeś

przegrałeś

przegrałeś

przegrałeś

...

przegrałeś

...

No mam problem z tymi nawiasami, przez to że tyle mam tych pętli while.

 

 

Link do komentarza
Share on other sites

while (Serial.available() == 0)
   {
    delay(25);
   while (proby < 3)
   {
    delay(25);
   }
    {<----- ta klamra to od czego?  
  liczbastring = Serial.readStringUntil('\n');
  liczba = liczbastring.toInt();
  Serial.println(liczba);

wydaje się że masz zdecydowanie za dużo wstawionych nawiasów... przez to ciężko nawet stwierdzić co i gdzie się ma wykonać

Link do komentarza
Share on other sites

9 godzin temu, radekwrc napisał:

Jak zapiszę to w ten sposób:


 while (proby < 3)
   {
    delay(25);
   }

Taka pętla nie jest poprawna, bo w jej środku jest tylko opóźnienie, a nigdzie nie zmieniasz wartości zmiennej "proby". W związku z tym, jeśli program raz wejdzie do tej pętli to już nigdy z niej nie wyjdzie. Zacznij proszę na spokojnie od poprawienia formatowania i wcięć nawiasów w swoim programie. Już samo to znacznie ułatwi rozwiązanie problemu.

Link do komentarza
Share on other sites

//#define diodazielona 8
//#define diodazolta 9
//#define diodaczerwona 10
//#define przycisk A5

String liczbastring = "";
int odczytanaWartosc = 0;
int liczba = 0;
int roznica = 0;
int proby = 0;
//boolean petle = true; 


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

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

}

void loop() {
  Serial.println("Ustaw potencjometr i wciśnij przycisk");
  odczytanaWartosc = analogRead(A5);
  Serial.println(odczytanaWartosc);
    while (odczytanaWartosc >= 0)
  {
   delay(25);
                   3                                                                                                                                                                                                                                                                                                                                                                    
  while (digitalRead(11) == LOW)
    {
   Serial.println("Podaj liczbe od 20 do 1023:");
    
   while (Serial.available() == 0)
      {
    delay(25);   
   
   while (proby < 3)
        {
    delay(25);
        
  liczbastring = Serial.readStringUntil('\n');
  liczba = liczbastring.toInt();
  Serial.println(liczba);
      
   roznica = liczba - odczytanaWartosc;
   if (roznica <= 50 && roznica >= -50)
   {
  Serial.println("wygrałes");
  digitalWrite(8, HIGH);
  delay(10000);
  digitalWrite(8,LOW);
   }
    else                       
      {
                                         
      proby = proby + 1;
      Serial.println("błędna odpowiedz, spróbuj jeszcze raz");
      digitalWrite(9, HIGH);
                                         
      }                                   
        } // while (proby<3)
      
        Serial.println("przegrałeś");
        digitalWrite(9,LOW);
        digitalWrite(10, HIGH);
       
        
      }//while (Serial.available() == 0)
 }//if (digitalRead(11) == LOW)
}//while (odczytanaWartosc >= 0)
}//void loop()

W tej konfiguracji dzieje się tak:

Podaj liczbe od 20 do 1023:
0
błędna odpowiedz, spróbuj jeszcze raz
0
błędna odpowiedz, spróbuj jeszcze raz
0
błędna odpowiedz, spróbuj jeszcze raz
przegrałeś

przegrałeś

przegrałeś

przegrałeś

...

przegrałeś

...

A jak po delay jest nawias to zatrzymuje się w tej pętli.

Link do komentarza
Share on other sites

@radekwrc jeszcze raz apeluję, aby na spokojnie zadbać o porządek w kodzie 🙂 Zobacz np. tutaj:

   delay(25);
                   3                                                                                                                                                                                                                                                                                                                                                                    
  while (digitalRead(11) == LOW)
    {
   Serial.println("Podaj liczbe od 20 do 1023:");

Co to za zagubione "3"? Wykorzystaj chociaż w Arduino opcję znajdującą się w Narzędzia > Automatyczne formatowanie - nie będzie idealnie, ale sam zobaczysz, że będzie już znacznie lepiej. Zrób później jeszcze porządek ręcznie usuwając np. zbędne puste linie i wklej program wtedy 🙂

Link do komentarza
Share on other sites

String liczbastring = "";
int odczytanaWartosc = 0;
int liczba = 0;
int roznica = 0;
int proby = 0;


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

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

void loop() 
{
  Serial.println("Ustaw potencjometr i wciśnij przycisk");
  odczytanaWartosc = analogRead(A5);
  Serial.println(odczytanaWartosc);
  while (odczytanaWartosc >= 0)
  {
    delay(25);
    while (digitalRead(11) == LOW)
    {
      Serial.println("Podaj liczbe od 20 do 1023:");
      while (Serial.available() == 0)
      {
        delay(25);
        while (proby < 3)
        {
          delay(25);
          liczbastring = Serial.readStringUntil('\n');
          liczba = liczbastring.toInt();
          Serial.println(liczba);

          roznica = liczba - odczytanaWartosc;
          if (roznica <= 50 && roznica >= -50)
          {
            Serial.println("wygrałes");
            digitalWrite(8, HIGH);
            delay(10000);
            digitalWrite(8, LOW);
          }
          else
          {
            proby = proby + 1;
            Serial.println("błędna odpowiedz, spróbuj jeszcze raz");
            digitalWrite(9, HIGH);
          }
        } // while (proby<3)

        Serial.println("przegrałeś");
        digitalWrite(9, LOW);
        digitalWrite(10, HIGH);

      }//while (Serial.available() == 0)
    }//if (digitalRead(11) == LOW)
  }//while (odczytanaWartosc >= 0)
}//void loop()

Teraz już jest ładnie:)

Link do komentarza
Share on other sites

@radekwrc 

A jakbyś tak na kartce sobie rozpisał po kolei co chcesz żeby program robił... i później porównał to z tym co napisałeś... np. start programu--> drukujemy "przekręć potencjometr i naciśnij przycisk-->teraz wypadałoby czekać na naciśnięcie przycisku...itd

Edytowano przez Screwdriv
Link do komentarza
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!

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.