Przeszukaj forum
Pokazywanie wyników dla tagów 'DS18B20'.
Znaleziono 5 wyników
-
System monitorowania poziomu wody w studni z funkcją stacji pogodowej Mój ogród, podobnie jak wiele innych, jest uzależniony od wody ze studni. Często borykałem się z problemem nieregularnego napełniania się studni, szczególnie w okresach suszy. Wielokrotnie zdarzało się, że pompa pracowała na sucho, co prowadziło do jej zapowietrzenia. Stworzyłem system monitoringu poziomu wody w studni, który sprawdza poziom wody i jej temperaturę. Pierwotnie w skład projektu wchodziły dwa urządzenia- nadajnik oparty o Pi Pico W umieszczony przy studni oraz odbiornik jako urządzenie oparte na Raspberry Pi pico. Oba urządzenia komunikowały się radiowo poprzez NRF24L01. Ze względu na problemy ze stabilizacją działania tych modułów radiowych projekt obecnie oparty jest na jednym Pi Pico W w specjalnie zaprojektowanej obudowie znajdującej się przy studni. Wysyła ono dane na serwer oparty na systemie Fedora Server. Serwer ten wstawia dane do bazy danych oraz generuje stronę www, która w sposób estetyczny pokazuje wyniki pomiarów. def send_data(data): ''' Sending data to the server''' try: # Determining the server address addr_info = socket.getaddrinfo('000.000.000.000', 5001) addr = addr_info[0][-1] # Creating and connecting a socket s = socket.socket() s.connect(addr) data = data.replace(' ', '+') # Preparing and sending an HTTP request request = "GET /update?data=" + str(data) + " HTTP/1.1\r\nHost: 000.000.000.000\r\nConnection: close\r\n\r\n" lcd.move_to(14,1) lcd.putstr('s1') s.send(bytes(request, 'utf8')) except: print(f'Failed to send data.') Przejdźmy do szczegółów. Do pomiaru poziomu wody użyłem wodoodpornego czujnika ultradźwiękowego JSN-SR04T. Swoją drogą naprawdę go polecam bo działa już 3 sezon bez żadnych problemów. Kluczem było tutaj odpowiednie zawieszenie sensora tak aby w jego zasięgu znajdowało się wyłącznie lustro wody a nie ścianki studni. Jego zakres pomiarowy to 20-450 cm a kąt pomiarowy mniej niż 50 stopni. Dokładność pomiarów +-3mm jak dla mnie wystarczająca do tego zastosowania. def get_distance(): count_d = 0 d = sensor.distance_cm() while d < 5: actual_time = formated_time() lcd.move_to(0,0) lcd.putstr(actual_time[9:18]) lcd.move_to(14,1) lcd.putstr('d' + str(count_d)) print('Proba uzyskania glebokosci studni: ' + str(count_d)) d = sensor.distance_cm() sleep(1) count_d = count_d + 1 if count_d >5: return 0 break # print('Distance:', distance, 'cm') #sleep(0.1) lcd.move_to(14,1) lcd.putstr(' ') return d W wodzie zanurzony jest kolejny z czujników kupiony zresztą też w sklepie Botland: DS18B20. Zakres pomiaru temperatury: -55°C do +125°C z dokładnością +- 0,5 stopnia. Nie sądzę abym za mojego życia potrzebował szerszego zakresu pomiarowego do pomiaru wody w studni 😉 Ja kupiłem wersję z 5 metrowym przewodem, ale z tego co widzę są wersje z krótszymi przewodami i dłuższymi. Do projektu dołożyłem także czujnik do pomiaru temperatury powietrza, wilgotności i ciśnienia atmosferycznego BME280. Zakres pomiarowy jest bardzo przyzwoity, temperaturę mierzy w zakresie-40°C - 85°C przy dokładności ±1°C. Wilgotność: 10% RH do 80% RH, dokładność ±3% RH. Ciśnienie powietrza: 300 hPa do 1100 hPa, dokładność ±1 hPa. temp, pressure, humidity = bme.read_compensated_data() temperature = temp / 100 # Temperatura w °C pressure = pressure / 100 / 256 # Ciśnienie w hPa humidity = humidity / 1024 # Wilgotność w % temperature = "{:02d}".format(round(temperature)) pressure = "{:02d}".format(round(pressure)) humidity = "{:02d}".format(round(humidity)) Co prawda z poziomu serwera można zarządzać czasem pomiaru to jednak dodałem niejako standardowo do projektu zegar DS1302 RTC. Urządzenie aktualizuje swój czas po włączeniu. def get_current_datetime(): response = urequests.get("http://worldtimeapi.org/api/timezone/Europe/Warsaw") data = response.json() datetime = data["datetime"] return datetime def set_ds1302_datetime(datetime_str): #print("Received datetime string:", datetime_str) datetime_obj = utime.localtime(utime.mktime((int(datetime_str[0:4]), int(datetime_str[5:7]), int(datetime_str[8:10]), int(datetime_str[11:13]), int(datetime_str[14:16]), int(datetime_str[17:19]), 0, 0,))) datetime_list = [datetime_obj[0], datetime_obj[1], datetime_obj[2], datetime_obj[6] + 1, datetime_obj[3], datetime_obj[4], datetime_obj[5], 0] #print("Converted datetime list:", datetime_list) ds.date_time(datetime_list) Moduł przy studni zawiera także wyświetlacz aby można było sprawdzić parametry będąc koło studni. Jest to typowy LCD 2x16 z konwerterem I2C LCM1602 W kodzie programu będzie widoczny import biblioteki NRF24L01. Mam ciągły „uraz” po pomimo dodania kondensatora elektronicznego i ceramicznego bezpośrednio przy VCC i GND modułu, nie byłem wstanie okiełznać w sposób zadowalający jego działania. Może kiedyś... W tym sezonie chciałbym rozbudować urządzenie o funkcję automatycznego włączania i wyłączania pompy w zależności od poziomu wody. Na zdjęciach obudowy można zobaczyć specjalne porty na kable wejściowe i wyjściowe. Jest także miejsce przekaźnik 250 VAC z optoizolacją. Pod jego 4 złącza podłączę w przyszłości zarówno pompę jak i elektrozawory poszczególnych linii nawadniania. Wyniki pomiarów mogę przeglądać na specjalnej stronie hostowanej na własnym serwerze. Dostosowana jest ona zarówno do smartfonów jak i do czytnika ebook. Strona pokazuje w sposób graficzny poziom napełnienia studni oraz jej poziom sprzed 5 minut. Na koniec- samodzielnie zaprojektowana obudowa, w której każdy element ma swoje miejsce. Zapraszam także do obejrzenia filmu prezentującego rozwiązanie: link do youtube. Będę bardzo wdzięczny za wszelkie rady ale także i konstruktywną krytykę.
-
Witam, zwracam się do wszystkich praktykujących o pomoc, jak w temacie, ws. kodu w Arduino. Jak większość początkujących miłośników programowania w Arduino i ja zacząłem od czujnika temperatury. Z uwagi na bardzo znikomą ilość mojej wiedzy, po wielu tygodniach poszukiwań rozwiązania do mojego projektu, już wiem że programowanie nie jest takie proste jak się wydawało. A szukanie gotowego rozwiązania to jak szukanie przysłowiowej igły w stogu siana. Pewnie wszyscy powiecie, że nie tędy droga. Tak, trochę się z tym zgadzam i choć drogi są różne to ważne żeby dotrzeć do celu. A cel jest taki, żeby dodać przycisk, który "wyłącza/włącza" buzzer po przekroczeniu konkretnej temperatury - tylko po to, żeby nie "hałasował". I tu dodatkowo rozwinę o co chodzi z tym "włącza/wyłącza" buzzer. Po przekroczeniu danej temp. włącza się alarm (buzzer) a wciśniecie przycisku (coś typu mikrostyk) wyłącza dźwięk, kolejne wciśnięcie włącza dźwięk i tak w kółko pod warunkiem że nadal jest przekroczona temp. - trochę takie sprawdzenie czy dalej alarm jest włączony. Oczywiście, kiedy alarm nie jest włączony, wciśnięcie przycisku nie daje żadnej reakcji. Poniżej dotychczasowy kod jaki udało się wykonać (bez przycisku). #include <OneWire.h> #include <DallasTemperature.h> #define ONE_WIRE_BUS 4 #define BUZZER 7 #define LED 8 OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); void setup() { pinMode(8,OUTPUT); pinMode(7,OUTPUT); Serial.begin(9600); Serial.println("Dallas DS18B20. Pomiar Temperatury."); sensors.begin(); } void loop(void) { Serial.print("Temperatura: "); Serial.print(sensors.getTempCByIndex(0)); sensors.requestTemperatures(); // Polecenie, aby uzyskać odczyty temperatury Serial.println(); delay(500); if (sensors.getTempCByIndex(0) >= 27) //Jeśli czujnik wskaże temp >27 stopni Celcjusza { digitalWrite(8, HIGH); //Włącz diodę tone(7, 1000, 100); // Uruchom brzęczyk delay(150); tone(7, 1000, 100); delay(150); tone(7, 1000, 100); delay(150); } if (sensors.getTempCByIndex(0) < 27) //Jeśli czujnik wskaże temp <27 stopni Celcjusza { digitalWrite(8, LOW); //Wyłącz diodę } } Z góry dziękuję wszystkim udzielającym rad, rozwiązań i innych propozycji do powyższego projektu. Pozdrawiam.
-
Witam, jak to często bywa, początkujący porywa się na gruby projekt 🙂 w tym przypadku też ale ambicje są, gorzej z praktyką i wiedzą 😉 Projekt jaki chcę stworzyć to mikro kontroler z zastosowaniem Mega 2560 do którego podłączone są dwa czujniki DS18B20 na osobnych pinach (by w przypadku uszkodzenia jednego z nich uniknąć ponownego programowania układu, a tutaj akurat znaczenie ma kolejność czujników) dwa wyświetlacze LED 7-segmentowe moduły komunikujące się na 1-wire( układ TM1637); Wyświetlacze na bieżąco podają temperaturę z czujników, przy czym po przekroczeniu nastawnej granicy temperatury dla czujnik drugiego uruchamia się przekaźnik dla lampy sygnalizacyjnej, Od włączenia układu następuje odliczanie od 0 do około 5 minut (300000ms) pod WARUNKIEM że na jednym z pinów jest stan niski (zwarcie z masą poprzez przekaźnik dostający sygnał z zewnętrznego urządzenia) gdy odliczanie dobiegnie do końca poprzez Ethernet shield wysyłane są dane pomiarów do bazy danych gdzieś w sieci lokalnej. po wysłaniu wszystko zaczyna się od początku, czyli zliczanie i kolejne wysyłanie danych. Tak na brudno w notatniku wypisałem sobie: po uruchomieniu programu: -wykrycie czujników ds18b20 na PIN 2 ("temp_in" -temp. wejścia powietrza do chłodzenia) i PIN 3 ("temp_out" -temp.powietrza po schłodzeniu obszaru/produktu); -wyświetlenie wartości "temp_in" na TM1637 wyświetlacz pierwszy jako "DisplayTin" oraz "temp_out" na "DisplayTout" - wyświetlacz drugi. Ze względu na brak znaku kropki wyświetlacza i 9-bit rozdzielczość pomiaru zamiast kropki wyświetlany znak stopni, np dla wartości temperatury 17.0 i 24.5: ---- ---- ---- | | | | | | | | | | | | ---- | | | | | | | | ---- ---- ---- ---- | | | | | | | | | | | | ---- ---- ---- ---- | | | | | | ---- ---- -sprawdzenie warunku jeśli temp_out >= tempALARM (wartość ustawiana i zapamietywana po zaniku zasilania) to na pinie alarmu stan wysoki wyzwalający przekaźnik; -sprawdzenie wciśnięcia przycisku (PINy 30-33) zmiany wartości maksymalnej temperatury na wyjsciu "tempALARM", lub numeru linii produkcyjnej "liniaNr"; -sprawdzenie wartości na wejściu pinu NARAwAuto (aktywne schladzanie w trybie automatycznym) jesli prawda uaktywniene zliczania licznika do 4.5-5min (300000 ms); --po osiąnięciu wartości max licznika 300000 ms uruchomienie funkcji dla EthShield wysyłającej dane pomiaru "temp_in" "temp_out" numer linii produkcyjnej "liniaNr" (ustawiany recznie i zapamietywany) oraz stan wyjscia pinu ALARMtemp; -podczas zmian nastawy tempALARM na wyświetlaczu pojawia się na 5 sekund wartość w postaci: ---- ---- ---- | | | | | | | | O | | ---- ---- ---- | | | O | | | | | | | ---- ---- ---- skok o 1 stopień celciusza, zakres 1 do 50 Dla zmiany numeru linii przykładowo wyświetla: ---- ---- | | | | O | | ---- | O | | | | | ---- ---- skok o 1, zakres od 1 do 63, obie wartości muszą być zapamiętane po zaniku zasilania; a podłączenie pinów mniej więcej tak rozmieszczone: /* informacje pinologii pin 0 pin 1 pin 2 DS18B20data temp_in //wejsciowa temp powietrza nr.1 pin 3 DS18B20data temp_out //temp po wyjsciu nr.2 pin 4 SDCardShield SS //SlaveSelect pin 5 CLK1 out //zegar dla wyswietlacza 1 na tm1637 pin 6 DIO1 out //dane dla wysw.1 pin 7 CLK2 out //zegar dla wyswietlacza 2 na tm1637 pin 8 DIO2 out //dane dla wysw.2 pin 9 ALARMtemp out relay //po przekroczeniu nastawionej temp alarm na buzzer/sygnalizator swietlny przez przekaznik pin 10 ETH SS Mega2560 pin 53 //SlaveSelect wybrannie ukladu perferyjnego eth/sd pin 11 ETH MOSI Mega2560 pin 50 //dane do ukladu pin 12 ETH MISO Mega2560 pin 51 //dane z ukladu pin 13 ETH SCK Mega2560 pin 52 //sygnal zegara pin 25 NARAwAuto in zRelay //zwarcie do masy po zapodaniu 24V z Nary do przekaznika pin 27 SendTemp_LED (Mega2560) //wyslanie danych do bazy danych info LED pin 30 keyENT lub keyAL_down pin 31 keyEXIT lub keyAL_up pin 32 keyDN lub keyLN_down pin 33 keyUP luk keyLN_up */ Dla pin 30-33 nie jestem pewien rozwiązania, czyli czy zrobić menu, i przeskakiwanie po wartościach nastawianych czyli temp. maxymalna i wyzwalanie alarmu plus numer linii/urządzenia pomiarowego. Czy na sztywno przyporządkować dany przycisk pod zwiększanie/zmniejszanie parametru pierwszego i drugiego. Co będzie lepszym rozwiązaniem? Znalazłem na forum temat myślę że nada się idealnie ta biblioteka dla mnie, jeden wątek na rozpoznanie czujników i wyświetlenie ich na wyświetlaczach + sprawdzenie wartości temp alarmu, drugi watek sprawdzający wciśnięcie jednego z przycisków i ewentualną zmianę wartości i jej zapisanie do pamięci, trzeci wątek odliczający ten czas 5 min (+czas na wykonanie pozostałych wątków) i po zakończeniu wysłania danych zresetowanie licznika. W obecnej chwili udało mi się ujarzmić wyświetlanie dwóch wyświetlaczy na bibliotece TM1637Display.h , kolejny krok którym się zajmuje to wyświetlanie wartości czujników na osobnych modułach. Następnie dodanie możliwości zmiany parametrów z przycisków. Jak się to uda to jestem w 1/3 drogi do sukcesu. Czy jakieś porady na początek, na co uważać, lub do samego zamysłu działania?
-
Cześć, Jak włączyć/wyłączyć zasilanie pasożytnicze na czujniku DS18B20? Z góry dziękuję. PS.: Przepraszam jeśli dałem temat w złej kategorii...
-
Wszystko działa dobrze, ale gdy temperatura spadnie poniżej 0 to pokazuje jakiś dziwny odczyt. Siedzę nad tym już drugi dzień i nie wiem o co chodzi. Używam arduino nano. Z góry dziękuję za pomoc 🙂 #include <ModbusRtu.h> #include <OneWire.h> #include <DallasTemperature.h> #include <Wire.h> #include <LiquidCrystal_I2C.h> #define SLAVE_ID 1 #define BUTTON_PIN 7 #define RS_PIN 5 #define DS_PIN 10 #define SUN_PIN A1 #define TEMP_REG 0 #define SUN_REG 1 uint16_t au16data[9] = { 9999, 9999, 2, 3, 2018, 11, 16, 8, 7}; Modbus slave(SLAVE_ID, 0, RS_PIN); OneWire oneWire(DS_PIN); DallasTemperature sensors(&oneWire); DeviceAddress ds18b20 = { 0x28, 0x90, 0x63, 0x45, 0x92, 0x06, 0x02, 0xE0 }; //1 //DeviceAddress ds18b20 = { 0x28, 0x68, 0xA6, 0x45, 0x92, 0x03, 0x02, 0x3C }; //2 //DeviceAddress ds18b20 = { 0x28, 0x12, 0xC6, 0x45, 0x92, 0x08, 0x02, 0x59 }; //3 LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); int temperature = 9999; unsigned long getTempTime = 0; unsigned long lastUpdate = 0; unsigned long buttonTime = 0; int buttonHoldTime = 0; byte sun = 0; bool lcdLight = true; void setup() { sensors.begin(); slave.begin( 9600 ); // baud-rate at 9600 lcd.begin(16,2); pinMode(BUTTON_PIN, INPUT); } void loop() { temperature = readTemp(); if(temperature != NULL || temperature < 200) au16data[TEMP_REG] = temperature; sun = readSun(); if(sun != NULL) au16data[SUN_REG] = sun; slave.poll(au16data, 16); if(millis()-lastUpdate >= 1500UL) { lcd.clear(); printTime(); lcd.setCursor(0, 1); printPage0(); lastUpdate = millis(); } if(digitalRead(BUTTON_PIN) == HIGH){ if(buttonTime == 0) buttonTime = millis(); buttonHoldTime += millis()-buttonTime; buttonTime = millis(); } else{ if(buttonHoldTime > 750){ if(lcdLight == true) lcdLight = false; else lcdLight = true; } else if(buttonHoldTime < 500 && buttonHoldTime > 50) ; buttonHoldTime = 0; buttonTime = 0; } if(lcdLight == true) lcd.backlight(); else lcd.noBacklight(); ////////////////////////////////////// } int readTemp(){ if(millis()-getTempTime >= 1000UL){ sensors.requestTemperatures(); getTempTime = millis(); return sensors.getTempC(ds18b20)*10; } else return temperature; } byte readSun(){ return map(analogRead(SUN_PIN), 0, 1023, 0, 100); } void printTime(){ if(au16data[7] < 10) lcd.print(0); lcd.print(au16data[7]); lcd.print(":"); if(au16data[8] < 10) lcd.print(0); lcd.print(au16data[8]); lcd.print(" "); lcd.print(au16data[6]); lcd.print("."); lcd.print(au16data[5]); lcd.print("."); lcd.print(au16data[4]); } void printPage0(){ lcd.print("T:"); lcd.print(au16data[TEMP_REG]/10); lcd.print("."); lcd.print(au16data[TEMP_REG]-au16data[TEMP_REG]/10*10); lcd.print("*C"); lcd.print(" "); lcd.print("SUN:"); lcd.print(au16data[SUN_REG]); lcd.print("%"); }