Arduino Polska Forum

Pełna wersja: Automatyczne włączenie pinu przy napięciu niższym niż 11V
Aktualnie przeglądasz uproszczoną wersję forum. Kliknij tutaj, by zobaczyć wersję z pełnym formatowaniem.
Stron: 1 2
Witam

Mam problem z następującym programem:


----------------------------------------------------------------------------------

int odczytanaWartosc = 0;
 
void setup() {
  pinMode(8, OUTPUT);
}
 
void loop() {
  odczytanaWartosc = analogRead(A4);
  delay(3000);
 
  if (odczytanaWartosc < 717) {                 //wartość mniejsza od 11V, z dzielnikiem 3,51V
     digitalWrite(8, HIGH);                             //Włączenie
     delay(25200000);                                 //Włączony przez 7h       
     digitalWrite(8, LOW);


  }
 
 
}

----------------------------------------------------------------------------------

Program ma podać napięcie na pinie cyfrowym 8, w momencie gdy na analogowym pinie 4 będzie wartość mniejsza niż 717, a więc niższa niż 3,51V (11V na wejściu). W celu obniżenia badanego napięcia skonstruowałem dzielnik oparty o rezystory 10k i 4,7k.

Niestety,  pomimo niespełnionego warunku, wyjście 8 podaje napięcie .
Aby się upewnić czy nie robię gdzieś błędu z podłączeniem, postanowiłem zewrzeć pin A4 z pinem 5V sekcji zasilającej Arduino. Jak dobrze rozumuję, wartość mierzona na pinie analogowym powinna wynosić 1024.
Niestety pin 8 jest ciągle włączony.

Jest w stanie mi ktoś podpowiedzieć co jest nie tak z tym programem ?
Do stworzenia programu posiłkowałem się poradnikiem o budowie woltomierza Smile  




Pozdrawiam i dzięki za odpowiedź
Gdy sie czyta dane z ADC, o ile to możliwe, wynika należy uśredniać.

Kod:
delay(25200000);
Tak duży delay? Jesteś świadom, że te 7 godzin będzie miało dużą i zależnie od programu, mniej lub bardziej nieprzewidywalną odchyłkę?

Wyślij na uart wartość którą przyjmuje "odczytanaWartosc " i dowiesz się, czy ADC pracuje poprawnie czy nie.
Podobnie wyślijj na UART jakiś komunikat gdy wykona sie warunek ale koniecznie przetd tym dziwnie dużym delay.
Otworzyłem monitor portu szeregowego.
Wartości utrzymują stałą wartość wynoszącą 1023.
(24-12-2018, 02:38)Pankracy napisał(a): [ -> ]Otworzyłem monitor portu szeregowego.
Wartości utrzymują stałą wartość wynoszącą 1023.

Teraz sprawdź jakie napięcie masz na wejściu ADC.
Na porcie jest napięcie 5V, pociągnąłem je bezpośrdenio z płytki.
Przy przełączeniu na 3,3V wartości wynoszą 675.
(24-12-2018, 02:51)Pankracy napisał(a): [ -> ]Na porcie jest napięcie 5V, pociągnąłem je bezpośrdenio z płytki.
Przy przełączeniu na 3,3V wartości wynoszą 675.

Czyli ADC pracuje prawidłowo.
Pokaż schemat jak podłączyłeś te rezystory, a jak wpisujesz jakąkolwiek liczbę to ona będzie int, czyli w zakresie 32000, jak chcesz większą liczbę to napisz delay(25200000UL); Używanie takich dużych wartości w delay i tak może być bez sensu, sam sobie przetestuj do jakiej wartości ma to sens.
Daj czas procesorowi na uruchomienie, dodaj delay(10); przed pomiarem. Wartość odczytuj kilka razy i wyciągaj średnią.
Lepiej jednak zapoznać się z innymi sposobami zarządzania czasem, polecam kurs i millis: https://forbot.pl/blog/kurs-arduino-srod...owac-id936 .
(24-12-2018, 03:15)kaczakat napisał(a): [ -> ]Daj czas procesorowi na uruchomienie, dodaj delay(10); przed pomiarem.
AVR na lampach jest i musi sie nagrzać?

(24-12-2018, 03:15)kaczakat napisał(a): [ -> ]Używanie takich dużych wartości w delay i tak może być bez sensu
Pisałem już o tym, po co powtażać zwłaszcza jak tego się nie uzasadnia?

(24-12-2018, 03:15)kaczakat napisał(a): [ -> ]Wartość odczytuj kilka razy i wyciągaj średnią.
O tym też pisałem.
Jak się potocznie nazywa osobę, która powtarza po innych?
Dodałem uśrednianie.
Teraz program wygląda następująco:


--------------------------------------------------------------------------

int odczytanaWartosc = 0;
int OW1 = 0;
int OW2 = 0;
int OW3 = 0;
int OW4 = 0;
int OW5 = 0;

void setup() {
pinMode(8, OUTPUT);
}

void loop() {
OW1 = analogRead(A4);
delay(10);
OW2 = analogRead(A4);
delay(10);
OW3 = analogRead(A4);
delay(10);
OW4 = analogRead(A4);
delay(10);
OW5 = analogRead(A4);
delay(10);

odczytanaWartosc = (OW1+OW2+OW3+OW4+OW5)/5 ;

if (odczytanaWartosc < 717) { //wartość mniejsza od 11V, z dzielnikiem 3,51V
digitalWrite(8, HIGH); //Włączenie
delay(10000); //Włączony przez 10s
digitalWrite(8, LOW);
}

}


----------------------------------------------------------------------------

Sprawdziłem czy to uśrednianie daje radę i w monitorze portu wskakują wartości 5115 jak nie mam dzielnika "5".
Z dzielnikiem normalnie wartości 1023 wskakują.

W moim programie natomiast niczego to nie zmienia:
-Jak mam zwarte piny A4 i 5V to pin8 jest w stanie wysokim.
-Natomiast jak rozłączę je na chwilę, to pin8 wyłącza się na 10s.
-Jak zamieniam "<" z ">" to co 10s na ułamek sekundy pin8 podaje napięcie(przy zwartych A4 i 5V)
Uśrednianie zrobiłeś beznadziejnie.
Co do
Cytat:-Jak mam zwarte piny A4 i 5V to pin8 jest w stanie wysokim.
-Natomiast jak rozłączę je na chwilę, to pin8 wyłącza się na 10s.
to wynika, że warunek
Kod:
if (odczytanaWartosc < 717)
działa na odwrót a w cuda nie wierzę, prędzej w to, że pokręciłeś ten opis i zwierasz A5 z masą tym bardziej, że wcześniej wspominałeś o podciąganiu A4 do 5V.

Jeszcze raz napiszę:
Cytat:Wyślij na uart wartość którą przyjmuje "odczytanaWartosc " (...)
Podobnie wyślijj na UART jakiś komunikat gdy wykona sie warunek

przy czym, za "if (odczytanaWartosc < 717)" wyświetlaj "odczytanaWartosc " a nie tylko informację, ze warunek wykonał się. Pokaż co wyświetlił terminal gdy na A4 podajesz 5V oraz co gdy zewrzesz z GND.
Stron: 1 2