Skocz do zawartości

Pomocna odpowiedź

(edytowany)

Przy setupie jak już masz tablicę z pinami to możesz kontynuować jej używanie - domyslam się że jest to pozostałość z poprzedniego podejścia, ale to nie jest teraz istotne.

Constrain najlepiej użyj przed map, wtedy masz pewność jakie argumenty wchodzą do kolejnego etapu. (Edit: no właśnie 🙂 nie zauważyłem kolejnej strony)

A na czym polega nie działanie?

 

Edytowano przez Gieneq

@Gieneq 

Problem tkwi chyba w samym podłączeniu diód do układu mimo, że jest wręcz podręcznikowe tak jak w każdym przerabianym przykładzie w kursie. 

Ponieważ odczytywanie wartości z fotorezystorów czy to czystych, czy to zmapowanych i ograniczonych przebiega jak najbardziej pomyślnie i dobrze. 

Samo odpalanie diód nie działa ponieważ w żadnym z możliwych przypadków nie świeci się ani jedna 😕 

@Gieneq @ethanak

DOBRA! Trochę się spóźnię do pracy ale musiałem zakończyć temat tego zadania.

Zmieniłem trochę sposób podłączenia diod do układu i DZIAAAAAAAAŁAAAAAAAA! 

Będę teraz pamiętał, że ten sposób sprawdza się lepiej od poprzedniego. 

Dziękuje jeszcze raz bardzo wszystkim za pomoc! 😍

  • Lubię! 2
  • 2 tygodnie później...

Witajcie,

Przedstawiam kod do Zadania 4.5. Wszystko działa aczkolwiek miałem pewien problem, który udało mi się rozwiązać dzięki przeczytaniu 11 stron komentarzy w tym wątku i dopisaniu w odpowiednim miejscu Serial.read(); (oznaczone komentarzem w kodzie). Mianowicie, kiedy nie było Serial.read(); to przy podaniu liczby i jej zatwierdzeniu, pętla wykonywała się dwa razy. Sytuację przedstawiam na dołączonym screenie - na potrzeby "wersji beta" dodałem w programie wyświetlanie w monitorze liczby jaką wprowadza użytkownik oraz liczby odczytanej z potencjometru. Po dodaniu Serial.read(); problem znika. Proszę o wytłumaczenie z czego to wynika i co dokładnie robi funkcja Serial.read();. Proszę też o ewentualne uwagi co do struktury kodu.

PS. Do programu dodałem dodatkowe sygnalizowanie diodami w przypadku startu systemu oraz błędnej odpowiedzi - proszę o niezwracanie na to uwagi.

Pozdrawiam.

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

int wartoscOdczytana = 0;
int liczbaPodana = 0;
int licznik = 0;
boolean przegrana = false;

void setup() 
{
  pinMode(przycisk, INPUT_PULLUP);
  pinMode(zielona, OUTPUT);
  pinMode(czerwona, OUTPUT);
  pinMode(zolta, OUTPUT);

  digitalWrite(zielona, HIGH);
  digitalWrite(czerwona, HIGH);
  digitalWrite(zolta, HIGH);
  delay(500);
  digitalWrite(zielona, LOW);
  digitalWrite(czerwona, LOW);
  digitalWrite(zolta, LOW);
}

void loop() 
{
 wartoscOdczytana = analogRead(A5);
 
 if(digitalRead(przycisk) ==  LOW)
    {
      Serial.begin(9600);
      Serial.println("Podaj liczbę:");
      delay(200);
    }

  if(licznik < 3)
    {
          if(Serial.available() > 0)
        {
          liczbaPodana = Serial.parseInt();
    
          Serial.println("Twoja liczba to: ");
          Serial.println(liczbaPodana);
          Serial.println("Wartość odczytana to: ");
          Serial.println(wartoscOdczytana);
    
          if((wartoscOdczytana - 50) < liczbaPodana && liczbaPodana < (wartoscOdczytana + 50))
            {
              digitalWrite(zielona, HIGH);
              delay(1000);
              Serial.println("Wygrałeś!");
              while(1){}
            }
          else
            {
              digitalWrite(zolta, HIGH);
              digitalWrite(czerwona, HIGH);
              delay(100);
              digitalWrite(czerwona, LOW);
              delay(100);
              digitalWrite(czerwona, HIGH);
              delay(100);
              digitalWrite(czerwona, LOW);
              delay(100);
              digitalWrite(czerwona, HIGH);
              delay(100);
              digitalWrite(czerwona, LOW);
              delay(100);
              Serial.println("Błąd! Spróbuj ponownie!");
            }
          licznik++;
          Serial.read();                                          //TUTAJ
        }  
    }
   else if (przegrana == false)
    {
      Serial.println("Przegrałeś ofiaro!");
      digitalWrite(czerwona, HIGH);
      przegrana = true;
    }
}

 

ococho.png

(edytowany)

@Stark w poprzedniej części kursu był podobny przykład, gdzie pobierało się od użytkownika dane:

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

void setup() {
  Serial.begin(9600); //Uruchomienie komunikacji
}

void loop() {
  if(Serial.available() > 0) { //Czy Arduino odebrało dane
    odebraneDane = Serial.readStringUntil('\n'); //Jeśli tak, to odczytaj je do znaku końca linii i zapisz w zmiennej odebraneDane
    Serial.println("Witaj " + odebraneDane + "!"); //Wyświetl komunikat
  }
}

Nie próbowałeś tego z tym powiązać i dopiero pobrany Sting zamienić na int (a w zasadzie na long)?

Co do Serial.read() to polecam dokumentację funkcja ta zwraca byte danych z bufora. Dlaczego zaczęło działać? Nie wiem 🙂 Może w jakiś sposób opróżnia coś z bufora, nie jest to jednak zbyt trafione użycie.

Edytowano przez Gieneq
14 godzin temu, Gieneq napisał:

Nie próbowałeś tego z tym powiązać i dopiero pobrany Sting zamienić na int (a w zasadzie na long)?

Tak, mogłem tak zrobić, ale chciałem zrobić to jak najbardziej optymalnie. Czy ten sposób albo funkcja jakiej użyłem są niepoprawne?

Z jakiegoś powodu w buforze znajduje się cyfra 0 po przesłaniu dowolnej liczby do programu, co powoduje, że pętla wykonuje się jeszcze raz. 

14 godzin temu, Gieneq napisał:

Co do Serial.read() to polecam dokumentację funkcja ta zwraca byte danych z bufora. Dlaczego zaczęło działać? Nie wiem 🙂

Tak, dziękuję. W kolejnej części kursu było wyjaśnione co robi funkcja o której mowa. W moim przypadku po zastosowaniu funkcji dane te zostały pobrane, co wyeliminowało kolejne wykonanie pętli. Moje pytanie - skąd wzięły się tam te dane?

Ponadto zauważyłem, że przed rozpoczęciem gry (wciśnięcie przycisku), kiedy transmisja danych jest już uruchomiona (w kodzie powyżej rozpoczęcie jest już po wciśnięciu przycisku) a prześlemy do programu dowolne liczby to będą one czekać w kolejce, aby po rozpoczęciu gry "same się wpisać" - to już jest dla mnie zrozumiałe. 

Pewnie kiedy bym wiedział, jak to wszystko dokładnie funkcjonuje to bym to rozszyfrował, ale dopiero zaczynam. Dziś minął mój czwarty dzień z Arduino, jestem już po lekcji ze sterowaniem silnikami DC - stworzyłem dziś pojazd, który jeździ, więc myślę, że idzie dość sprawnie.

Korzystając z okazji, ponownie dziękuję za te kursy, które niesamowicie przyspieszają proces nauki.

(edytowany)

Witam,

Szybkie pytanie - czy mogę użyć funkcji map(), żeby z interwału konwertera (0-1023) przeskalować go na interwał z liczbami zmiennoprzecinkowymi? W ten sposób można by ominąć tworzenie dwóch zmiennych w celu stworzenia naszego woltomierza.

Mój zmieniony program:

float voltage = 0; // Zmienna, na której będziemy działać

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

void loop() {
  voltage = analogRead(A5); // Zczytuje wartość z pinu - teraz jest w formie cyfrowej, interwał 0-1023
  voltage =  map(voltage, 0, 1023, 0.0, 5.0); // Przeskalowuje cyfrowy interwał na interwał, który pokazuje napięcie
  // Użyłem zapisu 0.0-5.0 zamiast 0-5, żeby uniknąć oczywistej omyłki
  Serial.println(voltage); // Pokazuje przeskalowane napięcie w Monitorze
  delay(200);
}

Program mimo zapisu z zerem po przecinku skaluje napięcie w taki sposób, że można zczytać je z dokładnością do cyfry jedności. Efekt podobny jak gdyby zastosować zapis 0-5, z tym że za każdą z tych cyfr pojawiają się dwa zera.

Przykładowo:
0.00
1.00
4.00 itd.

Czy używam nie poprawnie funkcji map() i nie powinno się jej używać do skalowania do interwałów z liczbami po przecinku (jak sugeruje google)? Czy może robię coś innego nie tak? Liczę na Waszą pomoc, z góry dziękuję 🙂

Edytowano przez Gieneq
Zachęcam do używania bloku kodu

@bujo2001 najlepiej napisz własną funkjcę, bo map od Arduino przyjmuje za argumenty longi:

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;
}

 

  • Lubię! 1
  • Pomogłeś! 1
  • 2 tygodnie później...

Witam, mam problem z zad. 4.5. Nie mogę dojść dlaczego po wygranej lub wykorzystaniu wszystkich prób program nie chce włączyć się od nowa, tak jakby zatrzymywał się w miejscach gdzie zaznaczyłem w kodzie. Już nie mam pomysłu co może być nie tak. Usunięcie pętli while na wciśnięcie przycisku nic nie daje.

#define czerwona 10
 #define zolta 9
 #define zielona 8
 #define przycisk 2 
 
 int odczytanaWartosc = 0; //Zmienna do przechowywania odczytu ADC
 String zgadywana_liczba= "";
 int zgadywana_liczba_int = 0;
 bool od_nowa =true;
 int proby = 0;

void setup() {
  
  pinMode(czerwona, OUTPUT);
  pinMode(przycisk,INPUT_PULLUP);
  pinMode(zolta, OUTPUT);
  pinMode(zielona, OUTPUT);
  digitalWrite(zielona, LOW);
  digitalWrite(czerwona, LOW);
  digitalWrite(zolta, LOW);
  Serial.begin(9600);
  
}
 
void loop() {

 if(od_nowa == true){
   digitalWrite(zielona, LOW);
   proby = 2;
   Serial.println("Przekrec potencjometr i wcisnij przycisk");
   while (digitalRead(przycisk)==HIGH);
   odczytanaWartosc = analogRead(A5);
   Serial.println(odczytanaWartosc);
   Serial.println("Podaj liczbe: ");
 }

 
   while (Serial.available() == 0);
   zgadywana_liczba = Serial.readStringUntil('\n');
   zgadywana_liczba_int = zgadywana_liczba.toInt();

   
   if(odczytanaWartosc - zgadywana_liczba_int <= 50 && odczytanaWartosc - zgadywana_liczba_int >= -50){
    Serial.println("Gratulacje wygrales! wcisnij przycis aby zagrac ponownie");
    digitalWrite(zielona, HIGH);
    digitalWrite(zolta, LOW);
    od_nowa == true;
    while (digitalRead(przycisk)==HIGH) delay(20); /////////////////////////w tym miejscu nie dzie dalej
   }
   else if(proby>0){
     od_nowa=false;
     proby--;
     Serial.println("Pozostalo prob: ");
     Serial.println(proby+1);
     digitalWrite(zolta, HIGH);
     Serial.println("Niestety nie trafiles. Podaj kolejna liczbe: ");
     digitalWrite(czerwona, HIGH); delay(3000); digitalWrite(czerwona, LOW);
    }
    else {
     digitalWrite(czerwona, HIGH); delay(3000); digitalWrite(czerwona, LOW);
     Serial.println("Koniec gry :( wcisnij przycisk i sproboj jeszcze raz!");
     digitalWrite(zolta, LOW);
     od_nowa == true;
     while (digitalRead(przycisk)==HIGH) delay(20); //w tym miejscu też nie dzie dalej (po usunięciu warunku na naciśnięcie przycisku też stoi w miejscu)
     }
    delay(5);
}

 

@kerifprzemek witam na forum 🙂 Te linijki "od_nowa == true;" to pozostało po jakimś warunku czy po prostu błąd przypisywania? Przypominam, że podwójny znak równości wykorzystujemy wewnątrz warunków do porównań - przypisywanie to pojedynczy znak równości. Daj znać skąd to się wzięło to ruszymy dalej ze sprawdzaniem 🙂

  • Lubię! 1
(edytowany)

@Treker Linijki "od_nowa == true;" wzięły się z głupiego przekopiowania z if'a na początku i nie zmienienia znaku == na =. Wiedziałem, że tak się nie robi a mimo tego nie zauważyłem. Tak to jest jak się człowiek spieszy i kopiuje bezmyślnie. Dziękuję za pomoc. Będzie nauczka na przyszłość. 🙂

Program wymagał jeszcze tylko dodania małego opóźnienia (zmieniłem wartość delay na końcu z 5 na 1000), ponieważ naciśnięcie przycisku powodowało jednoczesne spełnienie warunku z początku programu w wyniku czego po przejściu jednej pętli programu od razu przechodziło z polecenia "Przekrec potencjometr i wcisnij przycisk" do "podaj liczbę".

Edytowano przez kerifprzemek

@Wortan jeśli pytasz o to czy Arduino może wysłać do komputera jakąś komendę, która usunie wcześniej wysłane informacje z okna terminala to nie, nie ma takiej możliwości.

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...