Inteligentne domy są dziś modne. Jeśli ktoś lubi majsterkowanie można wykorzystać Raspberry do zrobienia własnego systemu inteligentnego domu. Na początek zaczniemy od pomiaru temperatury i wilgotności.
Wykorzystamy czujnik temperatury i wilgotności DHT11 (w cenie ok 10 zł), po prawidłowym podłączeniu czujnika zgodnie ze schematem:
(warto zajrzeć na stronę autora schematu).
Teraz napiszemy aplikację w C do obsługi czujnika i uruchomimy ją na Rasbperry Pi 3 jako skrypt CGI tak, aby odczyt z czujnika był możliwy poza domem.
Musimy mieć do tego celu skonfigurowany zewnętrzny adres IP, z którego widać PI. Na naszej malince stawiamy serwer apache i włączamy moduł CGI.
1 2 | sudo apt-get install apache2 sudo a2enmod cgi |
temperaturacgi.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | #include <wiringPi.h> #include <stdio.h> #include <stdlib.h> #include <stdint.h> #define MAXTIMINGS 85 #define DHTPIN 7 int dht11_dat[5] = { 0, 0, 0, 0, 0 }; int wczytaj_dht11() { uint8_t laststate = HIGH; uint8_t counter = 0; uint8_t j = 0, i; float f; dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0; pinMode( DHTPIN, OUTPUT ); digitalWrite( DHTPIN, LOW ); delay( 18 ); digitalWrite( DHTPIN, HIGH ); delayMicroseconds( 40 ); pinMode( DHTPIN, INPUT ); for ( i = 0; i < MAXTIMINGS; i++ ) { counter = 0; while ( digitalRead( DHTPIN ) == laststate ) { counter++; delayMicroseconds( 1 ); if ( counter == 255 ) break; } laststate = digitalRead( DHTPIN ); if ( counter == 255 ) break; if ( (i >= 4) && (i % 2 == 0) ) { dht11_dat[j / 8] <<= 1; if ( counter > 16 ) dht11_dat[j / 8] |= 1; j++; } } if ( (j >= 40) && (dht11_dat[4] == ( (dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF) ) ) { f = dht11_dat[2] * 9. / 5. + 32; printf( "Wilgotność = <b> %d,%d%%</b><br> Temperatura = <b>%d,%d \°C</b> (%.1f F)\n", dht11_dat[0], dht11_dat[1], dht11_dat[2], dht11_dat[3], f ); return 1; } else return 0; //błędny pomiar } int main( void ) { printf("Content-type: text/html\n\n"); printf( "<html>" "<head>" "<title>Temperatura i wilgotność</title>" "<meta charset="utf-8">" "</head>" "<body>" "<h3>Pomiar temperatury i wilgotności DHT11</h3>" ); if (wiringPiSetup()==-1) { printf( " <b>Błąd inicjacji czujnika</b>" "</body></html>" ); return 1; } while (!wczytaj_dht11()) //jeśli błąd odczytu - ponów za 100ms próbę do skutku delay(100); printf( "</body></html>" ); return 0; } |
Dość istotna sprawa – GPIO musi być uruchamiane jako root, a serwer www nie ma tych uprawnień. Aby skompilować program piszemy kilka poleceń:
1 2 3 4 | gcc temperaturacgi.c -o temperaturapokojowa.cgi -lwiringPi chown root temperaturapokojowa.cgi cp temperaturapokojowa.cgi /usr/lib/cgi-bin chmod 4755 /usr/lib/cgi-bin/temperaturapokojowa.cgi |
Nie dajemy w ten sposób uprawnień serwerowi, a jedynie jednemu naszemu programowi CGI. Raspberry Pi 3 domyślnie używa katalog /usr/lib/cgi-bin dla skryptów CGI.
teraz wpisując z dowolnego urządzenia adres www
1 | http://adresnaszejmaliny/cgi-bin/temperaturapokojowa.cgi |
otworzy nam się aktualny pomiar wilgotności i temperatury w pokoju.
Program też można uruchomić lokalnie z powłoki (wpisując ./temperaturapokojowa.cgi) – wygeneruje nam kod w HTML zawierający temperaturę i wilgotność.
Możliwości rozwoju projektu jest wiele:
- Można wykorzystać wykresy Google i przygotować graficzną wersję termometru z wykresem
- Można połączyć się z MySQL w C i zapisywać wyniki pomiarów co jakiś czas do bazy (zob. Cron), a potem na wyjściu rysować wykresy miesiąca, roku, tygodnia i dnia oraz zmiany temperatury i wilgotności
- Można skorzystać z zewnętrznych usług tworzenia takich wykresów