1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- from machine import ADC, Pin, SD, Timer
- import os
- import utime
- # Thresholds for the sensors
- LOWER_THRESHOLD = 500
- UPPER_THRESHOLD = 2500
- UPDATE_FREQ = 120 # seconds
- # File name for the data
- SENSOR_DATA = "plant_data.csv"
- # Format the time (epoch) for a better view
- def _format_time(tm_data):
- # Use a special shortcut to unpack tuple: *tm_data
- return "{0}-{1:0>2}-{2:0>2} {3:0>2}:{4:0>2}:{5:0>2}".format(*tm_data)
- class PlantMonitor:
- """
- This class reads soil moisture from one or more sensors and writes the
- data to a comma-separated value (csv) file as specified in the constructor.
- """
- # Initialization for the class (the constructor)
- def __init__(self, rtc):
- self.rtc = rtc
- # Try to access the SD card and make the new path
- try:
- sd = SD()
- os.mount(sd, '/sd')
- self.sensor_file = "/sd/{0}".format(SENSOR_DATA)
- print("INFO: Using SD card for data.")
- except:
- print("ERROR: cannot mount SD card, reverting to flash!")
- self.sensor_file = SENSOR_DATA
- print("Data filename = {0}".format(self.sensor_file))
- # Setup the dictionary for each soil moisture sensor
- adc = ADC(0)
- soil_moisture1 = {
- 'sensor': adc.channel(pin='P13', attn=3),
- 'power': Pin('P19', Pin.OUT),
- 'location': 'Green ceramic pot on top shelf',
- 'num': 1,
- }
- soil_moisture2 = {
- 'sensor': adc.channel(pin='P14', attn=3),
- 'power': Pin('P20', Pin.OUT),
- 'location': 'Fern on bottom shelf',
- 'num': 2,
- }
- # Setup a list for each sensor dictionary
- self.sensors = [soil_moisture1, soil_moisture2]
- # Setup the alarm to read the sensors
- a = Timer.Alarm(handler=self._read_sensors, s=UPDATE_FREQ,
- periodic=True)
- print("Plant Monitor class is ready...")
- # Clear the log
- def clear_log(self):
- log_file = open(self.sensor_file, 'w')
- log_file.close()
- # Get the filename we're using after the check for SD card
- def get_filename(self):
- return self.sensor_file
- # Read the sensor 10 times and average the values read
- def _get_value(self, sensor, power):
- total = 0
- # Turn power on
- power.value(1)
- for i in range (0,10):
- # Wait for sensor to power on and settle
- utime.sleep(5)
- # Read the value
- value = sensor.value()
- total += value
- # Turn sensor off
- power.value(0)
- return int(total/10)
- # Monitor the sensors, read the values and save them
- def _read_sensors(self, line):
- log_file = open(self.sensor_file, 'a')
- for sensor in self.sensors:
- # Read the data from the sensor and convert the value
- value = self._get_value(sensor['sensor'], sensor['power'])
- print("Value read: {0}".format(value))
- time_data = self.rtc.now()
- # datetime,num,value,enum,location
- log_file.write(
- "{0},{1},{2},{3},{4}\n".format(_format_time(time_data),
- sensor['num'], value,
- self._convert_value(value),
- sensor['location']))
- log_file.close()
- # Convert the raw sensor value to an enumeration
- def _convert_value(self, value):
- # If value is less than lower threshold, soil is dry else if it is greater than upper threshold, it is wet, else all is well.
- if (value <= LOWER_THRESHOLD):
- return "dry"
- elif (value >= UPPER_THRESHOLD):
- return "wet"
- return "ok"
|