mirror of
https://github.com/pimoroni/grow-python
synced 2025-10-25 15:19:23 +00:00
Start reference doc
This commit is contained in:
287
REFERENCE.md
Normal file
287
REFERENCE.md
Normal file
@@ -0,0 +1,287 @@
|
||||
# Grow <!-- omit in toc -->
|
||||
|
||||
Grow
|
||||
|
||||
- [Getting Started](#getting-started)
|
||||
- [Pre-requisites](#pre-requisites)
|
||||
- [Python 3 & pip](#python-3--pip)
|
||||
- [Enabling i2c and spi](#enabling-i2c-and-spi)
|
||||
- [Installing the library](#installing-the-library)
|
||||
- [Reference](#reference)
|
||||
- [Moisture](#moisture)
|
||||
- [Calibrating the moisture sensor](#calibrating-the-moisture-sensor)
|
||||
- [Moisture Reference](#moisture-reference)
|
||||
- [moisture](#moisture-1)
|
||||
- [saturation](#saturation)
|
||||
- [range](#range)
|
||||
- [new_data](#new_data)
|
||||
- [active](#active)
|
||||
- [Pump](#pump)
|
||||
- [Calibrating The Pump](#calibrating-the-pump)
|
||||
- [Pump Reference](#pump-reference)
|
||||
- [dose](#dose)
|
||||
- [set_speed](#set_speed)
|
||||
- [get_speed](#get_speed)
|
||||
- [stop](#stop)
|
||||
- [Light Sensor](#light-sensor)
|
||||
- [Display](#display)
|
||||
|
||||
## Getting Started
|
||||
|
||||
You'll need to install the LTP305 software library and enable i2c on your Raspberry Pi.
|
||||
|
||||
### Pre-requisites
|
||||
|
||||
#### Python 3 & pip
|
||||
|
||||
You should use Python 3, which may need installing on your Pi:
|
||||
|
||||
```
|
||||
sudo apt update
|
||||
sudo apt install python3 python3-pip
|
||||
```
|
||||
|
||||
#### Enabling i2c and spi
|
||||
|
||||
You can use `sudo raspi-config` on the command line, the GUI Raspberry Pi Configuration app from the Pi desktop menu, or use the following commands to enable i2c and spi:
|
||||
|
||||
```
|
||||
sudo raspi-config nonint do_i2c 0
|
||||
sudo raspi-config nonint do_spi 0
|
||||
```
|
||||
|
||||
### Installing the library
|
||||
|
||||
```python
|
||||
python3 -m pip install growhat
|
||||
```
|
||||
|
||||
This will also install the display driver - ST7735 - and a driver for the light sensor - LTR559.
|
||||
|
||||
## Reference
|
||||
|
||||
The Grow library includes several modules for monitoring, watering and conveying status information.
|
||||
|
||||
### Moisture
|
||||
|
||||
The moisture module is responsible for reading the moisture sensor.
|
||||
|
||||
Grow moisture sensors output pulses that correspond to the moisture content of the soil.
|
||||
|
||||
Wet soil will produce low frequency pulses, which will gradually become more frequent as the soil dries. (TODO: document exact range)
|
||||
|
||||
To set up a moisture sensor you must import and initialise the class with the channel number you want to monitor:
|
||||
|
||||
```python
|
||||
from grow.moisture import Moisture
|
||||
|
||||
moisture1 = Moisture(1) # Monitor channel 1
|
||||
```
|
||||
|
||||
Moisture channels are labelled on the PCB from left to right as S1, S2 and S3.
|
||||
|
||||
#### Calibrating the moisture sensor
|
||||
|
||||
Since every soil substrate and environment is different, you must tell Grow what Wet and Dry soil look like. You can do this using the methods `set_wet_point` and `set_dry_point`.
|
||||
|
||||
The wet and dry points are expressed as raw counts. You can read the raw moisture level of the soil at any time by using:
|
||||
|
||||
```python
|
||||
moisture1.moisture()
|
||||
```
|
||||
|
||||
These methods will either use the current read value or, optionally, a value that you supply so that you can save your calibration and load it again if you need to restart your script. A simple calibration process might look like the following:
|
||||
|
||||
```python
|
||||
# Leave the soil dry
|
||||
moisture1.set_dry_point()
|
||||
# Water the plant
|
||||
moisture1.set_wet_point()
|
||||
```
|
||||
|
||||
Or you could have variables that you wish to set as your wet/dry points:
|
||||
|
||||
```python
|
||||
DRY_POINT = 1000
|
||||
WET_POINT = 100
|
||||
moisture1.set_dry_point(DRY_POINT)
|
||||
moisture1.set_wet_point(WET_POINT)
|
||||
```
|
||||
|
||||
#### Moisture Reference
|
||||
|
||||
##### moisture
|
||||
|
||||
```python
|
||||
value = moisture1.moisture()
|
||||
```
|
||||
|
||||
Reads the raw moisture level of the sensor.
|
||||
|
||||
This is expressed in pulses-per-second and is inversely proportional to the moisture content of the soil.
|
||||
|
||||
(TODO: document exact range)
|
||||
|
||||
##### saturation
|
||||
|
||||
```python
|
||||
value = moisture1.saturation()
|
||||
```
|
||||
|
||||
Returns a value from 0.0 to 1.0 that corresponds to how moist the soil is.
|
||||
|
||||
The saturation level is calculated using the wet and dry points and is useful for populating visual indicators, logs or graphs.
|
||||
|
||||
##### range
|
||||
|
||||
```python
|
||||
moisture1.range()
|
||||
```
|
||||
|
||||
Returns the distance, in counts per second, between the wet and dry points. Used predominately in the calculation of saturation level, but may be useful.
|
||||
|
||||
##### new_data
|
||||
|
||||
```python
|
||||
moisture1.new_data()
|
||||
```
|
||||
|
||||
Returns `True` if the internal moisture reading has been updated since the last time `moisture()` or `saturation()` was called.
|
||||
|
||||
This allows you to log or run averaging over each new reading as it is collected or process readings in your program loop.
|
||||
|
||||
For example, this snippet will loop ~60 times a second but only append new moisture readings to `log` once every second:
|
||||
|
||||
```python
|
||||
import time
|
||||
from grow.moisture import Moisture
|
||||
|
||||
moisture1 = Moisture(1) # Monitor channel 1
|
||||
log = []
|
||||
|
||||
while True:
|
||||
if moisture1.new_data():
|
||||
log.append(moisture1.saturation())
|
||||
|
||||
time.sleep(1.0 / 60) # 60 updates/sec
|
||||
```
|
||||
|
||||
##### active
|
||||
|
||||
```python
|
||||
moisture1.new_data()
|
||||
```
|
||||
|
||||
Returns `True` if the moisture sensor is connected and returning valid readings. Currently not very reliable or responsive.
|
||||
|
||||
TODO: Find ways to make this better
|
||||
|
||||
### Pump
|
||||
|
||||
The Pump module is responsible for driving a pump. It uses PWM to run the pump at variable speeds.
|
||||
|
||||
To set up a pump you must import and initialise the class with the channel number you want to control:
|
||||
|
||||
```python
|
||||
from grow.pump import Pump
|
||||
|
||||
pump1 = Pump(1) # Control channel 1
|
||||
```
|
||||
|
||||
Pump channels are labelled on the PCB from left to right as P1, P2 and P3.
|
||||
|
||||
#### Calibrating The Pump
|
||||
|
||||
In order for your pump/hose setup to reliably deliver a sensible amount of water you will have to calibrate both the speed at which it runs, and the time that it runs for. The speed/time settings are collectively known as a "dose" and we've produced an example - `dose.py` - to help find the right values.
|
||||
|
||||
Higher pump speeds are useful for defeating gravity; in case where you water tank might be much lower than your plants. Longer pump times will deliver more water.
|
||||
|
||||
Refer to the instructions at the top of `dose.py` for its usage. Generally you should dial in the lowest pump speed that will get water to traverse your hose, and adjust the time to deliver the right amount of water.
|
||||
|
||||
These values are then passed into `pump.dose()` when watering.
|
||||
|
||||
#### Pump Reference
|
||||
|
||||
##### dose
|
||||
|
||||
```python
|
||||
pump1.dose(0.5, 0.5, blocking=False)
|
||||
```
|
||||
|
||||
Delivers a dose of water by running the pump at a specified speed for a specified time. Can be run in blocking (method takes time to return) or non-blocking (returns instantly and pump runs in the background) modes.
|
||||
|
||||
This is the recommended way to water plants, since it delivers a controlled, short dose and is less likely to result in unwanted floods.
|
||||
|
||||
##### set_speed
|
||||
|
||||
```python
|
||||
pump1.set_speed(0.5)
|
||||
```
|
||||
|
||||
Turns the pump on at the given speed. To stop the pump call `stop()` or `set_speed(0)`.
|
||||
|
||||
Unless your setup (vertical hydroponics for example) requires continuous pumping of water then you should not use this function and use the `dose` instead.
|
||||
|
||||
##### get_speed
|
||||
|
||||
```python
|
||||
speed = pump1.get_speed()
|
||||
```
|
||||
|
||||
Returns the current pump speed.
|
||||
|
||||
##### stop
|
||||
|
||||
```python
|
||||
pump1.stop()
|
||||
```
|
||||
|
||||
Stops the pump by setting the speed to 0. Does not interrupt a non-blocking `dose`. TODO: It probably should
|
||||
|
||||
### Light Sensor
|
||||
|
||||
Grow is equipped with an LTR-559 light and proximity sensor that you can use to limit waterings to daytime, or monitor the level of light your plant is receiving.
|
||||
|
||||
The LTR-559 has its own library, and should be initialised like so:
|
||||
|
||||
```python
|
||||
from ltr559 import LTR559
|
||||
light = LTR559()
|
||||
```
|
||||
|
||||
You can then update the sensor and retrieve the `lux` and `proximity` values like so:
|
||||
|
||||
```python
|
||||
while True:
|
||||
ltr559.update_sensor()
|
||||
lux = ltr559.get_lux()
|
||||
prox = ltr559.get_proximity()
|
||||
```
|
||||
|
||||
See the LTR559 library for a full reference: https://github.com/pimoroni/ltr559-python
|
||||
|
||||
### Display
|
||||
|
||||
The ST7735 display on Grow is 160x80 pixels and a great way to convey current watering status or build an interface for controlling your watering station.
|
||||
|
||||
The display must be set up like so:
|
||||
|
||||
```python
|
||||
display = ST7735.ST7735(
|
||||
port=0,
|
||||
cs=1, # Chip select 1 (BCM )
|
||||
dc=9, # BCM 9 is the data/command pin
|
||||
backlight=12, # BCM 12 is the backlight
|
||||
rotation=270,
|
||||
spi_speed_hz=80000000
|
||||
)
|
||||
display.begin()
|
||||
```
|
||||
|
||||
You should use the Python Image Library to build up what you want to display, and then display the finished image with:
|
||||
|
||||
```python
|
||||
display.display(image)
|
||||
```
|
||||
|
||||
See the examples for demonstrations of this. See the ST7735 library for a full reference: https://github.com/pimoroni/st7735-python/
|
||||
Reference in New Issue
Block a user