Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
1e3a252
Update README.md
seastate Oct 28, 2020
a3bf863
Initial commit of codes for light activities
seastate Oct 29, 2020
3d8b2c0
Merge pull request #14 from seastate/dg_sensors
leviner Nov 6, 2020
7f5b31e
remove redundant lcd, hide AQ sensor
leviner Nov 6, 2020
12b6123
Initial commit of multi-sensors w/ GPS
seastate Nov 23, 2020
b09ec60
Update README.md
leviner Nov 25, 2020
0663da6
Merge pull request #15 from publicsensors/dg_GPS
leviner Dec 14, 2020
d5f49a5
remove ignore, include draft AQ
leviner Dec 14, 2020
53dc2bc
merge multi_main and main
leviner Dec 14, 2020
4527de4
remove Adafruit from platform id, inconsistent across boards
leviner Dec 14, 2020
0d90345
repo copy default temp only
leviner Dec 14, 2020
f69625a
update spacing for lcd
leviner Dec 14, 2020
5712fbf
confirmed multi and single on stm, pyb1
leviner Dec 14, 2020
bcae422
Merge pull request #16 from leviner/multi_merge
leviner Dec 14, 2020
dc33884
adding hex version of firmware file
leviner Jan 18, 2021
2dcc801
change light sensor lcd print for space
leviner Jan 22, 2021
96788d7
change acoustic pins for stm to d11,12
leviner Jan 22, 2021
f11b271
Merge pull request #17 from leviner/lcd_tweak
leviner Jan 22, 2021
b58b507
revised fritzing diagram
leviner Jan 22, 2021
50ce39c
Delete hcsr04_Battery.png
leviner Jan 22, 2021
8686773
new fritzing acoustic
leviner Jan 22, 2021
01b99d1
new acoustic fritzing image
leviner Jan 22, 2021
65b8fef
Merge branch 'master' of https://github.com/leviner/MicrocontrollerKits
leviner Jan 22, 2021
7c84e02
Merge pull request #18 from leviner/master
leviner Jan 22, 2021
314ac33
Merge branch 'master' of https://github.com/publicsensors/Microcontro…
leviner Jan 29, 2021
f4de36e
add internal try for print_X eval
leviner Jan 29, 2021
346b44c
pr call in print_XX)
leviner Jan 29, 2021
3017b09
distance check
leviner Feb 5, 2021
eac5a25
remove print flag, add test func
leviner Feb 5, 2021
cf76118
remove print flag, add test func, print roms
leviner Feb 5, 2021
3330bb3
remove print flag, add test func, check roms
leviner Feb 5, 2021
cc1291c
get test flag
leviner Feb 5, 2021
55e1dad
set actives
leviner Feb 5, 2021
2b565bb
make active_sensors optional
leviner Feb 11, 2021
e72e801
modified main to compare active to found
leviner Feb 11, 2021
8e5c185
clear cache
leviner Feb 11, 2021
4f37593
Merge pull request #19 from leviner/multi_check
leviner Feb 11, 2021
dbbca41
add multisensor
leviner Feb 11, 2021
546471b
fix logic issue in main line 40
leviner Feb 21, 2021
832d695
Merge pull request #20 from leviner/master
leviner Feb 21, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21,042 changes: 21,042 additions & 0 deletions MicrocontrollerSetup/firmware.hex

Large diffs are not rendered by default.

15 changes: 14 additions & 1 deletion Sensors/Acoustic/read_dist.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from platform_defs import *

from machine import Pin, I2C
from i2c_lcd import I2cLcd
from esp8266_i2c_lcd import I2cLcd
import hcsr04
from time import sleep_ms

Expand All @@ -18,6 +18,19 @@ def __init__(self):

self.sensor = hcsr04.HCSR04(trigger_pin = p_hcsr_trig, echo_pin = p_hcsr_echo, c = hcsr_c)

# -------------------------------------------------------------------------------
# Test the distance sensor
# -------------------------------------------------------------------------------
def test_dist(self):
try: # Try to take a measurement, return 1 if successful, 0 if not
dist = self.sensor.distance()
if dist == -0.1:
return 0
else:
return 1
except:
return 0

# -------------------------------------------------------------------------------
# Progression for obtaining distance readings from the sensor
# -------------------------------------------------------------------------------
Expand Down
83 changes: 83 additions & 0 deletions Sensors/AirQuality/sampleAirQuality.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#from machine import UART
from time import sleep
from platform_defs import *
import sds011
from micropyGPS import MicropyGPS

#uart = UART(1, baudrate=9600, pins=('P21','P22'))
def sample_AQ():
dust_sensor = sds011.SDS011(uartAQ)
dust_sensor.set_reporting_mode_query()
dust_sensor.sleep()

while True:
#Datasheet says to wait for at least 30 seconds...
print('Start fan for 15 seconds.')
dust_sensor.wake()
sleep(65)

#Returns NOK if no measurement found in reasonable time
status = dust_sensor.read()
#Returns NOK if checksum failed
pkt_status = dust_sensor.packet_status

#Stop fan
dust_sensor.sleep()

if(status == False):
print('Measurement failed.')
elif(pkt_status == False):
print('Received corrupted data.')
else:
print('PM25: ', dust_sensor.pm25)
print('PM10: ', dust_sensor.pm10)

sleep(55)


while True:
status = dust_sensor.read(),print(status),print('PM25: ', dust_sensor.pm25,', PM10: ', dust_sensor.pm10)
sleep(20)


# turn on GPS power
p_pwr2.value(1)

while True:
if uartGPS.any():
try:
#gps_ln=uart4.readline()[:-2].decode('utf-8')
gps_ln=uartGPS.readline().decode('utf-8')
#gps_ln=chr(uart4.readchar())
#print('received gps read...')
#print(gps_ln,end='')
if len(gps_ln)>0:
#w=s.write(gps_ln)
#w=s.sendto(gps_ln,addr)
print(gps_ln,end='')
#print('send complete, ',w,' bytes')
gps_ln=''
sleep_ms(50)
except Exception as ex:
print('>>>>>>>error in decoding/sending GPS message: ',ex)

my_gps = MicropyGPS()
# Main Infinite Loop
while 1:
# Do Other Stuff Here.......

# Update the GPS Object when flag is tripped
if True:
while uartGPS.any():
my_gps.update(chr(uartGPS.readchar())) # Note the conversion to to chr, UART outputs ints normally

print('UTC Timestamp:', my_gps.timestamp)
print('Date:', my_gps.date_string('long'))
print('Latitude:', my_gps.latitude_string())
print('Longitude:', my_gps.longitude_string())
print('Horizontal Dilution of Precision:', my_gps.hdop)
print()
new_data = False # Clear the flag
sleep(20)


132 changes: 132 additions & 0 deletions Sensors/AirQuality/sds011.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
"""
Reading format. See http://cl.ly/ekot

0 Header '\xaa'
1 Command '\xc0'
2 DATA1 PM2.5 Low byte
3 DATA2 PM2.5 High byte
4 DATA3 PM10 Low byte
5 DATA4 PM10 High byte
6 DATA5 ID byte 1
7 DATA6 ID byte 2
8 Checksum Low byte of sum of DATA bytes
9 Tail '\xab'

"""

import ustruct as struct
import sys

_SDS011_CMDS = {'SET': b'\x01',
'GET': b'\x00',
'QUERY': b'\x04',
'REPORTING_MODE': b'\x02',
'DUTYCYCLE': b'\x08',
'SLEEPWAKE': b'\x06'}

class SDS011:
"""A driver for the SDS011 particulate matter sensor.

:param uart: The `UART` object to use.
"""
def __init__(self, uart):
self._uart = uart
self._pm25 = 0.0
self._pm10 = 0.0
self._packet_status = False
self._packet = ()

self.set_reporting_mode_query()

@property
def pm25(self):
"""Return the PM2.5 concentration, in µg/m^3."""
return self._pm25

@property
def pm10(self):
"""Return the PM10 concentration, in µg/m^3."""
return self._pm10

@property
def packet_status(self):
"""Returns False if the received packet is corrupted."""
return self._packet_status

@property
def packet(self):
"""Return the last received packet."""
return self._packet

def make_command(self, cmd, mode, param):
header = b'\xaa\xb4'
padding = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff'
checksum = chr(( ord(cmd) + ord(mode) + ord(param) + 255 + 255) % 256)
checksum = bytes(checksum, 'utf8')
tail = b'\xab'

return header + cmd + mode + param + padding + checksum + tail

def wake(self):
"""Sends wake command to sds011 (starts its fan)."""
cmd = self.make_command(_SDS011_CMDS['SLEEPWAKE'],
_SDS011_CMDS['SET'], chr(1))
self._uart.write(cmd)

def sleep(self):
"""Sends sleep command to sds011 (stops its fan)."""
cmd = self.make_command(_SDS011_CMDS['SLEEPWAKE'],
_SDS011_CMDS['SET'], chr(0))
self._uart.write(cmd)

def set_reporting_mode_query(self):
cmd = self.make_command(_SDS011_CMDS['REPORTING_MODE'],
_SDS011_CMDS['SET'], chr(1))
self._uart.write(cmd)

def query(self):
"""Query new measurement data"""
cmd = self.make_command(_SDS011_CMDS['QUERY'], chr(0), chr(0))
self._uart.write(cmd)

def process_measurement(self, packet):
try:
*data, checksum, tail = struct.unpack('<HHBBBs', packet)
self._pm25 = data[0]/10.0
self._pm10 = data[1]/10.0
checksum_OK = (checksum == (sum(data) % 256))
tail_OK = tail == b'\xab'
self._packet_status = True if (checksum_OK and tail_OK) else False
except Exception as e:
print('Problem decoding packet:', e)
sys.print_exception(e)

def read(self):
"""
Query a new measurement, wait for response and process it.
Waits for a response during 512 characters (0.4s at 9600bauds).

Return True if a response has been received, False overwise.
"""
#Query measurement
self.query()

#Read measurement
#Drops up to 512 characters before giving up finding a measurement pkt...
for i in range(512):
try:
header = self._uart.read(1)
if header == b'\xaa':
command = self._uart.read(1)

if command == b'\xc0':
packet = self._uart.read(8)
if packet != None:
self.process_measurement(packet)
return True
except Exception as e:
print('Problem attempting to read:', e)
sys.print_exception(e)

#If we gave up finding a measurement pkt
return False
31 changes: 31 additions & 0 deletions Sensors/AirQuality/sds011_simpletest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from machine import UART
import time
import sds011

uart = UART(1, baudrate=9600, pins=('P21','P22'))
dust_sensor = sds011.SDS011(uart)
dust_sensor.sleep()

while True:
#Datasheet says to wait for at least 30 seconds...
print('Start fan for 5 seconds.')
dust_sensor.wake()
time.sleep(5)

#Returns NOK if no measurement found in reasonable time
status = dust_sensor.read()
#Returns NOK if checksum failed
pkt_status = dust_sensor.packet_status

#Stop fan
dust_sensor.sleep()

if(status == False):
print('Measurement failed.')
elif(pkt_status == False):
print('Received corrupted data.')
else:
print('PM25: ', dust_sensor.pm25)
print('PM10: ', dust_sensor.pm10)

time.sleep(10)
File renamed without changes.
112 changes: 112 additions & 0 deletions Sensors/GPS/read_GPS.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# This script prints GSP readings from a unit attached to uartGPS

# Import platform-specific definitions
from platform_defs import *

from machine import Pin, I2C
from esp8266_i2c_lcd import I2cLcd
from micropyGPS import MicropyGPS
from time import sleep_ms


# -------------------------------------------------------------------------------
# Set up pins for power and usrtGPS
# -------------------------------------------------------------------------------
class read_GPS:

def __init__(self,num_sentences=3,timeout=5):
p_pwr2.value(1) # turn on power to the GPS
p_pwr3.value(1) # the GPS requires power from multiple GPIOs
p_pwr4.value(1)

self.num_sentences=num_sentences
self.timeout=timeout
self.my_gps = MicropyGPS() # create GPS parser object

# -------------------------------------------------------------------------------
# Progression for obtaining GPS readings from the sensor
# -------------------------------------------------------------------------------

def print_GPS(self,display=True, pr=1):
i2c = I2C(scl=Pin(p_I2Cscl_lbl),sda=Pin(p_I2Csda_lbl))
try:
lcd = I2cLcd(i2c, 0x27,2,16)
lcdF = 1
except:
lcdF = 0
# Create a loop to obtain several sentences from the GPS, to make sure
# all relevant fields in the parser are populated with recent data
sentence_count = 0
while True:
if uartGPS.any():
stat = self.my_gps.update(chr(uartGPS.readchar()))
if stat:
print(stat)
stat = None
sentence_count += 1

if sentence_count == self.num_sentences: # have necessary fixes, output data and return
# calculate decimal lat and long
dec_lat=self.my_gps.latitude[0]+self.my_gps.latitude[1]/60
if self.my_gps.latitude[2]=="S": # correction for southern hemisphere
dec_lat=-dec_lat
dec_long=self.my_gps.longitude[0]+self.my_gps.longitude[1]/60
if self.my_gps.longitude[2]=="W": # correction for western hemisphere
dec_long=-dec_long

if not display: # if False, return GPS data instead of displaying it
return (self.my_gps.date,self.my_gps.timestamp,dec_lat,dec_long)

#print('UTC Timestamp:', self.my_gps.timestamp)
#print('Date:', self.my_gps.date_string('long'))
#print('Latitude:', self.my_gps.latitude_string())
#print('Longitude:', self.my_gps.longitude_string())
#print('Altitude:', self.my_gps.altitude)#_string())
#print('Speed:', self.my_gps.speed_string())
#print('Compass direction:', self.my_gps.compass_direction())
#print('Course:', self.my_gps.course)#_string())
#print('Horizontal Dilution of Precision:', self.my_gps.hdop)
#print()
GPSstr='GPS: {}-{}-{} {}:{}:{} {},{}'.format(self.my_gps.date[0],self.my_gps.date[1],self.my_gps.date[2], \
self.my_gps.timestamp[0],self.my_gps.timestamp[1],self.my_gps.timestamp[2], \
dec_lat,dec_long)
print(GPSstr)
#print('GPS: {} {} {} {}'.format(self.my_gps.timestamp,self.my_gps.date,self.my_gps.latitude,self.my_gps.longitude))
if lcdF == 1 & pr==1:
lcd.clear() # Sleep for 1 sec
#GPSstr2='GPS: {}:{}:{} {},{}'.format(self.my_gps.timestamp[0],self.my_gps.timestamp[1], \
# self.my_gps.timestamp[2],dec_lat,dec_long)
GPSstr2='GPS: {},\n {}'.format(dec_lat,dec_long)
lcd.putstr(GPSstr2)
#lcd.putstr('GPS: {} {} {} {}'.format(self.my_gps.timestamp,self.my_gps.date,dec_lat,dec_long))
break;

# -------------------------------------------------------------------------------
# Get continuous GPS readings
# -------------------------------------------------------------------------------
def print_GPSs_start(self,samp_max=1000,interval=5):
sleep_microsec=int(1000*interval)
pause_microsec=1000
i2c = I2C(scl=Pin(p_I2Cscl_lbl),sda=Pin(p_I2Csda_lbl))
try:
lcd = I2cLcd(i2c, 0x27,2,16)
lcdF = 1
except:
lcdF = 0
sample_num=1 # Start sample number at 0 so we can count the number of samples we take
while sample_num <= samp_max: # This will repeat in a loop, until we terminate with a ctrl-c
(date,timestamp,dec_lat,dec_long) = self.print_GPS(display=False)
print("Sample: ",sample_num,', ',date,', ',timestamp,', ',dec_lat,', ',dec_long) # print the sample number and temperature
print("\n") # Print a line of space between temp readings so it is easier to read
if lcdF ==1:
lcd.clear() # Sleep for 1 sec
GPSstr3='#{} {},{}'.format(sample_num,dec_lat,dec_long)
lcd.putstr(GPSstr3)
#lcd.putstr("Sample: "+str(sample_num)+"\nTemp: "+str(round(self.ds.read_GPS(self.roms[0]),2))+" C")
sleep_ms(max(sleep_microsec-pause_microsec,0)) # Wait 5 sec, before repeating the loop and taking another reading
sample_num+=1 # Increment the sample number for each reading
if lcdF == 1:
lcd.clear()
lcd.putstr("Done!")
sleep_ms(2000)
lcd.clear()
Loading