Skocz do zawartości

Pomocna odpowiedź

Ja wiem co to jest kwantyzacja. Ponawiam pytanie: czy jesteś pewien że o to chodziło?

Konkretniej: czy po podaniu napięcia 5V na ADC program ma wypisać "5.0V" czy coś innego.

(edytowany)
1 godzinę temu, ethanak napisał:

Konkretniej: czy po podaniu napięcia 5V na ADC program ma wypisać "5.0V" czy coś innego.

A ile pokażesz gdy na wyjściu przetwornika a/c będzie 1? 1/1024*5V czy 1/1023*5V?

Rzeczywista wartość będzie 5V/1024 więc albo pokażesz 0,004883V czyli wartość rzeczywistą albo 0,004888V większą od rzeczywistej o 4,77303E-06V. 
Gdybym chciał wyświetlać wartości z mniejszym błędem mógłbym do każdej zmapowanej wartości dodawać połowę błędu, ale wówczas nigdy nie pokażę 0. Od użytkownika i przeznaczenia zmapowanych danych będzie zależało czy obliczona wartość będzie z niedomiarem czy nadmiarem.

Tu cytat z instrukcji do, której wcześniej zamieściłem link.

Kwantyzacja.thumb.png.b793f72c3a9b4c8ccfcac026dbd895cc.png

1578488751_Bdkwantyzacji_1.thumb.png.13290691c2c73501fd9e1571c55225d2.png   240950055_Bdkwantyzacji0.thumb.png.db6d7ef85c4c7bfa07cbe372399fbd11.png   

 

Edytowano przez Sylba
49 minut temu, ethanak napisał:

A tak bez odnośników do uniwersalnej teorii wszystkiego tudzież hipotez o powstaniu Wszechświata - odpowiesz na moje proste pytanie?

Ja bym przyjął zasadę opisaną powyżej czyli 1023/1024*5V=4,995112V.

A ja przyjąłbym proste mapowanie zakresów: jeśli dla 5V przetwornik zwraca 1023 to wyświetlaną wartoscią dla 1023 powinno być 5V a nie wyniki mnożenia z pierwszej wersji Pentium.

Coś jak uproszczona funkcja map.

int odczytanaWartosc = 0;//Odczytana wartość z ADC

void setup() {
  Serial.begin(9600);//Uruchomienie komunikacji przez USART
  pinMode(7, OUTPUT); //Konfiguracja wyjść pod diody LED
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(12, OUTPUT);
}
void loop() {
  odczytanaWartosc = analogRead(A5);//Odczytujemy wartość napięcia
  Serial.println(odczytanaWartosc);//Wysyłamy zmierzone napięcie
  odczytanaWartosc = map(odczytanaWartosc, 0, 1000, 1, 5);//Przeskalowanie wartości
  delay(100);//Czekamy, aby wygodniej odczytywać wyniki  


  if (odczytanaWartosc == 1) { //Pierwszy zakres
      digitalWrite(7, LOW); 
      digitalWrite(8, LOW); 
      digitalWrite(9, LOW); 
      digitalWrite(10, LOW); 
      digitalWrite(12, HIGH); 
  } else if (odczytanaWartosc == 2) { //Drugi zakres
      digitalWrite(7, LOW); 
      digitalWrite(8, LOW); 
      digitalWrite(9, LOW); 
      digitalWrite(10, HIGH); 
      digitalWrite(12, LOW);       
  } else if (odczytanaWartosc == 3) {  //Trzeci zakres
      digitalWrite(7, LOW); 
      digitalWrite(8, LOW); 
      digitalWrite(9, HIGH); 
      digitalWrite(10, LOW); 
      digitalWrite(12, LOW);        
  } else if (odczytanaWartosc == 4) {  //Czwarty zakres
      digitalWrite(7, LOW); 
      digitalWrite(8, HIGH); 
      digitalWrite(9, LOW); 
      digitalWrite(10, LOW); 
      digitalWrite(12, LOW);  
    } else if (odczytanaWartosc >=4) {//Piąty zakres
      digitalWrite(7, HIGH); 
      digitalWrite(8, LOW); 
      digitalWrite(9, LOW); 
      digitalWrite(10, LOW); 
      digitalWrite(12, LOW);        
  }
  delay(50); //Opóźnienie, aby nie odczytywać ADC zbyt szybko         
}

Zadanie domowe 4.6.

użyłem 

} else if (odczytanaWartosc >=4) {//Piąty zakres

próbowałem   } else {  //Pozostałe, czyli piąty zakres

ale w tej formie nie działał mi 5 zakres.

I analogicznie map(odczytanaWartosc, 0, 1000, 1, 5); musiałem max ustawić ok 1000 bo przy 1023  nie byłem w stanie osiągnąć świecenia ostatniej diody. Być może jakieś inne błędy? Prosze o sprawdzenie . W każdym razie w tym wykonaniu wszystko działa

 

Zadanie domowe 4.5 (GRA)

Nie jestem w stanie przebrnąć. Dochodzę do pewnych pułapów i wszystko zaczyna mi się krzaczyć. Siedzę nad jedna rzeczą 40 min i nie idzie . Myślę że pójdę z kursem dalej i wrócę za jakiś czas sprawdzić jak mi pójdzie

6 godzin temu, ethanak napisał:

A ja przyjąłbym proste mapowanie zakresów: jeśli dla 5V przetwornik zwraca 1023 to wyświetlaną wartoscią dla 1023 powinno być 5V a nie wyniki mnożenia z pierwszej wersji Pentium.

Stosując tę metodę uzyskujesz poprawny wynik (odpowiadający rzeczywistej wartości w dwóch punktach 0V i 5V. W pozostałych przedziałach kwantyzacji błąd będzie albo dodatni (mapowana wartość będzie większa od rzeczywistej), albo ujemny.

W metodzie gdy dzielisz przez 1024 i mnożysz przez 1023, przy każdej zmianie wartości sumy bitów wartość mapowana jest równa rzeczywistej, a potem błąd jest ujemny (mapowana wartość jest mniejsza od rzeczywistej) i jednakowy dla każdego przedziału kwantyzacji.

(edytowany)
Dnia 12.01.2025 o 20:32, PanMajster napisał:

I analogicznie map(odczytanaWartosc, 0, 1000, 1, 5); musiałem max ustawić ok 1000 bo przy 1023  nie byłem w stanie osiągnąć świecenia ostatniej diody. Być może jakieś inne błędy? Prosze o sprawdzenie . W każdym razie w tym wykonaniu wszystko działa

Błędu w kodzie nie ma. Dziwne zachowanie wynika z mapowania oraz przyjętych instrukcji warunkowych, przy których kolejne diody są włączane. Prawdopodobnie napięcie na wejściu analogowym było niższe od wartości progowej

Możesz to sprawdzić wstawiając przed pierwszą instrukcją if:

Serial.print("odczytanaWartość: "); Serial.println(odczytanaWartość);

Zobaczysz jaką największą wartość odczytuje przetwornik. Możesz także porównać odczyty z wejścia analogowego z pomiarami napięcia dokonanymi multimetrem.

W tabelce poniżej zestawiłem wyniki obliczeń dla trzech wariantów mapowania. Ten zaznaczony na zielono to mapowania 0-1000 na 1-5.
Jeśli na wyjściu analogowym jest maksimum 5V to pożądana wartość zmapowana 5 wystąpi dopiero przy  napięciu na na pinie analogowym ponad 4,88V.

image.thumb.png.a95dcd24d5b5aa567de9bd06bac34985.png

Możesz także nie używać funkcji map tylko posługiwać się w instrukcjach warunkowych wartościąOdczytaną. Jeśli cały zakres odczytów pinu analogowego = 1023, to po podzieleniu na 6 jednakowych obszarów, każdy będzie miał szerokość około 200 (dla uproszczenia rachunków). Teraz gdy odczytaną Wartość porównujesz z kolejnymi granicami przedziałów.

Np.

stan początkowy wszystkie diody wyłączone
odczytanaWartosc > 200 włączona pierwsza dioda
odczytanaWartosc > 400 włączona druga dioda
odczytanaWartosc > 600 włączona trzecia dioda
odczytanaWartosc > 800 włączona czwarta dioda
odczytanaWartosc > 1000 włączona piąta dioda

Edytowano przez Sylba
  • Lubię! 1
  • Pomogłeś! 1

@PanMajster Czasami tak jest , że nie możemy iść dalej, odstawiamy temat na drugi dzień i nagle wszystko staje się proste. Sam tak mam , że jeżeli na siłę chce coś osiągnąć to wchodzę w ślepą uliczkę. Po jakimś czasie okazuje się to wszystko banalnie proste. 

  • Lubię! 2
16 godzin temu, Sylba napisał:

Możesz to sprawdzić wstawiając przed pierwszą instrukcją if:

Serial.print("odczytanaWartość: "); Serial.println(odczytanaWartość);

Zobaczysz jaką największą wartość odczytuje przetwornik. Możesz także porównać odczyty z wejścia analogowego z pomiarami napięcia dokonanymi multimetrem.

Wartość zmierzona Arduino 1015 MAX a zatem idąc twoimi radami zrobiłem taki kod

void loop() {
  odczytanaWartosc = analogRead(A5);//Odczytujemy wartość napięcia
  Serial.println(odczytanaWartosc);//Wysyłamy zmierzone napięcie
  
  delay(100);//Czekamy, aby wygodniej odczytywać wyniki  

  if (odczytanaWartosc >= 0 && odczytanaWartosc <= 203) { //Pierwszy zakres
      digitalWrite(7, LOW); 
      digitalWrite(8, LOW); 
      digitalWrite(9, LOW); 
      digitalWrite(10, LOW); 
      digitalWrite(12, HIGH); 
  } else if (odczytanaWartosc >= 203 && odczytanaWartosc <= 406) { //Drugi zakres
      digitalWrite(7, LOW); 
      digitalWrite(8, LOW); 
      digitalWrite(9, LOW); 
      digitalWrite(10, HIGH); 
      digitalWrite(12, LOW);       
  } else if (odczytanaWartosc >= 406 && odczytanaWartosc <= 609) {  //Trzeci zakres
      digitalWrite(7, LOW); 
      digitalWrite(8, LOW); 
      digitalWrite(9, HIGH); 
      digitalWrite(10, LOW); 
      digitalWrite(12, LOW);        
  } else if (odczytanaWartosc >= 609 && odczytanaWartosc <= 812) {  //Czwarty zakres
      digitalWrite(7, LOW); 
      digitalWrite(8, HIGH); 
      digitalWrite(9, LOW); 
      digitalWrite(10, LOW); 
      digitalWrite(12, LOW);  
    } else if (odczytanaWartosc >= 812 && odczytanaWartosc <= 1015) {//Piąty zakres
      digitalWrite(7, HIGH); 
      digitalWrite(8, LOW); 
      digitalWrite(9, LOW); 
      digitalWrite(10, LOW); 
      digitalWrite(12, LOW);        
  }

Teraz wszystko śmiga chyba tak jak powinno. Nie trzeba sie wysilać żeby zapalić ostatnia diodę wystarczy latarkę przekierować na dana stronę i skrajna dioda świeci. Dzięki !

  • Lubię! 1
9 godzin temu, PanMajster napisał:

Teraz wszystko śmiga chyba tak jak powinno. Nie trzeba sie wysilać żeby zapalić ostatnia diodę wystarczy latarkę przekierować na dana stronę i skrajna dioda świeci.

Moje gratulacje.

(edytowany)
9 godzin temu, PanMajster napisał:
else if (odczytanaWartosc >= 812 && odczytanaWartosc <= 1015) {//Piąty zakres

Jeszcze mała uwaga. Nie ograniczałbym odczytanej wartości do 1015, bo jeśli odczytana wartość będzie 1016 lub więcej, piąta dioda się nie włączy. Chyba, że tak ma być. Wystarczy >=812 lub >811.

Edytowano przez Sylba
  • Lubię! 2
  • 2 miesiące później...
  • 3 miesiące później...

Hej chciałbym podzielić się z wami moim kodem do zadania domowego 4.6

#define red_L 7
#define yelow_L 8
#define green 9
#define yelow_R 10
#define red_R 11

int L_foto = 0;
int R_foto = 0;

int odczytanaWartosc_L = 0;
int odczytanaWartosc_R = 0;

void setup() {
  pinMode(red_L, OUTPUT);
  pinMode(yelow_L, OUTPUT);
  pinMode(green, OUTPUT);
  pinMode(yelow_R, OUTPUT);
  pinMode(red_R, OUTPUT);

  Serial.begin(9600);
  }

void loop() {
  L_foto = analogRead(A1);
  R_foto = analogRead(A0);

  odczytanaWartosc_L = L_foto / 100;
  odczytanaWartosc_R = R_foto / 100;

  String tekst = String(odczytanaWartosc_L) + ", " + String(odczytanaWartosc_R);
  Serial.println(tekst);

  if (odczytanaWartosc_L > 2 * odczytanaWartosc_R) {
    digitalWrite(red_L, HIGH);
    digitalWrite(yelow_L, LOW);
    digitalWrite(green, LOW);
    digitalWrite(yelow_R, LOW);
    digitalWrite(red_R, LOW);
  } else if (odczytanaWartosc_L > odczytanaWartosc_R) {
    digitalWrite(red_L, LOW);
    digitalWrite(yelow_L, HIGH);
    digitalWrite(green, LOW);
    digitalWrite(yelow_R, LOW);
    digitalWrite(red_R, LOW);
  } else if (odczytanaWartosc_L == odczytanaWartosc_R) {
    digitalWrite(red_L, LOW);
    digitalWrite(yelow_L, LOW);
    digitalWrite(green, HIGH);
    digitalWrite(yelow_R, LOW);
    digitalWrite(red_R, LOW);
  } else if (odczytanaWartosc_R > 2 * odczytanaWartosc_L) {
    digitalWrite(red_L, LOW);
    digitalWrite(yelow_L, LOW);
    digitalWrite(green, LOW);
    digitalWrite(yelow_R, LOW);
    digitalWrite(red_R, HIGH);
  } else if (odczytanaWartosc_R > odczytanaWartosc_L) {
    digitalWrite(red_L, LOW);
    digitalWrite(yelow_L, LOW);
    digitalWrite(green, LOW);
    digitalWrite(yelow_R, HIGH);
    digitalWrite(red_R, LOW);
  }

  delay(100);
}

 

  • Lubię! 1
  • 3 miesiące później...

witam . mam problem z przykladem z lekcji 4 z kursu arduino. to jest przyklad z 5 diodami led gdzie w zaleznosci od krecenia potencjometrem powinna zapalc sie inna dioda. Ale u mnie zapalaja sie tylko 3 diody. czerwone diody sie nie zpapalja i nie wiem dlaczego. Połaczenia prawidłowe, diody sa dobre, przyklad przepisany sklowo w slowo i znczek w znaczek. zmienialem potencjometry, zmienialem piny, ale caly czs to samo . zapalaja sie tylko 3 diody a nie 5. ktos moze wie czemu sie tak moze dziac? daniel

 

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...