ludollaooJulie FRAYSSEThéo Germain
Published

2PA2S (PolyPlants Advanded Surveillance System)

Autonomous plant monitoring system, follows the parameters of your plants and transmits them on the Ubidots platform via the Sigfox network

AdvancedFull instructions providedOver 5 days250
2PA2S (PolyPlants Advanded Surveillance System)

Things used in this project

Hardware components

Nucleo STM32L432KC
×1
DHT22 Temperature Sensor
DHT22 Temperature Sensor
×1
Adafruit Waterproof DS18B20 Digital temperature sensor
Adafruit Waterproof DS18B20 Digital temperature sensor
×1
Gravity: Analog Capacitive Soil Moisture Sensor- Corrosion Resistant
DFRobot Gravity: Analog Capacitive Soil Moisture Sensor- Corrosion Resistant
×1
Adafruit TCS34725
×1
Wisol BRKWS01 + antenna + 1 year Sigfox subscription
×1
Adafruit Monochrome 0.96" 128x64 OLED graphic display
×1
Pololu - USB Micro-B Connector Breakout Board
×1
SparkFun Resistor 1M Ohm
×2
Breadboard (generic)
Breadboard (generic)
×1
3.7 V LiPo Battery 1050mAh
×1
Solar Panel 2W
×1
Resistor 100k ohm
Resistor 100k ohm
×1
Resistor 1M ohm
Resistor 1M ohm
×1
MCP73831 Single Cell, Li-Ion/Li-Polymer Charge Management Controller
Microchip MCP73831 Single Cell, Li-Ion/Li-Polymer Charge Management Controller
×1
Pololu S7V8F3
×1
Resistor 2.21k ohm
Resistor 2.21k ohm
×1
Capacitor, 4.7 µF
Capacitor, 4.7 µF
×1
Small Signal Diode, Switching Diode
Small Signal Diode, Switching Diode
×1

Software apps and online services

Arm Mbed OS Mbed
Backend Sigfox
Ubidots
Ubidots
KiCad
KiCad

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
10 Pc. Jumper Wire Kit, 5 cm Long
10 Pc. Jumper Wire Kit, 5 cm Long

Story

Read more

Custom parts and enclosures

PCB supply stage

Electric Scheme supply stage

Code

main.cc

C/C++
Main code of 2PA2S project
#include "main.hh"

int main(){
    #ifdef DEEPSLEEP
    #endif

    #ifdef INTERRUPTEUR
    interrupteur = 1;
    #endif
    
    #ifdef OLED
    bouton.rise(interruption_bouton);
    initOLED();
    #endif
        
    while(1) {
        if(flag_readData)
            readData();
        flag_readData = true;
        #ifndef DEEPSLEEP
        wait(DUREE_OFF);
        #endif
        #ifdef DEEPSLEEP
        if(oled_on){
            wait(DUREE_ECRAN_ON);
            turnOffScreen();
            flag_readData = false;
        }
        else{
            WakeUp::set_ms(DUREE_OFF*1000);
            deepsleep();
        }
      #endif
    }
}

#ifdef AIR_PARAMETERS_DHT22
void air_temp_hum(){
    int err;
    wait(1);
    do{
        err = dht_sensor.readData();
        wait(1);
    }while(err != 0);
    temperature_air = dht_sensor.ReadTemperature(CELCIUS);
    humidity_air = dht_sensor.ReadHumidity();
}
#endif

#ifdef FLOOR_TEMPERATURE
void temp_sol()
{
    int result = 0;
    ds1820.begin();
    // start temperature conversion from analog to digital
    ds1820.startConversion();   
    // let DS1820 complete the temperature conversion
    wait(1.0);                  
    // read temperature from DS1820 and perform cyclic redundancy check      (CRC)
    result = ds1820.read(temperature_sol); 
    #ifdef DEBUG
    switch (result) {
        case 0:                 // no errors -> 'temp' contains the value of measured temperature
            pc.printf("temp = %3.1f C\r\n", temperature_sol);
            break;

        case 1:                 // no sensor present -> 'temp' is not updated
            pc.printf("no sensor present\n\r");
            break;

        case 2:                 // CRC error -> 'temp' is not updated
            pc.printf("CRC error\r\n");
    }
    #endif
    
}
#endif

#ifdef FLOOR_HUMIDITY
int fct_humidity_sol(void)
{
    float val_min = 0.377;
    float val_max = 0.772;
    float mesure, mesure_etalonnee;
    // Lecture of the raw value
    mesure = capteur_humidity_sol.read();
    // Raw value converted to a percentage
    mesure_etalonnee = (1-((mesure - val_min)/(val_max - val_min)))*100;
    #ifdef DEBUG
    pc.printf("hum sol: %d\n\r", (int) mesure_etalonnee);
    #endif
    return (int) mesure_etalonnee;
}
#endif

#ifdef RGB
void fct_RGB(void)
{
    int somme;
    uint16_t clear, red, green, blue;
    if (!RGBsens.begin())
    {
        #ifdef DEBUG
        pc.printf("No TCS34725 found ... check your connections");
        #endif
        //while (1); // halt!
    }
        RGBsens.getRawData(&red, &green, &blue, &clear);
        somme = red + green + blue;
        pr = red*100/somme;
        pg = green*100/somme;
        pb = blue*100/somme;
        lum = (unsigned short) RGBsens.calculateLux(red, green, blue);
        #ifdef DEBUG
        pc.printf("luminosite : %d \n\r", lum);
        pc.printf("rouge:%d vert:%d bleu:%d \n\r", pr, pg, pb);
        #endif
}
#endif

#ifdef SIGFOX
void sendDataSigfox(void){
    #ifdef DEBUG
    pc.printf("Sending Data to Sigfox \n\r");
    #endif
    short tempSol_short, tempAir_short;
    tempSol_short = (short)(temperature_sol*10);
    tempAir_short = (short)(temperature_air*10);

    wisol.printf("AT$SF=%04x%02x%04x%02x%04x%02x%02x%02x%02x\r\n",tempSol_short, humidity_sol, tempAir_short, humidity_air, lum, pr, pg, pb, vBat);
}
#endif

#ifdef OLED
void oledData(void){
    #ifdef DEBUG
    pc.printf("Displaying Data\r\n");
    #endif
    
    if(!oled_on){
        oled.wake();
        oled.clear();
        oled_on = 1;
    }
    oled.clear();
    oled.printf("AIR T : %.1f", temperature_air);
    oled.printf("\n\r");
    oled.printf("AIR H : %d", humidity_air);
    oled.printf("\n\r\n\r");
    oled.printf("FLOOR T : %.1f", temperature_sol);
    oled.printf("\n\r");
    oled.printf("FLOOR H : %d", humidity_sol);
    oled.printf("\n\r\n\r");
    oled.printf("Light : %d", lum);
    oled.printf("\n\r");
    oled.printf("R %d G %d B %d", pr, pg, pb);
    oled.update();
}
#endif

void readData(void){
    #ifdef INTERRUPTEUR
    interrupteur = 1;
    wait_ms(100);
    RGBsens.begin();
    wait_ms(100);
    #endif
    #ifdef DEBUG
    pc.printf("Reading Data\n\r");
    #endif
    #ifdef FLOOR_TEMPERATURE
    temp_sol();
    #endif
    #ifdef FLOOR_HUMIDITY
    humidity_sol = fct_humidity_sol();
    #endif
    #ifdef AIR_PARAMETERS_DHT22
    air_temp_hum();
    #endif
    #ifdef DEBUG
    printf("hum air: %d\n\r", humidity_air);   
    printf("temp air: %.1f\n\r", temperature_air);  
    #endif
    #ifdef RGB  
    fct_RGB();
    #endif
    #ifdef BATTERY_LVL
    readBatteryLvl();
    #endif
    #ifdef SIGFOX
    sendDataSigfox();
    #endif
    #ifdef OLED
    if(oled_on)
        oledData();
    #endif
    #ifdef INTERRUPTEUR
    // It takes time for the sigfox module to send data
    wait(8);
    interrupteur = 0;
    #endif
}

void interruption_bouton(){
    bouton.disable_irq();
    #ifdef DEBUG
    pc.printf("Button interrupt\r\n");
    #endif
    #ifdef OLED
    if(!oled_on){
        oledData();
    }
    #endif
    bouton.enable_irq();
}

#ifdef OLED
void turnOffScreen(void){
    #ifdef DEBUG
    pc.printf("Turning off screen \n\r");
    #endif
    oled_on = 0;
    oled.sleep();
}
#endif

#ifdef OLED
void initOLED(void){
    oled.on();
    oled.initialise();
    oled.clear();
    oled.set_contrast(255);
    oled.set_font(bold_font, 8);
    oled.printf("================");
    oled.printf("\n\r");
    oled.printf("      2PA2S");
    oled.printf("\n\r\n\r");
    oled.printf("FRAYSSE GERMAIN");
    oled.printf("\n\r\n\r");
    oled.printf("   DUPLESSIS");
    oled.printf("\n\r");
    oled.printf("================");
    oled.update();
    wait(10);
    oled.clear();
    oled.update();
    oled.sleep();
}
#endif

void readBatteryLvl(void){
    float calcVbat = 0;
    int batIn = 0;
    float ain = battery.read();
    for(int i = 0; i < NB_MESURES; i++){
        batIn = 100*ain;
        calcVbat += ((float)(batIn - BATTERIE_MIN)/(float)(BATTERIE_MAX - BATTERIE_MIN))*100;
    }
    vBat = (char)(calcVbat/NB_MESURES);
    if(vBat > 100)
        vBat = 100;
    #ifdef DEBUG
    pc.printf("batIn = %d\n\r", batIn);
    pc.printf("calcVbat = %d\n\r", calcVbat);
    pc.printf("vBat = %d\n\r", vBat);
    #endif
}

main.hh

C/C++
Declaration of necessary objects
#pragma once

#include "define.hh"
#include "mbed.h"
#include "DS1820.h"
#include "DHT.h"
#include "Adafruit_TCS34725.h"
#include "ssd1306.h"
#include "standard_font.h"
#include "bold_font.h"
#include "WakeUp.h"

#define DUREE_OFF 900       // Duration (in seconds) between two measurements + 10 seconds for the sigfox module and sensors in the code
#define DUREE_ECRAN_ON  10    // Duration in seconds of screen awakening

#define NB_MESURES 100

#define BATTERIE_MIN 30
#define BATTERIE_MAX 39


#ifdef INTERRUPTEUR
DigitalOut interrupteur(D11);
#endif

#ifdef DEBUG
Serial pc(SERIAL_TX, SERIAL_RX);
#endif

#ifdef SIGFOX
Serial wisol(D1,D0);
#endif

I2C i2c_2(D12,A6);

#ifdef OLED
// D6 D9 D10 A4 D2
SSD1306 oled(PB_1, PA_8, PA_11, PA_5, PA_12);
#endif

#ifdef BATTERY_LVL
AnalogIn battery(A1);
#endif

InterruptIn bouton(A2);

// Capteurs
#ifdef FLOOR_TEMPERATURE
DS1820 ds1820(A3);
#endif

#ifdef FLOOR_HUMIDITY
AnalogIn capteur_humidity_sol(A0);
#endif


#ifdef RGB
Adafruit_TCS34725 RGBsens = Adafruit_TCS34725(&i2c_2, TCS34725_INTEGRATIONTIME_154MS, TCS34725_GAIN_1X);
#endif

#ifdef AIR_PARAMETERS_DHT22
DHT dht_sensor(D5, 22);
#endif

// Functions
void    air_temp_hum(void);
void    temp_sol(void);
int     fct_humidity_sol(void);
void    fct_RGB(void);
void    sendDataSigfox(void);
void    oledData(void);
void    readData(void);
void    interruption_bouton(void);
void    turnOffScreen(void);
void    initOLED(void);
void    readBatteryLvl(void);


// Global variables
bool            oled_on = 0;             // flag OLED
float           temperature_sol;
unsigned char   humidity_sol;
float           temperature_air;
unsigned char   humidity_air;
unsigned char   pr, pg, pb;
unsigned short  lum;
char            vBat;
bool            flag_readData = true;

define.hh

C/C++
From this part of the code, you can comment/uncomment not to use all the features.
#pragma once

//#define DEBUG
#define SIGFOX
#define FLOOR_TEMPERATURE
#define FLOOR_HUMIDITY
#define RGB
#define OLED
#define INTERRUPTEUR
#define AIR_PARAMETERS_DHT22
#define DEEPSLEEP
#define BATTERY_LVL

Credits

ludollaoo

ludollaoo

1 project • 1 follower
Julie FRAYSSE

Julie FRAYSSE

1 project • 2 followers
Théo Germain

Théo Germain

1 project • 1 follower

Comments