• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Higrometr FC-28 - zawężony zakres wartości
#1
Chcę zrobić prosty pomiar wilgotności gleby za pomocą higrometru FC-28 i Arduino UNO.
Podłączyłem VCC - 5V, GND - GND, A0 - A0.
Program wygląda tak:
Kod:
int sensor_pin = A0;
int output_value ;

void setup() {
 Serial.begin(9600);
 Serial.println("Odczyt z czujnika ...");
 delay(2000);
 }

void loop() {

 output_value= analogRead(sensor_pin);
 output_value = map(output_value,812,224,0,100);
 Serial.print("Wilgotność : ");
 Serial.print(output_value);
 Serial.println("%");
 delay(1000);
 }

Wszystko działa, wartość 812 jest dla gleby suchej, 224 dla gleby mokrej, zalanej wodą.
Po włożeniu czujnika w ziemię zakres w procentach mieści się pomiędzy 0-100% natomiast np. po wyjęciu czujnika z ziemi pokazuje się w monitorze szeregowym wartość na poziomie -35%, oczywiście po włożeniu czujnika do wody wartość przekracza 100%. Chciałbym aby wartości mieściły się w zakresie 0-100 w każdych okolicznościach ale chyba zrobienie tego za pomocą zmiany wartości output_value będzie złym pomysłem, bo wtedy wilgotna gleba (obecnie około 60%) będzie wyświetlana jako około 30%, chyba, że źle rozumiem zasadę działania czujnika i muszę podać cały zakres wartości, który mierzy się gdy czujnik jest wyjęty z gleby oraz włożony do wody, wtedy będzie pełen zakres.

Jeżeli powyższe rozumowanie jest błędne i należy zrobić tak jak jest obecnie to trzeba byłoby zrobić aby wartości nie przekraczały 0-100%. Próbowałem zrobić to korzystając z if:
Kod:
 if (output_value > 812) { //Jeśli obliczona wartość jest większa od 812
   output_value = 812; //to ustaw ją na 812 (0% wilgotności)
 }
 if (output_value < 224) { //Jeśli obliczona odległość jest mniejsza od 224
   output_value = 224; //to ustaw ją na 224 (100% wilgotności)
 }
Niestety to nie działa, zmiana znaków >/< nic nie daje, po dodaniu tych linijek przed:
Kod:
Serial.print("Wilgotność : ");
 Serial.print(output_value);
 Serial.println("%");
 delay(1000);
 }
Powoduje, że na monitorze wyświetla się ciągle 224% i w żadnej sytuacji się to nie zmienia.
 
Odpowiedź
#2
Może źle interpretujesz pojęcie wilgotności gleby?
Tak dla przypomnienia, nie ma to nic wspólnego z obliczaniem wilgotności powietrza (oprócz nazwy). Nie da się nasycić gleby wodą. Wilgotność wagowa gleby, to stosunek wagowy wody do suchej gleby (wysuszonej w temperaturze 105°).
Jest jeszcze wilgotność objętościowa (sam sobie wydedukuj skąd taka nazwa), oraz stopień wilgotności gleby, który określa jak bardzo zalane są puste przestrzenie pomiędzy stałymi okruchami gleby.
W dwu pierwszych przypadkach wilgotność może przekraczać 100% i to grubo przekraczać.
Zastanów się więc co tak naprawdę mierzysz i dla czego mieszanina błota ma inną przewodność od czystej wody, a sucha gleba inną od powietrza.
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#3
Pewnie mu chodzi tylko to by to co on uznaje za w pełni podlane i w pełni suche dawało wyniki w granicach 0-100%.
Na początek pamiętaj, by czujnik zasilać tylko na czas pomiaru, nieco wydłużysz mu życie, nóżki szybko ulegają elektrolizie. Ewentualnie szukaj pojemnościowych, są odizolowane od gleby lakierem.
Co do konwersji zamieniasz max z min i może tu jest problem, nie mam czym dzisiaj przetestować tej funkcji, ale w przykładowym szkicu są takie funkcje:

Kod:
 sensorValue = analogRead(sensorPin);

 // apply the calibration to the sensor reading
 sensorValue = map(sensorValue, sensorMin, sensorMax, 0, 255);

 // in case the sensor value is outside the range seen during calibration
 sensorValue = constrain(sensorValue, 0, 255);

 // fade the LED using the calibrated value:
 analogWrite(ledPin, sensorValue);
Tu jest jednak pokazane, że podajesz w kolejności min i max. Jak chcesz to odwrócić to wystarczy wstawić 
 output_value = map(1023-output_value,224,812,0,100);
Podmiana z ifami też powinna działać ograniczając odczyty od 224 do 812, może co pomieszałeś w kodzie testowym.
Bardzo łatwo też przetestujesz wszystkie możliwe wartości podstawiając swoją zmienną x 0-1023 w pętli while czy for, drukując wyniki na serial i potem pętla while(1) by spokojnie obejrzeć wyniki.
 
Odpowiedź
#4
Tak, chodziło o to co dla mnie oznacza 0-100% ale jeżeli wiedziałbym jak zrobić program, który rzeczywiście pokazałby prawidłowo wilgotność gleby to bardzo chętnie z niego skorzystam. Nie wiem jak to zrobić prawidłowo.
Zmierzyłem suchą ziemię i wartość jaką odczytałem to 812, zalałem ją wodą i po chwili wartość jaką odczytałem to 224. Obecnie gdy czujnik jest poza glebą pokazuje mi wartość -35% dlatego chciałbym aby poniżej 0 nie pokazywało jak również gdy włożę czujnik do samej wody jest ponad 100%.

Opcja
Kod:
output_value = map(1023-output_value,224,812,0,100);
nie pomogła, cały czas wartość na - pokazuje gdy czujnik jest w powietrzu.

Nie wiem jaka częstotliwość pomiaru jest wystarczająca. Teoretycznie gdybym chciał w przyszłości dodać jakąś pompkę do podlewania, wtedy reakcja musi być szybka, ale już dalsze odświeżanie nie musi być takie szybkie. Niestety tutaj będzie problem w moim przypadku z napisaniem takiego programu.

Dostosowałem taki kod:
Kod:
  //////////////////////////////////////////////
 //        ARDUINO SOIL MOISTURE DEMO        //
//                                          //
//           http://www.educ8s.tv           //
/////////////////////////////////////////////



int sensorPin = A0;  
int sensorValue = 0;  
int percent = 0;

void setup() {
 Serial.begin(9600);
 Serial.println("Odczyt z czujnika ...");
 delay(2000);
}

void loop() {
 
 sensorValue = analogRead(sensorPin);
 percent = convertToPercent(sensorValue);
 printValuesToSerial();
 delay(1000);
}

int convertToPercent(int value)
{
 int percentValue = 0;
 percentValue = map(value, 1023, 465, 0, 100);
 return percentValue;
}

void printValuesToSerial()
{
 Serial.print("\n\nWartość analogowa: ");
 Serial.print(sensorValue);
 Serial.print("\nWilgotność: ");
 Serial.print(percent);
 Serial.print("%");
}
Teoretycznie jest lepiej, poniżej 0 nie schodzi ale po włożeniu do wody ponad 135%. Gdy ustawię zamiast 465 niższą wartość wtedy zmienia się zakres (w wodzie czujnik pokazuje minimalnie około 299). Nie wiem jak prawidłowo to skalibrować aby właśnie ta wilgotność miała coś wspólnego z rzeczywistością. A z ograniczeniem wyświetlania wartości póki co nie udało się poradzić.

Dodałem:
Kod:
if (percent < 100) { //Jeśli obliczona wilgotność jest większa od 100%
  percent = 100; //to ustaw ją na 100% wilgotności
}
Niestety żadnej zmiany.
 
Odpowiedź
#5
W nowym kodzie nie schodzi Ci do 0 bo rozciągnąłeś wartości do max wartości odczytywanej z ADC, jak zamiast 465 wstawisz 0 to też nie będziesz przekraczał 100%. Po prostu sprawdź sobie jak chciałeś na początku czy jest mniejszy/większy i ustaw do wartości granicznych.
Wystarczyło zrobić prostą pętlę i możesz sobie przetestować wszystkie wartości, masz nowe ustalenia to zmodyfikuj. To daje wartości od 0 -100:
Kod:
void setup() {
 // put your setup code here, to run once:
 Serial.begin(115200);
 for(int i=0;i<1024;i++)
 {
int testowana=i;
 if (testowana<224) testowana =224;
 if (testowana>812) testowana =812;
 

Serial.println(map(testowana, 812, 224, 0, 100) );  
 }

}

void loop() {
 // put your main code here, to run repeatedly:
 

}
Myślałem, że może map nie trawi odwrócenia wartości i stąd to 1023-ADC, ale jest OK.
 
Odpowiedź
#6
Tego nie skalibrujesz to jest tylko do nauki...

To nic innego jak dwie elektrody wbite w ziemię i jest odczytywane przejście napięcia wiec żeby skalibrować trzeba uwzględnić glebę , wodę , i długość średnica elektrod. Każda zmiana któregoś składnika powoduje rozkalibrowanie.

Wysusz glebę docelową w doniczce i ustaw jako "0%" podlej docelowa wodą na maxa i ustaw na "100%" Żadne sprawdzanie z szklanką wody albo po wyciągnięciu. Powietrze ma inną rezystancję niż sucha ziemia tak samo mokra ziemia ma inna rezystancję od samej wody..
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#7
(06-05-2019, 22:45)Jarewa0606 napisał(a): Tego nie skalibrujesz to jest tylko do nauki...

To nic innego jak dwie elektrody wbite w ziemię  i jest odczytywane przejście napięcia wiec żeby skalibrować trzeba uwzględnić glebę , wodę , i długość średnica elektrod. Każda zmiana któregoś składnika powoduje rozkalibrowanie.

Wysusz glebę docelową  w doniczce i ustaw jako "0%" podlej docelowa wodą na maxa i ustaw na "100%"  Żadne sprawdzanie z szklanką wody albo po wyciągnięciu.  Powietrze ma inną rezystancję niż sucha ziemia  tak samo mokra ziemia ma inna rezystancję od samej wody..

Tak też zrobiłem ale czasami potrafi wyjść poza 0-100% dlatego chciałbym ograniczyć aby nie pokazywało wartości wyższych i niższych niż podany zakres ale w żadnej kombinacji if nie chce zadziałać...
 
Odpowiedź
#8
(06-05-2019, 21:17)mrozilla napisał(a): Dodałem:
Kod:
if (percent < 100) { //Jeśli obliczona wilgotność jest większa od 100%
  percent = 100; //to ustaw ją na 100% wilgotności
}
Niestety żadnej zmiany.

Może dla tego, że jest to źle napisany warunek?
Nie ma takiej możliwości, że jeśli napiszesz poprawnie algorytm, to on nie zadziała.
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#9
(08-05-2019, 20:43)Robson Kerman napisał(a):
(06-05-2019, 21:17)mrozilla napisał(a): Dodałem:
Kod:
if (percent < 100) { //Jeśli obliczona wilgotność jest większa od 100%
  percent = 100; //to ustaw ją na 100% wilgotności
}
Niestety żadnej zmiany.

Może dla tego, że jest to źle napisany warunek?
Nie ma takiej możliwości, że jeśli napiszesz poprawnie algorytm, to on nie zadziała.

Domyślam się. W tym temacie zamieściłem kilka wersji tego warunku, żaden nie działa. Nie wiem gdzie robię błąd...
 
Odpowiedź
#10
Próbowałeś chociaż na próbę wgrać przykład z #5? Jak to Ci nie zadziała pokazując znacznie więcej 0 i 100 niż pozostałych wartości (bo poza skalą są do nich obcięte) to znaczy, że wgrywasz szkice do płytki A, a program testujesz na B.
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości