Skocz do zawartości
Komentator

Kurs Arduino - #4 - Przetwornik ADC

Pomocna odpowiedź

RC95, witam na forum, dziękuję za miłe słowa! Faktycznie w tej części nie ma informacji o xxx.toInt(), pierwotnie zamysł był taki, aby zmusić czytelników do szukania i główkowania 😉 Jeszcze zostawię to w takiej formie, jeśli pojawi się więcej problemów, to zrobię stosowną aktualizację.

Niestety nie wiem jak dokładnie chciałbyś inaczej podłączyć fotorezystor. W końcu dzielnik napięcia, to tak naprawdę szeregowe połączenie dwóch rezystorów. Nie rozumiem gdzie dokładnie chciałbyś dokonywać pomiaru. Spróbuj przerysować sobie schemat - może wtedy wszystko się rozjaśni.

Udostępnij ten post


Link to post
Share on other sites

Treker Przydało by się poprawić w kursie to co Pakos napisał.

Wybacz, że to piszę ale chwilę się męczyłem niczym doszedłem to tego co Pakos.

Już myślałem że uszkodziłem Arduino.

Mam kilka uwag do funkcji map(). W artykule zwracasz uwagę, że poprawne działanie "Wskaźnik na diodach" uzyskałeś zmieniając wartość z 1023 na 1021. Zgodnie z kodem funkcji map()
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
 return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

dla map(x, 0, 1023, 1, 5); piaty warunek zachodzi tylko gdy x=1023. Czyli sygnał analogowy podzielony jest na 4 przedziały i wystąpienie wartości max. Lepsze działanie kodu uzyskamy poprzez:

map(x, 0, 1023, 0, 5);

i zmieniając warunki lub

map(x, 0, 1023, 1, 6);

Udostępnij ten post


Link to post
Share on other sites

Krigare, dziękuję za sygnał - zapisuję do zmiany przy kolejnej aktualizacji kursu.

Udostępnij ten post


Link to post
Share on other sites

zadanie 4.6.

#define DiodaLL 12 //definicja diody skrajnej lewej
#define DiodaL 11 //definicja diody lewej
#define DiodaS 10 //definicja diody środkowej
#define DiodaP 9 //definicja diody prawej
#define DiodaPP 8 //definicja diody skrajnej prawej
#define FotoL A0 //definicja fotorezystora lewego
#define FotoP A1 //definicja fotorezystora prawego
int FRezL = 0; //odczyt fotorezystora lewego
int FRezP = 0; //odczyt fotorezystora prawego
int Wynik = 0; //różnica odczytów
void setup() {
digitalWrite(DiodaLL, LOW); //wyłączenie diod
digitalWrite(DiodaL, LOW);
digitalWrite(DiodaS, LOW);
digitalWrite(DiodaP, LOW);
digitalWrite(DiodaPP, LOW);
}
void loop() {
 FRezL = analogRead(FotoL); //zmienna otczytu lewej strony
 FRezL = map(FRezL, 40, 740, 1, 3); //mapowanie odczytu lewej strony
 FRezP = analogRead(FotoP); //zmienna odczytu prawej strony
 FRezP = map(FRezP, 40, 740, 1, 3); //mapowanie odczytu prawej strony
 Wynik = FRezP - FRezL; //różnica zmapowanych odczytów
 if(Wynik == 2){ //jeśli z prawej jest dużo więcej światła to
   digitalWrite(DiodaPP, HIGH); //zapal skrajnie prawą diodę
   digitalWrite(DiodaP, LOW); 
   digitalWrite(DiodaS, LOW);
   digitalWrite(DiodaL, LOW);
   digitalWrite(DiodaLL, LOW);
 } else if(Wynik == 1){ //jeśli jest więcej światła z prawej to
   digitalWrite(DiodaPP, LOW);
   digitalWrite(DiodaP, HIGH); //zapal prawą diodę
   digitalWrite(DiodaS, LOW);
   digitalWrite(DiodaL, LOW);
   digitalWrite(DiodaLL, LOW);
 } else if(Wynik == 0){ //jeśli jest tyle samo światła to
   digitalWrite(DiodaPP, LOW);
   digitalWrite(DiodaP, LOW);
   digitalWrite(DiodaS, HIGH); //zapal środkową diodę
   digitalWrite(DiodaL, LOW);
   digitalWrite(DiodaLL, LOW);
 } else if(Wynik == -1){ //jeśli jest więcej światła z lewej to
   digitalWrite(DiodaPP, LOW);
   digitalWrite(DiodaP, LOW);
   digitalWrite(DiodaS, LOW);
   digitalWrite(DiodaL, HIGH); //zapal lewą diodę
   digitalWrite(DiodaLL, LOW);
 } else if(Wynik == -2){ //jeśli jest dużo więcej światła z lewej to
   digitalWrite(DiodaPP, LOW);
   digitalWrite(DiodaP, LOW);
   digitalWrite(DiodaS, LOW);
   digitalWrite(DiodaL, LOW);
   digitalWrite(DiodaLL, HIGH); //zapal skrajnie lewą diodę
   }
   delay(100); // opóźnienie żeby układ nie wariował
}

i działa 🙂

Udostępnij ten post


Link to post
Share on other sites

wilq_89, witam na forum - super, że działa 🙂 Życzę powodzenia w dalszej nauce!

Udostępnij ten post


Link to post
Share on other sites

W ogóle to troszkę byłem zaskoczony po pierwszych próbach napisania czegokolwiek. Język jest bardzo intuicyjny (zaczynam z zerowym pojęciem o programowaniu) i widzę, że programowanie wymaga diabelskiej precyzji tego co muszę napisać- jeśli zostawię lukę w programie czyli warunki nie pokrywają 100% spektrum działania albo warunki nakładają się na siebie to program głupieje. I dodam jeszcze jedną uwagę- mi łatwiej jest najpierw cokolwiek zaprojektować jako komentarze do linii a potem przerabiać na kod. Po pierwsze łatwiej jest poskładać wszystko w całość a po drugie łatwiej wyszukać błąd w rozumowaniu programu. To dobry nawyk czy zaniechać? Z doświadczenia wiem, że jeśli od początku ktoś uczy się fuszerki to mu potem zostaje...

Udostępnij ten post


Link to post
Share on other sites

Praca domowa:

void setup() {
 pinMode(5, OUTPUT);
 Serial.begin(9600);

}


void loop() {

 odczyt = analogRead(A0);

 if (odczyt >= analogRead(A1)) {
   if (digitalRead(5) == LOW) {
     Serial.println(analogRead(A0));
   }
   digitalWrite(5, HIGH);
 }
 else {
   digitalWrite(5, LOW);
 }
 delay(200);
}

Udostępnij ten post


Link to post
Share on other sites
I dodam jeszcze jedną uwagę- mi łatwiej jest najpierw cokolwiek zaprojektować jako komentarze do linii a potem przerabiać na kod. Po pierwsze łatwiej jest poskładać wszystko w całość a po drugie łatwiej wyszukać błąd w rozumowaniu programu. To dobry nawyk czy zaniechać? Z doświadczenia wiem, że jeśli od początku ktoś uczy się fuszerki to mu potem zostaje...

Dość oryginalna taktyka, ale jeśli Tobie pomaga, to dobrze 😉 Zawsze możesz też rozpisywać działanie programu najpierw na kartce i dopiero później przerabiać to na kod. Oczywiście masz racje - programowanie, to bardzo precyzyjne zajęcie. Najlepszą nauką jest tutaj praktyka 😉

blazejszycz, witam na forum. Dzięki za podzielenie się Twoim kodem. Pamiętaj, aby stosować wcięcia w programie (tabulacje) i komentarze, bez tego innym może być ciężko analizować Twoje programy 😉

Udostępnij ten post


Link to post
Share on other sites

Cześć Wszystkim! Dzięki wielkie za kursy Forbota! Mam za sobą Elektronikę I i II. Teraz jadę z Arduino.

Poniżej propozycja zadania domowego 4.5. Jakie błędy robię, czego unikać, co zmienić? Będę wdzięczny za pomocną krytykę 🙂

 //Gra polega na odgadnięciu napięcia dzielnika. Gracz ma dwie próby symbolizowane przez 2 żółte LED. Kolor czerwony lub zielony LED oznacza odpowiednio przegraną lub wygraną. 


#define BUTTON          7
#define LED_YELLOW_1    8
#define LED_YELLOW_2    9
#define LED_RED         10
#define LED_GREEN       11
#define POTENTIOMETER   A5
String INTRO ="If you want to start a new game, please, press the button.";
String INSTRUCTION = "Change the potentiometer position and confirm the change by pushing the button.";
String ATTEMPT ="The number of atempts left: ";
String GIVE_NUMBER = "Please type a number from 0 to 1023. You win when you estimate the number set on the potentiometer with +/- 50 points of accuracy";
String CONGRATS ="Congratulations, you won!";
String FAILURE ="Sorry, you lost! Maybe you will be more lucky next time!";
String THE_RIGHT_VALUE = "The number from the potentiometer is ";
String WRONG_NUMBER ="Sorry, you typed the wrong number.";
String TYPED_NUMBER;
int TYPED_NUMBER_INT;
int WINNING_NUMBER=0;
int COUNTER=0;
int ATTEMPT_NUMBER=2;

void setup() // Start settings.
{
Serial.begin(9600);
pinMode(BUTTON,INPUT_PULLUP);
pinMode(LED_YELLOW_1,OUTPUT);
pinMode(LED_YELLOW_2,OUTPUT);
pinMode(LED_GREEN,OUTPUT);
pinMode(LED_RED,OUTPUT);
}

void loop() 
{
 while(COUNTER==0) //Starting the game, waiting for the confirmation.
 {
 Serial.println(INTRO);
 digitalWrite(LED_YELLOW_1,HIGH);
 digitalWrite(LED_YELLOW_2,HIGH);
 digitalWrite(LED_GREEN,LOW);
 digitalWrite(LED_RED,LOW);
 while (digitalRead(BUTTON)==1){};
 if (digitalRead(BUTTON)==0){COUNTER++;delay(1000);}
 }

 while (COUNTER==1)// Giving info on the game rules.
 {
 Serial.println(INSTRUCTION);
 while (digitalRead(BUTTON)==1){};
 if (digitalRead(BUTTON)==0){COUNTER++;delay(1000);}
 }

 while (COUNTER==2) // First attempt.
 { 
 int ATTEMPT_NUMBER=2;
 WINNING_NUMBER=analogRead(POTENTIOMETER);
 Serial.println(GIVE_NUMBER);
 delay(1000);
 Serial.println(ATTEMPT + ATTEMPT_NUMBER);
 while (Serial.available()==0){};

   if(Serial.available()>0) {TYPED_NUMBER=Serial.readStringUntil("\n");}
   TYPED_NUMBER_INT=TYPED_NUMBER.toInt();
   if((TYPED_NUMBER_INT<(WINNING_NUMBER+50))&&(TYPED_NUMBER_INT>(WINNING_NUMBER-50))) // Win at first try.
       {
       digitalWrite(LED_YELLOW_1,HIGH);
       digitalWrite(LED_YELLOW_2,HIGH);
       digitalWrite(LED_GREEN,HIGH);
       Serial.println(CONGRATS);
       delay(1000);
       Serial.println(THE_RIGHT_VALUE + WINNING_NUMBER);
       delay (3000);
       COUNTER=0;
       }
       else 
       {
       ATTEMPT_NUMBER--; //First mistake.
       digitalWrite(LED_YELLOW_1,HIGH);
       digitalWrite(LED_YELLOW_2,LOW);
       digitalWrite(LED_GREEN,LOW);
       digitalWrite(LED_RED,HIGH); 
       Serial.println(WRONG_NUMBER);
       delay(1000);
       Serial.println(GIVE_NUMBER);
       delay(1000);
       Serial.println(ATTEMPT + ATTEMPT_NUMBER);
       delay(1000);
       digitalWrite(LED_RED,LOW);
       while (Serial.available()==0){};

           if(Serial.available()>0) {TYPED_NUMBER=Serial.readStringUntil("\n");} //Second try.
           TYPED_NUMBER_INT=TYPED_NUMBER.toInt();
           if((TYPED_NUMBER_INT<(WINNING_NUMBER+50))&&(TYPED_NUMBER_INT>(WINNING_NUMBER-50)))// Win at second try.
           {
           digitalWrite(LED_YELLOW_1,HIGH);
           digitalWrite(LED_YELLOW_2,LOW);
           digitalWrite(LED_GREEN,HIGH);
           Serial.println(CONGRATS);
           delay(1000);
           Serial.println(THE_RIGHT_VALUE + WINNING_NUMBER);
           delay (3000);
           COUNTER=0;
           } 
           else //Second mistake. End of the game.
           {
           ATTEMPT_NUMBER--;
           digitalWrite(LED_YELLOW_1,LOW);
           digitalWrite(LED_YELLOW_2,LOW);
           digitalWrite(LED_GREEN,LOW);
           digitalWrite(LED_RED,HIGH); 

           Serial.println(WRONG_NUMBER);
           delay(1000);
           Serial.println(ATTEMPT + ATTEMPT_NUMBER);
           delay(3000);
           Serial.println (FAILURE);
           delay(1000);
           Serial.println(THE_RIGHT_VALUE + WINNING_NUMBER);
           COUNTER=0;
           }    
       }
 }
}

Udostępnij ten post


Link to post
Share on other sites

Gregorio, witam na forum 🙂 Cieszę się, że kursy są pomocne.

Jeśli chodzi o Twój program, to warto popracować nad kosmetyką, tzn.:

- WIELKIE_LITERY najlepiej zostawić na nazwy stałych. Nazwy zmiennych lepiej pisać małymi literami.

- Przydałoby się jeszcze więcej wcięć. Przykładowo zamiast:

  while (COUNTER==1)// Giving info on the game rules. 
 { 
 Serial.println(INSTRUCTION); 
 while (digitalRead(BUTTON)==1){}; 
 if (digitalRead(BUTTON)==0){COUNTER++;delay(1000);} 
 } 

Czytelniej będzie tak:

  while (COUNTER==1)// Giving info on the game rules. 
 { 
   Serial.println(INSTRUCTION); 
   while (digitalRead(BUTTON)==1){}; 
   if (digitalRead(BUTTON)==0){COUNTER++;delay(1000);} 
 } 

- Komentarze opisują ogólne zachowanie programu, a nie mówią co dokładnie robisz w danym miejscu. Za jakiś czas możesz zapomnieć, co dokładnie robi poniższa linia (a komentarz tego nie wyjaśnia):

if((TYPED_NUMBER_INT<(WINNING_NUMBER+50))&&(TYPED_NUMBER_INT>(WINNING_NUMBER-50))) // Win at first try. 

Oczywiście są to kwestie tylko kosmetyczne i nie wpływają na działanie programu 😉

Udostępnij ten post


Link to post
Share on other sites

Hej, czy ktoś mógłby mi wytłumaczyć działanie i zasady używania zmiennej boolean? Na prostym przykładzie z początków Arduino.

Dziękuję.

Udostępnij ten post


Link to post
Share on other sites

SOYER, a czego dokładnie nie rozumiesz? Boolean działa tak samo jak każda inna zmienna. Ten konkretny typ pozwala na wpisanie do niego tylko dwóch wartości 1 (PRAWDA) oraz 0 (FAŁSZ). W którym miejscu pojawia się problem 😉?

Udostępnij ten post


Link to post
Share on other sites

Kod użytkownika IGOR, mam nadzieję, że się nie obrazi (post z 20.05.2015):

#define zielona 8

#define czerwona 9

String odebraneDane = "";

boolean stanCzerwonej = false;

boolean stanZielonej = false;

void setup() {

Serial.begin(9600);

pinMode(zielona, OUTPUT);

pinMode(czerwona, OUTPUT);

digitalWrite(zielona, LOW);

digitalWrite(czerwona, LOW);

}

void loop() {

if(Serial.available() > 0) {

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

if (odebraneDane == "zielona") {

stanZielonej = !stanZielonej;

}

if (odebraneDane == "czerwona") {

stanCzerwonej = !stanCzerwonej;

}

if (odebraneDane != "czerwona" && odebraneDane != "zielona") {

Serial.println("Nieprawidlowy kolor! Wpisz 'zielona' lub 'czerwona'.");

}

digitalWrite(zielona, stanZielonej);

digitalWrite(czerwona, stanCzerwonej);

}

}

i teraz: skąd program wie, że "stanZielonej" odnosi się do pinu nr. 8, skoro pin nr. 8 ma zdefiniowany jako "zielona".

Więc jakim cudem wie w pierwszej pętli, że pin8 to "stanZielonej" i zmienia go na przeciwny(!stanZielonej)?

Czy żeby stosować zapis "stanZielonej = !stanZielonej" musi być stosowana zmienna boolean bo inaczej taki zapis nie będzie działał?

Rozumiem, że nazwa zmiennej boolean musi się różnić od nazwy zdefiniowanej pinowi, tak?

Po co i dlaczego na końcu programu jest zapis:

digitalWrite(zielona, stanZielonej);

digitalWrite(czerwona, stanCzerwonej);

czy to to samo co digitalWrite(czerwona, false(ew. LOW)) ???

bez tego wpisu program nie działa, co robi ten zapis? On jest w nawiasie pierwszego if-a, tego który pyta czy był jakiś wpis w konsoli, jeśli nie było wpisu (czyli kolejne if nic nie robią) ustawia piny zielona i czerwona tak jak zdefiniowano w zmiennej boolean czyli na false(LOW).

Ale jeśli był wpis w konsoli i wchodzą do gry kolejne if-y to skąd u licha program wie, że po wpisaniu stanZielonej = !stanZielonej odnosi się to do pinu 8?????

Stan na 11:12 10.11.2017:-) zaskoczyłem:-))

Program w if-ach działa tylko na zmiennych boolean, jeśli jest spełniony warunek to zmienia stan zmiennej, a dopiero po sprawdzeniu warunków i ustawieniu zmiennych przechodzi do sterowania diodami i każe im ustawić się według stanu zmiennych. TAK??

Kolejne moje pytanie, prosicie żeby korzystać z innego rodzaju zmiennych, char, int. Jak je odczytywać z konsoli bo komenda readStringUntil działa tylko na zmienną String.???

Jeszcze jedno:

Trochę zmodyfikowałem program:

#define zielona 8

#define czerwona 10

boolean zielona1 = false;

boolean czerwona1 = false;

String odebraneDane = ""; //Pusty ciąg odebranych danych

void setup() {

Serial.begin(9600); //Uruchomienie komunikacji

pinMode(zielona, OUTPUT); //Konfiguracja wyjść

pinMode(czerwona, OUTPUT);

digitalWrite(zielona, LOW); //Wyłączamy diody

digitalWrite(czerwona, LOW);

}

void loop() {

if(Serial.available() > 0) { //Czy Arduino odebrano dane

//Jeśli tak, to odczytujemy je do znaku końca linii i zapisz w zmiennej odebraneDane

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

if (odebraneDane == "zielona") { //Jeśli odebrano słowo "zielona"

zielona1 = !zielona1;

delay(1000);

zielona1 = !zielona1;

}

if (odebraneDane == "czerwona") { //Jeśli odebrano słowo "czerwona"

czerwona1 = !czerwona1;

delay(1000);

czerwona1 = !czerwona1;

}

}

digitalWrite(zielona, zielona1);

digitalWrite(czerwona, czerwona1);

}

Dlaczego po dopisaniu delay 1000ms i ponownej zmianie stanu diody program przestał w ogóle zapalać diody. Po zapaleniu powinien poczekać 1s i ją zgasić, a kolejne wpisanie komendy powinno ją znów odpalić. Czemu tak nie działa, a przed dopisaniem opóźnienia i drugiego zaprzeczenia stanu, działało...

Ok po zrozumieniu zasad boolean poprawiłem powyższy kod i już działa:-):

#define zielona 8

#define czerwona 10

boolean zielona1 = false;

boolean czerwona1 = false;

String odebraneDane = ""; //Pusty ciąg odebranych danych

void setup() {

Serial.begin(9600); //Uruchomienie komunikacji

pinMode(zielona, OUTPUT); //Konfiguracja wyjść

pinMode(czerwona, OUTPUT);

digitalWrite(zielona, LOW); //Wyłączamy diody

digitalWrite(czerwona, LOW);

}

void loop() {

if(Serial.available() > 0) { //Czy Arduino odebrano dane

//Jeśli tak, to odczytujemy je do znaku końca linii i zapisz w zmiennej odebraneDane

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

if (odebraneDane == "zielona") { //Jeśli odebrano słowo "zielona"

zielona1 = !zielona1;

digitalWrite(zielona, zielona1);

delay(1000);

zielona1 = !zielona1;

digitalWrite(zielona, zielona1);

}

if (odebraneDane == "czerwona") { //Jeśli odebrano słowo "czerwona"

czerwona1 = !czerwona1;

digitalWrite(czerwona, czerwona1);

delay(1000);

czerwona1 = !czerwona1;

digitalWrite(czerwona, czerwona1);

}

}

}

__________

Komentarz dodany przez: Treker

Kody programów należy umieszczać przez narzędzie KOD (znajdziesz je w edytorze pod ikonką "<>"). Dzięki niemu składania programów jest automatycznie kolorowana, a wtedy wszystkim znacznie łatwiej analizować wklejone programy. Proszę to poprawić - z góry dziękuję za zrozumienie i pomoc przy utrzymaniu porządku na forum.

Udostępnij ten post


Link to post
Share on other sites
Program w if-ach działa tylko na zmiennych boolean, jeśli jest spełniony warunek to zmienia stan zmiennej, a dopiero po sprawdzeniu warunków i ustawieniu zmiennych przechodzi do sterowania diodami i każe im ustawić się według stanu zmiennych. TAK??

Dokładnie wszystko się zgadza 🙂 Pamiętaj, aby wszystkie programy umieszczać na forum w tagach - bez tego ciężko analizować wklejane programy.

Udostępnij ten post


Link to post
Share on other sites

Efekt moich dzisiejszych ćwiczeń🙂

Kurcze, nie wstawiło się🙁

Jak wstawiać plik z kodem? Myślałem, że załącz plik...

Udostępnij ten post


Link to post
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...