Skocz do zawartości

Kurs Arduino - #4 - Przetwornik ADC


Pomocna odpowiedź

Mam cos takiego ale dziala tylko przy okreslonych wartosciach/oswietleniu.

Wydaje mi sie ze jak sie cos we funkcjach pokombinuje to cos z tego moze byc.

Co by tu naprawic? Czy w ogole zrezygnowac z funkcji map ? 🙄

#define zolta1 13
#define zolta2 4
#define czerwona1 12
#define czerwona2 7
#define niebieska 8

int fot1=0; //Fotorezystor 1
int fot2=0; //Fotorezystor 2


void setup() 
{
  Serial.begin(9600); //Przesylanie do terminalu

  pinMode(zolta1, OUTPUT);
  pinMode(zolta2, OUTPUT);
  pinMode(czerwona1, OUTPUT);
  pinMode(czerwona2, OUTPUT);
  pinMode(niebieska,OUTPUT);

}

void loop() 
{
  Serial.print("Fotorezystor 1: ");
  Serial.println(fot1);
  Serial.print("Fotorezystor 2: ");
  Serial.println(fot2);
  delay(500);
  
  fot1=analogRead(A4);
  fot1=map(fot1, 200, 460, 1, 5);
  fot2=analogRead(A5);
  fot2=map(fot2, 230, 605, 1, 5);

  if((fot1 == 5 )&&(fot2 <= 2))
  {
    digitalWrite(zolta1, HIGH); 
    digitalWrite(czerwona1, LOW); 
    digitalWrite(niebieska, LOW); 
    digitalWrite(czerwona2, LOW); 
    digitalWrite(zolta2, LOW);
  }
  else if((fot1<=5)&&(fot2==3))
  {
    digitalWrite(zolta1, LOW); 
    digitalWrite(czerwona1, HIGH); 
    digitalWrite(niebieska, LOW); 
    digitalWrite(czerwona2, LOW); 
    digitalWrite(zolta2, LOW);
  }
  else if(fot1==fot2)
  {
    digitalWrite(zolta1, LOW); 
    digitalWrite(czerwona1, LOW); 
    digitalWrite(niebieska, HIGH); 
    digitalWrite(czerwona2, LOW); 
    digitalWrite(zolta2, LOW);
  }
  else if((fot2<=5)&&(fot1==3))
  {
    digitalWrite(zolta1, LOW); 
    digitalWrite(czerwona1, LOW); 
    digitalWrite(niebieska, LOW); 
    digitalWrite(czerwona2, HIGH); 
    digitalWrite(zolta2, LOW);
  }
  else if((fot2==5)&&(fot1<=2))
  {
    digitalWrite(zolta1, LOW); 
    digitalWrite(czerwona1, LOW); 
    digitalWrite(niebieska, LOW); 
    digitalWrite(czerwona2, LOW); 
    digitalWrite(zolta2, HIGH);
  }
}

 

00000PORTRAIT_00000_BURST20190306152141138.jpg

Edytowano przez arek2007100
zly kod
Link do komentarza
Share on other sites

A co ma do tego map?

1) Nie masz obsadzonych wszystkich możliwości fot1/fot2 - konkretniej par [(1, 2), (1, 4), (2, 1), (2, 4), (4, 1), (4, 2), (4, 5), (5, 4)]

2) map nie gwarantuje, że wynik będzie ograniczony do podanego zakresu (czyli równie dobrze może być zero albo siedem).

Coś takiego:
 

fot1=map(fot1, 200, 460, 1, 5);
fot1 = constrain(fot1, 1, 5);

zagwarantuje że fot1 będzie w granicach 1 do 5 włącznie.

Pamiętaj, że constrain to makrodefinicja a nie funkcja, czyli zapis typu:

fot1 = constrain(map(fot1, 200, 460, 1, 5), 1, 5);

co prawda będzie działać, ale funkcja map może być niepotrzebnie wywołana dwukrotnie!

 

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

Dnia 5.03.2019 o 22:28, jogaszu napisał:

Czy jest jakieś specjalne polecenie pobrania z bufora? Czy po prostu trzeba dopisać jakąś funkcję, która zabierze dane i nic z nimi nie zrobi?

Możesz wykorzystać Serial.readStringUntil('\n') lub coś innego typu Serial.read() - w tym przypadku nie będzie to miało większego znaczenia. Drugie rozwiązanie będzie bardziej uniwersalne. Tutaj znajdziesz więcej na ten temat: https://www.arduino.cc/reference/en/language/functions/communication/serial/read/

Link do komentarza
Share on other sites

Witam, po pierwsze chciałbym pochwalić ten kurs, coś niesamowitego, prosty i wyrazisty 🙂 A Po drugie potrzebuje pomocy z zadaniem 4.5 😞 . Oto kod (cześciowy) niecałego zadania 4.5.

#define red 12
#define yellow 11
#define green 10
#define button 8

int odczytanaWartosc = 0;
long pobranaWartosc = 0;
int roznica = 0;
String haslo = "";
int proby = 3;

void setup(){
  for(int i = 10; i <=12 ; i++){
    pinMode(i, OUTPUT);
    digitalWrite(i, LOW);
  }

  pinMode( button, INPUT_PULLUP);
  Serial.begin(9600);
}

void loop(){
  Serial.println("Nastaw potencjometr i wcisnij przycisk");
  
  while(digitalRead(button) == HIGH){} //petla po to żeby nie wykonywał się kod dopóki nie zostanie naciśnięty klawisz
  
  delay(1000);//żeby nie wyłapało zakłóceń od klawisza
  
  Serial.println("Podaj liczbe:");
  
  if(Serial.available()){
    odczytanaWartosc = analogRead(A5);
    pobranaWartosc = Serial.read();
    Serial.println(pobranaWartosc);
    Serial.println(odczytanaWartosc);
    delay(5000); //po prostu opóźnienie dla mnie
  }
  }

Ale w czym problem? Na początku pojawia się na Monitorze "Nastaw potencjometr i wcisnij przycisk" i tak jak było zamierzone program czeka na wciśniecie klawisza, jednakże po jego wciśnięciu wyświetla się tylko kominukat "Podaj liczbe:" i po 5 sek od razu wykonuje ponownie pętle loop() bez pobrania wartości , co więcej nawet nie wyświetla tych wartości jaky pomijał to co jest w IF-ie. Z góry Dziękuję za pomoc 🙂 i Miłego dnia!

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

Dnia 20.03.2019 o 00:19, Majtas napisał:

Witam, po pierwsze chciałbym pochwalić ten kurs, coś niesamowitego, prosty i wyrazisty 🙂

Dziękuję za miłe słowa, cieszę się, że kurs jest pomocny 🙂

Dnia 20.03.2019 o 00:19, Majtas napisał:

Na początku pojawia się na Monitorze "Nastaw potencjometr i wcisnij przycisk" i tak jak było zamierzone program czeka na wciśniecie klawisza, jednakże po jego wciśnięciu wyświetla się tylko kominukat "Podaj liczbe:" i po 5 sek od razu wykonuje ponownie pętle loop() bez pobrania wartości , co więcej nawet nie wyświetla tych wartości jaky pomijał to co jest w IF-ie.

Program działa dokładnie tak jak go opisałeś, bo właśnie tak został napisany. Zwróć uwagę, że po wyświetleniu komunikatu proszącego o podanie liczby nie czekasz na jej wpisanie. Właściwie od razu sprawdzasz czy została podana (robisz to tak szybko, że człowiek nie ma szans wpisać wcześniej swojej propozycji). Pomyśl jak można to rozwiązać lepiej - np. za pomocą pętli while, która "opóźni" działanie programu do momentu odebrania danych 🙂

Link do komentarza
Share on other sites

#define red 8
#define blue 7
#define prz 9
String typedNumber = "";
byte voltage = 0;
boolean sent = false;
void setup() {
  Serial.begin(9600);
  pinMode(prz, INPUT_PULLUP);
  pinMode(red, OUTPUT);
  pinMode(blue, OUTPUT);

}

void loop() {
  voltage = analogRead(A5);
  if(digitalRead((prz) == LOW)){
    if (sent == false){
    Serial.println("insert number");
    sent = true;
    if(Serial.available() > 0){
      typedNumber = Serial.readStringUntil('\n');
      if(typedNumber == voltage){
        digitalWrite(blue, HIGH);
        
      }else{
        digitalWrite(red, HIGH);
      }
    }
   
  }
  }
}

Mam problem z tym kodem. Chcę ,aby wysyłał komunikat dopiero po wciśnięciu przycisku, a nie od razu w momencie włączenia monitora portu szeregowego. Próbowałem też zmieniać sposób wpinania przycisku i wartość z high na low, ale nic się nie zmieniło.Jestem tu nowy więc z góry dziękuję za pomoc.

Edytowano przez CARRUS17
Link do komentarza
Share on other sites

@CARRUS17 opisz proszę własnymi słowami jak według Ciebie działa ten program, bo mam wrażenie, że robi coś innego niż chciałeś 🙂 Jak dokładnie podłączyłeś przycisk? Tam nie ma zbyt dużego pola do manewru, w takiej sytuacji jest praktycznie tylko "jedna słuszna wersja".

Link do komentarza
Share on other sites

2 minuty temu, Treker napisał:

@CARRUS17 opisz proszę własnymi słowami jak według Ciebie działa ten program, bo mam wrażenie, że robi coś innego niż chciałeś 🙂 Jak dokładnie podłączyłeś przycisk? Tam nie ma zbyt dużego pola do manewru, w takiej sytuacji jest praktycznie tylko "jedna słuszna wersja".

Chciałem aby program w wypadku kiedy jest wciśnięty przycisk wyświetlił jednorazowo komunikat "insert number" i sprawdził, czy wpisana liczba jest zgodna z odczytem potencjometru. Jeżeli te liczby by się zgadzały, wtedy powinna zapalić się niebieski led. Jeśli byłyby różne, wtedy żółty led. Co do podłączenia nie mam niestety możliwości aby wysłać teraz zdjęcie. Jeżeli nie da się tego naprawić kodem, będę szukał problemu w podłączeniu.

Link do komentarza
Share on other sites

Program w obecnej formie jest błędny, ale mam nadzieję, że uda Ci się dojść krok, po kroku do rozwiązania 🙂

Upewnij się najpierw, że samo reagowanie na przycisk działa poprawnie. Usuń zbędę fragmenty kodu i zostaw tylko taki mechanizm, który będzie sprawdzał czy przycisk jest wciśnięty, a jeśli tak to włączy diodę. Później dodaj do tego UART.

Link do komentarza
Share on other sites

Witam, wykonałem zadanie 4.6, problem jest w tym, że ten program nie jest zoptymalizowany, i nie za bardzo wiem co tutaj mógłbym wrzucić/ zmienić aby był taki ambitny. Byłbym wdzięczny za wszelkie rady i uwagi 🙂

//projekt z fotorezystorami po ktorej stronie jest zrodlo swiatla
int rezystorPrawa = 0;
int rezystorLewa = 0;

#define PRAWA 13
#define PRAWAM  12
#define SRODEK 11
#define LEWAM 10
#define LEWA 9

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

  for(int i =13; i>8;i--)
  {
    pinMode(i,OUTPUT); 
    digitalWrite(i,LOW); 
  }
}

void loop() {
  rezystorPrawa = analogRead(A4);
  rezystorLewa = analogRead(A5);

  if( rezystorPrawa < 150 ){
    digitalWrite(LEWA, HIGH);
    digitalWrite(LEWAM, LOW);
    digitalWrite(SRODEK, LOW);
    digitalWrite(PRAWAM, LOW);
    digitalWrite(PRAWA, LOW);
  }
  if( rezystorPrawa > 170 && rezystorPrawa < 240 ){
    digitalWrite(LEWA, LOW);
    digitalWrite(LEWAM, HIGH);
    digitalWrite(SRODEK, LOW);
    digitalWrite(PRAWAM, LOW);
    digitalWrite(PRAWA, LOW);
  }
  if( rezystorPrawa < 320 && rezystorPrawa >260){
    digitalWrite(LEWA, LOW);
    digitalWrite(LEWAM, LOW);
    digitalWrite(SRODEK, HIGH);
    digitalWrite(PRAWAM, LOW);
    digitalWrite(PRAWA, LOW);
  }
  if( rezystorPrawa < 410 && rezystorPrawa >330 ){
    digitalWrite(LEWA, LOW);
    digitalWrite(LEWAM, LOW);
    digitalWrite(SRODEK, LOW);
    digitalWrite(PRAWAM, HIGH);
    digitalWrite(PRAWA, LOW);
  }
  if( rezystorPrawa > 420 ){
    digitalWrite(LEWA, LOW);
    digitalWrite(LEWAM, LOW);
    digitalWrite(SRODEK, LOW);
    digitalWrite(PRAWAM, LOW);
    digitalWrite(PRAWA, HIGH);
  }
  
}

 

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

@Majtas jeśli chcesz coś zmieniać to proponowałbym zacząć od wykorzystania funkcji map. Możesz np. obliczyć różnicę wskazań między lewym i prawym fotorezystorem, a następnie, za pomocą funkcji map zamienić ją na liczbę z zakresu od 1 do 5. Wartość tą będzie można później wykorzystać jako informację na temat numeru diody, która powinna świecić.

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

Postąpiłem wg. wskazań. Dzięki za pomoc 🙂 Pomógł byś też zastosować jakieś zabezpieczenia? Mam na myśli zniwelowanie stanów nieustalonych. Kiedy przesuwam latarką w jedną stronę w tej samej odległości od płytki, sa momenty, że diody "cofaja się" na moment i potem już normalnie program działa według założeń. Jakby był jakiś moment niedokładnego przełączenia. Co powiesz na ten temat? Aktualny kod:

//projekt z fotorezystorami po ktorej stronie jest zrodlo swiatla
int rezystorPrawa = 0;
int rezystorLewa = 0;
int roznica = 0;
int fotRezPrawOdn = 0;
int fotRezLewOdn = 0;

#define PRAWA 9
#define PRAWAM 10
#define SRODEK 11
#define LEWAM 12
#define LEWA 13

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

  for(int i =13; i>8;i--)
  {
    pinMode(i,OUTPUT); 
    digitalWrite(i,LOW); 
  }
  fotRezPrawOdn = analogRead(A4);
  fotRezLewOdn = analogRead(A5);
  Serial.println("Prawa strona odniesienie: ");
  Serial.println(fotRezPrawOdn);
  Serial.println("Lewa strona odniesienie: ");
  Serial.println(fotRezLewOdn);
}
//
void loop() {
  rezystorPrawa = analogRead(A4);
  rezystorLewa = analogRead(A5);
//
//  Serial.println("Prawa strona: ");
//  Serial.println(rezystorPrawa);
//  Serial.println("Lewa strona: ");
//  Serial.println(rezystorLewa);
  
  roznica = rezystorPrawa - rezystorLewa;
  roznica = map(roznica, -450, 450, 1,5);
 
  roznica+=8;
if(rezystorPrawa > (fotRezPrawOdn +20) && rezystorLewa > (fotRezLewOdn + 20))
{
  if( roznica == 13 ){
    digitalWrite(LEWA, HIGH);
    digitalWrite(LEWAM, LOW);
    digitalWrite(SRODEK, LOW);
    digitalWrite(PRAWAM, LOW);
    digitalWrite(PRAWA, LOW);
  }
  if( roznica == 12 ){
    digitalWrite(LEWA, LOW);
    digitalWrite(LEWAM, HIGH);
    digitalWrite(SRODEK, LOW);
    digitalWrite(PRAWAM, LOW);
    digitalWrite(PRAWA, LOW);
  }
  if( roznica == 11){
    digitalWrite(LEWA, LOW);
    digitalWrite(LEWAM, LOW);
    digitalWrite(SRODEK, HIGH);
    digitalWrite(PRAWAM, LOW);
    digitalWrite(PRAWA, LOW);
  }
  if( roznica == 10 ){
    digitalWrite(LEWA, LOW);
    digitalWrite(LEWAM, LOW);
    digitalWrite(SRODEK, LOW);
    digitalWrite(PRAWAM, HIGH);
    digitalWrite(PRAWA, LOW);
  }
  if(  roznica == 9){
    digitalWrite(LEWA, LOW);
    digitalWrite(LEWAM, LOW);
    digitalWrite(SRODEK, LOW);
    digitalWrite(PRAWAM, LOW);
    digitalWrite(PRAWA, HIGH);
  }
}
else{
  digitalWrite(LEWA, LOW);
    digitalWrite(LEWAM, LOW);
    digitalWrite(SRODEK, LOW);
    digitalWrite(PRAWAM, LOW);
    digitalWrite(PRAWA, LOW);
}
  
  
}

 

Link do komentarza
Share on other sites

@Majtas trochę nie rozumiem tego programu. Dlaczego skalujesz sobie wynik na zakres od 1 do 5, a później dodajesz do niego 8? Jaki w tym cel? Jak już dojdziesz do ładu z tym tematem to proponowałbym np. zamienić te if'y na jeden switch-case. Będzie wyglądało ładniej 😉

14 godzin temu, Majtas napisał:

Kiedy przesuwam latarką w jedną stronę w tej samej odległości od płytki, sa momenty, że diody "cofaja się" na moment i potem już normalnie program działa według założeń. Jakby był jakiś moment niedokładnego przełączenia. Co powiesz na ten temat?

Możesz dla testu wprowadzić w programie jakieś małe opóźnienie (typu 20-100 ms) i sprawdź czy to nie poprawi jego działania. Jeśli nie, to możesz jeszcze wykonywać kilka pomiarów i obliczać średnią wartość. Wtedy dane będą bardziej wiarygodne.

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

Dzięki bardzo za rady! Z tym switch casem nie wpadłem na pomysł rzeczywiście... A co do tej róznicy czemu nagle dodaje do niej 8. 😄 Myślałem żeby zobić to w ten sposób, że w zależnosci od wartości różnicy taka dioda się włącza, po prostu pokiełbasiłem w tych ifach. Miałem tą informację wykorzystać do tego, która dioda powinna świecić, ale jak widać nie zaimplementowałem tego ;(. Ale mimo to kod mógłby być nieczytelny.

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.