Skip to content

Commit bd11216

Browse files
committed
re-arranged the examples
1 parent cff76d8 commit bd11216

File tree

8 files changed

+551
-1
lines changed

8 files changed

+551
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ The classes that are currently supported are:
1717

1818
- umqttsimple.py - implementation of simple MQTT protocol for MicroPython.
1919
- ads1x15.py - ADS1x15 precide Analog-to-digital chip (available on extension board).
20+
- mcp23017.py - MCP23017 16-bit IO Expander (available on extension board).
2021
- at24c02.py - AT24C02 EEPROM module.
2122
- bh1750.py - BH1750 photodiode (light sensor).
2223
- bme280.py - 3 in 1: temperature, humidity and barometric sensor.
2324
- ds1307.py - DS1307 RTC module.
24-
- mcp23017.py - MCP23017 16-bit IO Expander (available on extension board).
2525
- pcf8574.py - PCF8574 8-bit IO Expander (available on valve extension board).
2626
- tds.py - To control TDS sensor through extension board.
2727

examples/eduponics_mqtt/boot.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
"""
2+
MicroPython MQTT Eduponics APP Client
3+
https://github.com/STEMinds/micropython-eduponics
4+
MIT License
5+
Copyright (c) 2020 STEMinds
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
23+
"""
24+
25+
from umqttsimple import MQTTClient
26+
import network
27+
import esp
28+
esp.osdebug(None)
29+
import gc
30+
gc.collect()
31+
32+
ssid = 'WIFI_NAME'
33+
password = 'WIFI_PASSWORD'
34+
35+
station = network.WLAN(network.STA_IF)
36+
37+
station.active(True)
38+
station.connect(ssid, password)
39+
40+
while station.isconnected() == False:
41+
pass
42+
43+
print('Connected to WiFi successfully, IP: %s' % station.ifconfig()[0])

examples/eduponics_mqtt/main.py

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
"""
2+
MicroPython MQTT Eduponics APP Client
3+
https://github.com/STEMinds/micropython-eduponics
4+
MIT License
5+
Copyright (c) 2020 STEMinds
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
23+
"""
24+
25+
from Eduponics import umqttsimple,bh1750,bme280
26+
import machine
27+
import time
28+
import json
29+
30+
# set adc (analog to digital) on pin 35
31+
adc = machine.ADC(machine.Pin(35))
32+
# set 11dB input attenuation (voltage range roughly 0.0v - 3.6v)
33+
adc.atten(machine.ADC.ATTN_11DB)
34+
35+
# Configure light sensor
36+
light_sensor = bh1750.BH1750()
37+
38+
# Configure BME280
39+
# setup I2C connection
40+
i2c = machine.I2C(scl=machine.Pin(15), sda=machine.Pin(4))
41+
# Initialize BME280 object with default address 0x76
42+
bme_sensor = bme280.BME280(i2c=i2c)
43+
# initialize dht object, DHT11 coonected to IO19
44+
#d = dht.DHT11(machine.Pin(19))
45+
46+
# define water level sensor as INPUT on IO pin number 21
47+
water_level = machine.Pin(21, machine.Pin.IN)
48+
49+
# define pump on pin IO23 as OUTPUT, define pump state
50+
pump = machine.Pin(23, machine.Pin.OUT)
51+
pump_state = False
52+
53+
# MQTT Unique ID
54+
UUID = "YOUR_UUID_GENERATED_ID"
55+
# MQTT Topics
56+
topics = ["plants/soil","plants/environment","plants/water"]
57+
58+
def handle_water_level(pin):
59+
global pump_state
60+
# water level triggered, turn off the pump
61+
# wait for 0.3 seconds to make sure it's just a little below the water sensor
62+
# else the pump might become unstable
63+
time.sleep(0.3)
64+
pump.value(0)
65+
pump_state = False
66+
67+
def get_soil_moisture():
68+
69+
# sensor min and max values
70+
# can be changed and callibrated
71+
minVal = 710
72+
maxVal = 4095
73+
74+
# read soil moisture sensor data
75+
val = adc.read()
76+
77+
# scale the value based on maxVal and minVal
78+
scale = 100 / (minVal - maxVal)
79+
# get calculated scale
80+
normal_reading = ("%s%s" % (int((val - maxVal) * scale),"%"))
81+
# we can also get inverted value if needed
82+
inverted_reading = ("%s%s" % (int((minVal - val) * scale),"%"))
83+
# for this example we'll return only the normal reading
84+
# put everything in a JSON format suitable for the eduponics app
85+
plant = {
86+
"id":0,
87+
"name":"Plant A",
88+
"enabled":1,
89+
"moisture":normal_reading
90+
}
91+
# return the data
92+
return str(plant).replace("'",'"')
93+
94+
def get_environmental_data():
95+
96+
# get light from the light sensor
97+
lux = int(light_sensor.readLight())
98+
# get bme280 sensor data
99+
bme280_values = bme_sensor.values
100+
temperature = bme280_values[0].replace("C","")
101+
pressure = bme280_values[1]
102+
humidity = bme280_values[2].replace("%","")
103+
# get DHT11 sensor data
104+
# measure sensor data
105+
#d.measure()
106+
# get temperature and humidity
107+
#temperature = d.temperature()
108+
#humidity = d.humidity()
109+
# get water quantity
110+
water_quantity = water_level.value()
111+
112+
# put all this data into a JSON object
113+
data = {
114+
"temp":temperature,
115+
"humidity":humidity,
116+
"sunlight":lux,
117+
"water_quantity":water_quantity
118+
}
119+
120+
return str(data).replace("'",'"')
121+
122+
def water_plant():
123+
global pump_state
124+
if(pump_state or water_level.value() == 1):
125+
# turn off the pump
126+
pump.value(0)
127+
pump_state = False
128+
else:
129+
# turn on the pump
130+
pump.value(1)
131+
pump_state = True
132+
return True
133+
134+
def on_message_callback(topic, msg):
135+
'''
136+
this is a callback, will be called when the app asks for certain information
137+
such as to water the plants when the watering button pressed
138+
'''
139+
# convert topic and message byte to string
140+
topic = str(topic, 'utf-8')
141+
msg = json.loads(str(msg, 'utf-8'))
142+
143+
if(topic == "%s/plants/soil" % UUID or topic == "%s/plants/environment" % UUID):
144+
# Do nothing, we only publish to those topics
145+
pass
146+
elif(topic == "%s/plants/water" % UUID):
147+
# when the app request for plant watering it goes here
148+
if("key" in msg and "status" in msg):
149+
# valid request, let's process it
150+
if(msg["status"] == "pending"):
151+
# it's waiting for us to water it, let's water it
152+
water_plant()
153+
# after watering, publish success message of watering
154+
response = {"key":msg["key"],"status":"ok"}
155+
client.publish("%s/plants/water" % UUID, str(response).replace("'",'"'))
156+
else:
157+
print((topic, msg))
158+
159+
def connect_and_subscribe():
160+
161+
print("[-] Connecting to MQTT client ...")
162+
# set the MQTT broker object
163+
client = umqttsimple.MQTTClient()
164+
# set a callback for incoming messages (subscribed topics)
165+
client.set_callback(on_message_callback)
166+
# connect to the broker
167+
client.connect()
168+
169+
# subscribe to the topics
170+
for topic in topics:
171+
client.subscribe("%s/%s" % (UUID,topic))
172+
print("[-] Subscribed to %s successfully" % topic)
173+
print("[-] Connected to %s MQTT broker successfully" % client.server)
174+
175+
return client
176+
177+
def restart_and_reconnect():
178+
# something went wrong, reconnect in 5 seconds ...
179+
print('[-] Failed to connect to MQTT broker. Reconnecting...')
180+
time.sleep(5)
181+
machine.reset()
182+
183+
try:
184+
client = connect_and_subscribe()
185+
except OSError as e:
186+
restart_and_reconnect()
187+
188+
# configure few variables
189+
last_message = 0
190+
message_interval = 5
191+
# set callback on the water level sensor, if no water stop the pump
192+
water_level.irq(trigger=machine.Pin.IRQ_RISING, handler=handle_water_level)
193+
194+
while True:
195+
try:
196+
# check if there are new messages pending to be processed
197+
# if there are, redirect them to callback on_message_callback()
198+
client.check_msg()
199+
200+
# check if the last published data wasn't less than message_interval
201+
if (time.time() - last_message) > message_interval:
202+
# get soil moisture
203+
soil_moisture = get_soil_moisture()
204+
# publish soil moisture data
205+
client.publish("%s/plants/soil" % UUID, soil_moisture)
206+
#print("[-] published soil moisture")
207+
208+
# update environmetal data
209+
env = get_environmental_data()
210+
client.publish("%s/plants/environment" % UUID, env)
211+
#print("[-] published evironmental data")
212+
213+
# update last message timestamp
214+
last_message = time.time()
215+
216+
except OSError as e:
217+
# if something goes wrong, reconnct to MQTT server
218+
restart_and_reconnect()
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"""
2+
MicroPython MQTT Eduponics APP Client
3+
https://github.com/STEMinds/micropython-eduponics
4+
MIT License
5+
Copyright (c) 2020 STEMinds
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.
23+
"""
24+
25+
import uuid
26+
27+
'''
28+
There are 3 different ways to generate unique UUID, choose which one suitable for you.
29+
'''
30+
31+
# make a UUID based on the host ID and current time, best option.
32+
uuid_x = uuid.uuid1()
33+
print(uuid_x)
34+
35+
# make a UUID using an MD5 hash of a namespace UUID and a name
36+
uuid_y = uuid.uuid3(uuid.NAMESPACE_DNS, 'steminds.com')
37+
print(uuid_y)
38+
39+
# make a random UUID
40+
uuid_z = uuid.uuid4()
41+
print(uuid_z)
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)