Giovanni LiscaValeria MarrasClaudio DeriuAnnarita Buttu
Published

Environmental sensing with Agruimino Lemon and E-Ink display

This project focuses on utilizing Lifely Agrumino sensors to monitor temperature and soli humidity, displaying the data on a E-Paper display

BeginnerProtip5 hours277
Environmental sensing with Agruimino Lemon and E-Ink display

Things used in this project

Hardware components

Agrumino
Lifely Agrumino
×1
1.9inch Segment E-Paper Module, 91 Segments, I2C Bus, Ideal for Temperature and humidity meter, Humidifier, Digital Meter
×1
Jumper wires (generic)
Jumper wires (generic)
×1
I2C cables
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Code

Soil-Temp-Monitoring

C/C++
This sketch send data in a 1.9inch Segment E-Paper Module. The original EPD_1.9 library has been modified as some control functions (GPIOInit, ReadBusy, and Reset) must refer to Agrumino library.
/*  This sketch send data in a 1.9inch Segment E-Paper Module.
    The original EPD_1.9 library has been modified as some control functions 
    (GPIOInit, ReadBusy, and Reset) must refer to Agrumino library. */
 
#include <stdio.h>
#include <Wire.h>             // used to communicate with I2C devices.
#include "Lifely_EPD_1in9.h"  // used to communicate with E-Paper Display.
#include <Agrumino.h>         // used to communicate with Agrumino board.
#define SLEEP_TIME_SEC 10     // used to set the deep sleep time in seconds.
Agrumino agrumino;

float temperature_value =0.0;
float humidity_value =0.0;
void delaySec(int sec) { delay(sec * 1000); }

void deepSleepSec(int sec) {
  ESP.deepSleep(sec * 1000000); // microseconds
}

char digit_left[] = {0xbf, 0x00, 0xfd, 0xf5, 0x47, 0xf7, 0xff, 0x21, 0xff, 0xf7, 0x00};  // individual segments for the left part od the digit, index 10 is empty
char digit_right[] ={0x1f, 0x1f, 0x17, 0x1f, 0x1f, 0x1d, 0x1d, 0x1f, 0x1f, 0x1f, 0x00};  // individual segments for the right part od the digit, index 10 is empty
char temperature_digits[] = {1, 2, 3, 4}; // temperature digits > 1, 2, 3, 4 = 123.4°C
char humidity_digits[] = {5, 6, 7}; // humidity digits > 5, 6, 7 = 56.7%
unsigned char eink_segments[]  = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       };  // all white, but will be updated later with proper digits

void GPIOInit()
{
  agrumino.setGPIOMode(GPIO_2 , GPIO_INPUT);  
  agrumino.setGPIOMode(GPIO_1 , GPIO_OUTPUT);  
}

void EPD_1in9_ReadBusy()
{   
  Serial.println("wait");
  delay(10);
  while(1)
  {  //=1 BUSY;
    if(agrumino.readGPIO(GPIO_2)==1) 
      break;
    delay(1);
  }
  delay(10);
    Serial.println("Down");
}
void EPD_1in9_Reset()
{

  agrumino.writeGPIO(GPIO_1, HIGH);
  delay(200);
  agrumino.writeGPIO(GPIO_1, LOW);
  delay(20);
  agrumino.writeGPIO(GPIO_1, HIGH);
  delay(200);
}


void setup()
{

  Serial.begin(115200); // start serial communication
  agrumino.setup();
  delay(200);
  agrumino.turnBoardOn();
  delay(200);
  Wire.begin();  // start I2C commnunication with the e-ink display
  Serial.println("Clear");
  GPIOInit();
  EPD_1in9_init();

}

void loop()
{

  temperature_value = agrumino.readTempC(); // set the temperature
  humidity_value = agrumino.readSoil(); // set the humidity
  Serial.println("temperature is:  " + String(temperature_value));
  Serial.println("humidity is:  " + String(humidity_value));
  // some updates for the e-ink display, I don´t understand most of it, so I´m keepin it here
  EPD_1in9_lut_5S();
  EPD_1in9_Write_Screen(DSPNUM_1in9_off);
  delay(500);
  EPD_1in9_lut_GC();
  EPD_1in9_lut_DU_WB();

  // set correct digits values based on the temperature
  temperature_digits[0] = int(temperature_value / 100) % 10;
  temperature_digits[1] = int(temperature_value / 10) % 10;
  temperature_digits[2] = int(temperature_value ) % 10;
  temperature_digits[3] = int(temperature_value * 10) % 10;

  // set correct digits values based on the humidity
  humidity_digits[0] = int(humidity_value / 10) % 10;
  humidity_digits[1] = int(humidity_value ) % 10;
  humidity_digits[2] = int(humidity_value * 10) % 10;

  // do not show leading zeros for values <100 and <10 both temperature and humidity
  if (temperature_value < 100) {temperature_digits[0] = 10;}
  if (temperature_value < 10) {temperature_digits[1] = 10;}  

  if (humidity_value < 10) {humidity_digits[0] = 10;}    

  // temperature digits
  eink_segments[0] = digit_right[temperature_digits[0]];
  eink_segments[1] = digit_left[temperature_digits[1]];
  eink_segments[2] = digit_right[temperature_digits[1]];  
  eink_segments[3] = digit_left[temperature_digits[2]];
  eink_segments[4] = digit_right[temperature_digits[2]] | B00100000 /* decimal point */;   
  eink_segments[11] = digit_left[temperature_digits[3]];
  eink_segments[12] = digit_right[temperature_digits[3]];    

  // humidity digits
  eink_segments[5] = digit_left[humidity_digits[0]];
  eink_segments[6] = digit_right[humidity_digits[0]];    
  eink_segments[7] = digit_left[humidity_digits[1]];
  eink_segments[8] = digit_right[humidity_digits[1]] | B00100000 /* decimal point */;        
  eink_segments[9] = digit_left[humidity_digits[2]];
  eink_segments[10] = digit_right[humidity_digits[2]] | B00100000 /* percentage sign */;  
  // special symbols - °C / °F, bluetooth, battery
  eink_segments[13] = 0x05 /* °C */ | B00001000 /* bluetooth */ | B00010000 /* battery icon */;
  // write segments to the e-ink screen
  EPD_1in9_Write_Screen(eink_segments);
  EPD_1in9_sleep();
  agrumino.turnBoardOff();
  deepSleepSec(SLEEP_TIME_SEC);
}

Lifely_EPD_1in9.h

C Header File
C Header for libraries
#ifndef _Lifely_EPD_1in9_H_
#define _Lifely_EPD_1in9_H_

#include <Arduino.h>
#include <Wire.h>
#include <stdlib.h>
// address
#define adds_com  	0x3C
#define adds_data	0x3D

#define EPD_BUSY_PIN 7
#define EPD_RST_PIN 8



extern unsigned char DSPNUM_1in9_on[];
extern unsigned char DSPNUM_1in9_off[];
extern unsigned char DSPNUM_1in9_WB[];
extern unsigned char DSPNUM_1in9_W0[];
extern unsigned char DSPNUM_1in9_W1[];
extern unsigned char DSPNUM_1in9_W2[];
extern unsigned char DSPNUM_1in9_W3[];
extern unsigned char DSPNUM_1in9_W4[];
extern unsigned char DSPNUM_1in9_W5[];
extern unsigned char DSPNUM_1in9_W6[];
extern unsigned char DSPNUM_1in9_W7[];
extern unsigned char DSPNUM_1in9_W8[];
extern unsigned char DSPNUM_1in9_W9[];

void GPIOInit(void);
void EPD_1in9_Reset(void);
void EPD_1in9_SendCommand(unsigned char Reg);
void EPD_1in9_SendData(unsigned char Data);
unsigned char EPD_1in9_readCommand(unsigned char Reg);
unsigned char EPD_1in9_readData(unsigned char Data);
void EPD_1in9_ReadBusy(void);
void EPD_1in9_lut_DU_WB(void);
void EPD_1in9_lut_GC(void);
void EPD_1in9_lut_5S(void);
void EPD_1in9_Temperature(void);
void EPD_1in9_init(void);
void EPD_1in9_Write_Screen(unsigned char *image);
void EPD_1in9_Write_Screen1(unsigned char *image);
void EPD_1in9_sleep(void);

#endif

Lifely_EPD_1in9.cpp

C/C++
Libraries definitions
#include <Arduino.h>
#include <Wire.h>
#include <stdlib.h>
#include "Lifely_EPD_1in9.h"
#include <Agrumino.h>

//////////////////////////////////////full screen update LUT////////////////////////////////////////////

unsigned char DSPNUM_1in9_on[]   = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,       };  // all black
unsigned char DSPNUM_1in9_off[]  = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,       };  // all white
unsigned char DSPNUM_1in9_WB[]   = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,       };  // All black font
unsigned char DSPNUM_1in9_W0[]   = {0x00, 0xbf, 0x1f, 0xbf, 0x1f, 0xbf, 0x1f, 0xbf, 0x1f, 0xbf, 0x1f, 0xbf, 0x1f, 0x00, 0x00,       };  // 0
unsigned char DSPNUM_1in9_W1[]   = {0xff, 0x1f, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00,       };  // 1
unsigned char DSPNUM_1in9_W2[]   = {0x00, 0xfd, 0x17, 0xfd, 0x17, 0xfd, 0x17, 0xfd, 0x17, 0xfd, 0x17, 0xfd, 0x37, 0x00, 0x00,       };  // 2
unsigned char DSPNUM_1in9_W3[]   = {0x00, 0xf5, 0x1f, 0xf5, 0x1f, 0xf5, 0x1f, 0xf5, 0x1f, 0xf5, 0x1f, 0xf5, 0x1f, 0x00, 0x00,       };  // 3
unsigned char DSPNUM_1in9_W4[]   = {0x00, 0x47, 0x1f, 0x47, 0x1f, 0x47, 0x1f, 0x47, 0x1f, 0x47, 0x1f, 0x47, 0x3f, 0x00, 0x00,       };  // 4
unsigned char DSPNUM_1in9_W5[]   = {0x00, 0xf7, 0x1d, 0xf7, 0x1d, 0xf7, 0x1d, 0xf7, 0x1d, 0xf7, 0x1d, 0xf7, 0x1d, 0x00, 0x00,       };  // 5
unsigned char DSPNUM_1in9_W6[]   = {0x00, 0xff, 0x1d, 0xff, 0x1d, 0xff, 0x1d, 0xff, 0x1d, 0xff, 0x1d, 0xff, 0x3d, 0x00, 0x00,       };  // 6
unsigned char DSPNUM_1in9_W7[]   = {0x00, 0x21, 0x1f, 0x21, 0x1f, 0x21, 0x1f, 0x21, 0x1f, 0x21, 0x1f, 0x21, 0x1f, 0x00, 0x00,       };  // 7
unsigned char DSPNUM_1in9_W8[]   = {0x00, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x1f, 0xff, 0x3f, 0x00, 0x00,       };  // 8
unsigned char DSPNUM_1in9_W9[]   = {0x00, 0xf7, 0x1f, 0xf7, 0x1f, 0xf7, 0x1f, 0xf7, 0x1f, 0xf7, 0x1f, 0xf7, 0x1f, 0x00, 0x00,       };  // 9

unsigned char VAR_Temperature=20; 

void EPD_1in9_SendCommand(unsigned char Reg)
{
	Wire.beginTransmission(adds_com);
	Wire.write(Reg);
	Wire.endTransmission(false);
}

/******************************************************************************
function :	send data
parameter:
    Data : Write data
******************************************************************************/
void EPD_1in9_SendData(unsigned char Data)
{
  Wire.beginTransmission(adds_data);
	Wire.write(Data);
	Wire.endTransmission();
}

/******************************************************************************
function :	read command
parameter:
     Reg : Command register
******************************************************************************/
unsigned char EPD_1in9_readCommand(unsigned char Reg)
{
	unsigned char a;
	Wire.beginTransmission(adds_com);
	delay(10);
	Wire.write(Reg);
	a = Wire.read();
	Wire.endTransmission();
	return a;
}

/******************************************************************************
function :	read data
parameter:
    Data : Write data
******************************************************************************/
unsigned char EPD_1in9_readData(unsigned char Data)
{
	unsigned char a;
  Wire.beginTransmission(adds_data);
	delay(10);
	Wire.write(Data);
	a = Wire.read();
	Wire.endTransmission();
	return a;
}

/******************************************************************************
function :	Wait until the busy_pin goes LOW
parameter:
******************************************************************************/


/*
# DU waveform white extinction diagram + black out diagram
# Bureau of brush waveform
*/
void EPD_1in9_lut_DU_WB(void)
{
	Wire.beginTransmission(adds_com);
	Wire.write(0x82);
	Wire.write(0x80);
	Wire.write(0x00);
	Wire.write(0xC0);
	Wire.write(0x80);
	Wire.write(0x80);
	Wire.write(0x62);
	Wire.endTransmission();
}

/*   
# GC waveform
# The brush waveform
*/
void EPD_1in9_lut_GC(void)
{
	Wire.beginTransmission(adds_com);
	Wire.write(0x82);
	Wire.write(0x20);
	Wire.write(0x00);
	Wire.write(0xA0);
	Wire.write(0x80);
	Wire.write(0x40);
	Wire.write(0x63);
	Wire.endTransmission();
}

/* 
# 5 waveform  better ghosting
# Boot waveform
*/
void EPD_1in9_lut_5S(void)
{
	Wire.beginTransmission(adds_com);
	Wire.write(0x82);
	Wire.write(0x28);
	Wire.write(0x20);
	Wire.write(0xA8);
	Wire.write(0xA0);
	Wire.write(0x50);
	Wire.write(0x65);
	Wire.endTransmission();	
}

/*
# temperature measurement
# You are advised to periodically measure the temperature and modify the driver parameters
# If an external temperature sensor is available, use an external temperature sensor
*/
void EPD_1in9_Temperature(void)
{
	Wire.beginTransmission(adds_com);
	if( VAR_Temperature < 10 )
	{
		Wire.write(0x7E);
		Wire.write(0x81);
		Wire.write(0xB4);
	}
	else
	{
		Wire.write(0x7E);
		Wire.write(0x81);
		Wire.write(0xB4);
	}
	Wire.endTransmission();

    delay(10);        

	Wire.beginTransmission(adds_com);
	Wire.write(0xe7);    // Set default frame time
        
	// Set default frame time
	if(VAR_Temperature<5)
		Wire.write(0x31); // 0x31  (49+1)*20ms=1000ms
	else if(VAR_Temperature<10)
		Wire.write(0x22); // 0x22  (34+1)*20ms=700ms
	else if(VAR_Temperature<15)
		Wire.write(0x18); // 0x18  (24+1)*20ms=500ms
	else if(VAR_Temperature<20)
		Wire.write(0x13); // 0x13  (19+1)*20ms=400ms
	else
		Wire.write(0x0e); // 0x0e  (14+1)*20ms=300ms
	Wire.endTransmission();
}

/*
# Note that the size and frame rate of V0 need to be set during initialization, 
# otherwise the local brush will not be displayed
*/
void EPD_1in9_init(void)
{
	unsigned char i = 0;
	EPD_1in9_Reset();
	delay(100);

	Wire.beginTransmission(adds_com);
	Wire.write(0x2B); // POWER_ON
	Wire.endTransmission();

	delay(10);

	Wire.beginTransmission(adds_com);
	Wire.write(0xA7); // boost
	Wire.write(0xE0); // TSON 
	Wire.endTransmission();

	delay(10);

	EPD_1in9_Temperature();
}

void EPD_1in9_Write_Screen( unsigned char *image)
{
	Wire.beginTransmission(adds_com);
	Wire.write(0xAC); // Close the sleep
	Wire.write(0x2B); // turn on the power
	Wire.write(0x40); // Write RAM address
	Wire.write(0xA9); // Turn on the first SRAM
	Wire.write(0xA8); // Shut down the first SRAM
	Wire.endTransmission();

	Wire.beginTransmission(adds_data);
	for(char j = 0 ; j<15 ; j++ )
		Wire.write(image[j]);

	Wire.write(0x00);
	Wire.endTransmission();


	Wire.beginTransmission(adds_com);
	Wire.write(0xAB); // Turn on the second SRAM
	Wire.write(0xAA); // Shut down the second SRAM
	Wire.write(0xAF); // display on
	Wire.endTransmission();

	EPD_1in9_ReadBusy();
	//delay(2000);
	
	Wire.beginTransmission(adds_com);
	Wire.write(0xAE); // display off
	Wire.write(0x28); // HV OFF
	Wire.write(0xAD); // sleep in	
	Wire.endTransmission();
}

void EPD_1in9_Write_Screen1( unsigned char *image)
{
	Wire.beginTransmission(adds_com);
	Wire.write(0xAC); // Close the sleep
	Wire.write(0x2B); // turn on the power
	Wire.write(0x40); // Write RAM address
	Wire.write(0xA9); // Turn on the first SRAM
	Wire.write(0xA8); // Shut down the first SRAM
	Wire.endTransmission();

	Wire.beginTransmission(adds_data);
	for(char j = 0 ; j<15 ; j++ )
		Wire.write(image[j]);

	Wire.write(0x03);
	Wire.endTransmission();

	Wire.beginTransmission(adds_com);
	Wire.write(0xAB); // Turn on the second SRAM
	Wire.write(0xAA); // Shut down the second SRAM
	Wire.write(0xAF); // display on
	Wire.endTransmission();

	EPD_1in9_ReadBusy();
	//delay(2000);

	Wire.beginTransmission(adds_com);
	Wire.write(0xAE); // display off
	Wire.write(0x28); // HV OFF
	Wire.write(0xAD); // sleep in	
	Wire.endTransmission();

}

void EPD_1in9_sleep(void)
{
	Wire.beginTransmission(adds_com);
	Wire.write(0x28); // POWER_OFF
	EPD_1in9_ReadBusy();
	Wire.write(0xAD); // DEEP_SLEEP
	Wire.endTransmission();

	delay(2000);
	// digitalWrite(EPD_RST_PIN, 0);
}

Credits

Giovanni Lisca
1 project • 0 followers
Contact
Valeria Marras
1 project • 0 followers
Contact
Claudio Deriu
1 project • 0 followers
Contact
Annarita Buttu
1 project • 0 followers
Contact

Comments

Please log in or sign up to comment.