Skocz do zawartości
Wiadomość dodana przez Treker,

Uwaga od redakcji!

Pamiętaj, że w dziale "Artykuły użytkowników" pojawiają się wpisy, które napisali czytelnicy Forbota. Każdy może opublikować tutaj swój poradnik (również Ty). Nie oceniamy i nie weryfikujemy tych treści przed publikacją - pamiętaj, że budowanie urządzeń zasilających z 230 V może być niebezpieczne dla życia i zdrowia! Dla bezpieczeństwa odradzamy osobom zupełnie początkującym budowanie tego typu projektów. Jeśli widzisz błąd merytoryczny to zgłoś go w komentarzach - kulturalna i merytoryczna krytyka jest zawsze mile widziana. Pamiętaj jednak o Polityce Przyjaznego Forum.

Pomocna odpowiedź

Rozwiązania inteligentnych domów, czujników oraz wszechobecnych urządzeń IoT coraz powszechniej wkraczają do naszego życia – zmieniając je, a także dając nam szerokie spektrum możliwości wpływania na otaczający nas świat. Jednym z podstawowych narzędzi wykonawczych jest inteligentne gniazdko 230V, którym oprócz programatora czasowego można sterować zdalnie z dowolnego miejsca na świecie. Gniazdko które ma prosty interfejs do komunikacji, a także umożliwia łatwą komunikację z innymi urządzeniami w jego otoczeniu. Te wymagania nie jest łatwo spełnić obecnym na rynku rozwiązaniom typu smart-home. Według mnie największym ich problemem jest brak otwartej architektury oraz konieczność instalowania aplikacji bez których owe urządzenia nie działają albo wymagają masy inżynierii wstecznej aby dobrać się do protokołu sterującego. Inna sprawą jest konieczność posiadania centralki która owe smart-gniazdka zbiera w jednym punkcie. Odpowiedzią na te wszystkie bolączki może być samodzielna budowa prostego „smart gniazdka”. W artykule postaram się zamieścić jak krok po kroku może wyglądać realizacja takiego urządzenia wraz z przykładami oprogramowania a także finalna wersja działająca już „na produkcji” u mnie w domu.

Ten artykuł bierze udział w naszym konkursie! 🔥
Na zwycięzców czekają karty podarunkowe Allegro, m.in.: 2000 zł, 1000 zł i 500 zł.

konkurs_forbot_nagrody_1-350x147.png

Potrafisz napisać podobny poradnik? Opublikuj go na forum i zgłoś się do konkursu!
Czekamy na ciekawe teksty związane z elektroniką i programowaniem. Sprawdź szczegóły »

Na wstępie zaprezentuję jak wygląda gotowe urządzenie

20210408_212915.thumb.jpg.1000e0b11876c1accaa70945a0ac6f2d.jpg

Zastanówmy się najpierw jakie cechy miałoby spełniać:

  • Włączanie/wyłączanie urządzeń zasilanych 230V (najlepiej dwóch niezależnie)
  • Pomiar temperatury i wilgotności w miejscu położenia (w celu ewentualnego wpięcia do Domoticza lub podobnego)
  • Łatwość programowania akcji zależnych od czasu i daty ewentualnie dnia tygodnia
  • Możliwość komunikacji z innymi smart urządzeniami w domu po Wifi
  • Łatwość kontroli przy użyciu telefonu bez specjalnej aplikacji

Mając na uwadze powyższe wymagania oraz to co akurat miałem na półce i się kurzyło lub mogłem kupić na szybko w zielonym dużym sklepie - powstało takie coś jak na zdjęciu powyżej. 

A o to lista użytych materiałów wraz z cenami aktualnymi w okolicach lutego 2021

  • Raspberry Pi3 - 169 zł
  • Moduł z dwoma przekaźnikami 10A/150VAC (10A/24VDC) - 9 zł
  • Czujnik temperatury i wilgotności DHT22 (AM2302) - 25zł
  • Zasilacz do Raspberry Pi 5V/3.1A microUSB eXtreme - 28 zł
  • Kolorowe przewody połączeniowe F-F - 1zł
  • Kostki elektryczne 1 zł
  • Puszka Elektryczna - 15 zł
  • Kabel z wtyczką 230V - 10 zł
  • Kabel USB - 9 zł
  • Podwójne Gniazdo Natynkowe 230V - 10zł
  • Tact Switch - 1zł
  • Śruby, nakrętki, podkładki fi 2; 2,5 oraz 3mm - 1 zł

Całość wyszła około 300 zł. Najdroższym elementem jest tutaj malina, ale jak zaznaczyłem na samym wstępie akurat miałem wersję 3 leżącą na półce, lecz przy tym użytkowaniu - spokojnie tutaj wystarczy najtańsza i najprostsza wersja. Poniżej zamieszczam schemat podłączenia układu wraz z użytymi pinami.

Gniazdko230V.thumb.png.72be7aa84e4d939ca2ae607e077d50ae.png

Sporą częścią całego projektu jest oprogramowanie. Całość napisana jest w pythonie.

  • Obsługa microswitcha PowerOff - umożliwia wyłączenie maliny bez konieczności logowania się po ssh i przeniesienia gniazdka w inne miejsce
  • Obsługa czujnika DHT22 - odczyt wartości temperatury i wilgotności oraz wysłanie ich (w moim przypadku do domoticza)
  • Obsługa przekaźników wraz z serwerem www - prosta stronka www z przyciskami do włączania i wyłączania przekaźników

Poniżej zamieszczam instrukcję jak dodać PowerOff do Raspberry PI. 

  • Należy zdefiniować plik shutdown.py w katalog na przykład /home/pi/Pythons/
# !/bin/python

import RPi.GPIO as GPIO
import time
import os

# Use the Broadcom SOC Pin numbers
# Setup the pin with internal pullups enabled and pin in reading mode.
GPIO.setmode(GPIO.BCM)
GPIO.setup(21, GPIO.IN, pull_up_down=GPIO.PUD_UP)

def Shutdown(channel):
    print("Shutting Down system in 2 seconds")
    time.sleep(2)
    os.system("sudo shutdown -h now")
    
# Add our function to execute when the button pressed event happens

GPIO.add_event_detect(21, GPIO.FALLING, callback=Shutdown, bouncetime=2000)

# Now wait!

while 1:
    time.sleep(1)

 

  • Następnie należy zmodyfikować plik rc.local komendą
sudo nano /etc/rc.local
  • Przed exit 0 należy wstawić odwołanie do naszego skryptu
sudo python3 /home/Pi/Pythons/shutdown.py &

Po powyższych zabiegach nasza malina powinna zamknąć system po wciśnięciu microswitcha lub innego rodzaju przycisku który podłączyliśmy do pinu 21 maliny.

Kolejnym etapem będzie obsługa czujnika temperatury i wilgotności DHT22

Należy zdefiniować plik dht22.py w katalog na przykład /home/pi/Pythons/

import Adafruit_DHT
import time
import urllib
import requests

DHT_SENSOR = Adafruit_DHT.DHT22
DHT_PIN = 4
sensor_idx  = 11

humidity, temperature = Adafruit_DHT.read_retry(DHT_SENSOR, DHT_PIN)


url_json    = "http://192.168.0.118:8080/json.htm?type=command&param=udevice&idx="
verbose = 1
#if humidity is not None and temperature is not None:
        #f.write('{0},{1},{2:0.1f}*C,{3:0.1f}%\r\n'.format(time.strftime('%m/%d/%y'), time.strftime('%H:%M'), temperature, humidity))
  #  print("Temp={0:0.1f}*C  Humidity={1:0.1f}%".format(temperature, humidity))
#else:
 #   print("Failed to retrieve data from humidity sensor")

    #time.sleep(30)
 
if humidity > 70:
  HUM_STAT = 3
elif humidity > 30:
  HUM_STAT = 1
else:
  HUM_STAT = 2
    
# use Domoticz JSON url to update
cmd = url_json  + str(sensor_idx) + "&nvalue=0&svalue=" + str(temperature) + ";" + str(humidity) + ";"+ str(HUM_STAT)
hf = urllib.request.urlopen(cmd)
if verbose > 0:
  print('Sensor data: temperature = {0:0.1f}C,  humidity =  {1:0.1f}%'.format(temperature, humidity))
  print('Uploaded to Pi: ' + cmd)
  print('Response: ' + hf.read().decode())
hf.close

Następnie dodać do crona odczyt czujnika co 5 minut. W tym celu należy komendą sudo crontab-e  wejść do edycji zadań crona i dodać linijkę

*/5 * * * * python3 /home/pi/Pythons/dht22.py

Kilka zdań chciałbym poświęcić temu co dzieje się w kodzie programu dht22.py.

Na wstępie mamy importowane biblioteki / moduły. Następnie definicja pinu użytego do danych - w tym przypadku jak na schemacie jest to pin 4. idx 11 oznacza id czujnika w systemie domoticza - odsyłam do artykułów na temat tego oprogramowania. Potem odczytujemy wartości z czujnika - korzystając z biblioteki AdaFruit_DHT. Na koniec zebrane dane w postaci komendy cmd wysyłamy do centralki domoticza (stoi u mnie na drugim Raspberry pi)

Ostatnim punktem oprogramowania będzie dodanie obsługi przekaźników oraz prosta strona www umożliwiająca to. Do tego celu wykorzystałem możliwości pythona i znalazłem oraz lekko zmodyfikowałem serwer www napisany w tym języku. Dzięki temu można łatwo przejść z kodu html do sterowania pinami. Serwer działa na ip 192.168.0.131 oraz porcie 8000. Serwer wystawia prostą stronkę www zawierającą 4 przyciski oraz odczyt temperatury procesora.

Kod przedstawiam poniżej:

# !/bin/python
import RPi.GPIO as GPIO
import os
from time import sleep
from http.server import BaseHTTPRequestHandler, HTTPServer

host_name = '192.168.0.131'  # Change this to your Raspberry Pi IP address
host_port = 8000


class MyServer(BaseHTTPRequestHandler):
    """ A special implementation of BaseHTTPRequestHander for reading data from
        and control GPIO of a Raspberry Pi
    """

    def do_HEAD(self):
        """ do_HEAD() can be tested use curl command
            'curl -I http://server-ip-address:port'
        """
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()

    def _redirect(self, path):
        self.send_response(303)
        self.send_header('Content-type', 'text/html')
        self.send_header('Location', path)
        self.end_headers()

    def do_GET(self):
        """ do_GET() can be tested using curl command
            'curl http://server-ip-address:port'
        """
        html = '''
           <html>
           <body style="width:960px; margin: 20px auto;">
           <h1>Welcome to my Raspberry Pi</h1>
           <p>Current CPU temperature is {}</p>
           <form action="/" method="POST">
               Turn Relay :
               <input style="height: 100px; width: 200px" type="submit" name="submit" value="Pin13On">
               <input style="height: 100px; width: 200px" type="submit" name="submit" value="Pin13Off">
               <input style="height: 100px; width: 200px" type="submit" name="submit" value="Pin19On">
               <input style="height: 100px; width: 200px" type="submit" name="submit" value="Pin19Off">
           </form>
           </body>
           </html>
        '''
        temp = os.popen("/opt/vc/bin/vcgencmd measure_temp").read()
        self.do_HEAD()
        self.wfile.write(html.format(temp[5:]).encode("utf-8"))

    def do_POST(self):
        """ do_POST() can be tested using curl command
            'curl -d "submit=On" http://server-ip-address:port'
        """
        content_length = int(self.headers['Content-Length'])  # Get the size of data
        post_data = self.rfile.read(content_length).decode("utf-8")  # Get the data
        post_data = post_data.split("=")[1]  # Only keep the value

        # GPIO setup
        GPIO.setmode(GPIO.BCM)
        GPIO.setwarnings(False)

        if post_data == 'Pin13On':
            GPIO.setup(13, GPIO.OUT, initial=GPIO.HIGH)
        elif post_data == 'Pin13Off':
            GPIO.output(13, GPIO.LOW)
            GPIO.cleanup(13)
        elif post_data == 'Pin19On':
            GPIO.setup(19, GPIO.OUT, initial=GPIO.HIGH)
        elif post_data == 'Pin19Off':
            GPIO.output(19, GPIO.LOW)
            GPIO.cleanup(19)
        print("Relay on port 13 is {}".format(post_data))
        print("Relay on port 19 is {}".format(post_data))
        self._redirect('/')  # Redirect back to the root url


if __name__ == '__main__':
    http_server = HTTPServer((host_name, host_port), MyServer)
    print("Server Starts - %s:%s" % (host_name, host_port))

    try:
        http_server.serve_forever()
    except KeyboardInterrupt:
        http_server.server_close()
    finally:
        GPIO.cleanup()
        print("Server down!")

A tutaj jak wygląda serwer w przeglądarce:

Server.thumb.png.3af20ff5b34cb419a7bcb601fe104d1c.png

Wielką zaletą takiego podejścia do sterowania jest możliwość kontroli przez dowolną inną malinę przy pomocy komendy curl co daje możliwość na przykład zdefiniowania akcji zależnych od innych czynników

curl -d "submit=Pin13On" http://192.168.0.131:8000

Serwer wymaga launchera w postaci skryptu launcherSrv.sh zawierającego:

#!/bin/sh
# launcherSrv.sh
# navigate to home directory, then to this directory, then execute python script, then back home

cd /
cd home/pi/Pythons
sudo python3 server.py
cd /

Aby serwer startował zaraz po starcie systemu należy do wcześniej wymienionego crona dodać linijkę z launcherem

@reboot sleep 20 && sh /home/pi/Pythons/launcherSrv.sh > /home/pi/Server/logs/cronlog 2&1

W razie niepowodzenia startu skryptu cron odłoży logi w utworzonym katalogu /home/pi/Server/logs

Na koniec dodaję parę zdjęć z montażu oraz wnętrza puszki.

1.thumb.jpg.5478d429f6625b5a8d2b35679b056d90.jpg2.thumb.jpg.8a533d22104355cb35f2e39d9430dd75.jpg3.thumb.jpg.9217eb4d9e869bdf0a73d21a2416639f.jpg4.thumb.jpg.bef71078af1da99359b85203309460f7.jpg5.thumb.jpg.33c9fa5191d1d16a14d25130564bd35e.jpg6.thumb.jpg.b30abf9c16ae9c8486322f12ec40ac00.jpg7.thumb.jpg.1f24291432d1d5c9ccc25849b74e9f14.jpg8.thumb.jpg.28a87ea5dee631f81451e7cc20f94424.jpg9.thumb.jpg.619f4dc89b4f02ee728949f677b54032.jpg10.thumb.jpg.777c9f48916d2a9ceabe0f811609ce85.jpg

Poniżej filmik z działającego urządzenia wraz z pokazaniem wnętrzności. Na filmie ładowarka jest na zewnątrz ale ona też wchodzi do środka, przez co jest tam jeszcze ciaśniej.

Krotki filmik obrazujący działanie gniazdka

Co można było zrobić lepiej

  • Trochę odizolować czujnik DHT22 żeby temperatura maliny nie wpływała na pomiar temperatury otoczenia
  • Dałbym większą puszkę - jak widać na ostatnim zdjęciu jest już tam plątanina kabli a nie ma jeszcze ładowarki USB
  • Należy dołożyć drugą ładowarkę do sterowania przekaźników - czasami chyba ze względu na lekki przysiad zasilania przy przełączaniu malina się zawiesza (muszę to sprawdzić)
  • Izolacja ekranem maliny (może to jest przyczyna tego powyżej) + uziemienie do przewodu PE

Projektu ogólnie uważam za udany. Rozbudowując go o więcej przekaźników oraz większą puszkę + możliwe chłodzenie maliny można naprawdę wiele urządzeń sterować w bardzo prosty sposób.

Link to post
Share on other sites
  • ZbigGd zmienił tytuł na: Gniazdo 230V o dużych możliwościach

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.