Dana Mah
Published © GPL3+

Lawn Maintenace

This project was to use some preset values to tell you when you should mow your lawn.

IntermediateWork in progress20 hours85
Lawn Maintenace

Things used in this project

Story

Read more

Schematics

Wiring Setup

Code

main code

Arduino
This app uses FreeRTOS to read sensors and display it to WIO Terminal
#include <SensirionCore.h>

#include <Seeed_Arduino_FreeRTOS.h>
#include <semphr.h>
#include <TFT_eSPI.h>
#include <SensirionI2CSht4x.h>
#include "sensirion_common.h"
#include "sgp30.h"

TaskHandle_t Handle_SHT4X;
TaskHandle_t Handle_MOISTURE;
TaskHandle_t Handle_DISPLAY;
TaskHandle_t Handle_GAS;
TaskHandle_t Handle_LIGHT;
 
TFT_eSPI tft = TFT_eSPI();
TFT_eSprite spr = TFT_eSprite(&tft);

SensirionI2CSht4x sht4x;

float gTemperature;
float gHumidity;
float gMoisture;
long gVOC;
long gCO2;
float gLight;

int iTempPosX = 5;
int iTempPosY = 50;
int iHumidityPosX = 100;
int iHumidityPosY = 50;
int iMoisturePosX = 205;
int iMoisturePosY = 50;  
int iVOCPosX = 5;
int iVOCPosY = 150;
int iCO2PosX = 100;
int iCO2PosY = 150;
int iLightPosX = 205;
int iLightPosY = 150;

void setup() {
  //Start up Temperature and Humidity sensor
  Wire.begin();    
  sht4x.begin(Wire);
  
  pinMode(WIO_LIGHT, INPUT);
  
  
  
  Serial.begin(115200);
  
  s16 err;
  u16 scaled_ethanol_signal, scaled_h2_signal;
  
  #if defined(ESP8266)
    pinMode(15, OUTPUT);
    digitalWrite(15, 1);
    Serial.println("Set wio link power!");
    delay(500);
  #endif
  
  while (sgp_probe() != STATUS_OK) {
    Serial.println("SGP failed");
    while (1);
  }  
  err = sgp_measure_signals_blocking_read(&scaled_ethanol_signal,
                                            &scaled_h2_signal);
    if (err == STATUS_OK) {
        Serial.println("get ram signal!");
    } else {
        Serial.println("error reading signals");
    }
  err = sgp_iaq_init();
    
  vNopDelayMS(1000); // prevents usb driver crash on startup, do not omit this

  
  drawScreen();
  
  Serial.println("");
  Serial.println("******************************");
  Serial.println("        Program start         ");
  Serial.println("******************************");
  
  // Create the threads that will be managed by the rtos
  // Sets the stack size and priority of each task
  // Also initializes a handler pointer to each task, which are important to communicate with and retrieve info from tasks
  xTaskCreate(SHT4X_TASK,    "SHT4X_TASK",    256,  NULL, tskIDLE_PRIORITY + 2, &Handle_SHT4X);
  xTaskCreate(MOISTURE_TASK, "Moisture TASK", 256,  NULL, tskIDLE_PRIORITY + 2, &Handle_MOISTURE);
  xTaskCreate(LIGHT_TASK,    "Light TASK",    256,  NULL, tskIDLE_PRIORITY + 2, &Handle_LIGHT);
  xTaskCreate(GAS_TASK,      "Gas TASK",      1000, NULL, tskIDLE_PRIORITY + 2, &Handle_GAS);
  xTaskCreate(DISPLAY_TASK,  "Display TASK",  200,  NULL, tskIDLE_PRIORITY + 1, &Handle_DISPLAY);
  //Start the RTOS, this function will never return and will schedule the tasks.
  vTaskStartScheduler();
}

void loop() {
  //NOTHING
}

static void drawScreen(){
  tft.begin();
  tft.setRotation(3);

  //Heading
  tft.fillScreen(TFT_BLACK);
  tft.setFreeFont(&FreeSerifBold18pt7b);
  tft.setTextColor(TFT_WHITE);
  tft.fillRoundRect(3, 3 , tft.width() -3 , 45, 10, TFT_BLUE); 
  tft.drawString("Grass Monitor", 35, 10 , 1);

  //Temperature
  tft.setFreeFont(&FreeSerifBold9pt7b);
  tft.setTextColor(TFT_YELLOW) ;
  tft.drawString("Temp", iTempPosX + 15  , iTempPosY + 5 , 1);
  tft.setTextColor(TFT_WHITE);
  tft.drawString("o", iTempPosX + 47, iTempPosY + 35, 1);
  tft.drawString("C", iTempPosX + 57, iTempPosY + 50, 1);

  //Humidity
  tft.setFreeFont(&FreeSerifBold9pt7b);
  tft.setTextColor(TFT_YELLOW) ;
  tft.drawString("Humidity", iHumidityPosX + 2  , iHumidityPosY + 5 , 1); 
  tft.setTextColor(TFT_WHITE);
  tft.drawString("(%)", iHumidityPosX + 77, iHumidityPosY + 5, 1);

  //Moisture
  tft.setFreeFont(&FreeSerifBold9pt7b);
  tft.setTextColor(TFT_YELLOW) ;
  tft.drawString("Moisture", iMoisturePosX + 2  , iMoisturePosY + 5 , 1); 
  tft.setTextColor(TFT_WHITE);
  tft.drawString("(%)", iMoisturePosX + 77, iMoisturePosY + 5, 1); 

  //VOC
  tft.setFreeFont(&FreeSerifBold9pt7b);
  tft.setTextColor(TFT_YELLOW) ;
  tft.drawString("VOC", iVOCPosX + 12  , iVOCPosY + 5 , 1); 
  tft.setTextColor(TFT_WHITE);
  //tft.drawString("ppb", iVOCPosX + 57, iVOCPosY + 50, 1);
  tft.drawString("(ppb)", iVOCPosX + 57, iVOCPosY + 5, 1);

  //CO2
  tft.setFreeFont(&FreeSerifBold9pt7b);
  tft.setTextColor(TFT_YELLOW) ;
  tft.drawString("CO2", iCO2PosX + 12  , iCO2PosY + 5 , 1); 
  tft.setTextColor(TFT_WHITE);
  tft.drawString("(ppm)", iCO2PosX + 57, iCO2PosY + 5, 1);

  //Light
  tft.setFreeFont(&FreeSerifBold9pt7b);
  tft.setTextColor(TFT_YELLOW) ;
  tft.drawString("Light", iLightPosX + 12  , iLightPosY + 5 , 1); 
  tft.setTextColor(TFT_WHITE);
  tft.drawString("(lm)", iLightPosX + 57, iLightPosY + 5, 1); 
}

static void SHT4X_TASK (void* pvParameters) {
  Serial.println("Thread SHT4X: Started");
  
  float temperature;
  float humidity;
  
  for(;;){
    uint16_t err;
    err = sht4x.measureHighPrecision(temperature, humidity);
    gTemperature = temperature;
    gHumidity = humidity;
    vTaskDelay(1000);
  }
  vTaskDelete( NULL );
}
 
static void MOISTURE_TASK (void* pvParameters) {
  Serial.println("Thread MOISTURE: Started");
  
  int iMoistureSensorPin = A0;
  
  for(;;){
    gMoisture = analogRead(iMoistureSensorPin) / 7;
    vTaskDelay(1000);
  }
  vTaskDelete( NULL );   
}

static void GAS_TASK (void* pvParameters) {
  Serial.println("Thread GAS: Started");
  s16 err = 0;
  u16 tvoc_ppb, co2_eq_ppm;
  
  for(;;){    
    err = sgp_measure_iaq_blocking_read(&tvoc_ppb, &co2_eq_ppm);
 
    gVOC = (long)tvoc_ppb;
    gCO2 = (long)co2_eq_ppm;
    
    vTaskDelay(1000);
  }
  vTaskDelete( NULL );
} 

static void LIGHT_TASK (void* pvParameters) {
  Serial.println("Thread LIGHT: Started");
  for(;;){
    gLight = analogRead(WIO_LIGHT) / 10;
    vTaskDelay(1000);
  }    
  vTaskDelete( NULL );
}

void DISPLAY_TASK(void* pvParameters) {
  Serial.println("Task DISPLAY: Started");  
  for(;;){
    //Temperature
    spr.createSprite(40, 30);
    spr.setFreeFont(&FreeSerifBold18pt7b);
    spr.setTextColor(TFT_GREEN);
    spr.drawNumber(gTemperature, 0, 0, 1);
    spr.pushSprite(iTempPosX + 7, iTempPosY + 40);
    spr.deleteSprite();
  
    //Humidity
    spr.createSprite(100, 30);
    spr.setFreeFont(&FreeSerifBold18pt7b);
    spr.setTextColor(TFT_GREEN);
    spr.drawNumber(gHumidity, 0, 0, 1);
    spr.pushSprite(iHumidityPosX + 37, iHumidityPosY + 40);
    spr.deleteSprite();
    
    //Moisture
    spr.createSprite(100, 30);
    spr.setFreeFont(&FreeSerifBold18pt7b);
    spr.setTextColor(TFT_GREEN);
    spr.drawNumber(gMoisture, 0, 0, 1);
    spr.pushSprite(iMoisturePosX + 40, iMoisturePosY + 40);
    spr.deleteSprite();

    //VOC
    spr.createSprite(100, 30);
    spr.setFreeFont(&FreeSerifBold12pt7b);
    spr.setTextColor(TFT_GREEN);
    spr.drawNumber(gVOC, 0, 0, 1);
    spr.pushSprite(iVOCPosX + 27, iVOCPosY + 40);
    spr.deleteSprite();
    
    //CO2
    spr.createSprite(100, 30);
    spr.setFreeFont(&FreeSerifBold12pt7b);
    spr.setTextColor(TFT_GREEN);
    spr.drawNumber(gCO2, 0, 0, 1);
    spr.pushSprite(iCO2PosX + 27, iCO2PosY + 40);
    spr.deleteSprite();
    
    //Light
    spr.createSprite(100, 30);
    spr.setFreeFont(&FreeSerifBold12pt7b);
    spr.setTextColor(TFT_GREEN);
    spr.drawNumber(gLight, 0, 0, 1);
    spr.pushSprite(iLightPosX + 27, iLightPosY + 40);
    spr.deleteSprite();

    vTaskDelay(1000);
  }
  vTaskDelete(NULL);
}
 

Credits

Dana Mah
12 projects • 27 followers
I'm a hobbyist interested in microcontroller solutions to simple problems.
Contact
Thanks to Salman Faris.

Comments

Please log in or sign up to comment.