Skocz do zawartości

Kurs Arduino - #4 - Przetwornik ADC


Pomocna odpowiedź

Siemka, mam problem z zadaniem domowym 4.6 z fotorezystorami

Dokładnie to chodzi o tą część - "Czy analizując różnicę między pomiarami z dwóch czujników jesteś w stanie napisać program, który określi, po której stronie płytki znajduje się silniejsze źródło światła? Spróbuj wskazać kierunek na 5 diodach (bardziej w lewo, środek, bardziej w prawo itd.)!"

 

W moim programie naprzemiennie świeci sie dioda lewa żółta i czerwona, po dodaniu dodatkowego źródła światła, oprócz nich świecą sie jedynie po prawej stronie diody tak jak powinny.

Naprowadzi ktoś co jest nie tak z kodem?

#define grleft 12 // zielony lewy
#define ylleft 11 // zolty lewy
#define rd 10
#define ylright 9
#define grright 8

int prawy;
int lewy;

void setup() {

pinMode(grleft, OUTPUT);
pinMode(ylleft, OUTPUT);
pinMode(rd, OUTPUT);
pinMode(grright, OUTPUT);
pinMode(grright, OUTPUT);


    digitalWrite(grright, LOW);
    digitalWrite(ylright, LOW);
    digitalWrite(rd, LOW);
    digitalWrite(ylleft, LOW);
    digitalWrite(grleft, LOW);

  Serial.begin(9600);
  // put your setup code here, to run once:





}

void loop() {
  prawy = analogRead(A5);
  lewy = analogRead(A4); //odczyt z adc


  if(prawy > 800){
    digitalWrite(grright, HIGH);
    digitalWrite(ylright, LOW);
    digitalWrite(rd, LOW);
    digitalWrite(ylleft, LOW);
    digitalWrite(grleft, LOW);
    Serial.println("swieci zielony prawy");
    delay(50);
  }
if((prawy > 400) && (prawy < 800)){
    digitalWrite(grright, LOW);
    digitalWrite(ylright, HIGH);
    digitalWrite(rd, LOW);
    digitalWrite(ylleft, LOW);
    digitalWrite(grleft, LOW);
    Serial.println("swieci zolty prawy");
    delay(50);
 }
if((prawy < 400) && (lewy < 400)){
    digitalWrite(grright, LOW);
    digitalWrite(ylright, LOW);
    digitalWrite(rd, HIGH);
    digitalWrite(ylleft, LOW);
    digitalWrite(grleft, LOW);
    Serial.println("swieci czerwony");
    delay(50);
 }
if((lewy > 400) && (lewy < 800));{
    digitalWrite(grright, LOW);
    digitalWrite(ylright, LOW);
    digitalWrite(rd, LOW);
    digitalWrite(ylleft, HIGH);
    digitalWrite(grleft, LOW);
    Serial.println("swieci zolty lewy");
    delay(50);

}
if(lewy > 800){
  digitalWrite(grright, LOW);
    digitalWrite(ylright, LOW);
    digitalWrite(rd, LOW);
    digitalWrite(ylleft, LOW);
    digitalWrite(grleft, HIGH);
    Serial.println("swieci zielon lewy");
    delay(50);
}

  

  
  // put your main code here, to run repeatedly:

}

 

Link do komentarza
Share on other sites

@Djfaraon a spróbuj odjąć od siebie 2 pomiary. Jeżeli różnica wyjdzie 0 to znaczy że pomiary są podobne = światło na wprost.

Zależnie jak masz zbudowany układ to np. jeżeli masz różnicę -100 to znaczy że lewy jest bardziej oświetlony, a jak +100 to znaczy że prawy. Czyli znak będzie informował o kierunku, ale wartość bezwzględna o tym jak duża jest różnica.

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

  1. @@Gieneq próbowałem zrobić podobnie jak poradziłeś, przy okazji znalazłem jeszcze jeden błąd w kodzie. Ale problem polega na tym, że nie ważne co zrobie cały czas świeci sie pomarańczowa lewa dioda. Przeglądałem już kod dziesiątki razy i nie mam pojęcia co to powoduje. 😕

 

     Edit:Dobra, problem rozwiązany, miałem średnik wstawiony w niewłaściwe miejsce, troche siedziałem zanim to znalazłem ale teraz hula jak złe. 😀

Edytowano przez Djfaraon
Aktualizacja
  • Lubię! 2
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

Zadanie z 5 diodami zmodyfikowałem w ten sposób, aby diody pokazywały mi stopień naładowania baterii 1.5V. Do jednego z wolnych wejść GND podłączyłem wolny kabel, z kolei z wejścia A5 (od potencjometru) kabel podłączyłem do plusa baterii.

Funkcję map przeliczyłem w ten sposób, aby:
- dla wartości 1V pokazywana była minimalna wartość (czerwona dioda dolna - bateria rozładowana),
- dla wartości 1.5V pokazywana była maksymalna wartość (górna dioda zielona - bateria nieużywana).

Oto zmieniony fragment kodu:
 

void loop() {
  odczytanaWartosc = analogRead(A5); //Odcztanie wartości z wejścia analogowego A5
  odczytanaWartosc = map(odczytanaWartosc, 205, 300, 1, 5); //Przeskalowanie wartości dla baterii 1,5V, 205 to 1V, 300 to 1.5V

A oto efekt na dwóch różnych bateriach 🙂

335695848_bateria1V.thumb.jpg.b00aa5c6db0e46c09767a6e396cee01e.jpg

1614353298_bateria15V.thumb.jpg.429728a58509af5cf33b2cb0f90d0a71.jpg

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

@slv7 ciekawy pomysł 🙂 Zdaję sobie sprawę, że nie wszystko jest na początek wiadome, ale jakbym podłączał baterię do wyprowadzeń to trochę bym się bał, nie wiem czy miałeś tu pewne wątpliwości.

Gdybyś podłączył baterię do wyprowadzenia ustawionego jako wyjście ze stanem 0 to byłoby bardzo źle, bo popłynie spory prąd. Na szczęście jak startuje Arduino to wszystkie wyjścia są ustawione jako wejścia czyli mają wysoką impedanację (wysoki opór) i prąd płynie znikomy.

Na wszelki wypadek dałbym rezystor w szeregu z baterią, żeby ograniczyć ewentualny za duży prąd. Rezystor nie wprowadza spadku napięcia (zakłóceń pomiaru) bo prąd przy pomiarze jest mały, a mały prąd daje mały spadek napięcia.

Link do komentarza
Share on other sites

Siemka, od dawna walcze z zadaniem z grą. Może ktoś zerknie na kod i mnie troche naprowadzi bo nie mam już pomysłów. 🙂

 

#define przycisk 11
#define zielona 8
#define zolta 9
#define czerwona 10

int obrot;
boolean gra;
int wygrana;
int nacisk;
int blad;
int liczba;
int proby = 0;
int wpisane;
String odbior;


void setup() {

  pinMode(przycisk, INPUT_PULLUP);
  pinMode(zielona, OUTPUT);
  pinMode(zolta, OUTPUT);
  pinMode(zielona, OUTPUT);

  Serial.begin(9600);
  Serial.println("witaj w grze");
  
  // put your setup code here, to run once:

}

void loop() {

  
  nacisk = digitalRead(przycisk);
  obrot = analogRead(A5);

 if(nacisk == LOW){
  gra = true;
  Serial.println("podaj wartość od 1 dp 1024, masz 3 proby");
 }

  if(gra == true){

    digitalWrite(zielona, LOW);
    digitalWrite(zolta, LOW);
    digitalWrite(czerwona, LOW);

    while(!Serial) delay(10); // czekamy na otwarcie serial monitora
    Serial.println("Przekrec potencjometr i nacisnij przycisk.");

    
   wygrana = obrot < obrot + 50 && obrot - 50 < obrot; // warunek wygranej

   if(Serial.available() > 0){
   odbior = Serial.readStringUntil('\n');
   }
  
 while((odbior = wygrana) && (proby <3)){
  digitalWrite(zielona, HIGH);
  digitalWrite(zolta, LOW);
  digitalWrite(czerwona, LOW);
  Serial.println("brawo");
  delay(50); 
 }
while(proby <2){
  digitalWrite(zolta, HIGH);
  digitalWrite(zielona, LOW);
  digitalWrite(czerwona, LOW);
  proby = proby + 1;
  Serial.println("blad");
  
  delay(50); 
}

while(proby = 3){
  digitalWrite(czerwona, HIGH);
  digitalWrite(zolta, LOW);
  digitalWrite(zielona, LOW);
  Serial.println("zjebales");
  delay(50);
}





}
  
  // put your main code here, to run repeatedly:

}

 

Link do komentarza
Share on other sites

Dnia 27.05.2015 o 17:24, igor napisał:

4.4



int wartoscA5 = 0;
int prog = 0;
boolean wyslano = false;

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

void loop() {
 wartoscA5 = analogRead(A5);
 prog = analogRead(A4);

 if (wartoscA5 < prog) {
   digitalWrite(8, HIGH);
   if (wyslano == false) {
   Serial.println(wartoscA5);
   wyslano = true;
   }
 }
 else {
   digitalWrite(8, LOW);
   wyslano = false;
 }
 delay(100);
}
 

Da się jakoś bez tworzenia zmiennej "wyslano"?

4.5



// Przypisanie pinów.
#define led_zolta 8
#define led_zielona 7
#define led_czerwona 9
#define przycisk 5
#define pin_odczyt A4

int odczyt = 0; // odczyt z potencjometru
String podana_liczba = 0; // liczba podana przez gracza
int podana_liczba_int = 0; // liczba podana przez gracza przekształcona na zmienną int
byte proby = 2; // ilość prób jakie pozostały do końca gry
boolean od_nowa = true; // czy gramy od nowa, czy kontynuujemy grę

void setup() {
 pinMode(przycisk, INPUT_PULLUP);
 pinMode(led_czerwona, OUTPUT);
 pinMode(led_zielona, OUTPUT);
 pinMode(led_zolta, OUTPUT);
 Serial.begin(9600);
}

void loop() {

 if (od_nowa == true) { // jeśli rozpoczynamy grę lub gramy od nowa
   proby = 2;
   digitalWrite(led_zielona, LOW);
   digitalWrite(led_zolta, LOW);
   digitalWrite(led_czerwona, LOW);

   while(!Serial) delay(10); // czekamy na otwarcie serial monitora
   Serial.println("Przekrec potencjometr i nacisnij przycisk.");

   while (digitalRead(przycisk) ==LOW) delay(20); // czekamy na zwolnienie przycisku po wznowieniu gry
   while (digitalRead(przycisk) == HIGH) delay(20); // czekamy na wciśnięcie przycisku
   odczyt = analogRead(pin_odczyt); // sczytujemy ustawienie potencjometru
   Serial.println("Podaj liczbe z zakresu 0 - 1023.");
 }

 while (Serial.available() == 0); // czekamy na podanie liczby

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

 if (odczyt - podana_liczba_int <= 50 && odczyt - podana_liczba_int >= -50) { // jeśli podana liczba jest +-50 równa odczytowi
   Serial.println("Udalo Ci sie trafic! Brawo.");
   digitalWrite(led_zielona, HIGH);
   digitalWrite(led_zolta, LOW);
   od_nowa = true;
   Serial.println("Jesli chcesz zagrac ponownie - nacisnij przycisk.");
   while (digitalRead(przycisk) == HIGH) delay(20); // czekamy na naciśnięcie przycisku
 }
 else { // jeśli podana liczba nie jest +-50 równa odczytowi

   if (proby > 0) { // jeśli mamy jeszcze próby
     od_nowa = false; // nie rozpoczynamy od nowa
     digitalWrite(led_zolta, HIGH);
     Serial.print("Nie trafiles. Pozostalo prob: ");
     Serial.println(proby);
     Serial.println("Podaj kolejna liczbe:");
     proby --; // odejmujemy jedną próbę
     while(Serial.available() == 0); // czekamy na podanie kolejnej liczby
   }
   else { // nie mamy już prób
     digitalWrite(led_czerwona, HIGH);
     digitalWrite(led_zolta, LOW);
     Serial.println("Przegrales. Jesli chcesz zagrac ponownie - nacisnij przycisk.");
     od_nowa = true; // rozpoczynamy następną grę od nowa
     while (digitalRead(przycisk) == HIGH) delay(20); // czekamy na naciśnięcie przycisku
   }
 } 
 delay(5);   
}
 

Tu też nie wiem czy optymalnie to napisałem...

Mam pytanie czy zmienne można przypisać na początku pętli loop, czy muszą być w tym konkretnym miejscu? 

 

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

 

Edytowano przez mn860618
brak okna na kod
Link do komentarza
Share on other sites

Mozesz utworzyc w loop() ale bedzie to zmienna lokalna i przy kazdym obiegu petli bedzie tworzona od nowa.. (tracisz zapisana wartosc wczesniejsza)...jezeli chcesz zapamietac wartosc to przed typem dopisujesz "static" , taka zmienna jest tworzona tylko raz i sobie istnieje

Edytowano przez farmaceuta
Link do komentarza
Share on other sites

@farmaceuta podał byś przykład zastosowania?

@mn860618 po zastosowaniu się do porad, problem się zmienił, po wciśnięciu przycisku program na zmiane pokazuje komunikaty, o wciśnięciu przycisku i prosbie o podanie liczby oraz o starcie gry 😕 mam pustke w głowie.

 

Jest sens to poprawiać? Czy lepiej zacząć pisać program od początku?

 

Link do komentarza
Share on other sites

int x; 
void setup() {
}
void loop() {
  x++;
}

To jest zmienna globalna...widziana w calym kodzie i istniejaca caly czas...

void setup() {
}
void loop() {
  int x = 0;
  x++;
}

To jest zmienna lokalna tworzona od nowa przy kazdym obiegu petli...takie zmienne uzywasz tylko do przechowywania tymczasowych wartosci do obliczen etc..(dodatkowo odrazu musisz przypisac jakas wartosc do takiej zmiennej bo moga sie w niej znajdowac "smieci"

void setup() {
}
void loop() {
  static int x = 0;
  x++;
}

Tu masz zmienna ktora istnieje czaly czas i tylko raz jest inicjowana (jak zmienna globalna) z tym ze mozesz jej uzywac tylko w petli w ktorej sie znajduje..w tym przypadku tylko w petli loop()

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

1 godzinę temu, Djfaraon napisał:

@farmaceuta podał byś przykład zastosowania?

@mn860618 po zastosowaniu się do porad, problem się zmienił, po wciśnięciu przycisku program na zmiane pokazuje komunikaty, o wciśnięciu przycisku i prosbie o podanie liczby oraz o starcie gry 😕 mam pustke w głowie.

 

Jest sens to poprawiać? Czy lepiej zacząć pisać program od początku?

 

Nie przejmuj się że masz pustkę, tak chyba miał każdy. Każdego dnia trochę próbować bardziej rutynowo... Do tego podejdź. 🙃

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

Dnia 28.05.2015 o 18:50, Treker napisał:

Pewnie się da, ale tak jest bardzo dobrze. Jedynie proponowałbym nazywać inaczej zmienne:


  wartoscA5 = analogRead(A5); 
 

Taki zapis nie mówi zbyt dużo, lepiej nazwać zmienną jako "czujnikSwiatla", czyli tak, aby wskazywać wykorzystanie zmiennej. To, że jest tam trzymana wartość odczytana z A5 jest mało pomocne.

Dlaczego w drugim kodzie napisałeś takie dwie linijki?


    while (digitalRead(przycisk) ==LOW) delay(20); // czekamy na zwolnienie przycisku po wznowieniu gry 
   while (digitalRead(przycisk) == HIGH) delay(20); // czekamy na wciśnięcie przycisku 
 

Hejka, nie mogę znaleźć dyskusji na temat tych dwóch pętli while przedzielonych pętla while o przeciwnym warunku ale chyba ma to na celu w programie odseparowanie je od siebie podczas gdy jest wciśnięty przycisk. Puszczamy przycisk i wskakuje do tej w której HIGH stan i czeka na przerwanie go poprzez wciśnięcie przycisku i doprowadzenie LOW i wyjście z pętli. Treker czy jest inne rozwiązanie ?

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.