There is now enough implemented that all functions will work from pico-lights and pico-power, assuming that the hub module is directly connected to the relays and the lights module is connected over I2C.
At present, the code will connect to a wifi network, build a core website and serve it on the IP allocated by DHCP on port 80. The module will assume it is a Pico W with a relay board attached and load a local relay control module. If connected via I2C, a pico running the latest firmware in pico-lights will be detected and all pico-lights functions are available over the API via I2C.
The index page provides links to the lights and relay pages and APIs.
A pico powered network of boat automation devices with the ultimate goal of proividing cheap, configurable options to automating your boat (or any space really), with integrations with Signal-K (open source boat networking protocol) and Home-Assistant (awesome home automation server). Hence Pico-boat-assistant.
The module presents as an I2C slave by default at address 0x41 defined in var "RESPONDER_ADDRESS".
The I2C frequency should be 100000 defined in var "I2C_FREQUENCY"
The master I2C device is expected to issue a command at the target address and then wait for the expected data length to be returned by the lights module for that command.
Each hub module has a pico lights library that is built around this premise and the following data structures. The variables module_id = 0b00000010 and version = str("x.y") can be interrogated by two of these commands in order to confirm that the library code will reliably work with this version of the boatman module.
Review pico_lights.py of a matching version in a Boatman hub module repository for an example implementation against this protocol.
Commands and data should be sent as a byte array.
The commands are constructed as a 1 byte command with supplementary data bytes as defined below where required. The pico module will read 8 bytes into the read buffer, so pad remaining data bytes with 0 to ensure no unexpected results.
0b01GRIIII 0bDDDDDDDD - set light or light group duty cycle
G: 1 = Group, 0 = Individual light
R: 1 = Reset other lights to duty cyle of 0, 0 = update only this target
IIII = 4 bit Light or Group ID
DDDDDDDD = 0-255 Duty cycle value 0 = off, 255 = fully on
0b10000001: Get module ID - Pico lights should return 0b00000010
0b10000010: Get version
0b10000011: Get group assignments
- 0b01xxxxxx: Get/set light values - 1 byte
- 0: Success
- 1: Received reserved command
- 2: Group config out of sync (only on group set command, issue a group sync command)
- 3: Unrecognised get/set config command
- 10: Group ID out of range (only on group set command)
- 20: Duty value out of range
- 30: Group ID not in local config
- 0b10000001: Get module ID - 1 byte - 0b00000010
- 0b10000010: Get version - 1 byte big endian defining payload length - immediate send of version string, decode as ansi string e.g. "0.2.0"
- 0b10000011: Get group assignments - 2 bytes big endian defining payload length - immediate send of JSON of that length that can be fed into python json.loads(). This is a python dictionary for use in set light group command.
The Boatman pico lights module forms part of a wider Boatman ecosystem documented in the Boatman project repository
The hardware detailed below is built around the relatively new Raspberry Pi Pico microprocessor using the micropython firmware option.
The module leverages all of the 16 onboard PWM drivers, which should be fed into LED driver circuitry to address the current requirements of LED strips (See hardware section).
Control of the module is performed by a custom protocol on the I2C bus, using a community library to have the pico present as an I2C slave on the bus. A pico hub module performs the role of I2C master and depending on the hub, will have a variety of ways to drive the lights module config (Serial UART, REST API, web page etc.)
The module does not use any off the shelf Pico hats and is wired directly to the level shifters for the LED strips and connects to the hub module by 2 wire I2C as illustrated in the pinout diagram:
This module release was developed against Pico Micropython v1.18.
See https://micropython.org/download/rp2-pico/ for more details.
As of this release, group configruation is hard coded and must be updated in firmware. Future releases are planned to allow configuration to be set remotely by the Boatman hub. The firmware should set var "groupConfigInSync == FALSE" on startup, to ensure an error is produced until the Boatman hub issues a group sync command to reduce the risk of unexpected group control behaviour.
- Raspberry Pi Pico: Pi hut pico
- MOSFET PWM Drivers: Amazon Mosfet with connectors on PCB
- 2x1Kohm resistors
- Push button reset switch (optional)
Pico W based relay controller for web based control of DC and AC circuits onboard.
This code is built around the Pimoroni Pico W firmware v1.19.9
-
Uses Pico W board mounted on the PiHut relay board
-
Optional LiPo and charger shim allows the Pico to reset circuits it is powered by without shutting down, you will need to connect VSYS to VBUS to power the relays from the shim.
- Populate wifi SSID and password in the config.py file
- Set the startup relay states in the config.py file using the dictionary format example given.
- Determine pico IP from DHCP server (hostname appears to be "PYBD")
- Navigate to http://:80 for further instructions
The board has a power LED to show that the Pico AND the relay board have power i.e. 5v on VBUS as opposed to just VSYS.
The relays each have an LED to show relay state on/off.
The Pico LED is normally off in proper operation.
When connecting to the wifi the LED will flash once per second. Should the conection fail, the LED will flash 5 times per second for the retry backoff period then loop back to connecting.
Refer to the config file comments for options to enable polling a specified website at a given interval for a successful http response and take action to reset a specified relay and rerun the wifi connection on any failures.
Dynamic importing of modules is currently beyond me. To create a new module perform the following steps.
- Copy the template_module folder and rename to your module name
- Adjust the class name in init.py to pba_<your_module_name>
- Add a sys path and import line to the top of hub.py similar to lights and relay
- Add an entry to the registered_modules list in config.py, increment the ID number to an unused value, use this ID in the module definition
- Copy the template code block in the hub.py section under comment "# configuration - manually add your module lines here", uncomment and adjust instances of <module_name> to init your module
- Build a whole load of code in the module template folder similar to the lights and relay module essentially replace the word "template" for your module and update/extend webpage and API definitions and build out a hardware abstraction - This only supports local modules at present