Thomas BroussardJeanne BaumierAnaïs Auberval
Published © CC BY-NC-SA

PlantSigfox Monitoring

Retrieving air/soil moisture & temperature and brightness (and RGB rays). It also sends the localization, and so gives weather forecasts.

IntermediateFull instructions providedOver 1 day5,489
PlantSigfox Monitoring

Things used in this project

Hardware components

STM32 Nucleo STM32 L432KC
×1
Sigfox Breakout TD1208R
×1
DHT22 Temperature Sensor
DHT22 Temperature Sensor
×1
Seeed Studio Grove Moisture Sensor
×1
Breadboard (generic)
Breadboard (generic)
×1
Adafruit TSL2561 Lux Sensor
×1
Adafruit TCS34725 RGB Color Sensor
×1
Seeed Studio Grove DS18B20 Temperature Sensor
×1
Adafruit Monochrome 0.96" 128x64 OLED graphic display
×1
Pololu - USB Micro-B Connector Breakout Board
×1
DC-005 5.5 * 2.1 mm Power Jack Socket
×1
SparkFun Resistor 1M Ohm
×2
Female/Female Jumper Wires
Female/Female Jumper Wires
×1
SparkFun Male Header Pins
×1
SparkFun Female Header Pins
×2
Seeed Studio Grove - Universal 4 pin connector
×1
Seeed Studio LiPo Rider Pro
×1
3.7 V LiPo Battery
×1
Solar Panel 2W
×1

Software apps and online services

BlueMix
IBM BlueMix
Fusion 360
Autodesk Fusion 360
Autodesk EAGLE
Autodesk EAGLE
Arm OS Mbed
Node-RED on IBM Cloud
Node-RED on IBM Cloud
Backend Sigfox

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)
Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Custom parts and enclosures

CAD - Solar Powered Battery Enclosure

CAD files of Battery Enclosure, from Fusion360

CAD - PlantSigfox Enclosure

CAD files of PlantSigfox Enclosure, from fusion360

PlantSigfox Enclosure

Test

Solar Powered Battery Enclosure

Monitoring Plant Program

Main program for STM32L432KC

Printed Circuit Board Gerber Files

Files to create the Printed Board Circuit
Developed on EAGLE Software

Schematics

Overall schematic

Overall scheme of the system

Code

main.cpp

C/C++
Main part of the code
Available on https://os.mbed.com/teams/Radiopotache/code/plant-monitoring/
/****************************************************************************************************************************************************
Titre : Full_Sensors
Auteur : Jeanne Baumier, Anas Auberval et Thomas Broussard
Date : 29/11/17
Plateforme : STM32L432KC
Projet : PlantSigfox - Monitoring de plante  distance 
--------------------------------
Description : 
Ce programme permet d'effectuer des relves des diffrents capteurs mtorologiques toute les T secondes. 
Les donnes reues par les capteurs sont traites puis transmises via un module Sigfox TD1208R sur un serveur sigfox (https://backend.sigfox.com)
puis rediriges vers un dashboard (https://plantsigfox.eu-gb.mybluemix.net/ui)

L'ensemble des composants peuvent tre configurs dans le fichier Mapping.h,  savoir : 
- l'activation ou la dsactivation d'un composant
- les paramtres d'talonnage et de mesure des capteurs
- les broches programmes pour le microcontrleur

****************************************************************************************************************************************************/

// ------------------------------------------------------------------------------
//                                  LIBRAIRIES
// ------------------------------------------------------------------------------
#include "mbed.h"       
#include "DS18B20.h"            // OneWire Temperature
#include "DHT.h"                // DHT22
#include "TSL2561.h"            // Lux
#include "TCS34725.h"           // RGB
#include "Adafruit_SSD1306.h"   // OLED
#include "Mapping.h"
#include "WakeUp.h"             // Low Power Energy
// ------------------------------------------------------------------------------
//                          CLASSES ET STRUCTURES
// ------------------------------------------------------------------------------

#ifdef OLED_ACTIF
    // sub-class SPI : 
    // Caractristiques par dfaut de la communication SPI avec le SSD1306
    class SPIPreInit : public SPI
    {
    public:
        SPIPreInit(PinName mosi, PinName miso, PinName clk) : SPI(mosi,miso,clk)
        {
            format(8,3); 
            frequency(2000000);
        };
    };
#endif

// ------------------------------------------------------------------------------
//                    INITIALISATION DES GPIO DU MICROCONTROLEUR
// ------------------------------------------------------------------------------
#ifdef DEBUG_UART_ACTIF
    // Liaison UART pour Debug
    Serial pc(USBTX, USBRX);
#endif 

#ifdef SIGFOX_ACTIF
    // Liaison UART Sigfox
    Serial Sigfox(SIGFOX_RX, SIGFOX_TX); 
#endif

#ifdef OLED_ACTIF
    // Ecran OLED (communication SPI)
    SPIPreInit gSpi(MOSI,MISO,CLK);
    Adafruit_SSD1306_Spi OLED(gSpi,DC,RST_SPI,CS,HAUTEUR_OLED,LARGEUR_OLED);
#endif

#ifdef GROVE_MOIST_ACTIF
    // Capteur d'humidit du sol Grove
    AnalogIn Capteur_Moisture(GROVE_MOIST_PIN);
#endif

#ifdef ONEWIRE_TEMP_ACTIF
    //Capteur de Temprature du sol One Wire CRC
    DS18B20 Temperature(true, true, false, ONEWIRE_TEMP_PIN); // Temperature( crcOn, useAddress, parasitic, mbed pin )
#endif

#ifdef DHT_ACTIF
    //Capteur Temprature/Humidit de l'air Grove DHT22
    DHT sensor(DHT_PIN,SEN51035P); // Use the SEN11301P sensor
#endif

#ifdef I2C_ACTIF
    I2C          i2c(I2C_SDA,I2C_SCL);    // SDA, SCL
    //Capteur de Luminosit et RGB Adafruit (tous les deux connects au bus i2c)
    #ifdef LUX_ACTIF
        TSL2561      lum(i2c);  
    #endif
    #ifdef RGB_ACTIF  
        TCS34725     rgb(i2c);   
    #endif 
#endif

#ifdef BATTERIE_ACTIF
    //Batterie
    AnalogIn Batterie(BATTERIE_PIN);
#endif


// ------------------------------------------------------------------------------
//                           PROGRAMME PRINCIPAL
// ------------------------------------------------------------------------------
int main()
{
/*********************************
         Variables locales
*********************************/    
// Divers
int i;
int line = 0; 

// Variables permettant de stocker les donnes  relever
float VBAT = 0;
float HumidSol = 0; 
float TempSol  = 0;
float TempAir  = 0;
float HumidAir = 0;
float Lumiere  = 0;
float Niveau_Batterie = 101;
int   Clear    = 0;
int   Red      = 0;
int   Green    = 0;
int   Blue     = 0; 

wait(2);
/*********************************
         Initialisation
*********************************/   
#ifdef BATTERIE_ACTIF
    float BATTERIE_MIN = 33;
    float BATTERIE_MAX = 42; 
#endif

#ifdef OLED_ACTIF
    // Initialisation de l'cran 
    OLED.fillRect(0,0,LARGEUR_OLED,HAUTEUR_OLED,BLACK); 
    OLED.setTextCursor(0,10); OLED.printf("==================="); 
    OLED.setTextCursor(0,20); OLED.printf("    PlantSigfox    ");  
    OLED.setTextCursor(0,30); OLED.printf("   Projet ei2i-4   ");  
    OLED.setTextCursor(0,40); OLED.printf("Jeanne Anais Thomas");
    OLED.setTextCursor(0,50); OLED.printf("==================="); 
    OLED.display();
#endif

#ifdef DEBUG_UART_ACTIF
    // Initialisation des communication UART
    pc.format(8,SerialBase::None,1);
    pc.baud(9600);
#endif

#ifdef SIGFOX_ACTIF
    Sigfox.format(8,SerialBase::None,1);
    Sigfox.baud(9600);
#endif

#ifdef ONEWIRE_TEMP_ACTIF
    // Initialisation du capteur de temprature
    while (!Temperature.initialize());    // on attend que le capteur soit initialis avant de pouvoir effectuer des mesures
#endif

#ifdef RGB_ACTIF
    // Initialisation du TCS34725
    rgb.init_RGB();
#endif

// Attente de 5 secondes avant le dmarrage du programme
wait(5);


/*********************************
         Boucle principale
*********************************/  
while(1) 
{   
    /*********************************
              Mesure des ADC
    *********************************/  

    // On effectue une moyenne sur une quantit de relevs ( pour avoir une mesure fiable )
    #if defined(GROVE_MOIST_ACTIF) || defined(BATTERIE_ACTIF)
        Niveau_Batterie = 0;    
        HumidSol = 0;
        
        for (i=0; i < NB_MESURES; i++)
        {
            #ifdef BATTERIE_ACTIF
                // Batterie 
                VBAT = 100 * Batterie; // Lecture de l'entre ADC
                Niveau_Batterie += ((VBAT - BATTERIE_MIN) / (BATTERIE_MAX - BATTERIE_MIN)) * 100 ; 
            #endif
            
            #ifdef GROVE_MOIST_ACTIF
                // Humidit du Sol (Grove)
                HumidSol += ((Capteur_Moisture  - GROVE_MOIST_MIN) / (GROVE_MOIST_MAX - GROVE_MOIST_MIN)) * 100;
            #endif
            
            wait(TEMPS_MESURE);
        }
    #endif
    
    // Moyennage du rsultat
    #ifdef GROVE_MOIST_ACTIF
        HumidSol /= NB_MESURES; 
    #endif
    
    #ifdef BATTERIE_ACTIF
        Niveau_Batterie /= NB_MESURES;
        // Limitation de la batterie
        if (Niveau_Batterie >100) Niveau_Batterie = 100;
        // Si la batterie est dconnecte, on doit le faire remarquer (code : 101)
        if (Niveau_Batterie < 0) Niveau_Batterie = 101;
    #endif
    
    /*********************************
        Temprature du sol (OneWIRE)
    *********************************/  
    #ifdef ONEWIRE_TEMP_ACTIF
        Temperature.setResolution(twelveBit); // Le choix de la rsolution se fait avant le relev des donnes
        TempSol = Temperature.readTemperature(); // relev de donnes 
    #endif
    
    /*********************************
     Temprature/Humidit Air (Grove)
    *********************************/      
    #ifdef DHT_ACTIF  
        int err;
        wait(1); // wait 1 second for device stable status
        do
        {
            err = sensor.readData();
            wait(1);
        }
        while (err != 0);
        if (err == 0)
        {
            TempAir = sensor.ReadTemperature(CELCIUS);
            HumidAir = sensor.ReadHumidity();
        }
    #endif
    
    /*********************************
          Luminosit / RGB(Adafruit)
    *********************************/  
    #ifdef LUX_ACTIF
        Lumiere = COEF_LUX * lum.lux();
    #endif
    
    #ifdef RGB_ACTIF
        rgb.GET_RGB(&Clear,&Red,&Green,&Blue);
        #ifdef RGB_1_OCTET
            // On rduit la prcision des donnes brutes en divisant par 256 pour n'avoir qu'un octet seulement
            Clear   /= 256;
            Red     /= 256;
            Green   /= 256;
            Blue    /= 256;
        #endif
    #endif
    
    /*********************************
            Affichage OLED
    *********************************/  
    #ifdef OLED_ACTIF
        // OLED Reset
        OLED.fillRect(0,0,LARGEUR_OLED,HAUTEUR_OLED,BLACK);
        line = 0;
        
        // Sol : 
        #if defined(GROVE_MOIST_ACTIF) && defined(ONEWIRE_TEMP_ACTIF)
            OLED.setTextCursor(0,line);
            OLED.printf("Sol = %d \tC // %d \t/\t",(int)TempSol,(int)HumidSol);
            line +=10;
        #endif
        
        // Air :
        #ifdef DHT_ACTIF
            OLED.setTextCursor(0,line);
            OLED.printf("Air = %d \tC // %d \t/\t",(int)TempAir,(int)HumidAir);
            line +=10;
        #endif
        
        // Intensit lumineuse
        #if defined(LUX_ACTIF) && defined(I2C_ACTIF) 
            OLED.setTextCursor(0,line);
            OLED.printf("Light = %d", (int)Lumiere);
            OLED.setTextCursor(110,line);           
            OLED.printf("Lux");
            line +=10;
        #endif
        
        // Couleurs RGB
        #if defined(RGB_ACTIF) && defined(I2C_ACTIF) 
            OLED.setTextCursor(0,line);
            OLED.printf("RGB = %d/%d/%d",Red,Green,Blue);
            line +=10;   
            OLED.setTextCursor(0,line);
            OLED.printf("Clear = %d",Clear);
            line +=10;     
        #endif
        
        // Batterie
        #ifdef BATTERIE_ACTIF
            OLED.setTextCursor(0,line);
            if (((int)Niveau_Batterie >= 0) && ((int)Niveau_Batterie <= 100)) 
            {
                OLED.printf("Batterie : %d", (int)Niveau_Batterie);
                OLED.setTextCursor(110,line);
                OLED.printf("\t/\t");
            }
            else 
            {
                OLED.printf("Prise Secteur");
            }
        #endif
        
        // Display
        OLED.display();
    #endif
    
    /****************************************************************************
         Envoi des donnes via le module Sigfox (dpend du format des donnes)
    *****************************************************************************/
    #ifdef SIGFOX_ACTIF
        #if defined(RGB_2_OCTET) && !defined(RGB_1_OCTET)
            // trame 1 : [TAir , Hum Air , TSol , Hum Sol , Lumiere , Batterie]
            Sigfox.printf("AT$SS=%02x %02x %02x %02x %04x %02x \r\n",(int)TempAir,(int)HumidAir,(int)TempSol, (int)HumidSol, (int)Lumiere,(int)Niveau_Batterie);
            // trame 2 : [Clear, Red, Green, Blue]
            Sigfox.printf("AT$SS=%04x %04x %04x %04x \r\n",Clear, Red, Green, Blue);
        #endif
        
        #if defined(RGB_1_OCTET) && !defined(RGB_2_OCTET)
            // trame : [TAir , Hum Air , TSol , Hum Sol , Lumiere , Batterie, Clear, Red, Green, Blue]
            Sigfox.printf("AT$SS=%02x %02x %02x %02x %04x %02x %02x %02x %02x %02x \r\n",(int)TempAir,(int)HumidAir,(int)TempSol, (int)HumidSol, (int)Lumiere,(int)Niveau_Batterie,Clear, Red, Green, Blue);
        #endif
    #endif
    
    // Envoi des donnes sur le debug UART (optionnel)
    #ifdef DEBUG_UART_ACTIF
        #if defined(RGB_2_OCTET) && !defined(RGB_1_OCTET)
            // trame 1 : [TAir , Hum Air , TSol , Hum Sol , Lumiere , Batterie]
            pc.printf("AT$SS=%02x %02x %02x %02x %04x %02x \r\n",(int)TempAir,(int)HumidAir,(int)TempSol, (int)HumidSol, (int)Lumiere,(int)Niveau_Batterie);
            // trame 2 : [Clear, Red, Green, Blue]
            pc.printf("AT$SS=%04x %04x %04x %04x \r\n",Clear, Red, Green, Blue);
        #endif
        
        #if defined(RGB_1_OCTET) && !defined(RGB_2_OCTET)
            // trame : [TAir , Hum Air , TSol , Hum Sol , Lumiere , Batterie, Clear, Red, Green, Blue]
            pc.printf("AT$SS=%02x %02x %02x %02x %04x %02x %02x %02x %02x %02x \r\n",(int)TempAir,(int)HumidAir,(int)TempSol, (int)HumidSol, (int)Lumiere,(int)Niveau_Batterie,Clear, Red, Green, Blue);
        #endif
    #endif
    
    
    /*********************************
        Mise en veille de l'appareil
    *********************************/  
    #if defined(OLED_ACTIF) && defined(OLED_VEILLE)
        // Test : teindre l'cran au bout d'un temps donn
        wait (DUREE_AFFICHAGE);
        OLED.fillRect(0,0,LARGEUR_OLED,HAUTEUR_OLED,BLACK);
        OLED.display();
          
        WakeUp::set_ms((TEMPS_RELEVE-DUREE_AFFICHAGE)* 1000);
        deepsleep();
    #else
        WakeUp::set_ms(TEMPS_RELEVE * 1000);
        deepsleep();
    #endif
    
    /***********************************************************************************
            On attend le rveil de l'appareil pour excuter le prochain relev
    ***********************************************************************************/ 
   }
}


void my_wakeup()
{
}

Mapping.h

C/C++
Use this code to configure the components

Also available on https://os.mbed.com/teams/Radiopotache/code/plant-monitoring/
/****************************************************************************************************************************************************
Titre : Mapping.h
Auteur : Jeanne Baumier, Anas Auberval et Thomas Broussard
Date : 29/11/17
Plateforme : STM32L432KC
Projet : PlantSigfox - Monitoring de plante  distance 
--------------------------------
Description : 
Configuration du programme principal : 
- activation ou dsactivation des composants
- paramtres d'talonnage et de mesure des capteurs
- slection des broches pour le microcontrleur
****************************************************************************************************************************************************/

#ifndef __MAPPING_H__
#define __MAPPING_H__

    // ##############################################################################
    //                         DEFINITION DES COMPOSANTS A UTILISER
    // ##############################################################################
    // Utilisation du composant (decommenter pour activer le composant)  
    // Composants gnraux (affichage, communication...)
    #define OLED_ACTIF
    #define SIGFOX_ACTIF
    #define I2C_ACTIF
    //#define DEBUG_UART_ACTIF
    
    // Capteurs / Monitoring
    #define DHT_ACTIF
    #define GROVE_MOIST_ACTIF
    #define ONEWIRE_TEMP_ACTIF
    #define LUX_ACTIF
    #define RGB_ACTIF
    #define BATTERIE_ACTIF
    
    // ##############################################################################
    //                   CONFIGURATION ET MAPPING DE LA CARTE STM32L432KC
    // ##############################################################################
    
    // ------------------------------------------------------------------------------
    // Ecran OLED
    // Reference : OLED 0.96" (Adafruit)
    // ------------------------------------------------------------------------------
    
    // Mise en veille de l'cran (commenter pour laisser l'ecran actif tout le temps)
    #define OLED_VEILLE
    
    // Dimensions de l'ecran (pixels)
    #define LARGEUR_OLED       128
    #define HAUTEUR_OLED       64
    
    // Mapping
    #define MISO                NC
    #define MOSI                D2
    #define CLK                 A1
    #define DC                  D9  
    #define RST_SPI             D10
    #define CS                  D11
    
    // ------------------------------------------------------------------------------
    // Nom :  Capteur Luminosite et RGB
    // Reference : TSL2561 et TCS34725 (Adafruit)
    // Communication : i2c
    // ------------------------------------------------------------------------------
    
    // Etalonnage du capteur de luminosite
    #define COEF_LUX            25
    
    // Precision du capteur RGB en octets (decommenter celui a utiliser)
    // il faut oblitagoirement en definir un seul des deux pour utiliser le RGB
    #define RGB_1_OCTET
    //#define RGB_2_OCTET
    
    // Mapping i2c
    #define I2C_SDA             D4
    #define I2C_SCL             D5
    
    // ------------------------------------------------------------------------------
    // Capteur d'Humidite/Temperature de l'air
    // Reference : DHT22 (Seeed)
    // ------------------------------------------------------------------------------
    
    // Mapping
    #define DHT_PIN             A0
    
    // ------------------------------------------------------------------------------
    // Capteur d'Humidite du Sol
    // Reference : Moisture Sensor (Grove)
    // ------------------------------------------------------------------------------
    
    // Etalonnage du capteur
    #define GROVE_MOIST_MAX     0.55
    #define GROVE_MOIST_MIN     0
    
    // Mapping
    #define GROVE_MOIST_PIN     A3
    
    // ------------------------------------------------------------------------------
    // Capteur de Temperature du Sol 
    // Reference : One Wire CRC
    // ------------------------------------------------------------------------------
    
    // Mapping
    #define ONEWIRE_TEMP_PIN    A2
    
    // ------------------------------------------------------------------------------
    // Module Sigfox
    // Reference :  TD1208 (SnootLab)
    // ------------------------------------------------------------------------------
   
    // Mapping
    #define SIGFOX_RX           D1
    #define SIGFOX_TX           D0
    
    // ------------------------------------------------------------------------------
    // Batterie
    // ------------------------------------------------------------------------------
    // Etalonnage : dfini dans le programme principal
     
    // Mapping
    #define BATTERIE_PIN        A6   
       
    // ------------------------------------------------------------------------------
    // Mesures realisees par les ADC
    // ------------------------------------------------------------------------------
    // Nombre de point de mesure utilisees pour moyenner les resultats
    #define NB_MESURES          100
    
    // Temps entre chaque point de mesure (Secondes)
    #define TEMPS_MESURE        0.1 
    
    // Temps entre chaque releve de mesure (Secondes)
    #define TEMPS_RELEVE        600
    
    // Temps d'affichage a l'ecran (Secondes)
    // important : doit etre inferieur a TEMPS_RELEVE 
    #define DUREE_AFFICHAGE     30
    
    // ##############################################################################
    //      Verification des paramtres lors de la compilation du programme
    // ##############################################################################
    
    // On s'assure que les timings soient coherents 
    #if defined(OLED_VEILLE) && (TEMPS_RELEVE <= DUREE_AFFICHAGE)
        #error "TEMPS_RELEVE ne peut pas etre inferieur a DUREE_AFFICHAGE !"
    #endif

    // Verification des paramtres RGB
    #if defined(RGB_1_OCTET) && defined(RGB_2_OCTET)
        #error "RGB_1_OCTET et RGB_2_OCTET ne peuvent pas etre definis en meme temps !"
    #endif
    
    #if defined(RGB_ACTIF) && !defined(RGB_1_OCTET) && !defined(RGB_2_OCTET)
        #error "Le capteur RGB est actif mais aucun format de donnees n'a ete choisi !"
        #error "Pensez a decommenter une des lignes RGB_OCTET"
    #endif

#endif

Credits

Thomas Broussard

Thomas Broussard

0 projects • 1 follower
Jeanne Baumier

Jeanne Baumier

0 projects • 1 follower
Anaïs Auberval

Anaïs Auberval

0 projects • 1 follower
Thanks to Thomas Broussard, Jeanne Baumier, Anaïs Auberval, Yann Douze, Sylvain Viateur, and Polytech Sorbonne.

Comments