-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
First working version of the Cellular ExpressLink WeatherStation
- Loading branch information
Showing
3 changed files
with
213 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import json | ||
import time | ||
import board | ||
import adafruit_bme680 | ||
import busio | ||
from countio import Counter, Edge | ||
from digitalio import DigitalInOut, Direction, Pull | ||
from analogio import AnalogIn | ||
|
||
from expresslink import ExpressLink | ||
|
||
time.sleep(2) | ||
print("WeatherStation Startup") | ||
|
||
def GetVoltage(pin): | ||
return (pin.value * 3.3) / 65536 | ||
|
||
# Resistor table | ||
resistorTable = (('N',33000), ('NNE',6570), ('NE',8200), ('ENE',891), ('E',1000), ('ESE',688), ('SE',2200),('SSE',1410),('S',3900),('SSW',3140),('SW',16000),('WSW', 14120),('W',120000),('WNW',42120),('NW',64900), ('NNW', 21880)) | ||
|
||
# Compute correct Resistance | ||
# Top resistor 10k | ||
# Supply voltage is 3.3v | ||
# R = (v * 10000)/(3.3-v) | ||
|
||
def getDirection(pin)->str: | ||
v = GetVoltage(pin) | ||
r = (v * 10000.0) / (3.3 - v) | ||
smallestValue = 10000000 | ||
direction = "" | ||
for entry in resistorTable: | ||
distance = abs(r - entry[1]) | ||
if distance < smallestValue: | ||
direction = entry[0] | ||
smallestValue = distance | ||
return direction | ||
|
||
lastTime = 0 | ||
oldSpeed = 0 | ||
def getSpeed(pin:Counter)->float: | ||
global lastTime, oldSpeed | ||
thisTime = time.time() | ||
deltaTime = thisTime - lastTime | ||
if deltaTime > 10: | ||
windCount = pin.count | ||
pin.reset() | ||
lastTime = thisTime | ||
hz = windCount / deltaTime | ||
oldSpeed = 2.4 * hz # km/hr | ||
return oldSpeed | ||
|
||
lastTip = 0 | ||
previousTipCount = 0 | ||
def getRainDepth(pin:Counter)->float: | ||
global lastTip, previousTipCount | ||
now = time.time() | ||
tips = pin.count | ||
if previousTipCount != tips: | ||
lastTip = now | ||
previousTipCount = tips | ||
else: | ||
if now - lastTip > (24*3600): # if there are no tips for 24 hours, | ||
pin.reset() # reset the count | ||
previousTipCount = 0 | ||
tips = 0 | ||
return tips * 0.2794 # depth in mm | ||
|
||
|
||
windDirection = AnalogIn(board.A0) | ||
|
||
uart = busio.UART(board.UART_TX1, board.UART_RX1, baudrate=115200, timeout=30) | ||
el = ExpressLink(uart, DigitalInOut(board.G5), DigitalInOut(board.G2), DigitalInOut(board.G6) ) | ||
|
||
el.begin() | ||
|
||
print("ExpressLink Started") | ||
|
||
i2c = board.I2C() | ||
bme680 = adafruit_bme680.Adafruit_BME680_I2C(i2c,debug=False) | ||
|
||
temperature_offset=-5 | ||
|
||
rain = Counter(board.D1, edge=Edge.FALL, pull=Pull.UP) | ||
rain.reset() | ||
wind = Counter(board.PWM0, edge=Edge.FALL, pull=Pull.UP) | ||
wind.reset() | ||
|
||
response = el.sendCommand('AT+CONF? ThingName') | ||
thingName = response[3:] | ||
response = el.sendCommand("AT+CONF Topic1=weather/sensor/" + thingName) | ||
|
||
while True: | ||
|
||
if el.connect(): | ||
report = {} | ||
report["temperature"] = bme680.temperature+temperature_offset | ||
report["gas"] = bme680.gas | ||
report["humidity"] = bme680.relative_humidity | ||
report["pressure"] = bme680.pressure | ||
report["wind direction"] = getDirection(windDirection) | ||
report["wind speed"] = getSpeed(wind) | ||
report["rain"] = getRainDepth(rain) | ||
data = json.dumps(report) | ||
print("Reporting : " + data) | ||
el.sendCommand("AT+SEND1 " + data) | ||
else: | ||
print("No connection") | ||
el.begin() | ||
|
||
time.sleep(1) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import busio | ||
import time | ||
from digitalio import DigitalInOut, Direction, Pull | ||
|
||
class ExpressLink: | ||
event_pin:DigitalInOut # change to be an input pin with a callback | ||
powerOn_pin:DigitalInOut | ||
powerCheck_pin:DigitalInOut | ||
_connected:bool | ||
port:serial | ||
|
||
def __init__(self, port, event, powerOn, powerCheck): | ||
self.port = port | ||
self.event_pin = event | ||
self.powerOn_pin = powerOn | ||
self.powerCheck_pin = powerCheck | ||
self.event_pin.direction = Direction.INPUT | ||
self.powerCheck_pin.direction = Direction.INPUT | ||
self.powerOn_pin.direction = Direction.OUTPUT | ||
self.powerOn_pin.value = False | ||
|
||
# This function relies upon the SARA_ON signal to work | ||
def _powerOn(self)->bool: | ||
while self.powerCheck_pin.value == True: | ||
self.powerOn_pin.value = True | ||
time.sleep(.50) | ||
self.powerOn_pin.value = False | ||
time.sleep(.1) | ||
print("ExpressLink Powered") | ||
return True | ||
|
||
def _comCheck(self)->bool: | ||
print("Checking Communications") | ||
response = "" | ||
while response.find("OK") != 0: | ||
time.sleep(.5) | ||
response = self.sendCommand("AT") | ||
return True | ||
|
||
def begin(self): | ||
self._connected = False | ||
self._powerOn() | ||
self._comCheck() | ||
print("ExpressLink Up") | ||
|
||
def connect(self)->bool: | ||
response = self.sendCommand("AT+CONNECT?") | ||
print("connect_check : " + response) | ||
code = response.find("OK 1") | ||
if code == -1: | ||
self._connected = False | ||
response = self.sendCommand("AT+CONNECT") | ||
print("connect:"+response) | ||
if self.checkResponse(response) == 0: | ||
self._connected = True | ||
else: | ||
self._connected = True | ||
return self._connected | ||
|
||
def sendCommand(self, command:str)->str: | ||
command += '\n' | ||
self.port.write(command.encode("utf-8")) | ||
time.sleep(1) | ||
response = self.port.readline() | ||
if response != None: | ||
return response.decode("utf-8") | ||
else: | ||
return "" | ||
|
||
def checkResponse(self, response:str)->int: | ||
if response.find("OK") == 0: | ||
return 0 | ||
else: | ||
if response.find("ERR") == 0: | ||
return int(response[3:]) | ||
else: | ||
return -1 | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# U-Blox SARA R5 ExpressLink CircuitPython Demo | ||
|
||
# ExpressLink Configuration | ||
Execute manual steps in the expresslink getting started guide to get the Ublox ExpressLink connected to your AWS account. | ||
|
||
# HW Configuration | ||
The SARA R5 ExpressLink board must be configured to enable the power state feedback. This signal is labeled SARA_ON on the schematic. | ||
On the back of the board, you must apply a solder blob to the two pads labeled SARA_ON to connect that signal to G6 on the micromod. | ||
|
||
The tipping bucket is connected to signal D1 on the right side of the expresslink board. | ||
The wind speed is connected to signal PWM0 on the right side of the expresslink board. | ||
The wind direction is connected to signal A1 on the right side of the expresslink board. | ||
The wind direction is also connected to 3.3v via a 10k resistor. I was able to bridge A1 to the QWICC 3v3 pin with a surface mount resistor and a bit of wire. | ||
|
||
Attach the QWICC BME680 cable between the BME680 and the ExpressLink bkard. | ||
|
||
# SW Configuration | ||
Install the CircuitPython image from this location: https://circuitpython.org/board/sparkfun_micromod_rp2040/ | ||
|
||
Install the BME680 CircuitPython library from this location: https://github.com/adafruit/Adafruit_CircuitPython_BME680 | ||
The BME680 library can be simply copied into the LIB folder present on the CIRCUITPY filesystem after the CircuitPython image is installed. | ||
Connect a USB cable to the board and open a terminal. 115200 8N1 | ||
copy expresslink.py and code.py into the CIRCUITPY filesystem and watch the data. | ||
|