Ashok Ghildiyal
Published

Smart Farming System

Smart Farming System: Implement automated irrigation & ventilation systems based on the sensor data to optimize crop growth & productivity.

IntermediateFull instructions provided3 days620

Things used in this project

Hardware components

CY8CPROTO-062-4343W
Infineon CY8CPROTO-062-4343W
×1
Infineon XENSIV PAS CO2 sensor
×1
Infineon BLDC Shield IFX007T
×1
Moisture Sensor
×1
DC motor (generic)
×2
Adapter 12 Volt
×1
Resistor 1 Kohm
×1

Software apps and online services

MicroPython
MicroPython
Arduino IDE
Arduino IDE
Thonny

Story

Read more

Code

main.py

MicroPython
from machine import I2C, Pin
from machine import ADC
from utime import sleep

import network
import secrets as s
import pasco2 as sensor

#define pin
p0 = Pin('P6_2', Pin.OUT)
p1 = Pin('P0_5', Pin.OUT)

def network_connect():
    ''' Helper function to connect to the network '''
    wlan = network.WLAN(network.STA_IF)
    if wlan.isconnected():
        print('[network-module] : Already connected')
    else:
        # Enable and connect to WLAN
        wlan.active(True)
        wlan.connect(s.ssid, s.key)
        # Wait for connection to establish
        while not wlan.isconnected():
            pass
        print('[network-module] : Connected to network')

def sensor_init():
    ''' Helper function to initialize the sensor
        Returns: co2 object if success, else -1
    '''
    bus = I2C(0)
    pasco2 = sensor.PASCO2(bus)
    init_status = pasco2.initialize()
    if init_status != 0:
        print("[co2-module] : Sensor setup failed!")
        return -1
    else:
        print("[co2-module] : Sensor setup done successfully!")
        return pasco2

def read_sensor_data(co2Obj):
    ''' Helper function to read sensor data and stream to cloud DB
        Args :   co2Obj - Sensor Object
        Returns: CO2 ppm value or -1 if not ready
    '''
    # Wait for the value to be ready
    sleep(10)
    # Get CO2 values
    co2ppm = co2Obj.get_co2_value()
    if co2ppm == -1:
        print("[co2-module] : Measurement not ready yet")
    else:
        print("[co2-module] : CO2 ppm value: ", co2ppm)
    return co2ppm

def moisture_sensor():
    # create an ADC object on ADC pin
    adc = ADC(Pin("P10_0"))
    val = adc.read_u16() / 65535
    value = 1- val
    value1 = round(value*100)
    print("Moisture of Soil", value1, "%")
    if value1 < 42:
        p1.high()
    else:
        p1.low()  
    sleep(0.5)
    return value1
def main():
    ''' Application Main '''
    network_connect()
    sleep(2)
    co2Obj = sensor_init()
    if co2Obj != -1:
        while True:
            moisture_sensor()
            # Read sensor value and stream to IoT cloud
            co2ppm = read_sensor_data(co2Obj)
            if co2ppm is not None and co2ppm < 720:
                p0.high()
            else:
                p0.low()

if __name__ == "__main__":
    main()

secrets.py

MicroPython
# Add user configuration details

ssid 	 = 'ssid_name'
key 	 = 'password'

motor.ino

Arduino
Arduino program for motor control
#include "IFX007T-Motor-Control.h"

uint8_t MotorNr1 = 0;
uint8_t MotorNr2 = 1;
uint8_t speed = 0;
int Pin1 = 7;
int Pin2 = 8;

//Create an instance of 'IFX007TMotorControl' called 'MyMotor'
IFX007TMotorControl MyMotor = IFX007TMotorControl();

void setup()
{
  pinMode(Pin1, INPUT);
  digitalWrite(Pin1, LOW);
  pinMode(Pin2, INPUT);
  digitalWrite(Pin2, LOW);
  MyMotor.begin();

}

void loop()
{
  // First Argument: Choose which Motor to drive: 0 = U, 1 = V, 2 = W
  // Second Argument: Choose how fast it should turn: a value between 0 and 255

if (digitalRead(Pin1) == HIGH){
    speed = 50;
    MyMotor.setUniDirMotorSpeed(MotorNr1, speed);
    delay(1000);
}
else if (digitalRead(Pin2) == HIGH){
  speed = 50;
  MyMotor.setUniDirMotorSpeed(MotorNr2, speed);
} 
else {
    speed = 0;
    MyMotor.setUniDirMotorSpeed(MotorNr1, speed);
    MyMotor.setUniDirMotorSpeed(MotorNr2, speed);
    delay(1000);
}
}

pasco2.py

MicroPython
# Infineon XENSIV PAS CO2 sensor driver for MicroPython

from machine import I2C
from utime import sleep, sleep_ms

# Sensor Register Address Stack
_PASCO2_REG_SENS_STS = const(0x01)  # Sensor status register address
_PASCO2_REG_MEAS_RATE_H = const(0x02)  # Measurement period MSB configuration register address
_PASCO2_REG_MEAS_CFG = const(0x04)  # Measurement mode configuration register address
_PASCO2_REG_CO2PPM_H = const(0x05)  # CO2 concentration result MSB register address
_PASCO2_REG_MEAS_STS = const(0x07)  # Measurement status register address
_PASCO2_REG_SENS_RST = const(0x10)  # Soft reset register address
_PASCO2_REG_PROD_ID = const(0x00)  # Product and revision ID register address

# Error codes
_PASCO2_SUCCESS = 0
_PASCO2_ERROR = -1

addr = 0
mask = 1


class PASCO2:
    """IFX - XENSIV PAS CO2 sensor driver"""

    # RegAddr, Mask, <Later extend with register access type, bit position etc.>
    regMap = {
        "REG_SENS_STS_BITF_SENS_RDY": [_PASCO2_REG_SENS_STS, 0x80],  # Sensor status bit
        "REG_MEAS_CFG_BITF_OP_MODE": [_PASCO2_REG_MEAS_CFG, 0x03],  # Operation Mode type bit
        "REG_MEAS_STS_BITF_DATA_RDY": [_PASCO2_REG_MEAS_STS, 0x10],  # Data ready status bit
        "REG_CO2PPM_H_BITF_CO2_PPM_H": [_PASCO2_REG_CO2PPM_H, 0xFF],  # Stored CO2 value bit
        "REG_PROD_ID_BITF_PROD": [_PASCO2_REG_PROD_ID, 0xE0],  # Product id bit
        "REG_PROD_ID_BITF_REV": [_PASCO2_REG_PROD_ID, 0x1F],  # Revision id bit
    }

    def __init__(self, bus, measInterval=10, sensorAddr=0x28):
        """ " Intialize the sensor and required dependencies"""
        self.bus = bus
        self.sensorAddr = sensorAddr
        self.measInterval = measInterval
        self.softResetCode = b"\xa3"

    def _read_reg(self, regAddr, bytesToRead=1):
        """Internal function to read data from the sensor register and returns it raw"""
        readVal = self.bus.readfrom_mem(self.sensorAddr, regAddr, bytesToRead)
        return readVal

    def _write_reg(self, regAddr, writeData):
        """Internal function to write data to sensor register"""
        self.bus.writeto_mem(self.sensorAddr, regAddr, writeData)

    def _is_sensor_ready(self):
        """Helper function to check the sensor status"""
        reg = self.regMap["REG_SENS_STS_BITF_SENS_RDY"]
        return self._read_reg(reg[addr])[0] & reg[mask]

    def _soft_reset(self):
        """Helper function to perform soft reset of the sensor"""
        self._write_reg(_PASCO2_REG_SENS_RST, self.softResetCode)

    def _set_mode(self, mode):
        """Helper function to set the mode of sensor. Currently supported modes:
        1. Idle
        2. Continuous
        """
        if mode == "idle":
            modeVal = 0x00
        if mode == "continuous":
            modeVal = 0x02

        reg = self.regMap["REG_MEAS_CFG_BITF_OP_MODE"]
        readData = self._read_reg(reg[addr])[0]
        writeData = bytes([(readData & ~(reg[mask])) | modeVal])
        self._write_reg(_PASCO2_REG_MEAS_CFG, writeData)

    def initialize(self):
        """Public function to initialize the sensor"""
        try:
            # wait for sensor to be ready
            sensor_ready = self._is_sensor_ready()
            while not sensor_ready:
                sleep(1)
                sensor_ready = self._is_sensor_ready()

            # soft reset sensor register
            self._soft_reset()
            sleep_ms(800)

            # set measure rate
            buf = bytes([(self.measInterval >> 8) & 0xFF, self.measInterval & 0xFF])
            self._write_reg(_PASCO2_REG_MEAS_RATE_H, buf)

            # reset operation mode to idle mode
            self._set_mode("idle")

            # start continuous mode
            self._set_mode("continuous")

            return _PASCO2_SUCCESS

        except:
            return _PASCO2_ERROR

    def get_co2_value(self):
        """Public function to get the CO2 value"""
        while True:
            try:
                # get meas status
                reg = self.regMap["REG_MEAS_STS_BITF_DATA_RDY"]
                readStatus = self._read_reg(reg[addr])
                data_ready = readStatus[0] & reg[mask]

                if data_ready:
                    # get CO2 value
                    reg = self.regMap["REG_CO2PPM_H_BITF_CO2_PPM_H"]
                    readVal = self._read_reg(reg[addr], 2)
                    co2_value = (readVal[0] << 8) | readVal[1]
                    return co2_value
            except:
                return _PASCO2_ERROR

    def get_prod_id(self):
        """Public function to get the sensor product id"""
        try:
            reg = self.regMap["REG_PROD_ID_BITF_PROD"]
            readID = (self._read_reg(reg[addr])[0] & 0xE0) >> 5
            return readID

        except:
            return _PASCO2_ERROR

    def get_rev_id(self):
        """Public function to get the sensor revision id"""
        try:
            reg = self.regMap["REG_PROD_ID_BITF_REV"]
            readID = (self._read_reg(reg[addr])[0] & 0x1F) >> 0
            return readID

        except:
            return _PASCO2_ERROR

Credits

Ashok Ghildiyal

Ashok Ghildiyal

1 project • 0 followers
Having working experience in different boards like Arduino, ESP32, Infineon PSoC6 & XMC and various sensors PAS CO2, Spectral, Pressure etc.

Comments