diff --git a/README.md b/README.md index d2dc418..507822e 100644 --- a/README.md +++ b/README.md @@ -18,4 +18,15 @@ import upip upip.install('umqtt.simple') upip.install('umqtt.robust') ``` +for later versions of MicroPython, you should use `mip` instead... +``` +import network +wlan = network.WLAN(network.STA_IF) +wlan.active(True) +wlan.connect("Wi-Fi AP", "PASSWORD") + +import mip +mip.install('umqtt.simple') +mip.install('umqtt.robust') +``` - Upload files onto PICO, adjust params (such as Wi-Fi Credentials // pins // etc ), deploy to your PICO W diff --git a/hcsr04_funcs.py b/hcsr04_funcs.py new file mode 100644 index 0000000..ec177d1 --- /dev/null +++ b/hcsr04_funcs.py @@ -0,0 +1,34 @@ +import time + +''' +hcsr04_funcs: Helper functions to interact with the HC-SR04 sensor. +''' + +def read_hc_sr04(trig, echo): + """ + reads the HC-SR04 sensor. + returns tuple(temperature, humidity) if no errors + returns None if there was an error + """ + try: + trig.value(0) + time.sleep(0.1) + + trig.value(1) + time.sleep_us(2) + + trig.value(0) + + while echo.value()==0: + pulse_start = time.ticks_us() + + while echo.value()==1: + pulse_end = time.ticks_us() + + pulse_duration = pulse_end - pulse_start + distance = pulse_duration * 17165 / 1000000 + distance = round(distance, 2) + + return distance + except: + return None \ No newline at end of file diff --git a/main.py b/main.py index cd47a7f..c6d709d 100644 --- a/main.py +++ b/main.py @@ -1,107 +1,29 @@ +# Built-in's import network import rp2 import time import json import machine -from machine import Pin + +# From PyPI from umqtt.robust import MQTTClient -import dht -import urequests -import wifi_config + +# From this project... import mqtt_config +from pico_funcs import read_cpu_temp, wlan_up, led_error_code +from hcsr04_funcs import read_hc_sr04 # Change this GPIO PIN where your DHT22 sensor is connected -DHT_22_GPIO_PIN = 3 +TRIG_PIN = 3 +ECHO_PIN = 2 # Debug Mode DEBUG = False - -def read_cpu_temp(): - """ - If you print the value of the temperature value you are going to get an integer number between 0 and 65535. - So, we have to convert this value either to the Celsius degree scales. - - The temperature sensor works by delivering a voltage to the ADC4 pin that is proportional to the temperature. - From the datasheet, a temperature of 27 degrees Celsius delivers a voltage of 0.706 V. - With each additional degree the voltage reduces by 1.721 mV or 0.001721 V. - The first step in converting the 16-bit temperature is to convert it back to volts, which is done based on the 3.3 V maximum voltage used by the Pico board. - ref: https://how2electronics.com/read-temperature-sensor-value-from-raspberry-pi-pico/ - """ - cpu_temp_conversion_factor = 3.3 / 65535 - cpu_temp_sensor = machine.ADC(4) - reading = cpu_temp_sensor.read_u16() * cpu_temp_conversion_factor - temperature_c = 27 - (reading - 0.706) / 0.001721 - temperature_f = temperature_c * 9/5. + 32.0 - return temperature_f - -def read_dht_22(sensor): - """ - reads the temperature and humidity from dht.DHT22 sensor. - returns tuple(temperature, humidity) if no errors - returns None if there was an error - """ - try: - sensor.measure() - temperature = sensor.temperature() - humidity = sensor.humidity() - return temperature, humidity - except: - time.sleep(2) - return None - -def wlan_up(wlan): - wlan.active(True) - wlan.connect(wifi_config.HOME_WIFI_SSID, wifi_config.HOME_WIFI_PWD) - - # Wait for connect or fail - max_wait = 10 - while max_wait > 0: - if wlan.status() < 0 or wlan.status() >= 3: - break - max_wait -= 1 - if DEBUG: - print('Waiting for WiFi connection...') - time.sleep(1) - - if max_wait == 0: - return None - - ifconfig = wlan.ifconfig() - if DEBUG: - print(ifconfig) - return ifconfig - -def led_error_code(led, error_code: int): - """Blink LED for a given error code (int). error code == number of times to blink""" - if DEBUG: - print("LED Error Status code: {}".format(error_code)) - - # Run a quick 'start error code sequence' - # So we know when LED error sequence starts - start_sequence_counter = 0 - while start_sequence_counter < 3: - led.value(True) - time.sleep(0.1) - led.value(False) - time.sleep(0.1) - start_sequence_counter += 1 - - # Run real error code sequence - blink_counter = 0 - while blink_counter < error_code: - time.sleep(1) - led.value(True) - time.sleep(1) - led.value(False) - blink_counter += 1 - # Make sure to turn off LED when this subroutine finished - led.value(False) - if DEBUG: - print("LED Error Status code finished for: {}".format(error_code)) - def main(): + + # Start Up Activities if DEBUG: print("Start up") @@ -110,7 +32,7 @@ def main(): led.value(False) led_error_code(led, 1) - # Set Wi-Fi Country + # Set Wi-Fi Country and Create a Wireless Interface rp2.country('US') wlan = network.WLAN(network.STA_IF) @@ -120,8 +42,9 @@ def main(): server = mqtt_config.MQTT_HOST_NAME, ) - # Create DHT22 - sensor = dht.DHT22(Pin(DHT_22_GPIO_PIN)) + # Create HC-SR04 + trig = machine.Pin(TRIG_PIN, machine.Pin.OUT) + echo = machine.Pin(ECHO_PIN, machine.Pin.IN, machine.Pin.PULL_DOWN) # Let's Go! if DEBUG: @@ -138,20 +61,18 @@ def main(): # Create Local Flags for Control wifi_ready = False mqtt_ready = False - dht22_ready = False + hc_sr04_ready = False - # DHT22 and CPU Reading. + # CPU Reading. try: - # CPU Reading. cpu_temp = read_cpu_temp() + except: + continue - # DHT22 Reading. - dht22_reading = read_dht_22(sensor) - #debug_str = "None" - if dht22_reading is not None: - temp,hum = dht22_reading - temp = temp * 9/5. + 32.0 - dht22_ready = True + # HC-SR04 Reading. + try: + distance = read_hc_sr04(trig, echo) + hc_sr04_ready = True except: continue @@ -196,18 +117,17 @@ def main(): # Ready to Publish? try: - if wifi_ready and mqtt_ready and dht22_ready: + if wifi_ready and mqtt_ready and hc_sr04_ready: # Timestamp time_now = time.localtime() timestamp = "{}/{}/{} {}:{}:{}".format(time_now[1],time_now[2],time_now[0],time_now[3],time_now[4],time_now[5]) # Build JSON Payloads - dht_data = { + hc_sr04_data = { 'Location':mqtt_config.MQTT_ZONE_ID, - 'Temperature':temp, - 'Relative Humidity':hum, + 'Distance':distance, } - dht_payload = json.dumps(dht_data) + hc_sr04_payload = json.dumps(hc_sr04_data) hw_data = { 'Timestamp':timestamp, @@ -218,7 +138,7 @@ def main(): hw_payload = json.dumps(hw_data) # Publish - mqtt_client.publish("home/{}".format(mqtt_config.MQTT_ZONE_ID),dht_payload, retain=True) + mqtt_client.publish("home/{}".format(mqtt_config.MQTT_ZONE_ID),hc_sr04_payload, retain=True) mqtt_client.publish("hw/{}".format(mqtt_config.MQTT_HW_ID),hw_payload, retain=True) mqtt_client.disconnect() diff --git a/pico_funcs.py b/pico_funcs.py new file mode 100644 index 0000000..9211612 --- /dev/null +++ b/pico_funcs.py @@ -0,0 +1,68 @@ +import machine +import network +import wifi_config +import time + +''' +pico_funcs: Helper functions for things the pico can do. +''' + +def read_cpu_temp(): + """ + If you print the value of the temperature value you are going to get an integer number between 0 and 65535. + So, we have to convert this value either to the Celsius degree scales. + + The temperature sensor works by delivering a voltage to the ADC4 pin that is proportional to the temperature. + From the datasheet, a temperature of 27 degrees Celsius delivers a voltage of 0.706 V. + With each additional degree the voltage reduces by 1.721 mV or 0.001721 V. + The first step in converting the 16-bit temperature is to convert it back to volts, which is done based on the 3.3 V maximum voltage used by the Pico board. + ref: https://how2electronics.com/read-temperature-sensor-value-from-raspberry-pi-pico/ + """ + cpu_temp_conversion_factor = 3.3 / 65535 + cpu_temp_sensor = machine.ADC(4) + reading = cpu_temp_sensor.read_u16() * cpu_temp_conversion_factor + temperature_c = 27 - (reading - 0.706) / 0.001721 + temperature_f = temperature_c * 9/5. + 32.0 + return temperature_f + +def wlan_up(wlan): + wlan.active(True) + wlan.connect(wifi_config.HOME_WIFI_SSID, wifi_config.HOME_WIFI_PWD) + + # Wait for connect or fail + max_wait = 10 + while max_wait > 0: + if wlan.status() < 0 or wlan.status() >= 3: + break + max_wait -= 1 + time.sleep(1) + + if max_wait == 0: + return None + + ifconfig = wlan.ifconfig() + return ifconfig + +def led_error_code(led, error_code: int): + """Blink LED for a given error code (int). error code == number of times to blink""" + + # Run a quick 'start error code sequence' + # So we know when LED error sequence starts + start_sequence_counter = 0 + while start_sequence_counter < 3: + led.value(True) + time.sleep(0.1) + led.value(False) + time.sleep(0.1) + start_sequence_counter += 1 + + # Run real error code sequence + blink_counter = 0 + while blink_counter < error_code: + time.sleep(1) + led.value(True) + time.sleep(1) + led.value(False) + blink_counter += 1 + # Make sure to turn off LED when this subroutine finished + led.value(False) \ No newline at end of file