Skocz do zawartości

Kurs Arduino - #4 - Przetwornik ADC


Pomocna odpowiedź

@crus7pl wygląda dobrze 🙂 tylko jeszcze jedna uwaga:

if (odczytana_wartosc<prog) {
    wyslany_komunikat = true;
  }

  else {
    wyslany_komunikat = false;
   }

można zawinąć do:

wyslany_komunikat = odczytana_wartosc<prog;

 

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

Witam

Mam dwa pytania

1. Działania funkcji AnalogRead czy funkcja ta odpowiada za zamianę sczytanego napięcia analogowego na sygnał cyfrowy w bitach od 0 do 1023 czy te bity sygnał analogowy zamieniony na reprezentację przez bity?

2. W programie woltomierza napięcie się zwiększa w sposób przewidywalny tzn. im bardziej kręcę potencjometrem w lewo od wartości równej 0.00V tym większe napięcie się na nim odkłada tak do momentu kiedy napięcie na potencjometrze zaczyna wynosić około 4.40 V wtedy zaczyna dziwnie zmieniać swoje wartości. Mam pytanie czy to jest związane z złym potencjometrem, coś może jest źle z kodem, czy Arduino.

image.thumb.png.4a59b33477e29879c7c4815fc35468dd.png

int odczytanawartosc = 0;//UTWORZENIE ZMIENNEJ int O NAZWIE odczytanawartosc JAKO ZERO 
float napiecie = 0;//UTWORZENIE ZMIENNEJ foat O NAZWIE napiecie JAKO ZERO

void setup() {
Serial.begin(115200);//ROZPOCZĘCIE TRANSMISJI Z ARDUINO O ZADANEJ PRĘDKOŚCI

}

void loop() {
odczytanawartosc = analogRead(A0);//ODCZYTYWANIE WARTOŚĆ NAPIĘCIA Z PINU A0 PRZY POMOCY ADC(ANG ANALOG TO DIGITAL CONVERTER) KONWERSJA WARTOŚCI CIĄGŁEJ NA WARTOŚĆ CYFROWĄ OD 0 DO 1023 I PRZYPISANIE NIEJ DO ZMIENNEJ odczytanawartosc
napiecie=odczytanawartosc*(5.0/1024.0);//ZAMIANA ODCZYTANEJ WARTOŚCI CYFROWEJ NA WARTOŚĆ ANALOGOWĄ NAPIĘCIA OD 0V DO 5V 
Serial.println(napiecie);//POKAZANIE ZMIENIONEJ WARTOŚCI NA MONITORZE PORTU SZEREGOWEGO 
delay(200);//OPÓŹNIENIE 0,2 s W CELU LEPSZEGO WYŚWIETLANIA SIĘ ODCZYTANEJ WARTOŚCI NA MONITORZE PORTU SZEREGOWEGO

}

 

Link to post
Share on other sites
(edytowany)
15 godzin temu, wobyty napisał:

1. Działania funkcji AnalogRead czy funkcja ta odpowiada za zamianę sczytanego napięcia analogowego na sygnał cyfrowy w bitach od 0 do 1023 czy te bity sygnał analogowy zamieniony na reprezentację przez bity?

Trochę nie rozumiem pytania czy mógłbyś to jakoś inaczej opisać? W wyniku działania wspomnianej funkcji otrzymujesz odczyt z przetwornika ADC, który zwraca dane w zakresie od 0 do 1023, gdzie 0 to 0 V, a 1023 to 5V na wejściu (upraszczając).

15 godzin temu, wobyty napisał:

im bardziej kręcę potencjometrem w lewo od wartości równej 0.00V tym większe napięcie się na nim odkłada tak do momentu kiedy napięcie na potencjometrze zaczyna wynosić około 4.40 V wtedy zaczyna dziwnie zmieniać swoje wartości.

Drobne wahania są zupełnie normalne. Co dzieje się, gdy kręcisz potencjometrem jeszcze dalej (tak, aby na wejściu było 5 V)?

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

 

#define green 13
#define red 12
#define yellow 11
#define button 8
#define resistor A5

int valueToGuess = 0;
int attempt = 0;
int duration = 500;

void setup() {
  pinMode(green, OUTPUT);
  pinMode(red, OUTPUT);
  pinMode(yellow, OUTPUT);
  pinMode(button, INPUT_PULLUP);

  Serial.begin(9600);
  Serial.println("Zagrajmy - ustaw potencjometr i wciśnij guzik");
}

void loop() {
  String userInput = "";
  int userValue = 0;
  attempt = 0;
  while (digitalRead(button) == HIGH) {} //czekaj na przycisk
  valueToGuess = analogRead(resistor);
  
  while (attempt < 4) {
    attempt++;
    Serial.println("podaj liczbę od 0 do 1023");
    Serial.println("próba: "  + String(attempt));
    while (Serial.available() == 0); //czekaj na podaną przez użytkownika liczbę
    userInput = Serial.readStringUntil('\n');
    userValue = userInput.toInt();
    if (attempt == 3) {
      Serial.println("Przegrałeś, aby zagrać jeszcze raz pokręć potencjometrem i wciśnij guzik");
      blinkLed(red, duration);
      break;
    }
    if ((valueToGuess - 50) <= userValue && userValue <= (valueToGuess + 50)) {
      Serial.println("Zgadłeś w probie: " + String(attempt));
      blinkLed(green, duration);
      Serial.println("Aby zagrać jeszcze raz pokręć potencjometrem i wciśnij guzik");
      break;
    } else {
      Serial.println("Próbuj dalej");
      blinkLed(yellow, duration);
    }
  }
}

void blinkLed(int pin, int duration) {
  digitalWrite(pin, HIGH);
  delay(duration);
  digitalWrite(pin, LOW);
}

To moje rozwiązanie zadania 4.5 inspirowane rozwiązaniem @piret

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

@Raccoon fajnie że podesłałeś rozwiazanie. Możesz jeszcze spróbować wdrożyć w rozwiązaniu maszynę stanów, żeby dało się przegrać i wznowić grę od zera 🙂 Wtedy nie będzie potrzebne opóźnienie na początku:

while (digitalRead(button) == HIGH) {} //czekaj na przycisk

które co prawda działa, ale nie jest szczytem kunsztu programistycznego 😄 

Na razie jest dobrze, ale jak przeczytasz część z kontynuacji kursu o millis i maszynie stanów to zachęcam Cię do wrócenia do tego zadania.

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

@Gieneq wiem, dopiero przy pisaniu tego programu ogarnąłem jak działa funkcja loop() 🙂 - że jest wołana kolejny raz po zakończeniu poprzedniej iteracji a nie regularnie co jakiś odstęp czasu. Poza tym późno było jak to pisałem. Zapiszę sobie przypominajkę, żeby wrócić do tego zadania wyposażony w maszynę stanów.

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

u mnie 4.5 wygląda tak.. myślę że jest ok, co sądzicie?

#define SWITCH 2
#define YELLOW 3
#define RED 4
#define GREEN 5

int WartoscNaPotencmetrze=0;
   int Proby = 3;
  boolean raz = false;
 // boolean dwa = false;
  


void setup() {
  // put your setup code here, to run once:
pinMode(YELLOW,OUTPUT);
pinMode(RED,OUTPUT);
pinMode(GREEN,OUTPUT);

digitalWrite(YELLOW,LOW);
digitalWrite(RED,LOW);
digitalWrite(GREEN,LOW);
while(!Serial);
Serial.begin(9600);
pinMode(SWITCH,INPUT_PULLUP);
}

  

void loop() {
  // put your main code here, to run repeatedly:
 //Serial.println("Wcisnij przycisk");
  if(digitalRead(SWITCH) == LOW){
    WartoscNaPotencmetrze = digitalRead(A2);
    if(raz == false){
  Serial.println("Podaj liczbę");

  raz = true;
    }
    
  }
  if(raz == true){
    WartoscNaPotencmetrze = analogRead(A2);
    Serial.print(WartoscNaPotencmetrze);
    Serial.print("LICZBA ZAPISANA TO :"  );
    
    delay(15000);
    int LiczbaWpisana =  Serial.parseInt();
      
   
    if(LiczbaWpisana - WartoscNaPotencmetrze<= 50 && LiczbaWpisana >= WartoscNaPotencmetrze 
      || LiczbaWpisana - WartoscNaPotencmetrze >= -50  && LiczbaWpisana < WartoscNaPotencmetrze) {
      digitalWrite(YELLOW,LOW);
      digitalWrite(RED,LOW);
      digitalWrite(GREEN,HIGH);
      delay(5000);
      digitalWrite(GREEN,LOW);
    }else{
      digitalWrite(GREEN,LOW);
      digitalWrite(YELLOW,LOW);
      digitalWrite(RED,HIGH);
      delay(3000);
      digitalWrite(RED,LOW);
      
      
        for(;Proby > 1; Proby--){
          
          digitalWrite(RED,LOW);
           digitalWrite(GREEN,LOW);
           digitalWrite(YELLOW,HIGH);
           Serial.print("Podaj jeszcze raz liczbe:");
           delay(15000);
           LiczbaWpisana =  Serial.parseInt();
           delay(3000);
           digitalWrite(YELLOW,LOW);

        if(LiczbaWpisana - WartoscNaPotencmetrze<= 50 && LiczbaWpisana >= WartoscNaPotencmetrze 
      || LiczbaWpisana - WartoscNaPotencmetrze >= -50  && LiczbaWpisana < WartoscNaPotencmetrze){
      digitalWrite(YELLOW,LOW);
      digitalWrite(RED,LOW);
      digitalWrite(GREEN,HIGH);
      delay(5000);
      digitalWrite(GREEN,LOW);
    }else{
      digitalWrite(YELLOW,LOW);
      digitalWrite(RED,HIGH);
      digitalWrite(GREEN,LOW);
      delay(3000);
       digitalWrite(RED,LOW);
    }
    }
  
   
    }
  }
  //delay(20000);
 //raz == false;
 //Proby = 3;
 
}
  

 

 

Edytowano przez michaltoja
Link to post
Share on other sites

Tu moje rozwiązanie zadania 4.6 - ze wskazywaniem kierunku światła. Zrobiłem na 3 diodach bo na 5-ciu byłby bałagan na płytce a zasada działania taka sama. Tu układ narysowany w Fritzing - niestety znalazłem tylko czerwone LEDy 😞

adc4_6_bb.thumb.png.b904cccf050d84cfdc92b3673cf79893.png

A tu program:

#define center 13
#define left 12
#define right 11
#define leftInput A0
#define rightInput A1

float scaledLeft = 0;
float scaledRight = 0;
float difference = 0;

void setup() {
  pinMode(left, OUTPUT);
  pinMode(center, OUTPUT);
  pinMode(right, OUTPUT);

  digitalWrite(left, LOW);
  digitalWrite(center, LOW);
  digitalWrite(right, LOW);
}

void loop() {
  //magiczne stałe :(
  scaledLeft = (analogRead(leftInput) - 105) / 865.0;
  scaledRight = (analogRead(rightInput) - 95) / 827.0;
  difference = scaledLeft - scaledRight;
  if (difference < -0.1) {
    digitalWrite(left, HIGH);
    digitalWrite(center, LOW);
    digitalWrite(right, LOW);
  } else if (-0.1 <= difference && difference <= 0.1) {
    digitalWrite(left, LOW);
    digitalWrite(center, HIGH);
    digitalWrite(right, LOW);
  } else {
    digitalWrite(left, LOW);
    digitalWrite(center, LOW);
    digitalWrite(right, HIGH);
  }
  delay(50);
}

Magiczne stałe wzięte z pomiarów dzielników napięcia fotorezystor  - rezystor 1KΩ w celu przeskalowania wartości na przedział [0-1]. Dzięki temu potem łatwo można porównać wskazania i np. dołożyć jeszcze 2 diody z progiem włączenia jak różnica pomiarów wyniesie np. 0.2. 

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

@michaltoja witam na forum 🙂 Oj coś w tym kodzie mi nie pasuje. Czy przypadkiem wkleiłeś poprawną wersję? Pomijając już kwestie niepoprawnych wcięć w kodzie to np.: taka pętle wygląda już bardzo podejrzanie: "for(;Proby > 1; Proby--){".

@Raccoon dobra robota, powodzenia w dalszych eksperymentach 😉 Pamiętaj tylko na przyszłość o dodawaniu komentarzy do kodu, za jakiś czas sam zapomnisz np. czym były te "magiczne liczby" 😉

 

Link to post
Share on other sites

Siemka. Mam pytanie dlaczego w przykładzie "Wskaźnik na diodach" połączenie diod i oporników jest zrobione w inny sposób niż było zawsze ? Dlaczego dłuższa nóżka podłączona jest do minusa a nie do odpowiedniego pinu ? 

Link to post
Share on other sites

zadanie domowe 4.1 - na skrajnej wartości 0, dioda świeci praktycznie bez przerwy ale znacznie słabiej.

Dlaczego? Hmm, wydaje mi się, że z dwóch powodów:

1. przy opóźnieniu (odczytanym z potencjometra) 0 ms dioda nie zdąża się w pełni rozświetlić (pewnie nagrzać)

2. odczytanie wartości z wejścia A5 trwa, a ta instrukcja jest przed włączenie, czyli w stanie w którym (krótko bardzo, ale jednak) dioda jest wyłączona

Reasumując dioda włacza i wyłacza się bardzo szybko, ale jednak stan wyłączenia trwa dłużej, czyli w sumie mniej świeci.

Dobrze myślę?

Link to post
Share on other sites
5 godzin temu, pawelmb napisał:

dioda nie zdąża się w pełni rozświetlić (pewnie nagrzać)

Dioda to nie żarówka 😄

Chodzi o to, że mając opóźnienie 0 dioda naprzemiennie się włącza i wyłącza przez co powstaje (teoretycznie) prostokątny sygnał PWM. Przełączanie diód i żarówek (nie wszystkich) z dużą częstotliwością jest typowym zastosowaniem PWM, dzięki któremu możemy regulować ich jasność.

image.thumb.png.22311375b1988f0cbd99a7583dc8ea17.png

W skrócie dioda świeci przez x/T czasu, gdzie T= 2x, więc świeci z jasnością około 50%. (to jest teoria, w praktyce różnie bywa, czasem ciut więcej czasem ciut mniej, zależy od jakości użytych części).

Link to post
Share on other sites

@H1M4W4R1  Hmm, no dobrze, przejrzałem część o PWM (jeszcze muszę przeczytać dokładnie) i z silnikiem wyraźnie jest napisane:

Cytat

w momencie włączenia zasilania silnik natychmiast osiąga swoje maksymalne obroty? Nie, najpierw musi się rozpędzić.

No właśnie. Czyli z diodą jak rozumiem jest tak samo. Może z "nagrzewaniem się" trochę przesadziłem, ale jest to jednak efekt tego, że nie zdąży osiągnąć swojej maksymalnej jasności. Jakaś bezwładność wyraźnie. Czyż nie?

Link to post
Share on other sites
(edytowany)
8 minut temu, pawelmb napisał:

No właśnie. Czyli z diodą jak rozumiem jest tak samo. Może z "nagrzewaniem się" trochę przesadziłem, ale jest to jednak efekt tego, że nie zdąży osiągnąć swojej maksymalnej jasności. Jakaś bezwładność wyraźnie. Czyż nie?

Polecam poczytać trochę z fizyki 🙂. Dioda świeci z pełną jasnością, aczkolwiek ilość wydzielonego przez nią promieniowania świetlnego (fotonów) jest o połowę mniejsza, bo świeci z jasnością l1 = l0 przez czas t1 = 0.5*t0. Gdyby musiała się "nagrzewać" to w przypadku sterowania PWM posiadałaby nieliniową charakterystykę jasności (podstawy matematyki), co jednak ma miejsce, więc to sugeruje, że dioda zawsze świeci z pełną jasnością. Tutaj możesz zobaczyć to w Slow-Motion. Podobnie działają matryce LED z dużą ilością diód i multiplekserem.

Edytowano przez H1M4W4R1
Link to post
Share on other sites

@H1M4W4R1  Dobra, przekonałeś mnie. Dzięki. Nie czytałem fizyki, więc nie wiem. Dlatego pytam.

Czyli element bezwładnościowy jest, ale nie w diodzie (która z prędkością światła generuje pełną jasność, tak?), tylko w oku (a pewnie dokładniej w interpretacji sygnału oka przez mózg), który szybkie migotanie interpretuje jako stałe światło, a jednocześnie suma promieniowania świetlnego (fotonów) jest mniejsza, więc światło mniej intensywne.

Teraz jest dobrze?

  • Lubię! 1
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.