JeetShetty / GreenPiThumb

https://mtlynch.io/greenpithumb/
Apache License 2.0
82 stars 12 forks source link

Integrate GPIO stuff in moisture sensor #43

Closed mtlynch closed 7 years ago

mtlynch commented 7 years ago

I realized the code for moisture_sensor.py omits some critical elements we need. The moisture sensor is powered by the GPIO pins, because I think if we leave it powered all the time, the copper starts to corrode.

We can see how Dickson Chow does it here:

https://github.com/dicksondickson/PlantFriends/blob/7c172e9f80c2de2fdfc373d31a89de66787a7756/sensor_node/RFM69/sensor_node.ino#L306...L329

So it looks like what we need to do is:

  1. Set one pin to high, one pin to low
  2. Read the sensor value from the ADC
  3. Set both pins to low
  4. Wait for capacitive effects to go away (he waits 88 milliseconds)
  5. Repeat 1-2, but with the pins swapped and inverting the value from 1023
  6. Turn off both pins
  7. Average the two readings as the moisture level
JeetShetty commented 7 years ago

What pins are we writing to in step 1? I'm confused about how this works through the ADC.

mtlynch commented 7 years ago

So there 6 GPIO pins in play here. The ADC needs 4 pins, but the moisture_sensor module doesn't care about those 4 pins because it just needs an ADC instance (the instance worries about those pins and abstracts it away from moisture_sensor).

BUT moisture_sensor needs to control power to the sensor, so it needs to use two GPIO pins as output so that it can turn power on and off to the moisture sensor. Then it needs to know which ADC channel the moisture sensor is plugged into. In our schematic, the moisture sensor is plugged into ADC channel 7.

This is the quick 'n dirty script I used to test the soil moisture sensor as a standalone program. The numbers match the Fritzing schematic we have for the wiring.

import time

import Adafruit_MCP3008
import RPi.GPIO as GPIO

# mtlynch: The moisture_sensor module wouldn't need to care about this stuff because it'd
# have an ADC initialized already
CLK  = 18
MISO = 23
MOSI = 24
CS   = 25
mcp = Adafruit_MCP3008.MCP3008(clk=CLK, cs=CS, miso=MISO, mosi=MOSI)

# Below this line is going to be kind of similar to what we want to do in moisture_sensor
ADC_CHANNEL_MOISTURE_SENSOR = 7

GPIO_PIN_1 = 16
GPIO_PIN_2 = 12

GPIO.setmode(GPIO.BCM)
GPIO.setup(GPIO_PIN_1, GPIO.OUT)
GPIO.setup(GPIO_PIN_2, GPIO.OUT)

i = 0
print('Reading MCP3008 values, press Ctrl-C to quit...')
# mtlynch: This just reads in a loop and alternates which pin has power on each iteration.
# In moisture_sensor, we'd want to read once with (pin_1 high, pin_2 low) and once with
# (pin_1 low, pin_2 high) and take the average.
while True:
    if i % 2 == 0:
        GPIO.output(GPIO_PIN_1, GPIO.LOW)
        GPIO.output(GPIO_PIN_2, GPIO.HIGH)
    else:
        GPIO.output(GPIO_PIN_1, GPIO.HIGH)
        GPIO.output(GPIO_PIN_2, GPIO.LOW)
    reading = mcp.read_adc(ADC_CHANNEL_MOISTURE_SENSOR)
    if i % 2 == 1:
        reading = 1023 - reading
    print reading
    time.sleep(0.5)
    i += 1