Skocz do zawartości

Kurs Arduino - #4 - Przetwornik ADC


Pomocna odpowiedź

Hej!

Zrobiłem zadanie 4.5 i biorę się zaraz do zadania 4.6. Po dłuższej przerwie od kursu, bo studia zjadły większość mojego czasu, wróciłem i to zadanie było dla mnie ciekawym wyzwaniem które sprawiło mi wiele frajdy! Przesyłam swój kod poniżej, chętnie się dowiem jak dużo rzeczy źle zrobiłem😆. Nauczyłem się nowej funkcji na potrzeby tego zadania Serial.flush(), bo miałem kłopoty z komunikacją między komputerem a Arduino. Zadania jednak nie zrobiłem dobrze, bo poległem na dodaniu marginesu błędu. Jak widać dane zapisuje w zmiennych typu String, czy jest możliwość przekształcenia tego do typu Int? Widzę w przykładzie osoby wyżej coś jakby dopisek do zmiennej .toInt() jak on działa? To moje pierwsze styczności z programowaniem, więc z chęcią przyjmę każdą radę:)

#define cz 12 //diody czerwona, 3 żółte i jedna zielona
#define z1 11
#define z2 10
#define z3 9
#define z 8
#define p 7 //przełącznik

String start = " "; //start gry
String odczytanawartosc = " ";
String odebranedane = " ";
int x = 3; // licznik rpob
int y = 0; // licznik procesu
int v = 0; // licznik migania

void setup() {
  Serial.begin(9600);  // uruchomienie komunikacji przez USART
  pinMode (cz, OUTPUT);
  pinMode (z1, OUTPUT);
  pinMode (z2, OUTPUT);
  pinMode (z3, OUTPUT);
  pinMode (z, OUTPUT);
  pinMode (p, INPUT_PULLUP);

  digitalWrite(cz, LOW);
  digitalWrite(z1, LOW);
  digitalWrite(z2, LOW);
  digitalWrite(z3, LOW);
  digitalWrite(z, LOW);
  Serial.println("Witaj!");
}

void loop() {

  if (y == 0) {//proces 1 początek gry
    Serial.println("Aby zagrać wpisz ,,Start''"); //tekst powitalny
    y = y + 1;
  }

  if (y == 1) {//proces 2 rozpoczęcie gry i polecenie dla gracza
    if (Serial.available() > 0) { //sprawdzenie czy sa dane
      start = Serial.readStringUntil('\n');// dane do zmiennej
      Serial.flush();//czyszczenie terminala

      if (start == "Start" || start == "start")
      {
        Serial.println("Ustaw potencjometr i wciśnij guzik");


      } else {
        Serial.println("Coś kombinujesz, musisz napisać start!");

      }
    }
  }

  if (digitalRead(p) == LOW && y == 1) { //wciśnięcie guzika podczas procesu 2 aby zapisać dane z potencjometru

    delay(300);
    digitalWrite(z1, HIGH);
    digitalWrite(z2, HIGH);
    digitalWrite(z3, HIGH);
    odczytanawartosc = analogRead(A5);
    Serial.print(odczytanawartosc);
    //Serial.println(" odczytanawartosc");//kody w grze
    //Serial.println("Podaj wartość");//kody aby sprawdzić jaką wartość potencjometru odczytuje arduino
    y = 2;
  } else if (digitalRead(p) == LOW) {
    Serial.println("Nie wolno, pobite gary!");//komentarz jak ktoś chce kombinować w trakcie gry
    delay(300);
  }

  if (y == 2) {//proces 3 zgadywanie wyniku

    if (Serial.available() > 0) {
      odebranedane = Serial.readStringUntil('\n');//dane do zmiennej
      Serial.flush();//czyszczenie terminala
      //Serial.print(odebranedane); //kody w grze
      // Serial.println(" odebranedane"); //kody aby sprawdzić jaką wartość odczytuje arduino

      if ( odebranedane == odczytanawartosc) {
        Serial.println("Gratulacje wygrałeś!"); //wygrana
        y = y + 1;
      }

      else {
        Serial.print("Niestety jest to zły wynik, zostało Ci tyle prób: ");//błąd
        Serial.println(x - 1);//liczba prób
        x = x - 1;

        digitalWrite(cz, HIGH);
        delay (200);
        digitalWrite(cz, LOW);

      }
      if (x == 3) {
        digitalWrite(z1, HIGH);//liczba prób pokazana na diodach
        digitalWrite(z2, HIGH);
        digitalWrite(z3, HIGH);
      }
      if (x == 2) {
        digitalWrite(z1, LOW);
        digitalWrite(z2, HIGH);
        digitalWrite(z3, HIGH);
      }
      if (x == 1) {
        digitalWrite(z1, LOW);
        digitalWrite(z2, LOW);
        digitalWrite(z3, HIGH);
      }
      if (x == 0) {
        Serial.println("Przegrałeś.");//przegrana
        digitalWrite(z1, LOW);
        digitalWrite(z2, LOW);
        digitalWrite(z3, LOW);
        delay(2000);
        Serial.println("Nic nie szkodzi, spróbuj jeszcze raz!");
        delay(1000);
        x = 3;// reset zmiennych
        y = 0;
      }
    }
  }

  if ( y == 3) {// proces 4 miganie lampek na osłodę wygranej
    if ( v < 5) {

      digitalWrite(cz, HIGH);
      digitalWrite(z1, HIGH);
      digitalWrite(z2, HIGH);
      digitalWrite(z3, HIGH);
      digitalWrite(z, HIGH);
      delay(250);

      digitalWrite(cz, LOW);
      digitalWrite(z1, LOW);
      digitalWrite(z2, LOW);
      digitalWrite(z3, LOW);
      digitalWrite(z, LOW);
      delay(250);

      v = v + 1;
    } else {
      x = 3;//reset zmiennych
      v = 0;
      y = 0;
      delay(2000);
      Serial.println("Chcesz spróbować jeszcze raz?");
      delay(1000);
    }
  }


}

 

  • Lubię! 1
Link do komentarza
Share on other sites

@Bobo witam na forum 🙂 Fajnie ze próbujesz swoich sił z zadaniami domowymi.

Dnia 26.06.2021 o 14:32, Bobo napisał:

więc z chęcią przyjmę każdą radę:)

To mam kilka uwag 😉 

  1. definy czyli takie jakby stałe (jakby bo one są dla preprocesora nie kompilatora) powinny mieć ładniejsze nazwy - nie żałuj liter, bo kompletnie nie wiem co one oznaczają. Nazwa typu LED_1_PIN jest już lepsza.
  2. Podobnie zmienne, y == 1. Hmm... Może np state == CORRECT, gdzie CORRECT to stała zdefiniowana dyrektywą define 🙂 
  3. No i ten string. Lepiej będzie jak zamienisz go od raz na int funkcją o której wspomniałeś .toInt(), w ogóle najlepiej jakbyś w locie zamienił odczytane znaki na int bez zabawy ze stringiem, w Arduino najlepiej unikać stringów jak ognia 🙂 
  • Pomogłeś! 1
Link do komentarza
Share on other sites

Cytat

No i ten string. Lepiej będzie jak zamienisz go od raz na int funkcją o której wspomniałeś .toInt(), w ogóle najlepiej jakbyś w locie zamienił odczytane znaki na int bez zabawy ze stringiem, w Arduino najlepiej unikać stringów jak ognia  

Ta funkcja toInt zmienia String na int czy long?

Link do komentarza
Share on other sites

@StefanekP Zwraca long, patrz opis funkcji. Możesz przypisać wynik do zmiennej int, ale zostanie ucięty (dla małyc liczb poniżej 2^16-1 nie ma to znaczenia). Long ma 32 bity, a int 16. Też taka ciekawostka, ze masz bibliotekę inttypes gdzie są typy danych np int8_t uint8_t itp. Możesz wtedy bardziej swobodnie wybrać typ danych kierując się rozmiarem w bitach. Np. dla płytek Arduino zbudowanych na 8bitowym mikrokontrolerze AVR najszybszym typem danych będzie coś 8 bitowego 🙂 

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

4 godziny temu, Gieneq napisał:

@YURYS myślę, że to będzie to 🙂 

https://forbot.pl/blog/leksykon/potencjometr

no niestety nie znalazłem tam odpowiedzi więc powiem więcej o moim pytaniu:

Arduino mierzy napięcie na potencjometrze - to już wcześniej wyczytałem na Forbocie,

jednak wiem, że jako że rezystancja między Vcc, a GND jest stała to U miedzy nimi również jest stałe,

natomiast rezystancja wraz z napięciem między bocznymi wyprowadzeniami potencjometru a środkowym

jest zmienna, więc jak się domyślam Arduino mierzy zapewne jedne z tych napięć. I tu pada pytanie:

mierzy napięcie między nóżkami z których wychodzą kabelki pomarańczowy i niebieski, czy może między

czerwonym, a pomarańczowym, czy może dzieje się to jeszcze inaczej?

obraz.png

Edytowano przez YURYS
Link do komentarza
Share on other sites

@YURYS ok nie zrozumiałem o co pytasz, ale w artykule masz budowę potencjometru co jest potrzebne do zrozumienia gdzie jest pomiar.

1 godzinę temu, YURYS napisał:

z których wychodzą kabelki pomarańczowy i niebieski

Dokładnie tu. Dlatego że pomiar napięcia odbywa się względem masy. Tak jak w woltomierzu mierzysz napięcie 2 sondami, tu jedna jest na masie.

Jest możliwość pomiaru w inny sposób, 2 kablami w trybie tzw. różnicowym ale Arduino tego nie ma w sprzęcie 😞 

  • Pomogłeś! 1
Link do komentarza
Share on other sites


int pot;
String liczbaGracza ;
int stringGracza;
int proba = 3;
bool przycisk;
bool ostatniPrzycisk = HIGH;

void setup() {
  Serial.begin(9600);
  pinMode(A5, INPUT_PULLUP);
  pinMode(8, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(2, INPUT_PULLUP);
  pinMode(5, OUTPUT);
}

void loop(){
  ostatniPrzycisk = HIGH;
  int pot = analogRead(A5) ;
liczbaGracza = Serial.readStringUntil('\n');
stringGracza = liczbaGracza.toInt(); // zamieniamy zmienną string na int
 przycisk = digitalRead(2);
 
if(przycisk == LOW and ostatniPrzycisk == HIGH){
ostatniPrzycisk = przycisk;
digitalWrite(8, HIGH);
digitalWrite(7, LOW);
digitalWrite(6, LOW);
digitalWrite(5, LOW);
Serial.println("pierwsza Próba");
Serial.println (pot);
Serial.println ("pozostałe próby:");
Serial.println(proba);
}
 while (Serial.available() == 0);
  if (pot - stringGracza  <= 50 and pot - stringGracza >= -50) {
    Serial.println ("wygrałes");  
  }
    else  {
      proba -- ;
      Serial.println("pozostałe próby");
      Serial.println(proba);
      digitalWrite(7, HIGH);
      digitalWrite(8, LOW);
      digitalWrite(6, LOW);    
      digitalWrite(5, LOW);
      Serial.println (pot);
 while (Serial.available() == 0);
    }


 if (pot - stringGracza  <= 50 and pot - stringGracza >= -50) {
    Serial.println ("wygrałes");   
  }
    else{
      proba -- ;
      Serial.println("pozostałe próby");
      Serial.println(proba);
      digitalWrite(7, LOW);
      digitalWrite(8, LOW);
      digitalWrite(6, HIGH);  
      digitalWrite(5, LOW); 
    
Serial.println (pot);
 while (Serial.available() == 0);
    }

 if (pot - stringGracza  <= 50 and pot - stringGracza >= -50) {
    Serial.println ("wygrałes");   
  }
  
    else{
      Serial.println("game over");
      digitalWrite(7, HIGH);
      digitalWrite(8, HIGH);
      digitalWrite(6, HIGH);   
      digitalWrite(5, LOW);
      delay(2000);   
    }



}

Wiem, że jeszcze sporo zostało mi do zrobienia, ale czemu nie zawsze zatrzymuje mi się wtedy kiedy jest " while (Serial.available() == 0); " ? No i czemu zawsze zaraz po odpaleniu programu nie chce mi mówić "wygrałes" a potem już tak? ( na zdjeciu cały czas wpisywałem 1000 czyli cały czas powinienem wygrywać)

obraz.png

Link do komentarza
Share on other sites

@YURYS szczerze program jest trochę nieczytelny 😞 w warunkach zrób nawiasy żeby dla pewności odgrodzić porównania wartości i lepiej używaj operatorów && i || zamiast and i or, chyba że lubisz Pythona 😉 

 while (Serial.available() == 0);

Spróbuj się tego pozbyć, albo zamień tylko na odbieranie danych a nie oczekiwanie. Jeżeli ci się uda wydziel jakiś fragment do osobnej funkcji, dodaj kilka komentarzy żeby kod był czytelniejszy.

  • Pomogłeś! 1
Link do komentarza
Share on other sites

Dzień dobry,

oto mój pomysł na zadanie domowe 4.5, proszę o informacje czy wszystko zgodnie ze standardami.

 

Pozdrawiam serdecznie.

Jakub_St

#define zielona1 10
#define zielona2 11
#define zielona3 12
#define czerwona 9
#define przycisk 8

int wartoscPotencjometru = 0;
boolean bloker = true;
int iloscProb = 3;
String Proba;
int Proba1;

void setup (){
Serial.begin(9600);
  pinMode(przycisk, INPUT_PULLUP);
    pinMode(czerwona, OUTPUT);
       pinMode(zielona1, OUTPUT);
          pinMode(zielona2, OUTPUT);
             pinMode(zielona3, OUTPUT);
             
Serial.println("Nacisnij przycisk i zaczynamy nasza gre:");
}


void loop ()
{
if (digitalRead(przycisk) == LOW)
{
bloker = false;
delay (500);
iloscProb = 3;
Serial.println ("Podaj liczbe:");
Serial.println("ilosc prob:");
Serial.println(iloscProb);

digitalWrite (czerwona, LOW);
digitalWrite (zielona1, HIGH);
digitalWrite (zielona2, HIGH);
digitalWrite (zielona3, HIGH);  


}


if(Serial.available() >0){
        Proba = Serial.readStringUntil ('\n');
        Proba1 = Proba.toInt();
  
  wartoscPotencjometru = analogRead (A5);

  if ( bloker == true)
  {
    Serial.println("musisz uzyc przycisku");
  }
  else if (Proba1 <= (wartoscPotencjometru + 50) && Proba1 >= (wartoscPotencjometru - 50) )
  {
  Serial.println ("Zmiesciles sie w tolerancji, brawo. Jesli chcesz zagrac ponownie uzyj przycisku");
  delay (100);
  bloker = true;
  }else {
    Serial.println("Jescze raz");
    iloscProb = iloscProb - 1;
    Serial.println("ilosc prob:");
    Serial.println(iloscProb); 
  }

 if (iloscProb == 2)
  {
digitalWrite (zielona1, LOW);
digitalWrite (zielona2, HIGH);
digitalWrite (zielona3, HIGH);   
digitalWrite (9, LOW);
  } else if(iloscProb == 1)
{
digitalWrite (zielona1, LOW);
digitalWrite (zielona2, LOW);
digitalWrite (zielona3, HIGH);   
digitalWrite (czerwona, LOW);
  } else if (iloscProb == 0)
  {
digitalWrite (zielona1, LOW);
digitalWrite (zielona2, LOW);
digitalWrite (zielona3, LOW);   
digitalWrite (czerwona, HIGH);
bloker = true;
Serial.println ("Koniec gry nastepna osoba, zrestartuj przyciskiem");
}
}
}

 

  • Lubię! 1
Link do komentarza
Share on other sites

@Jakub_St taka pierwsza dobra rada 😉 Podmieniłem Ci kod, ale na przyszłość wklejaj uporządkowany:

image.thumb.png.f01321039b00ee8b984de5798ce1721c.png

Fajnie że zabrałeś sie za to zadanie, nie jest ono aż takie oczywiste. Na początek kilak drobiazgów: magiczna liczba


      digitalWrite (9, LOW);

Zmienne z małych liter:

    Proba = Serial.readStringUntil ('\n');
    Proba1 = Proba.toInt();

Liczba prób (ilość wody w zbiorniku, liczba jabłek na drzewie):


    iloscProb = 3;

Dobrze dać wszystko z wielkich liter i podkreślników:


#define czerwona 9
#define przycisk 8

Co do samej logiki kodu to całkiem całkiem, logika będzie spełniona, przycisk resetujący ok. Jedno co mógłbyś poprawić ale wiem że nie ma tego w kursie to włożyć obsługę ledów do tablic, żeby nie było tej kaskady ifów. Poczytaj o tablicach - przejrzyj np kurs STM32 i popróbuj 🙂 

https://forbot.pl/blog/kurs-stm32l4-wejscia-wyjscia-czyli-gpio-stm32-id46571

Link do komentarza
Share on other sites

Dzień dobry,

dziękuje serdecznie za porady do zadania 4.5. Przyjąłem i zastosowałem w praktyce w zadaniu 4.6.

Do tego zadania postanowiłem podejść trochę inaczej i wykorzystać elementy które zostały mi z kursu Elektronika I, Elektronika II oraz Elektronika Cyfrowa.

Postanowiłem że połączę wyjścia cyfrowe pin 7 oraz pin 8 poprzez rezystory o rożnej rezystancji (Kolejno:330Ω; 470Ω; 1kΩ; 3,3kΩ; 10kΩ) z Diodami które ustawiłem między fotorezystorami. W efekcie miał powstać efekt "stopniowania" ze wskazaniem która strona jest jaśniejsza. Niestety na zdjęciach jest to słabo widoczne. Myślę że gdybym użył rezystorów nie o aż tak skrajnych rezystancjach to efekt byłby lepszy. Niestety posiadam w tym momencie tylko takie.

Prosty program porównuje wartości z fotorezystorów z lewej i prawej strony i decyduje na który pin podać sygnał HIGH:

#define Lewa 7
#define Prawa 8

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


  pinMode(Lewa, OUTPUT);
  pinMode(Prawa, OUTPUT);
  digitalWrite(Lewa, LOW);
  digitalWrite(Prawa, LOW);
}
void loop() {

  int fotolewy = 0;
  int fotoprawy = 0;
  fotolewy = analogRead (A5);
  fotoprawy = analogRead (A4);

  Serial.println("Chwilowa wartosc na fotorezystorze lewym: ");
  Serial.println(fotolewy);
  Serial.println("Chwilowa wartosc na fotorezystorze prawym: ");
  Serial.println(fotoprawy);
  delay (500);

  if (fotolewy < fotoprawy)
  {
    digitalWrite(Lewa, HIGH);
    digitalWrite(Prawa, LOW);
  } else
  {
    digitalWrite(Prawa, HIGH);
    digitalWrite(Lewa, LOW);
  }
}

Poniżej zdjęcia układu oraz sposób jego działania. 

IMG_20210803_203608_8.thumb.jpg.32453a855ab75cadd9b1c4ed628c7922.jpg

IMG_20210803_203935_1.thumb.jpg.ae74a7f2cbcf3b02c5e128d171750498.jpgIMG_20210803_203924_1.thumb.jpg.0078e3305425867165b27bd58782b231.jpg

Link do komentarza
Share on other sites

Dnia 26.07.2021 o 07:56, Gieneq napisał:

w warunkach zrób nawiasy żeby dla pewności odgrodzić porównania wartości


 while (Serial.available() == 0);

Spróbuj się tego pozbyć, albo zamień tylko na odbieranie danych a nie oczekiwanie.

Dzięki za wcześniejsza odpowiedź

Niezbyt rozumiem gdzie dokładnie dołożyć tych nawiasów i jakie to mają być nawiasy.

 

Nie mam też niestety pomysłu na pozbywanie się mojego sposobu na oczekiwanie -

Pomógł byś?

Link do komentarza
Share on other sites

@Jakub_St ciekawe, możesz poczytać o tym jak zamieniać sygnały cyfrowe na analogowe, może to pomoże. Tematy jak "Arduino DAC", "resstor ladder" lub po polsku "drabinka rezystorowa" mogą być trafne 😉 W przypadku drabinki rezystorów każdy rezystor (bit) ma na wyjściu inny rezystor który wnosi swój prąd do sumy we wspólnym węźle. Im bardzie znaczący bit tym większy prąd jest wnoszony.

 

@YURYS coś takiego np:

 //while (Serial.available() == 0);
 // if (pot - stringGracza  <= 50 and pot - stringGracza >= -50) {
 //   Serial.println ("wygrałes");  
 // }

 while (Serial.available() == 0);

  if ((pot - stringGracza  <= 50) && (pot - stringGracza >= -50)) {
    Serial.println ("wygrałes");  
  }

Tak teraz patrzę na nazwy zmiennych, nie wpływa to na logikę ale jest nieczytelne, bo te nazwy są najwidoczniej zamienione:

liczbaGracza = Serial.readStringUntil('\n');
stringGracza = liczbaGracza.toInt(); // zamieniamy zmienną string na int

 

  • Pomogłeś! 1
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.