Parcourir la source

initial commit

Sven Hinz il y a 2 ans
Parent
commit
2df4d5d332
5 fichiers modifiés avec 390 ajouts et 0 suppressions
  1. 19 0
      boot.py
  2. 131 0
      dfplayer.py
  3. 98 0
      main.py
  4. 114 0
      mq135.py
  5. 28 0
      mq135_dht11_example.py

+ 19 - 0
boot.py

@@ -0,0 +1,19 @@
+# This file is executed on every boot (including wake-boot from deepsleep)
+#import esp
+#esp.osdebug(None)
+#import webrepl
+#webrepl.start()
+import network
+
+wlan = network.WLAN(network.STA_IF) # create station interface
+wlan.active(True)       # activate the interface
+wlan.scan()             # scan for access points
+#wlan.isconnected()      # check if the station is connected to an AP
+wlan.connect('WLAN+', 'XPmeg8i2U9') # connect to an AP
+#wlan.config('mac')      # get the interface's MAC address
+print(wlan.ifconfig())         # get the interface's IP/netmask/gw/DNS addresses
+
+#ap = network.WLAN(network.AP_IF) # create access-point interface
+#ap.config(ssid='ESP-AP') # set the SSID of the access point
+#ap.config(max_clients=10) # set how many clients can connect to the network
+#ap.active(True)         # activate the interface

+ 131 - 0
dfplayer.py

@@ -0,0 +1,131 @@
+import utime
+from machine import UART, Timer
+
+IDLE = 0
+PAUSED = 1
+PLAYING = 2
+
+
+class Player:
+    def __init__(self, pin_TX, pin_RX):
+        self.uart = UART(1, 9600, tx=pin_TX, rx=pin_RX)
+        self.cmd(0x3F)  # send initialization parametres
+        self._fadeout_timer = Timer(-1)
+
+        self._volume = 5
+        self._max_volume = 15
+        self._fadeout_speed = 0
+        
+        self.current_folder = False
+        
+        self.volume(self._volume)
+
+    def cmd(self, command, parameter=0x00):
+        query = bytes([0x7e, 0xFF, 0x06, command,
+                       0x00, 0x00, parameter, 0xEF])
+        self.uart.write(query)
+        
+    def cmd2(self, command, par1=False, par2=False):
+
+        #print("Folder: " + str(par1) + ", Track: " + str(par2))
+        if par1 and par2:
+            query1 = bytes([0x7e, 0xFF, 0x06, command, 0x00])
+            query2 = bytes([par1])
+            query3 = bytes([par2])
+            query4 = bytes([0xEF])
+            self.uart.write(query1)
+            self.uart.write(query2)
+            self.uart.write(query3)
+            self.uart.write(query4)
+
+    def _fade_out_process(self, timer):
+        new_volume = self._volume - self._fadeout_speed
+        
+        if new_volume <= 0:
+            print("fadeout finished")
+            new_volume = 0
+            self._fadeout_timer.deinit()
+            self.stop()
+            new_volume = self._max_volume # reset volume to max 
+        self.volume(new_volume)
+
+    # playback
+
+    def play(self, track_id=False):
+        self.play_from_folder(self.current_folder, track_id)
+            
+    def play_from_folder(self, folder_id=False, track_id=False):
+        if isinstance(folder_id, int):
+            self.current_folder = folder_id
+        elif isinstance(self.current_folder, int):
+            folder_id = self.current_folder
+        else:
+            folder_id = 1
+            self.current_folder = folder_id
+        
+        if not track_id:
+            track_id = 3
+        elif track_id == 'next':
+            self.cmd(0x01)
+        elif track_id == 'prev':
+            self.cmd(0x02)
+
+        self.cmd2(0x0F, folder_id, track_id)
+        #self.cmd2(command=0x0F, par1=1, par2=3)
+
+    def pause(self):
+        self.cmd(0x0E)
+
+    def resume(self):
+        self.cmd(0x0D)
+
+    def stop(self):
+        self.cmd(0x16)
+
+    def fadeout(self, fadeout_ms=1000):
+        # more than 500ms and less than 3000ms
+        fadeout_ms = int(sorted([500, fadeout_ms, 3000])[1])
+        fade_out_step_ms = 100
+        self._fadeout_speed = self._volume * \
+            fade_out_step_ms / fadeout_ms  # ten steps per second
+        self._fadeout_timer.init(
+            period=fade_out_step_ms, callback=self._fade_out_process)
+
+    def loop_track(self, track_id):
+        self.cmd(0x08, track_id)
+
+    def loop(self):
+        self.cmd(0x19)
+
+    def loop_disable(self):
+        self.cmd(0x19, 0x01)
+
+    # volume control
+
+    def volume_up(self):
+        self._volume += 1
+        self.cmd(0x04)
+
+    def volume_down(self):
+        self._volume -= 1
+        self.cmd(0x05)
+
+    def volume(self, volume=False):
+        if volume:
+            self._volume = int(sorted([0, volume, self._max_volume])[1])
+            #print("volume", self._volume)
+            self.cmd(0x06, self._volume)
+        
+        return self._volume
+
+    # hardware
+
+    def module_sleep(self):
+        self.cmd(0x0A)
+
+    def module_wake(self):
+        self.cmd(0x0B)
+
+    def module_reset(self):
+        self.cmd(0x0C)
+

+ 98 - 0
main.py

@@ -0,0 +1,98 @@
+from machine import Pin, PWM
+from time import sleep
+import dht
+from mq135 import MQ135
+from dfplayer import Player
+import urequests
+
+led_pin = Pin(2, Pin.OUT)    # create output pin on GPIO0
+temp_pin = dht.DHT11(Pin(14))
+door_relais_pin = Pin(25, Pin.OUT) # Relais 2
+bell_relais_pin = Pin(26, Pin.OUT) # Relais 1
+pir_pin = Pin(39, Pin.IN)
+gas_pin = MQ135(Pin(36)) # analog PIN
+bell = Player(17, 16)
+button_pin = Pin(27, Pin.IN, Pin.PULL_UP) # Doorbell button: GPIO27 -> GND
+servo_pin = Pin(4)
+servo = PWM(servo_pin,freq=50) # duty for servo is between 40 - 115
+
+bell.volume(15)
+
+#server_address = "https://haeusle.svhub.de"
+server_address = "https://haeusle.hinz.casa"
+
+servo_off = 50
+servo_on = 100
+servo.duty(servo_off)
+
+#try:
+#    temp_pin.measure()
+#    temperature = temp_pin.temperature()
+#    humidity = temp_pin.humidity()
+#except:
+#    print("Error: DHT11 not working")
+
+def doorbell_event():
+    
+    led_pin.on()
+    
+    # -> DFPlayer play mp3
+    #bell.volume(3)
+    bell.play_from_folder(01, 03)
+    
+    # -> Send signal to server
+    try:
+        response = urequests.get(server_address + "/event?event=doorbell_button")
+        response.close()
+    except:
+        print("Error: Sending doorbell signal to server failed")
+    
+    # -> Servo to push button
+    servo.duty(servo_on)
+    sleep(1)
+    servo.duty(servo_off)
+    
+    # Relais
+    #door_relais_pin.on()
+    #bell_relais_pin.on()
+    
+    
+def pir_event():
+    pass
+    
+    
+def send_sendor_data():
+    
+    try:
+        temp_pin.measure()
+        temperature = temp_pin.temperature()
+        humidity = temp_pin.humidity()
+        print("Temperature: " + str(temp_pin.temperature()) + " Celsius")
+        print("Humidity: " + str(temp_pin.humidity()) + "%")
+        rzero = gas_pin.get_rzero()
+        corrected_rzero = gas_pin.get_corrected_rzero(temperature, humidity)
+        resistance = gas_pin.get_resistance()
+        ppm = gas_pin.get_ppm()
+        corrected_ppm = gas_pin.get_corrected_ppm(temperature, humidity)
+        print("DHT11 Temperature: " + str(temperature) +"\t Humidity: "+ str(humidity))
+        print("MQ135 RZero: " + str(rzero) +"\t Corrected RZero: "+ str(corrected_rzero)+
+              "\t Resistance: "+ str(resistance) +"\t PPM: "+str(ppm)+
+              "\t Corrected PPM: "+str(corrected_ppm)+"ppm")
+
+    except:
+        #pass
+        print("Error: send_sendor_data()")
+        
+def off_signals():
+    door_relais_pin.off()
+    bell_relais_pin.off()
+    led_pin.off()
+    servo.duty(servo_off)
+    
+while True:
+    if pir_pin.value() > 0: #pir signal on
+        pir_event()
+    elif button_pin.value() == 0: #button pressed
+        doorbell_event()
+    else:
+        off_signals()

+ 114 - 0
mq135.py

@@ -0,0 +1,114 @@
+"""Micropython library for dealing with MQ135 gas sensor
+Based on Arduino Library developed by G.Krocker (Mad Frog Labs)
+and the corrections from balk77 and ViliusKraujutis
+
+More info:
+    https://hackaday.io/project/3475-sniffing-trinket/log/12363-mq135-arduino-library
+    https://github.com/ViliusKraujutis/MQ135
+    https://github.com/balk77/MQ135
+"""
+
+import math
+import time
+from machine import ADC
+
+class MQ135(object):
+    """ Class for dealing with MQ13 Gas Sensors """
+    # The load resistance on the board
+    RLOAD = 10.0
+    # Calibration resistance at atmospheric CO2 level
+    RZERO = 76.63
+    # Parameters for calculating ppm of CO2 from sensor resistance
+    PARA = 116.6020682
+    PARB = 2.769034857
+
+    # Parameters to model temperature and humidity dependence
+    CORA = 0.00035
+    CORB = 0.02718
+    CORC = 1.39538
+    CORD = 0.0018
+    CORE = -0.003333333
+    CORF = -0.001923077
+    CORG = 1.130128205
+
+    # Atmospheric CO2 level for calibration purposes
+    ATMOCO2 = 397.13
+
+
+    def __init__(self, pin):
+        self.pin = pin
+
+    def get_correction_factor(self, temperature, humidity):
+        """Calculates the correction factor for ambient air temperature and relative humidity
+
+        Based on the linearization of the temperature dependency curve
+        under and above 20 degrees Celsius, asuming a linear dependency on humidity,
+        provided by Balk77 https://github.com/GeorgK/MQ135/pull/6/files
+        """
+
+        if temperature < 20:
+            return self.CORA * temperature * temperature - self.CORB * temperature + self.CORC - (humidity - 33.) * self.CORD
+
+        return self.CORE * temperature + self.CORF * humidity + self.CORG
+
+    def get_resistance(self):
+        """Returns the resistance of the sensor in kOhms // -1 if not value got in pin"""
+        adc = ADC(self.pin)
+        value = adc.read()
+        if value == 0:
+            return -1
+
+        return (1023./value - 1.) * self.RLOAD
+
+    def get_corrected_resistance(self, temperature, humidity):
+        """Gets the resistance of the sensor corrected for temperature/humidity"""
+        return self.get_resistance()/ self.get_correction_factor(temperature, humidity)
+
+    def get_ppm(self):
+        """Returns the ppm of CO2 sensed (assuming only CO2 in the air)"""
+        try:
+            return self.PARA * math.pow((self.get_resistance()/ self.RZERO), -self.PARB)
+        except:
+            return 0
+
+    def get_corrected_ppm(self, temperature, humidity):
+        """Returns the ppm of CO2 sensed (assuming only CO2 in the air)
+        corrected for temperature/humidity"""
+        try:
+            return self.PARA * math.pow((self.get_corrected_resistance(temperature, humidity)/ self.RZERO), -self.PARB)
+        except:
+            return 0
+        
+    def get_rzero(self):
+        """Returns the resistance RZero of the sensor (in kOhms) for calibratioin purposes"""
+        return self.get_resistance() * math.pow((self.ATMOCO2/self.PARA), (1./self.PARB))
+
+    def get_corrected_rzero(self, temperature, humidity):
+        """Returns the resistance RZero of the sensor (in kOhms) for calibration purposes
+        corrected for temperature/humidity"""
+        return self.get_corrected_resistance(temperature, humidity) * math.pow((self.ATMOCO2/self.PARA), (1./self.PARB))
+
+
+def mq135lib_example():
+    """MQ135 lib example"""
+    # setup
+    temperature = 21.0
+    humidity = 25.0
+
+    mq135 = MQ135(0) # analog PIN 0
+
+    # loop
+    while True:
+        rzero = mq135.get_rzero()
+        corrected_rzero = mq135.get_corrected_rzero(temperature, humidity)
+        resistance = mq135.get_resistance()
+        ppm = mq135.get_ppm()
+        corrected_ppm = mq135.get_corrected_ppm(temperature, humidity)
+
+        print("MQ135 RZero: " + str(rzero) +"\t Corrected RZero: "+ str(corrected_rzero)+
+              "\t Resistance: "+ str(resistance) +"\t PPM: "+str(ppm)+
+              "\t Corrected PPM: "+str(corrected_ppm)+"ppm")
+        time.sleep(0.3)
+
+if __name__ == "__main__":
+    mq135lib_example()

+ 28 - 0
mq135_dht11_example.py

@@ -0,0 +1,28 @@
+import time
+from dht import DHT11
+from machine import Pin
+from mq135 import MQ135
+
+
+# setup
+mq135 = MQ135(Pin(0)) # analog PIN 0
+dht11 = DHT11(Pin(14))
+
+# loop
+while True:
+
+    dht11.measure()
+    temperature = dht11.temperature()
+    humidity = dht11.humidity()
+
+    rzero = mq135.get_rzero()
+    corrected_rzero = mq135.get_corrected_rzero(temperature, humidity)
+    resistance = mq135.get_resistance()
+    ppm = mq135.get_ppm()
+    corrected_ppm = mq135.get_corrected_ppm(temperature, humidity)
+
+    print("DHT11 Temperature: " + str(temperature) +"\t Humidity: "+ str(humidity))
+    print("MQ135 RZero: " + str(rzero) +"\t Corrected RZero: "+ str(corrected_rzero)+
+          "\t Resistance: "+ str(resistance) +"\t PPM: "+str(ppm)+
+          "\t Corrected PPM: "+str(corrected_ppm)+"ppm")
+    time.sleep(1)