-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from Keegan-Evans/docs
DOCS: adding docs
- Loading branch information
Showing
18 changed files
with
1,082 additions
and
45 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 @@ | ||
{} |
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,62 @@ | ||
# Getting the firmware onto the Pico. | ||
|
||
## Preparing the Pico | ||
You should ensure the pico's flash memory has been completely cleared of other code by | ||
|
||
- Boot Pico in Developement Mode. To do so hold the `bootsel` button while | ||
plugging the pico in. | ||
|
||
- Drag the `flashnuke.uf2` firmware file onto the `RPI-RP2` drive to ensure the | ||
Pico's memory has been completely cleared.[Flash Nuke | ||
Download](https://www.raspberrypi.com/documentation/microcontrollers/raspberry-pi-pico.html#resetting-flash-memory). | ||
|
||
> **ⓘ** When developing for the pico, be sure to commment out the Watchdog | ||
Timer in the `Sensor` class, as it will cause the Pico to reboot and disconnect | ||
anytime an error is encountered, without emiting error information to your | ||
developement environment, leading to a very frustrating experience. This can | ||
happen in sneaky ways as well, such as if you previously had added a file that | ||
was run on boot by the pico that contained code that ran the WDT, hence the | ||
admonition to use the `flashnuke` firmware any time you are changing software on | ||
the pico. | ||
|
||
- When the `RPI-RP2` drive re-appears, drag the [latest MicroPython | ||
firmware](https://micropython.org/download/RPI_PICO_W/) onto it. Be sure to get | ||
the firmware for the Pico-W rather than Pico, as the `network` module is needed. | ||
|
||
## Uploading Files | ||
|
||
|
||
### Files to upload | ||
|
||
- `main.py`: This is the file that is loaded by the Pico on boot. It should | ||
contain a call to whatever run command your program requires. For examples look | ||
in the `examples/mains` directory. If you would like to use one of these, simply | ||
copy it to the Pico and rename to `main.py` so that MicroPython loads it on | ||
boot. | ||
|
||
- `sensor.py`: This file contains the base class definition to initialize the | ||
Pico for use with the `Sensor-Hub` ecosystem. | ||
|
||
- **I2C driver files**: Files that provide definitions to take measurements from | ||
I2C sensors, must provide a measurement method that can be handed to the | ||
`Sensor` class instance as a no-arguement function. | ||
|
||
- `util.py`: Provides functionality such as automated network connectivity. | ||
|
||
## After upload | ||
|
||
Once the files are uploaded to the Pico, it should be ready to run. Upon first | ||
boot and connection, the Pico should automatically download and install the | ||
required `mqtt` micropython library. This may cause an error that seems to cause | ||
the Pico to hang when it is finished installing, but should function normally | ||
upon power cycling. Then as long as `Sensor-Hub` is within Wi-Fi range, it | ||
should now connect and begin loggin data automatically. | ||
|
||
|
||
## Other Tools | ||
|
||
- [rshell](https://github.com/dhylands/rshell) | ||
|
||
- | ||
[MicroPico](https://marketplace.visualstudio.com/items?itemName=paulober.pico-w-go)(VSCode | ||
Extension) |
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 |
---|---|---|
@@ -1,42 +1,31 @@ | ||
# Register New Analog Sensor | ||
## Register New Analog Sensor | ||
|
||
Analog sensors can be registered by passing a dictionary and base sensor instance to the `registre_analog_function_to_sensor` function found in the `registration` module. | ||
|
||
Because the analog sensors rely on directly taking a reading from the end-point | ||
Because analog sensors rely on directly taking a reading from the end-point | ||
sensor, the only things we need to tell our board about them is what we would | ||
like them to be called and the pin from which the analog reading should be | ||
taken. The reading is taken using the Micropython `machine.ADC.read_u16` | ||
function. | ||
|
||
In addition to specifying the pin to be read and correctly attaching it, you should hook the power supply of the sensor to the `ADC_VREF` pin on the Pico(that is, pin #35). | ||
In addition to specifying the pin to be read and correctly attaching it, you should hook the power supply of the sensor to the `ADC_VREF` pin on the Pico(that is, pin #35), from which the Pico supplies a stable reference voltage, against which the analog sensor reading can be taken. | ||
|
||
### Registering the Soil Moisture Sensor | ||
|
||
As an example, we will here register a capacitive soil moisture sensor to a Pico. | ||
|
||
As an example, we will here register a capacitive soil moisture sensor to our pico. | ||
|
||
To begin with, we create the dictionary that associates the name `soil_moisture_reg_test` to the pin number we want to take our reading from. | ||
|
||
On the Pico, the pins available for use as ADC pins are 26, 27, and 28. It is possible to use other pins as ADC pins through careful software sampling, but that is well beyond the usecase here, but the option is available to developers in the future. | ||
On the Pico, the pins available for use as analog-to-digital converter (ADC) pins are 26, 27, and 28. It is possible to use other pins as ADC pins through careful software sampling, but that is well beyond the usecase here, but the option is available to developers in the future. | ||
|
||
Taking a look at the `soil_moisture.py` file in our library, the dictionary we use to define the soil moisture sensor looks like: | ||
We can look at the `soil_moisture_main.py` file in the `mains` directory for how we can go about registering the soil moisture sensor. | ||
|
||
``` | ||
sm = {'soil_moisture_reg_test': 28} | ||
``` | ||
In turn this is imported during the demon, and then handed to our registration function(you can run this from `demos/demo_analog_sensor_registration.py`). | ||
|
||
``` | ||
```python | ||
from sensor import Sensor | ||
from registration import register_analog_function_to_sensor | ||
from soil_moisture import sm | ||
|
||
sensor = Sensor(sensor_name="demo_sensor_1") | ||
register_analog_function_to_sensor(sensor=sensor, def_dict=sm) | ||
``` | ||
if __name__ == "__main__": | ||
sensor = Sensor(sensor_name="soil_moisture_demo_1") | ||
sensor.register_analog_sensor_function("soil_moisture", 28) | ||
|
||
You must first initialize a base sensor instance, then hand that instance in as the `sensor` parameter of the registration function, and the dictionary associating the name with the pin number as the argument to `def_dict`. | ||
sensor.run() | ||
``` | ||
|
||
Whatever name use for the sensor will be recorded as the `measurement` name in the SensorHub database. | ||
You must first initialize a base sensor instance, then use the `register_analog_sensor_function` method to name the reading to be taken from pin 28 "soil_moisture". Then at the specified reporting interval, the pico will take a reading from pin 28 and report it via MQTT message to the `Sensor-Hub`. Whatever name use for the sensor will be recorded as the `measurement` name in the `Sensor-Hub` database. | ||
|
||
To check that the sensor was registered appropriately, you can print `<sensor-instance>.measurement_functions`, and you should see the name you provided as one of the keys in the output. |
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,52 @@ | ||
# Registering A New I2C Sensor | ||
|
||
The process of registering an I2C sensor are somewhat more challenging than | ||
those of registering an analog sensor. That is because the interface for | ||
interacting with each particular sensor is determined by the design of the | ||
sensor itself. If there is not a pre-built library for the sensor available in | ||
`Micropython`, then it will be necessary to write one from scratch. To do so, it | ||
is often helpful to look at various Arduino libraries, such as [`Arduino | ||
SensorKit`](https://github.com/arduino-libraries/Arduino_SensorKit), or the | ||
sensor IC's data sheet. When implementing the driver library for the particular | ||
sensor, the end goal is to create a single function call that will request and | ||
return a reading from the sensor. | ||
|
||
In the `Sensor` class, the method `register_i2c_sensor_function` takes the name | ||
you would like the measurement to be given, and the actual function to be called | ||
to get the reading from the sensor module. As of now, the only type of function | ||
with a place to be registered are measurement functions, though it would be | ||
possible to add registration for other types of I2C functions in the future. | ||
|
||
## BME280 example | ||
Here we will take a look at using the BME280 with the Pico. To see how this done | ||
at a high level, we can take a look at `mains/atmospheric_main.py`: | ||
|
||
```python | ||
from sensor import Sensor | ||
from bme280 import BME280 | ||
|
||
sensor = Sensor(sensor_name="atmospheric", | ||
topic='sensor_data/atmospheric', | ||
reporting_interval_sec=2, | ||
I2CSensor=True) | ||
|
||
environ_sensor = BME280(i2c=sensor.i2c_bus) | ||
sensor.register_i2c_sensor_function('temperature', | ||
environ_sensor.read_temperature) | ||
sensor.register_i2c_sensor_function('humidity', | ||
environ_sensor.read_humidity) | ||
sensor.register_i2c_sensor_function('pressure', | ||
environ_sensor.read_pressure) | ||
|
||
|
||
sensor.run() | ||
``` | ||
|
||
Here, the sensor functions are defined in the `bme280` module. There is a single | ||
function to get the reading value of each of our target measurements, | ||
`temperature`, `humidity`, and `pressure`. | ||
|
||
Setting `I2CSensor` to `True` to tell the Sensor base class to initialize with a | ||
I2C bus connection enabled. The bus connection here is passed to the `BME280` | ||
class for use when it is calling I2C functions. | ||
|
Oops, something went wrong.