Skip to content

Commit

Permalink
Merge pull request #3 from /dev: v2.7.1 (final release of internal v2…
Browse files Browse the repository at this point in the history
….7-rcs)

Dev: v2.7.1 - SCD41 (new), LoRa (improved), GPS (working), errors (improved), pinout
  • Loading branch information
StevenCellist authored May 29, 2023
2 parents 0863aa0 + d74d485 commit 69b7b2f
Show file tree
Hide file tree
Showing 17 changed files with 733 additions and 433 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ __pycache__/

pymakr.conf

**secret.py
**secret.py
software/update-mjlo-*
24 changes: 15 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ Let op: versie 3.1 van dit breakout board verschilt op meer vlakken van v3.0 dan
[Voltage divider: mess](https://community.hiveeyes.org/t/batterieuberwachung-voltage-divider-und-attenuation-fur-micropython-firmware/2128/46?page=2)

## Stroomgebruik en spanning
***Verouderd: v2.0 i.t.t. huidige v2.5***
***Verouderd: v2.0 i.t.t. huidige v2.7***
Zie de figuur hieronder voor het stroomgebruik van de vorige versie software. De gemiddelde stroomsterkte tijdens activiteit is 105 mA; in deepsleep 3.4 mA.
De vermoedde accuduur is drie weken, waarbij het zonnepaneel buiten beschouwing wordt gelaten.
![Stroomgebruik MJLO-12 op v19.01.22](Stroomgebruik_v19_01_22.png)

## Schema
Zie de figuur voor de opbouw van het circuit in de sensorkastjes.
![Schematic v2.5 15-08-2022](Schematic_Meet_je_leefomgeving_2022-09-01.svg)
![Schematic v2.7 15-04-2023](Schematic_Meet_je_leefomgeving_2023-04-15.svg)

## Custom firmware
De eenvoudige variant voor het ontwikkelen van software is het uploaden van alle losse bestanden naar `/flash`. Bij het wijzigen van een bestand kan dat losse bestand snel gewijzigd en opnieuw geupload worden. Er zijn echter meerdere nadelen aan verbonden:
Expand Down Expand Up @@ -82,15 +82,21 @@ De volgende twee regels moeten elke keer uitgevoerd worden bij het openen van ee

(De volgende opmerkingen gaan er allemaal vanuit dat je je in de map `pycom-micropython-sigfox/esp32` bevindt.)

Om bestanden in te vriezen, moeten ze in de subfolder `/frozen/Base` geplaatst worden. Standaard staan daar een `_boot.py` en `_main.py`: die kunnen overschreven worden met de desbetreffende bestanden uit deze repository zonder verlies van functionaliteit.
Om bestanden te bevriezen, moeten ze in de subfolder `/frozen/Base` geplaatst worden. Standaard staan daar een `_boot.py` en `_main.py`: die kunnen overschreven worden met de desbetreffende bestanden uit deze repository zonder verlies van functionaliteit.
Om relatieve imports te behouden (bijvoorbeeld `import lib.SSD1306`) kan de map `/lib` ook gewoon binnen de map `/frozen/Base` geplaatst worden.
Let op: het is niet mogelijk de bestanden `boot.py` en `main.py` zelf te bevriezen: die worden standaard geleegd bij het compilen.

Om de versienaam aan te passen:
* `nano pycom_version.h` -> regel 13: aanpassen
[bron](https://forum.pycom.io/topic/3902/frozen-modules-for-my-sipy-solved/3)

Om aan te passen welk bestand er uitgevoerd wordt na `_boot.py` en `_main.py` (in dit geval `"error.py"` in `/frozen/Base`):
* `nano mptask.c` -> regel 339: vervang `pyexec_file(main.py)` door `pyexec_frozen_module("error.py")`
[bron](https://forum.pycom.io/topic/2038/flashing-with-frozen-main-py-and-boot-py/4)

Om een `OrderedDict` toe te voegen:
* `nano mpconfigport.h` -> regel 79 nieuwe regel: `#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1)`
[bron](https://forum.pycom.io/topic/972/enable-ordereddict-support-by-default/5)

De volgende regels zijn (elke keer) nodig om de firmware te compilen:
* `make clean`
Expand All @@ -99,9 +105,9 @@ De volgende regels zijn (elke keer) nodig om de firmware te compilen:

Het resulterende `.tar.gz` bestand staat in de subfolder `/build`. Dit bestand kan gebruikt worden om de LoPy4 te flashen via de Pycom Firmware Updater. Om het `.bin` bestand te verkrijgen dat nodig is voor de OTA updates, moet de `.tar.gz` uitgepakt worden via bijvoorbeeld `tar -xzf filename`: het resulterende `lopy4.bin` is het gezochte bestand.

[Installing pycom-esp-idf](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/linux-macos-setup.html)
[Installing pycom-micropython-sigfox](https://github.com/pycom/pycom-micropython-sigfox)
[Frozen modules documentation](https://docs.pycom.io/advance/frozen/)
[Modyfing startup sequence](https://forum.pycom.io/topic/2038/flashing-with-frozen-main-py-and-boot-py/6)
[Relative frozen imports](https://forum.pycom.io/topic/7255/lib-folder-in-frozen-base)
[Pycom Firmware Updater](https://docs.pycom.io/updatefirmware/device/)
[Installing pycom-esp-idf](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/linux-macos-setup.html)
[Installing pycom-micropython-sigfox](https://github.com/pycom/pycom-micropython-sigfox)
[Frozen modules documentation](https://docs.pycom.io/advance/frozen/)
[Modyfing startup sequence](https://forum.pycom.io/topic/2038/flashing-with-frozen-main-py-and-boot-py/6)
[Relative frozen imports](https://forum.pycom.io/topic/7255/lib-folder-in-frozen-base)
[Pycom Firmware Updater](https://docs.pycom.io/updatefirmware/device/)
5 changes: 0 additions & 5 deletions Schematic_Meet_je_leefomgeving_2022-09-01.svg

This file was deleted.

Binary file not shown.
5 changes: 5 additions & 0 deletions Schematic_Meet_je_leefomgeving_2023-04-15.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
125 changes: 125 additions & 0 deletions software/LoRa.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import network
import socket
import pycom
import time

_configs = { # bytes, offset, precision
'temp' : (2, 100, 0.01 ),
'pres' : (2, 0, 0.1 ),
'humi' : (1, 0, 0.5 ),
'voc' : (2, 0, 1 ),
'uv' : (2, 0, 1 ),
'lx' : (2, 0, 1 ),
'volu' : (1, 0, 0.5 ),
'batt' : (2, 0, 0.001 ),
'co2' : (2, 0, 0.1 ),
'pm25' : (2, 0, 0.1 ),
'pm10' : (2, 0, 0.1 ),
'lat' : (3, 90, 0.0001),
'long' : (3, 180, 0.0001),
'alt' : (2, 100, 0.1 ),
'hdop' : (1, 0, 0.1 ),
'fw' : (1, 0, 1 ),
'error': (1, 128, 1 )
}

class LoRaWAN:
def __init__(self, sf = None, fport = None):
# create lora object
self.lora = network.LoRa(mode = network.LoRa.LORAWAN, region = network.LoRa.EU868)

# maybe we got here from error.py after already creating this object in main.py
# in that case, we should not restore from nvram as that would erase the information
if not self.has_joined:
self.lora.nvram_restore()

# if, after restoring data from nvram, it turns out that lora is not joined, join now
# this join is performed non-blocking as it should have completed before sending a message
if not self.has_joined:
import secret
self.lora.join(activation = pycom.nvs_get('lora'), # 0 = OTAA, 1 = ABP
auth = secret.auth(), # get keys for this specific node
dr = 12 - pycom.nvs_get('sf_h')) # always join using maximum power
self._fcnt = 0 # default LoRa frame count
else:
self._fcnt = pycom.nvs_get('fcnt') # restore LoRa frame count from nvRAM

if sf:
self._dr = 12 - sf
else:
self._dr = 12 - pycom.nvs_get('sf_l') # default SF (low)
if self._fcnt % pycom.nvs_get('adr') == 0:
self._dr = 12 - pycom.nvs_get('sf_h') # every adr'th message, send on high SF

if fport:
self._fport = 4
else:
self._fport = 1 # default LoRa packet decoding type 1 (no GPS)

self._frame = bytes([])

@property
def fcnt(self):
return self._fcnt

@property
def sf(self):
return 12 - self._dr

@sf.setter
def sf(self, sfactor):
self._dr = 12 - sfactor

@property
def dr(self):
return self._dr

@property
def fport(self):
return self._fport

@fport.setter
def fport(self, port):
self._fport = port

@property
def frame(self):
return self._frame

@property
def has_joined(self):
return self.lora.has_joined()

@staticmethod
def pack(name, values):
numbytes, offset, precision = _configs[name]
value = round((values + offset) / precision) # add offset, then round to precision
value = max(0, min(value, 2**(8*numbytes) - 1)) # stay in range 0 .. int.max_size - 1
out = value.to_bytes(numbytes, 'big') # pack to bytes
return out

def make_frame(self, odict):
for key, values in odict.items():
self._frame += LoRaWAN.pack(key, values)

return len(self._frame)

def send_frame(self, join_flag = False):
if not self._frame:
raise AttributeError("empty frame")

if join_flag:
while not self.has_joined:
time.sleep(1)

# send LoRa message and store LoRa context + frame count in NVRAM
sckt = socket.socket(socket.AF_LORA, socket.SOCK_RAW) # create a LoRa socket (blocking by default)
sckt.setsockopt(socket.SOL_LORA, socket.SO_DR, self._dr) # set the LoRaWAN data rate
sckt.bind(self._fport) # set the type of message used for decoding the packet
sckt.send(self._frame)
sckt.close()

self.lora.nvram_save()
pycom.nvs_set('fcnt', self._fcnt + 1)

self._frame = bytes([])
Loading

0 comments on commit 69b7b2f

Please sign in to comment.