Update from simple test script to more complete script

This commit is contained in:
Pierrick C 2018-07-29 13:02:16 +02:00
parent 71310249c3
commit db92dbe984

View File

@ -1,126 +1,229 @@
# Simple weather and GPS logger # Weather and GPS logger
import board ##########
# Config #
##########
print_data = True
data_to_neopixel = True
gps_enable = False
update_interval = 5.0 # in seconds
send_json_data = True
#######################
import board, time, microcontroller
import gc, micropython, os
from busio import I2C, UART from busio import I2C, UART
from time import sleep
from analogio import AnalogIn from analogio import AnalogIn
import microcontroller
import gc
import micropython
import os
from adafruit_bme280 import Adafruit_BME280_I2C from adafruit_bme280 import Adafruit_BME280_I2C
from adafruit_gps import GPS from adafruit_gps import GPS
import neopixel import neopixel
######### ###########
# Setup # # Classes #
######### ###########
# BME280 sensors (I2C) class Data:
i2c = I2C(board.SCL, board.SDA) """Class for handling data format and transmission"""
bme280 = Adafruit_BME280_I2C(i2c) def __init__(self):
self.data = {}
# Integrated Neopixel def update(self):
pixel = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) """Read the data from various sensors and update the data dict variable"""
#Data from Feather board
self.data['SYS'] = {'v_bat': { 'val': vbat.value*0.000100708, 'unit': 'V' },
'CPU_temp': { 'val': microcontroller.cpu.temperature, 'unit': '°C' }}
# Note about v_bat calculation :
# 0.000100708 = 2*3.3/65536 with
# 2 : voltage is divided by 2
# 3.3 : Vref = 3.3V
# 65536 : 16bit ADC
# Battery voltage #Data from BME280
vbat = AnalogIn(board.D9, ) self.data['BME280'] = {'temp': { 'val': bme280.temperature, 'unit': '°C' },
'hum': { 'val': bme280.humidity, 'unit': '%' },
'press': { 'val': bme280.pressure, 'unit': 'hPa' }}
if gps_enable:
if gps.has_fix:
self.data['GPS'] = {'timestamp': '{:04}/{:02}/{:02} {:02}:{:02}:{:02}'.format(gps.timestamp_utc.tm_year,
gps.timestamp_utc.tm_mon,
gps.timestamp_utc.tm_mday,
gps.timestamp_utc.tm_hour,
gps.timestamp_utc.tm_min,
gps.timestamp_utc.tm_sec),
'lat': {'val': gps.latitude, 'unit': 'deg'},
'lon': {'val': gps.longitude, 'unit': 'deg'},
'alt': {'val': gps.altitude_m, 'unit': 'm'},
'qual': {'val': gps.fix_quality, 'unit': None}}
else:
self.data['GPS'] = {'lat': {'val': None, 'unit': 'deg'},
'lon': {'val': None, 'unit': 'deg'},
'alt': {'val': None, 'unit': 'm'}}
else:
self.data['GPS'] = None
# GPS on Feather board def show(self):
gps_uart = UART(board.TX, board.RX, baudrate=9600, timeout=3000) """Serialize data to json-formatted string for
gps = GPS(gps_uart) visualization on serial console
# Turn on the basic GGA and RMC info """
gps.send_command('PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0') for source in self.data.keys():
gps.send_command('PMTK220,2000') # 1000 ms refresh print(source + ": ")
if not self.data[source] == None:
for d in self.data[source].items():
print("\t{0}: {val} {unit}".format(d[0], **d[1]))
gc.collect() def json(self):
micropython.mem_info() """Serialize data to json-formatted string"""
output = "{"
temp, hum, press = 0.0, 0.0, 0.0 for source in self.data.keys():
rouge, vert, bleu = 0, 0, 0 output = "".join((output, "'", source, "': \n"))
if not self.data[source] == None:
# Check if data directory exists for d in self.data[source].items():
if 'data' not in os.listdir(): output = "".join((output, "{",
os.mkdir('data') "'{}': ".format(d[0]),
os.mkdir('data/hourly') "{",
os.mkdir('data/daily') "'val': {val},'unit': {unit}".format(**d[1]),
"}}\n"))
output = output + "}, \n"
output = output + "}"
return output
############# #############
# Main loop # # Functions #
############# #############
while True:
sleep(5) def check_data_dir():
"""Check if data directories exists"""
gc.collect() if 'data' not in os.listdir():
# micropython.mem_info(1) os.mkdir('data')
# print('Memory free: {} allocated: {}'.format(gc.mem_free(), gc.mem_alloc())) os.mkdir('data/hourly')
os.mkdir('data/daily')
temp = bme280.temperature elif 'hourly' not in os.listdir('data'):
hum = bme280.humidity os.mkdir('data/hourly')
press = bme280.pressure elif 'daily' not in os.listdir('data'):
os.mkdir('data/daily')
print("Temperature: {:>+.1f} degC | Humidite: {:>.1f} % | Pression: {:>.1f} hPa".format(temp, hum, press))
print("Tension batterie : {:>.2f} V | CPU Temp: {:>+.1f} degC".format((vbat.value*2*3.3/65536), microcontroller.cpu.temperature)) def update_gps():
# 0.00644531 = 2*3.3/1024 : """Update and print data from GPS module"""
# 2 : voltage is divided by 2 if not gps.has_fix:
# 3.3 : Vref = 3.3V # Try again if we don't have a fix yet.
# 1024 : 10bit ADC print('Waiting for fix...{}-{}'.format(gps.has_fix, gps.satellites))
# Conversion des donn?es en couleur else: # GPS fix OK !!!
# ROUGE => temp?rature : max = 35?C, min =10?C soit une amplitude de 25?C #UTC Time
rouge = int((temp-10)*255/25) print('{}/{}/{} {:02}:{:02}:{:02}'.format(
gps.timestamp_utc.tm_mon, # Grab parts of the time from the
gps.timestamp_utc.tm_mday, # struct_time object that holds
gps.timestamp_utc.tm_year, # the fix time. Note you might
gps.timestamp_utc.tm_hour, # not get all data like year, day,
gps.timestamp_utc.tm_min, # month!
gps.timestamp_utc.tm_sec))
if gps.altitude_m is not None:
print('Lat: {}deg | Lon: {}deg | Alt: {}m'.format(gps.latitude,
gps.longitude,
gps.altitude_m))
else:
print('Lat: {}deg | Lon: {}deg'.format(gps.latitude,
gps.longitude))
print('Qual: {}'.format(gps.fix_quality))
# Some attributes beyond latitude, longitude and timestamp are optional
# and might not be present. Check if they're None before trying to use!
# if gps.satellites is not None:
# print('# sat: {}'.format(gps.satellites))
# if gps.track_angle_deg is not None:
# print('Speed: {} knots'.format(gps.speed_knots))
# if gps.track_angle_deg is not None:
# print('Track angle: {} degrees'.format(gps.track_angle_deg))
# if gps.horizontal_dilution is not None:
# print('Horizontal dilution: {}'.format(gps.horizontal_dilution))
# if gps.height_geoid is not None:
# print('Height geo ID: {} meters'.format(gps.height_geoid))
def update_neopixel(data):
"""Conversion des données en couleur pour affichage sur NeoPixel
* ROUGE => temp?rature : max = 35?C, min =10?C soit une amplitude de 25?C
* BLEU => humidit? : max= 100%, mini=0%
* VERT => Pression : mini=960hPa, maxi = 1030hPa soit une amplitude 70hPa
"""
rouge = int((data['BME280']['temp']['val']-10)*255/25)
if rouge > 255: if rouge > 255:
rouge = 255 rouge = 255
if rouge < 0: if rouge < 0:
rouge = 0 rouge = 0
# BLEU => humidit? : max= 100%, mini=0% bleu = int(data['BME280']['hum']['val']*255/100)
bleu = int(hum*255/100)
vert = int((data['BME280']['press']['val']-960)*255/70)
# VERT => Pression : mini=960hPa, maxi = 1030hPa soit une amplitude 70hPa
vert = int((press-960)*255/70)
if vert > 255: if vert > 255:
vert = 255 vert = 255
if vert < 0: if vert < 0:
vert = 0 vert = 0
rvb = (rouge, vert, bleu) if print_data:
print("Couleur : {}".format(rvb)) print("Col:{}".format((rouge, vert, bleu)))
pixel[0] = rvb
return (rouge, vert, bleu)
gps.update()
if not gps.has_fix: #########
# Try again if we don't have a fix yet. # Setup #
print('Waiting for fix... {} - {}'.format(gps.has_fix, gps.satellites)) #########
continue
gc.collect()
print('Fix timestamp: {}/{}/{} {:02}:{:02}:{:02}'.format( micropython.mem_info()
gps.timestamp_utc.tm_mon, # Grab parts of the time from the
gps.timestamp_utc.tm_mday, # struct_time object that holds # BME280 sensors (I2C)
gps.timestamp_utc.tm_year, # the fix time. Note you might i2c = I2C(board.SCL, board.SDA)
gps.timestamp_utc.tm_hour, # not get all data like year, day, # i2c addresses for BME280 breakout :
gps.timestamp_utc.tm_min, # month! # 0x77 = adafruit board
gps.timestamp_utc.tm_sec)) # 0x76 = chinese board
if gps.altitude_m is not None: bme280 = Adafruit_BME280_I2C(i2c, address=0x76)
print('Latitude: {} deg | Longitude: {} deg | Altitude: {} m'.format(gps.latitude,
gps.longitude, # Battery voltage
gps.altitude_m)) vbat = AnalogIn(board.D9, )
else:
print('Latitude: {} deg | Longitude: {} deg'.format(gps.latitude, # GPS on FeatherWing board
gps.longitude)) if gps_enable:
gps_uart = UART(board.TX, board.RX, baudrate=9600, timeout=3000)
print('Fix quality: {}'.format(gps.fix_quality)) gps = GPS(gps_uart)
# Some attributes beyond latitude, longitude and timestamp are optional # Turn on the basic GGA and RMC info
# and might not be present. Check if they're None before trying to use! gps.send_command('PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0')
if gps.satellites is not None: gps.send_command('PMTK220,1000') # 1000 ms refresh rate
print('# satellites: {}'.format(gps.satellites))
if gps.track_angle_deg is not None: # Integrated Neopixel
print('Speed: {} knots'.format(gps.speed_knots)) if data_to_neopixel:
if gps.track_angle_deg is not None: pixel = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2)
print('Track angle: {} degrees'.format(gps.track_angle_deg)) else:
if gps.horizontal_dilution is not None: #if neopixel is disable : turn off the LED
print('Horizontal dilution: {}'.format(gps.horizontal_dilution)) pixel = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2)
if gps.height_geoid is not None: pixel[0] = (0,0,0)
print('Height geo ID: {} meters'.format(gps.height_geoid)) pixel = None
check_data_dir()
#############
# Main loop #
#############
data = Data()
last_update = time.monotonic()
while True:
if gps_enable:
gps.update()
current = time.monotonic()
if current - last_update >= update_interval:
last_update = current
data.update()
if print_data:
data.show()
# print(data.json())
if data_to_neopixel:
pixel[0] = update_neopixel(data.data)
gc.collect()
# micropython.mem_info(1)
# print('Memory free: {} allocated: {}'.format(gc.mem_free(), gc.mem_alloc()))