Skocz do zawartości

Kurs Arduino - #4 - Przetwornik ADC


Pomocna odpowiedź

@Lukasz1979 odkładając teorię na bok, w takich hobbystycznych rozwiązaniach dzielnie przez 1023 lub 1024 nie spowoduje właściwie żadnej różnicy 😉 Warto o tym pamiętać, ale nie trzeba się tym przejmować.

Link do komentarza
Share on other sites

Jako "świeżaka" zastanawia mnie jedno.... Jeżeli korzystam z funkcji Serial.readStringUntil('\n') to (jeśli dobrze rozumiem) odczyt mogę przypisać jedynie do zmiennej typu String (tekstowej) - w innym wypadku już na etapie kompilacji pojawia się problem. Jakiej funkcji użyć, żeby odczytać z portu szeregowego wartość cyfrową (int lub byte)?

Próbowałem wykonać "zadanie domowe" z grą (zadanie 4.5) i na samym początku "poległem" przy próbie porównywania wartości odczytanej z potencjometru oraz wartości odebranej z terminala (nawet jeśli były takie same program traktował je jako różne - przypuszczam, że wynikało to z różnego typu zmiennych i wartość np. 10 odczytaną z potencjometru (jako int) nie była dla mikrokontrolera tożsama z wartością "10" odczytaną z terminala jako String). Będę wdzięczny za komentarz...

Link do komentarza
Share on other sites

15 minut temu, Lukasz1979 napisał:

Jako "świeżaka" zastanawia mnie jedno.... Jeżeli korzystam z funkcji Serial.readStringUntil('\n') to (jeśli dobrze rozumiem) odczyt mogę przypisać jedynie do zmiennej typu String (tekstowej) - w innym wypadku już na etapie kompilacji pojawia się problem. Jakiej funkcji użyć, żeby odczytać z portu szeregowego wartość cyfrową (int lub byte)?

Próbowałem wykonać "zadanie domowe" z grą (zadanie 4.5) i na samym początku "poległem" przy próbie porównywania wartości odczytanej z potencjometru oraz wartości odebranej z terminala (nawet jeśli były takie same program traktował je jako różne - przypuszczam, że wynikało to z różnego typu zmiennych i wartość np. 10 odczytaną z potencjometru (jako int) nie była dla mikrokontrolera tożsama z wartością "10" odczytaną z terminala jako String). Będę wdzięczny za komentarz...

Serial.parseInt() to funkcja odpowiadająca za odbieranie liczb całkowitych. Jesli chodzi o odbieranie stringa to można też użyć rzutowania na liczby całkowite, ale to opisane jest w dalszej częsci kursu, więc nie będę uprzedzał faktów.  Sam niedawno przez to przechodziłem.

Pozdrawiam

  • 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

7 minut temu, Qbek napisał:

Serial.parseInt() to funkcja odpowiadająca za odbieranie liczb całkowitych. Jesli chodzi o odbieranie stringa to można też użyć rzutowania na liczby całkowite, ale to opisane jest w dalszej częsci kursu, więc nie będę uprzedzał faktów.  Sam niedawno przez to przechodziłem.

Pozdrawiam

Serdeczne dzięki. Serial.parseInt() rozwiązało mój problem na tę chwilę. Kolejne etapy będę realizował sukcesywnie - tu chyba brakowało tej informacji w kursie (niezbędnej do wykonania zadania). Na szczęście jest forum!

Link do komentarza
Share on other sites

@Lukasz1979 nie tyle brakowało, co trochę celowo jej nie podawałem w kursie, aby zmusić do samodzielnego szukania, ale chyba przy najbliższej aktualizacji kursu jednak o tym wspomnę 🙂 Metod jest wiele, można również odczytać wartość jako String, a dopiero później wykorzystać opcje konwersji tekstu na liczbę: https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/toint/

Link do komentarza
Share on other sites

Dnia 2.11.2019 o 18:51, Treker napisał:

@Lukasz1979 nie tyle brakowało, co trochę celowo jej nie podawałem w kursie, aby zmusić do samodzielnego szukania, ale chyba przy najbliższej aktualizacji kursu jednak o tym wspomnę 🙂 Metod jest wiele, można również odczytać wartość jako String, a dopiero później wykorzystać opcje konwersji tekstu na liczbę: https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/toint/

Tak dla jasności - pisząc "brakowało" w żadnym wypadku nie chciałem umniejszać wartości kursu ani krytykować zawartości. Po prostu nie mogłem przeskoczyć tego zagadnienia (próbowałem eksperymentować z samym Serial.read() ale otrzymane wartości zdecydowanie nie były właściwe.... Dziękuję za link, zapoznam się 🙂

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

Mój pomysł na zadanie domowe (działa😀:

#define czer 4
#define nieb 5
#define ziel 3
#define przy 13
int pot = 0;            //wartosc z potencjometru
int wcisprzy = 0;       //do wcisnięcia przycisku
String odczytZpc = "";  //odczyt w string
int odczytZpcINT = 0;    //odczyt w int
int proby = 3;           //liczba prób którą możemy zmieniać
String probyST = "";     //liczba prób w string

void setup() {
 Serial.begin(9600);
 pinMode(czer, OUTPUT);
 pinMode(ziel, OUTPUT);
 pinMode(nieb, OUTPUT);
 pinMode(przy, INPUT_PULLUP);
}

void loop() {
  digitalWrite(ziel, LOW);
  digitalWrite(nieb, LOW);
  digitalWrite(czer, LOW);
  
  if(digitalRead(przy) == LOW) {     //gdy przycisk wcisniety ustaw 1
    wcisprzy = 1;                     //zmienna do wejscia w pętle
    Serial.println("Podaj liczbę");
    pot = analogRead(A5);               //odczytaj potencjometr
  }
  
  while(wcisprzy == 1){
  
  while(Serial.available() == 0){}                      //czekaj na wiadomosc
  
  odczytZpc = Serial.readStringUntil('\n');             //odczytaj
  odczytZpcINT = odczytZpc.toInt();                        //zmiana zmiennej na int
 
  if(pot - odczytZpcINT <= 50 && pot - odczytZpcINT >= -50){     //gdy odczyt +-50
    digitalWrite(ziel, HIGH);                       //zapal zieoną diodę
    digitalWrite(nieb, LOW);                       //zgas niebieską diodę
    Serial.println("Wygrałes!");                    //napisz na czacie
    delay(2000);                       
    Serial.println("Spróbuj jeszcze raz");
    wcisprzy = 0;                                  //wróć na poczatek void loop
  } else {
    digitalWrite(nieb, HIGH);                      //zapal nieb diodę
    proby = proby - 1;                             //zmiejszz licznik prob
    probyST = String(proby);                       //zamien probyST na aktulną watosc prob
    Serial.println("Nie udało się. Zostało prób: " + probyST); //poinformuj
    delay(500);
  }
  if(proby == 0){
    digitalWrite(nieb, LOW);
    digitalWrite(czer, HIGH);
    Serial.println("Niestety przegrałes, spróbuj ponownie zakręcić potencjometrem");
    delay(2000);
    wcisprzy = 0;                 //wróc na początek
  }
  }
  proby = 3;        //zmień liczbę prób znowu na 3
}

 

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

Zadanie domowe 4.4

Treker, czy dobrze wykonałem zadanie 4.4? Czy jest inna metoda aby to zrobić? Lepsza, lżejsza dla procesora, może bez używania dodatkowej zmiennej? Pytam bo dopiero stawiam pierwsze kroki a chciałbym się uczyć zgodnie ze sztuką programoawnia.

ps. wpadnięcie na to rozwiązanie zajęło mi kilka dni....

Bez tytułu.jpg

Aktualizacja:

#define ledll 6
#define ledl 5
#define leds 4
#define ledp 3
#define ledpp 2

int dzielniklewy= 0;
int dzielnikprawy= 0;
bool blokada=0;

int lewymap=0;
int prawymap=0;
int diody=0;

void setup(){
  
  pinMode(ledll, OUTPUT);
  pinMode(ledl, OUTPUT);
  pinMode(leds, OUTPUT);
  pinMode(ledp, OUTPUT);
  pinMode(ledpp, OUTPUT);
  
  digitalWrite (ledll, LOW);
  digitalWrite (ledl, LOW);
  digitalWrite (leds, LOW);
  digitalWrite (ledp, LOW);
  digitalWrite (ledpp, LOW);
  
  Serial.begin(9600);
  
}

void loop(){

  dzielniklewy=analogRead(A1);
  dzielnikprawy=analogRead(A2);

  lewymap = map(dzielniklewy,350,650,1,4);
  prawymap = map(dzielnikprawy,350,650,1,4);
  diody= lewymap - prawymap;
  
  
  if (diody==-6 || diody==-5 || diody==-4){
  digitalWrite (ledll, LOW);
  digitalWrite (ledl, LOW);
  digitalWrite (leds, LOW);
  digitalWrite (ledp, LOW);
  digitalWrite (ledpp, HIGH);
  }
  if (diody==-3 || diody==-2){
  digitalWrite (ledll, LOW);
  digitalWrite (ledl, LOW);
  digitalWrite (leds, LOW);
  digitalWrite (ledp, HIGH);
  digitalWrite (ledpp, LOW);
  }
  if (diody==-1 || diody==0 || diody==1){
  digitalWrite (ledll, LOW);
  digitalWrite (ledl, LOW);
  digitalWrite (leds, HIGH);
  digitalWrite (ledp, LOW);
  digitalWrite (ledpp, LOW);
  }
  if (diody==3 || diody==2){
  digitalWrite (ledll, LOW);
  digitalWrite (ledl, HIGH);
  digitalWrite (leds, LOW);
  digitalWrite (ledp, LOW);
  digitalWrite (ledpp, LOW);
  }
  if (diody==6 || diody==5 || diody==4){
  digitalWrite (ledll, HIGH);
  digitalWrite (ledl, LOW);
  digitalWrite (leds, LOW);
  digitalWrite (ledp, LOW);
  digitalWrite (ledpp, LOW);
  }
    
/*  
  Serial.println(diody);
  Serial.print("lewy dzielnik ");  Serial.print(dzielniklewy);
  Serial.print("     ");
  Serial.print("prawy dzielnik "); Serial.println(dzielnikprawy);
  
  Serial.print("lewe mapowanie "); Serial.print(lewymap);
  Serial.print("     ");
  Serial.print("prawe mapowanie "); Serial.println(prawymap);
  Serial.println();
 
   delay(1000);
*/  
  delay(50);
}

A oto mój kod, jeszcze czekam na dostawę płytki Arduino ale już działam w symulatorze. https://drive.google.com/open?id=1GvVWKDdrWx0I9Rnu4j98uVurnfbdXgmV

Teraz tylko kwestia dobrać odpowiednie parametry przełączania diod i byłoby jeszcze lepiej. Generalnie jest to mały symulator robota światłoluba, czy się mylę?

Link do komentarza
Share on other sites

Dnia 21.12.2019 o 16:10, bakardi92 napisał:

Treker, czy dobrze wykonałem zadanie 4.4? Czy jest inna metoda aby to zrobić? Lepsza, lżejsza dla procesora, może bez używania dodatkowej zmiennej? Pytam bo dopiero stawiam pierwsze kroki a chciałbym się uczyć zgodnie ze sztuką programoawnia.

W tego typu programach raczej trudno będzie wskazać jakąś "lżejszą" wersję dla procesora, bo te zadania są dla niego bardzo łatwe. Na tym etapie nauki można śmiało założyć, że jeśli układ działa, a program nie jest jakoś przesadnie skomplikowany to wszystko jest dobrze. Najważniejsze, że siedziałeś tak długo aż coś wymyśliłeś - takie podejście zasługuje na pochwałę 😉

Drugi kod, który wkleiłeś na pewno da się skrócić za pomocą pętli, ale na tym etapie też bym się nie upierał, że jest to niezbędne. Najważniejsze, że udało się napisać działający program. Jak przyjdzie płytka i będziesz testował całość w praktyce to też będzie łatwiej, bo symulatory nie są idealne.

Dnia 21.12.2019 o 16:10, bakardi92 napisał:

Generalnie jest to mały symulator robota światłoluba, czy się mylę?

W sumie masz rację, kwestia tylko zamiany diod na silniki i powstanie z tego mały światłolub 😉

Link do komentarza
Share on other sites

Witam wszystkich

I chciałbym podziękować za część tego jak i całego kursu dzięki tej części skonstruowałem w pełni działające urządzenie do pokazywania stanu naładowania baterii AA oraz AAA, przy okazji umieściłem potencjometr do regulacji zakresu badanego ogniwa lub baterii, przy okazji wyeliminowałem powstające w układzie zakłócenia, który mogły wpłynąć na pomiar. Kod raczej nie jest potrzebny bo nie okłamujmy się to jest banalne, ale gdyby ktoś potrzebował to umieszczę, 

int x;


void setup() {
  // put your setup code here, to run once:
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);

}

void loop() {
  // put your main code here, to run repeatedly:
  x = analogRead(A5);
  x = map(x, 0, 324, 1, 4);

  if(x == 1){
    digitalWrite(5, HIGH);
    digitalWrite(4, LOW);
    digitalWrite(3, LOW);
    digitalWrite(2, LOW);
  }

  if (x==2){
    digitalWrite(5, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(3, LOW);
    digitalWrite(2, LOW);
  }

  if (x==3){
    digitalWrite(5, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(2, LOW);
  }

  if(x==4){
    digitalWrite(5, HIGH);
    digitalWrite(4, HIGH);
    digitalWrite(3, HIGH);
    digitalWrite(2, HIGH);
  }

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

@lploch01 witam na forum, cieszę się, że kurs jest cały czas pomocny 🙂 Jeśli chciałbyś jeszcze dopracować program to pamiętaj, że w przyszłości warto wykorzystać tutaj konstrukcję switch...case lub całkiem skrócić wszystko za pomocą pętli (np. for). Warto poeksperymentować z tym w wolnym czasie.

Link do komentarza
Share on other sites

Smaruje zadanie 4.5

nie jest skończone, nie czepiać się nierównych nawiasów 😛

chciałem sprawdzić czy nie ma błędów i skompilować to co nabazgrałem.

i wywala mi expected primary-expression before '=' token przy #define przycisk = 11 

o co chodzi?? przecież w tym miejscu jest wszystko ok..

 

#define czer = 8
#define pom = 9
#define ziel = 10
#define przycisk = 11
	int wartosc = 0;
String odebrane = "";
	bool send = false;
void setup() {
Serial.begin(9600);
pinMode(czer, OUTPUT);
pinMode(pom, OUTPUT);
pinMode(ziel, OUTPUT);
pinMode(przycisk, INPUT_PULLUP);
}
	void loop() {
wartosc = analogRead(A5);
if (digitalRead(przycisk) == LOW){
  Serial.println("Podaj liczbe:");
  delay(1000);
  if(Serial.available()>0) {
    odebrane = Serial.readStringUntil('\n'); 
  }
}
}
	

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.