Armando Leonardo
Published © CC0

Portable Environmental Monitoring Device

This project will help people who enjoy outdoor activities and being in contact with nature, helping them to preserve their health.

IntermediateFull instructions providedOver 1 day83
Portable Environmental Monitoring Device

Things used in this project

Hardware components

ESP32S
Espressif ESP32S
×1
GPS-NEO6MV2
GPS module based on the NEO-6M module, capable of identifying global location via satellite (GPS) and reporting it via simple RS232 TTL (UART) communication. Operating voltage: 3.3 VDC; standard speed: 9600 Baud Rate; 50 channels; sensitivity: -146 dBm to -160 dBm; maximum altitude: 164,042 ft (50 km); maximum speed: 500 m/s.
×1
Generic Ultraviolet Sensor
Developed for use with microcontroller systems, especially the Arduino and Raspberry Pi, demonstrating wide applicability and excellent results. It operates with voltages from 3.3V to 5V, sending analog signals to the microcontroller, varying its output voltage according to the level of UV rays detected. Output Voltage: DC 0-1 V; Accuracy: 1 UV INDEX; Response Wavelength: 200nm-370nm.
×1
BME280
Measures atmospheric pressure, humidity, and temperature, also known as a barometer. High-capacity and high-resolution digital module. Supply voltage: 1.8 - 3.3V DC. Interface: I2C (up to 3.4MHz), SPI (up to 10MHz). Measurement ranges: Temperature: -40 to +85°C. Humidity: 0-100%. Pressure: 300-1100 hPa. Accuracy: Temperature: +-1°C. Humidity: +-3%. Pressure: +-1Pa
×1
128x64 Pixel Blue OLED Display
1.3 Inch, 4 I2C Pins
×1
Pushbutton switch 12mm
SparkFun Pushbutton switch 12mm
×2
Coin Cell Battery CR2032
Coin Cell Battery CR2032
×1
3.7v Rechargeable Lithium Battery
if you don't want to use the CR2032 battery
×1
TP4056 Lithium Battery Charger Module
If using a 3.7V rechargeable battery
×1
Resistor 10k ohm
Resistor 10k ohm
×1
female to female jumper cables
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)

Story

Read more

Custom parts and enclosures

corpo2_QzCMBy12Wm.stl

Sketchfab still processing.

tampa_bateria_aaxuQtCaDL.stl

Sketchfab still processing.

tampa_N2JyxziQUU.stl

Sketchfab still processing.

Structure

The structure was designed in FreeCAD and strives for maximum portability.
It is a rectangular object measuring 13cm x 5cm. It is easy to handle and can be carried in a small waist bag.
The connections between the components are made using female-to-female jumper cables.
The electronic components must be glued directly to the structure, partly on the body and partly on the lid.
The structure is divided into a body and lid, and there are two versions of the body: one for those who want to use a CR2032 battery and another for those who want to use a rechargeable 3.7V lithium battery.
The parts are available for 3D printing in PLA.
The attached images show the arrangement of the components in the structure.

Sketchfab still processing.

Schematics

Circuit Diagram of Portable Environmental Monitoring Device

The UV module is connected to the Rx and Tx pins of the ESP32.
The BMe280 sensor and the OLED display are connected to pins IO21 for the SDA port and IO22 for the SCL port.
The UV sensor is connected to pin IO02.
The pushbuttons are connected to pins IO18 and IO19, as well as GND.
The positive output of the battery is connected to a 10K resistor, which in turn is connected to the VIN and IO34 pins of the ESP32.
The battery charger is connected directly to the battery.

front view

internal view 1

internal view 2

internal view 3

main screen

temperature, pressure and humidity screen

date time screen

GPS screen

Code

DPMA1VF.ino

Arduino
As mentioned previously, the Arduino IDE was used.
The software structure is divided into six functions, in addition to the Setup and Loop functions: medUV (to measure the intensity of ultraviolet rays); GPS (for date, time, and geographic location information); medTPU (to measure temperature, humidity, and atmospheric pressure); DataHora (to indicate the local time and the day of the month and week); Menu (for navigating between functions); and gpsLoop (to check the GPS signal).
The loop() function calls the gpsLoop() function to check the GPS signal, the Menu() function to enable navigation, and a switch to access the functions.
The home screen is always the medUV() function.
I have attached the files for uploading to the ESP32.
/* Codigo adaptado com auxlio da IA CHATGPT*/

//BIBLIOTECA, VARIVEIS e DEFINIES-----------------------------------------------------------------------------

// Incluso de bibliotecas
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <SoftwareSerial.h> //Para os pinos do Esp32 funcionar como porta serial
#include <TinyGPS++.h>
#include <Pushbutton.h> //Configurao dos botes
 
//Bibliotecas e definies GPS
#define GPS_RX 16
#define GPS_TX 17
#define GPS_Serial_Baud 9600
SoftwareSerial gpsSerial(GPS_RX, GPS_TX); //Rx=16 e Tx=17
TinyGPSPlus gps;

//Variveis GPS
int k,kr, //Variveis relgio
		HHGST,MMGST,SSGST,HLST,HLT,HL,HH,MM,DL,Seg,DJ,Ano3; //Variveis da Hora Sideral
char c;
long satelites;
bool recebido = false;
unsigned long hora1,Dia,Mes,Ano,Mes2,Ano2;
float longit,MM1,SS1,mn2,Dia2,GMTh,EsteDia,GMST,Mes3,
      Hora,Minuto,Segundo,s2,
      regis_Z; //Varivel da inclinao

int satelitesant = 0, ano;
int AA;
double t,passo1,passo2,passo3,to,n1,h1,n2,latitude, longitude, altitude, curso, lat, lon;
long chs,a,b;
unsigned long data,horaRE;
byte mes, dia, hora, minuto, segundo, centesimo, horalocal;
float altitudeGPS, lat1, long1, lat2, long2, s;
float mn,hora2,d;
int Cg; //Curso geografico - dado pelo GPS
int Pg; //Posicao geografica - calculado
long lat3,lon3,latAnt=0,lonAnt=0; //Latitude e longitude
int ValorAlinha=0;
bool recCg = false;

//Variveis e definies do Sensor BME 280
#define SEALEVELPRESSURE_HPA (1013.25) //necessrio para a leitura da altitude
Adafruit_BME280 bme;
bool status;  // Cria uma varivel status de iniciao do sensor BME

// Definio da Altura e largura do display OLED 
#define SCREEN_WIDTH 128 // Largura display, em pixels 
#define SCREEN_HEIGHT 64 // Altura display, em pixels
// Declarao pino reset para I2C do display OLED
#define OLED_RESET 	-1 // Ser o mesmo reset da placa
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // Criao objeto display

// Variveis Sensor de UV
int UVSensorPin = 2;// Conectado ao pino A0 (GPIO2)
float sensorValue;
int sensorUV;
int nivelUV;

//Biblioteca, variveis e definies dos botes
#define BUTTON_NAV 18     // Boto para navegao
#define BUTTON_SELECT 19  // Boto para seleo

// Variveis do Menu
int menuIndex = 0;
unsigned long ultimaLeitura = 0;
const unsigned long debounceDelay = 200;
static bool ultimaNaveg = HIGH;  //Boto de navegalo recebe  alto
static bool ultimaSelec = HIGH; //Boto de seleo recebe  alto

// Pino analgico que recebe a tenso da bateria (via divisor de tenso, ex: GPIO 34)
#define VBAT_PIN 34
// Tenso mxima e mnima da CR2032
#define VBAT_MAX 3.0
#define VBAT_MIN 2.0

//Declaraes das Funes
void medUv(); //Funo que mede o UV
void GPS(); //Funo GPS
void medTPU(); //Funo Temperatura,Presso e Umidade
void DataHora(); //Funo Data e Hora
void Menu(); //Funo Menu
void gpsLoop(); //Funo de verificao de conexo com GPS


//SETUP-------------------------------------------------------------------------------------------------------
void setup(){
	Serial.begin(115200); //Inicia a cominicao serial
  
  gpsSerial.begin(GPS_Serial_Baud); //Inicia a conexo com gps

  pinMode(BUTTON_NAV, INPUT_PULLUP); //Aloca os botes
  pinMode(BUTTON_SELECT, INPUT_PULLUP);
	
	if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { //Inicia OLED
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }

  status = bme.begin(0x76, &Wire); //Inicia o sensor TPU. Endereo 0x76
	
}
//LOOP------------------------------------------------------------------------------------------------- 
void loop(){
  
  gpsLoop();
  Menu();
 
  switch (menuIndex) {
    case 0:
      medUV();
      break;
    case 1:
      medTPU();
      break;
    case 2:
      DataHora();
      break;
    case 3:
      GPS();
      break;
  }
  	  
}

gpsLoop.ino

Arduino
The gpsLoop() function reads the GPS signal received by the antenna.
/*Loop de verificao do GPS*/

void gpsLoop() {
  while (gpsSerial.available() > 0) {
    gps.encode(gpsSerial.read());
  }
}

Menu.ino

Arduino
The Menu() function enables the navigation and selection buttons. The navigation button opens the other functions of the device, and the selection button returns the device to the home screen.
/*Funo Menu*/

void Menu(){
  
  bool nav = digitalRead(BUTTON_NAV);
  bool select = digitalRead(BUTTON_SELECT);

  if (nav == LOW && ultimaNaveg == HIGH && millis() - ultimaLeitura > debounceDelay) {
    menuIndex = (menuIndex + 1) % 4;
    ultimaLeitura = millis();
  }

  if (select == LOW && ultimaSelec == HIGH && millis() - ultimaLeitura > debounceDelay) {
    menuIndex = 0; // Reinicia para UV aps seleo
    ultimaLeitura = millis();
  }
  ultimaNaveg = nav;
  ultimaSelec = select;
}

medUV.ino

Arduino
The medUV function is the device's main screen, where it displays the intensity of ultraviolet rays.
As you know, the most well-known solar radiation is the visible range. However, two other very important ranges are ultraviolet (UV) and infrared (IR). The ultraviolet range is more energetic than light (it has a shorter wavelength) and therefore penetrates the skin more deeply, causing burns when exposed to solar radiation for too long. The Ultraviolet Index (UVI) is a measure of the intensity of ultraviolet (UV) radiation incident on the Earth's surface and relevant to its effects on human skin. The UVI represents the maximum daily value of ultraviolet radiation, that is, during the period corresponding to solar noon, the time of maximum solar radiation intensity. The UVI is always displayed for clear sky conditions, that is, for the absence of clouds, which, in most cases, represents the maximum radiation intensity. This index is presented as an integer. According to the World Health Organization (WHO), UVI is grouped according to its intensity and duration of sun exposure. The ultraviolet index (UVI) categories are: Low (<2), Moderate (3 to 5), High (6 to 7), Very High (8 to 10), and Extreme (>11).
The UV sensor used in this project measures a wavelength range from 200 to 370nm, with an analog output of 0 to 1V, or 0 to 1000mV. Therefore, comparing the distribution of values received by the sensor and the UVI scale, we obtain:
a) Values below 226mV, UVI=0;
b) Values between 227 and 317mV, UVI=1;
c) Values between 318 and 407mV, UVI=2;
d) Values between 408 and 502mV, UVI=3;
e) Values between 503 and 605 mV, UVI=4;
f) Values between 606 and 695 mV, UVI=5;
g) Values between 696 and 794 mV, UVI=6;
h) Values between 795 and 880 mV, UVI=7;
i) Values between 881 and 975 mV, UVI=8;
j) Values between 976 and 1078 mV, UVI=9;
k) Values above 1079 mV, UVI=10 and 11.
For the iconic characterization of the UVI, icons were established with the drawing of the sun, with various expressions, as shown in the attached figures, and the initial letters of the categories, in Portuguese.
Thus, on the main screen, we have the UVI classification by number, on the left, and the representation by icon on the right.
At the top we have the representation, from left to right, of the battery percentage, the battery icon and the number of Volts remaining.
Os ícones foram feitos com a ajuda do site: https://javl.github.io/image2cpp/
/* Funo de Medida de Raios Ultra Violeta */

void medUV(){

	display.clearDisplay();

  // Figura do 'UVBaixo', 64x64px
  const unsigned char epd_bitmap_UVBaixo [] PROGMEM = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xf8, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0x80, 0x00, 
	0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 
	0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0xf9, 0xf8, 0x00, 
	0x00, 0x00, 0x00, 0x3c, 0x1f, 0xe0, 0x78, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x0f, 0xe0, 0x7c, 0x00, 
	0x00, 0x00, 0x00, 0x78, 0x0f, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f, 0xe0, 0x7e, 0x00, 
	0x00, 0x00, 0x00, 0xfc, 0x0f, 0xe0, 0x7e, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0xf0, 0xfe, 0x00, 
	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x00, 
	0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x00, 
	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x00, 
	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x01, 0xfe, 0x00, 
	0x00, 0x00, 0x00, 0x7f, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x01, 0xfc, 0x00, 
	0x00, 0x00, 0x00, 0x3f, 0x80, 0x03, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x03, 0xf0, 0x00, 
	0x00, 0x00, 0x00, 0x1f, 0xc0, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x1f, 0xe0, 0x00, 
	0x00, 0x1f, 0x80, 0x07, 0xff, 0xff, 0xc0, 0x00, 0x00, 0xff, 0xe0, 0x01, 0xff, 0xff, 0x00, 0x00, 
	0x01, 0xff, 0xf0, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x03, 0xf9, 0xf0, 0x00, 0x3f, 0xf8, 0x00, 0x00, 
	0x03, 0xf1, 0xf0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0xf1, 0xf0, 0x00, 0x01, 0x00, 0x00, 0x00, 
	0x01, 0xf1, 0xe0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0xf3, 0xc0, 0x00, 0x01, 0x00, 0x00, 0x00, 
	0x03, 0xe7, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x00, 0x01, 0x00, 0x00, 0x00, 
	0x03, 0xef, 0xe0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0xc1, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x07, 0xc1, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc1, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x0f, 0x81, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x81, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x0f, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x01, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
	};

  // Figura do 'UVModerado', 64x64px
  const unsigned char epd_bitmap_UVModerado [] PROGMEM = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0xf8, 0x02, 0x00, 
	0x00, 0x00, 0x00, 0x60, 0xff, 0xfe, 0x04, 0x00, 0x00, 0x00, 0x00, 0x33, 0xff, 0xff, 0x88, 0x00, 
	0x00, 0x00, 0x00, 0x17, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xe0, 0x00, 
	0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0xf9, 0xf8, 0x00, 
	0x00, 0x00, 0x00, 0x3c, 0x1f, 0xe0, 0x78, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0f, 0xe0, 0x7c, 0x00, 
	0x00, 0x00, 0x00, 0x78, 0x0f, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f, 0xc0, 0x7c, 0x00, 
	0x00, 0x00, 0x00, 0xfc, 0x0f, 0xe0, 0x7e, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0xf0, 0xfe, 0x00, 
	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x00, 
	0x00, 0x00, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x00, 
	0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0x00, 
	0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xfd, 0xfc, 0x00, 
	0x00, 0x00, 0x00, 0x7e, 0x7f, 0xfd, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x7f, 0xf9, 0xfc, 0x00, 
	0x00, 0x00, 0x00, 0x3f, 0x9f, 0xf3, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe1, 0x0f, 0xf0, 0x00, 
	0x00, 0x00, 0x00, 0x1f, 0xfc, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xe0, 0x00, 
	0x00, 0x00, 0x00, 0x37, 0xff, 0xff, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x63, 0xff, 0xff, 0x18, 0x00, 
	0x00, 0x00, 0x00, 0xc0, 0xff, 0xfe, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1f, 0xf0, 0x04, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x1e, 0x01, 0xe0, 0x01, 0x00, 0x00, 0x00, 
	0x00, 0x1f, 0x03, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x03, 0xe0, 0x01, 0x00, 0x00, 0x00, 
	0x00, 0x3f, 0x07, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x87, 0xe0, 0x01, 0x00, 0x00, 0x00, 
	0x00, 0x3f, 0x8f, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x8f, 0xe0, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0xef, 0x9f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0x9b, 0xe0, 0x00, 0x00, 0x00, 0x00, 
	0x01, 0xe7, 0xbb, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc7, 0xf3, 0xe0, 0x00, 0x00, 0x00, 0x00, 
	0x03, 0xc7, 0xf3, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x03, 0x87, 0xe3, 0xf0, 0x00, 0x00, 0x00, 0x00, 
	0x07, 0x87, 0xe1, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x07, 0x03, 0xc1, 0xf8, 0x00, 0x00, 0x00, 0x00, 
	0x0e, 0x03, 0xc0, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x80, 0x70, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
	};

  // Figura do 'UVAlto', 64x64px
  const unsigned char epd_bitmap_UVAlto [] PROGMEM = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x80, 0x07, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x3f, 0xf8, 0x02, 0x00, 
	0x00, 0x00, 0x00, 0x60, 0xc0, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x33, 0x3f, 0xf1, 0x98, 0x00, 
	0x00, 0x00, 0x00, 0x14, 0xff, 0xfc, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x09, 0xff, 0xff, 0x20, 0x00, 
	0x00, 0x00, 0x00, 0x13, 0xff, 0xff, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x27, 0x3f, 0xf9, 0xd8, 0x00, 
	0x00, 0x00, 0x0c, 0x2c, 0x1f, 0xe0, 0x68, 0xc0, 0x00, 0x00, 0x03, 0xd8, 0x0f, 0xe0, 0x67, 0x00, 
	0x00, 0x00, 0x00, 0xd8, 0x0f, 0xc0, 0x74, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x0f, 0xc0, 0x76, 0x00, 
	0x00, 0x00, 0x00, 0xbc, 0x0f, 0xe0, 0x7a, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x1f, 0xf0, 0xfa, 0x00, 
	0x00, 0x00, 0x00, 0xbf, 0xff, 0xff, 0xfa, 0x00, 0x00, 0x00, 0x40, 0x7f, 0xff, 0xff, 0xfa, 0x00, 
	0x00, 0x00, 0x7f, 0x7f, 0xff, 0xff, 0xfb, 0xfc, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfa, 0x00, 
	0x00, 0x00, 0x00, 0xbf, 0xff, 0xff, 0xfa, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xff, 0xff, 0xfa, 0x00, 
	0x00, 0x00, 0x00, 0xbf, 0xff, 0xff, 0xfa, 0x00, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x01, 0xf4, 0x00, 
	0x00, 0x00, 0x03, 0xdf, 0x00, 0x01, 0xf6, 0x00, 0x00, 0x00, 0x0e, 0x5f, 0xff, 0xff, 0xe7, 0x80, 
	0x00, 0x00, 0x00, 0x2f, 0xff, 0xff, 0xe8, 0x60, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xd0, 0x00, 
	0x00, 0x00, 0x00, 0x13, 0xff, 0xff, 0x90, 0x00, 0x00, 0x00, 0x00, 0x19, 0xff, 0xff, 0x20, 0x00, 
	0x00, 0x00, 0x00, 0x34, 0xff, 0xfe, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x61, 0x3f, 0xf1, 0x18, 0x00, 
	0x00, 0x00, 0x00, 0xc0, 0xc0, 0x04, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1f, 0xf0, 0x04, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
	0x00, 0x1f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 
	0x00, 0x1f, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 
	0x00, 0x3f, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0xf7, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x01, 0xe3, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x0f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x07, 0x81, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x1f, 0x01, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
	};

  // figura do 'UVMAlto', 64x64px
  const unsigned char epd_bitmap_UVMAlto [] PROGMEM = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xfa, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x81, 0xc1, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x7f, 0xfd, 0x82, 0x00, 
	0x00, 0x00, 0x00, 0x6c, 0xc0, 0x06, 0x64, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x3f, 0xf1, 0xb8, 0x00, 
	0x00, 0x00, 0x00, 0x34, 0xff, 0xfc, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x69, 0xff, 0xff, 0x28, 0x00, 
	0x00, 0x00, 0x00, 0x53, 0xff, 0xff, 0xb4, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x3f, 0xf9, 0xda, 0x00, 
	0x00, 0x00, 0x0d, 0xac, 0x1f, 0xe0, 0x6a, 0xc0, 0x00, 0x00, 0x03, 0xd8, 0x0f, 0xe0, 0x67, 0x00, 
	0x00, 0x00, 0x01, 0xd8, 0x0f, 0xc0, 0x75, 0x00, 0x00, 0x00, 0x02, 0xb8, 0x0f, 0xc0, 0x75, 0x00, 
	0x00, 0x00, 0x02, 0xbc, 0x0f, 0xe0, 0x7a, 0x80, 0x00, 0x00, 0x02, 0xbe, 0x1f, 0xf0, 0xfa, 0x80, 
	0x00, 0x00, 0x02, 0xbf, 0xff, 0xff, 0xfa, 0x80, 0x00, 0x00, 0x02, 0x7f, 0xff, 0xff, 0xfa, 0x80, 
	0x00, 0x00, 0x7f, 0x7f, 0xff, 0xff, 0xfb, 0xfc, 0x00, 0x00, 0x02, 0x7f, 0xff, 0xff, 0xfa, 0x80, 
	0x00, 0x00, 0x02, 0xbf, 0xff, 0xff, 0xfa, 0x80, 0x00, 0x00, 0x02, 0xbf, 0xe0, 0x0f, 0xfa, 0x80, 
	0x00, 0x00, 0x02, 0xbf, 0x9f, 0xe7, 0xfa, 0x80, 0x00, 0x00, 0x03, 0xbf, 0x3f, 0xfb, 0xf5, 0x00, 
	0x00, 0x00, 0x03, 0xdf, 0x7f, 0xfd, 0xf7, 0x00, 0x00, 0x00, 0x0f, 0x5e, 0xff, 0xfd, 0xe7, 0x80, 
	0x00, 0x00, 0x00, 0xae, 0xff, 0xfe, 0xea, 0x60, 0x00, 0x00, 0x00, 0xa7, 0xff, 0xff, 0xd6, 0x00, 
	0x00, 0x00, 0x00, 0x53, 0xff, 0xff, 0x94, 0x00, 0x00, 0x00, 0x00, 0x39, 0xff, 0xff, 0x28, 0x00, 
	0x00, 0x00, 0x00, 0x34, 0xff, 0xfe, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x3f, 0xf1, 0x38, 0x00, 
	0x00, 0x00, 0x00, 0xc6, 0xc0, 0x06, 0xcc, 0x00, 0x00, 0x00, 0x01, 0x03, 0x9f, 0xf7, 0x84, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0xe1, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1f, 0xf2, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x38, 0x03, 0x82, 0x01, 0x01, 0x00, 0x00, 
	0x00, 0x7c, 0x0f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x0f, 0x80, 0x01, 0x00, 0x00, 0x00, 
	0x00, 0x7e, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0xfe, 0x3f, 0x80, 0x1e, 0x00, 0x00, 0x00, 0x01, 0xde, 0x3f, 0x80, 0x7f, 0x00, 0x00, 0x00, 
	0x01, 0xde, 0x7f, 0x80, 0xef, 0x00, 0x00, 0x00, 0x03, 0x9e, 0x6f, 0x81, 0xcf, 0x00, 0x00, 0x00, 
	0x03, 0x9f, 0xef, 0x83, 0xcf, 0x80, 0x00, 0x00, 0x07, 0x9f, 0xcf, 0x87, 0x9f, 0x80, 0x00, 0x00, 
	0x07, 0x1f, 0xcf, 0xc7, 0x8f, 0x80, 0x00, 0x00, 0x0f, 0x0f, 0x8f, 0xc7, 0x9f, 0x80, 0x00, 0x00, 
	0x0e, 0x0f, 0x87, 0xef, 0xf7, 0x80, 0x00, 0x00, 0x1c, 0x0f, 0x07, 0xef, 0xf7, 0x80, 0x00, 0x00, 
	0x3c, 0x07, 0x03, 0xe7, 0xe7, 0x80, 0x00, 0x00, 0x30, 0x02, 0x00, 0xc3, 0x87, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
	};

  // 'UVExtremo', 64x64px
  const unsigned char epd_bitmap_UVExtremo [] PROGMEM = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xf9, 0x00, 0x00, 
	0x00, 0x00, 0x02, 0x01, 0xc3, 0x87, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0xfd, 0x7b, 0xc0, 0x00, 
	0x00, 0x00, 0x01, 0x89, 0xc1, 0x07, 0x61, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x7f, 0xfd, 0x92, 0x00, 
	0x00, 0x00, 0x00, 0x6c, 0xc0, 0x06, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x3f, 0xf1, 0xbc, 0x00, 
	0x00, 0x00, 0x00, 0xb4, 0xff, 0xfc, 0xfa, 0x00, 0x00, 0x00, 0x01, 0x69, 0xff, 0xff, 0x2d, 0x00, 
	0x00, 0x00, 0x33, 0x53, 0xff, 0xff, 0xb5, 0x00, 0x00, 0x00, 0x1a, 0xa7, 0xff, 0xff, 0xda, 0xb0, 
	0x00, 0x00, 0x07, 0xaf, 0xff, 0xff, 0xea, 0xc0, 0x00, 0x00, 0x05, 0xdf, 0xff, 0xff, 0xe7, 0x40, 
	0x00, 0x00, 0x05, 0xd8, 0x0f, 0xc0, 0x75, 0x40, 0x00, 0x00, 0x0a, 0xbf, 0xff, 0xff, 0xf5, 0x40, 
	0x00, 0x00, 0x0a, 0xbf, 0xff, 0xff, 0xfa, 0xa0, 0x00, 0x00, 0x0a, 0xbf, 0xff, 0xff, 0xfa, 0xa0, 
	0x00, 0x00, 0x0a, 0xbf, 0xff, 0xff, 0xfa, 0xa0, 0x00, 0x00, 0x0a, 0x7f, 0xff, 0xff, 0xfa, 0xa0, 
	0x00, 0x00, 0x7f, 0x7f, 0xff, 0xff, 0xfb, 0xfc, 0x00, 0x00, 0x0a, 0x7f, 0xff, 0xff, 0xfa, 0xa0, 
	0x00, 0x00, 0x0a, 0xbf, 0xff, 0xff, 0xfa, 0xa0, 0x00, 0x00, 0x0a, 0xbf, 0xe0, 0x0f, 0xfa, 0xa0, 
	0x00, 0x00, 0x0a, 0xbf, 0x9f, 0xe7, 0xfb, 0xa0, 0x00, 0x00, 0x0b, 0xbf, 0x3f, 0xfb, 0xf5, 0x40, 
	0x00, 0x00, 0x07, 0xdf, 0x7f, 0xfd, 0xf5, 0x40, 0x00, 0x00, 0x1d, 0x5e, 0xff, 0xfd, 0xe7, 0xc0, 
	0x00, 0x00, 0x06, 0xae, 0xff, 0xfe, 0xea, 0xe0, 0x00, 0x00, 0x02, 0xe7, 0xff, 0xff, 0xd4, 0xb0, 
	0x00, 0x00, 0x01, 0x53, 0xff, 0xff, 0x95, 0x00, 0x00, 0x00, 0x01, 0x39, 0xff, 0xff, 0x2b, 0x00, 
	0x00, 0x00, 0x00, 0xb4, 0xff, 0xfe, 0xd2, 0x00, 0x00, 0x00, 0x00, 0x6b, 0x3f, 0xf1, 0x2c, 0x00, 
	0x00, 0x00, 0x00, 0xe6, 0xc0, 0x06, 0xcc, 0x00, 0x00, 0x00, 0x01, 0x1b, 0x9f, 0xf7, 0x34, 0x00, 
	0x00, 0x00, 0x02, 0x0c, 0xf1, 0x1e, 0x62, 0x00, 0x00, 0x03, 0x80, 0x03, 0x1f, 0xe3, 0x81, 0x00, 
	0x00, 0x0f, 0xe0, 0x01, 0xe1, 0x0f, 0x00, 0x00, 0x00, 0x3c, 0xe0, 0x02, 0x1f, 0xf1, 0x00, 0x00, 
	0x00, 0x79, 0xe0, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xe0, 0x00, 0x01, 0x00, 0x00, 0x00, 
	0x01, 0xf1, 0xe0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0xe3, 0xc0, 0x00, 0x01, 0x00, 0x00, 0x00, 
	0x03, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x07, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x0f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x07, 0xc1, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe7, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x07, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
	};

  //L os valores do sensor de UV e classifica-os na tabela de ndice de UV
  
  sensorValue = analogRead(UVSensorPin); /*L o sensor e estabelece o valor UV*/
 
  if (sensorValue <= 226)  {
    sensorUV = 0;
		// mostra o valor do UV no display
		display.setTextSize(2,2);
  	display.setCursor(14,50);
  	display.println("U.V");
		display.setTextSize(4,4);
  	display.setCursor(20,15);
  	display.println(sensorUV);
    				
		// mostra a figura Nivel UV
		int xx=65; //posio da figura
  	int yy=2;
  	int tt=0;
  	display.setTextColor(WHITE);
  	display.setTextColor(WHITE);
  	display.setCursor(0,0);
  	display.drawBitmap(xx, yy, epd_bitmap_UVBaixo, 64, 64, 1);
  	display.setCursor(0,0);
  
  } else if (sensorValue >= 227 & sensorValue <= 317) {
    sensorUV = 1;
    // mostra o valor do UV no display
		display.setTextSize(2,2);
  	display.setCursor(14,50);
  	display.println("U.V");
		display.setTextSize(4,4);
  	display.setCursor(20,15);
  	display.println(sensorUV);
    				
		// mostra a figura Nivel UV
		int xx=65; //posio da figura
  	int yy=2;
  	int tt=0;
  	display.setTextColor(WHITE);
  	display.setTextColor(WHITE);
  	display.setCursor(0,0);
  	display.drawBitmap(xx, yy, epd_bitmap_UVBaixo, 64, 64, 1);
  	display.setCursor(0,0);
    

  } else if (sensorValue >= 318 & sensorValue <= 407) {
    sensorUV = 2;
    // mostra o valor do UV no display
		display.setTextSize(2,2);
  	display.setCursor(14,50);
  	display.println("U.V");
		display.setTextSize(4,4);
  	display.setCursor(20,15);
  	display.println(sensorUV);
    				
		// mostra a figura Nivel UV
		int xx=65; //posio da figura
  	int yy=2;
  	int tt=0;
  	display.setTextColor(WHITE);
  	display.setTextColor(WHITE);
  	display.setCursor(0,0);
  	display.drawBitmap(xx, yy, epd_bitmap_UVBaixo, 64, 64, 1);
  	display.setCursor(0,0);
    

  }else if (sensorValue >= 408 & sensorValue <= 502) {
    sensorUV = 3;
    // mostra o valor do UV no display
		display.setTextSize(2,2);
  	display.setCursor(14,50);
  	display.println("U.V");
		display.setTextSize(4,4);
  	display.setCursor(20,15);
  	display.println(sensorUV);
    				
		// mostra a figura Nivel UV
		int xx=65; //posio da figura
  	int yy=2;
  	int tt=0;
  	display.setTextColor(WHITE);
  	display.setTextColor(WHITE);
  	display.setCursor(0,0);
  	display.drawBitmap(xx, yy, epd_bitmap_UVModerado, 64, 64, 1);
  	display.setCursor(0,0);
   
  }else if (sensorValue >= 503 & sensorValue <= 605) {
    sensorUV = 4;
    // mostra o valor do UV no display
		display.setTextSize(2,2);
  	display.setCursor(14,50);
  	display.println("U.V");
		display.setTextSize(4,4);
  	display.setCursor(20,15);
  	display.println(sensorUV);
    				
		// mostra a figura Nivel UV
		int xx=65; //posio da figura
  	int yy=2;
  	int tt=0;
  	display.setTextColor(WHITE);
  	display.setTextColor(WHITE);
  	display.setCursor(0,0);
  	display.drawBitmap(xx, yy, epd_bitmap_UVModerado, 64, 64, 1);
  	display.setCursor(0,0);
   
  }else if (sensorValue >= 606 & sensorValue <= 695) {
    sensorUV = 5;
    // mostra o valor do UV no display
		display.setTextSize(2,2);
  	display.setCursor(14,50);
  	display.println("U.V");
		display.setTextSize(4,4);
  	display.setCursor(20,15);
  	display.println(sensorUV);
    				
		// mostra a figura Nivel UV
		int xx=65; //posio da figura
  	int yy=2;
  	int tt=0;
  	display.setTextColor(WHITE);
  	display.setTextColor(WHITE);
  	display.setCursor(0,0);
  	display.drawBitmap(xx, yy, epd_bitmap_UVModerado, 64, 64, 1);
  	display.setCursor(0,0);
   
  }else if (sensorValue >= 696 & sensorValue <= 794) {
    sensorUV = 6;
    // mostra o valor do UV no display
		display.setTextSize(2,2);
  	display.setCursor(14,50);
  	display.println("U.V");
		display.setTextSize(4,4);
  	display.setCursor(20,15);
  	display.println(sensorUV);
    				
		// mostra a figura Nivel UV
		int xx=65; //posio da figura
  	int yy=2;
  	int tt=0;
  	display.setTextColor(WHITE);
  	display.setTextColor(WHITE);
  	display.setCursor(0,0);
  	display.drawBitmap(xx, yy, epd_bitmap_UVAlto, 64, 64, 1);
  	display.setCursor(0,0);
   
  }else if (sensorValue >= 795 & sensorValue <= 880) {
    sensorUV = 7;
    // mostra o valor do UV no display
		display.setTextSize(2,2);
  	display.setCursor(14,50);
  	display.println("U.V");
		display.setTextSize(4,4);
  	display.setCursor(20,15);
  	display.println(sensorUV);
    				
		// mostra a figura Nivel UV
		int xx=65; //posio da figura
  	int yy=2;
  	int tt=0;
  	display.setTextColor(WHITE);
  	display.setTextColor(WHITE);
  	display.setCursor(0,0);
  	display.drawBitmap(xx, yy, epd_bitmap_UVAlto, 64, 64, 1);
  	display.setCursor(0,0);
    
  }else if (sensorValue >= 881 & sensorValue <= 975) {
    sensorUV = 8;
    // mostra o valor do UV no display
		display.setTextSize(2,2);
  	display.setCursor(14,50);
  	display.println("U.V");
		display.setTextSize(4,4);
  	display.setCursor(20,15);
  	display.println(sensorUV);
    				
		// mostra a figura Nivel UV
		int xx=65; //posio da figura
  	int yy=2;
  	int tt=0;
  	display.setTextColor(WHITE);
  	display.setTextColor(WHITE);
  	display.setCursor(0,0);
  	display.drawBitmap(xx, yy, epd_bitmap_UVMAlto, 64, 64, 1);
  	display.setCursor(0,0);
       
  }else if (sensorValue >= 976 & sensorValue <= 1078) {
    sensorUV = 9;
    // mostra o valor do UV no display
		display.setTextSize(2,2);
  	display.setCursor(14,50);
  	display.println("U.V");
		display.setTextSize(4,4);
  	display.setCursor(20,15);
  	display.println(sensorUV);
    				
		// mostra a figura Nivel UV
		int xx=65; //posio da figura
  	int yy=2;
  	int tt=0;
  	display.setTextColor(WHITE);
  	display.setTextColor(WHITE);
  	display.setCursor(0,0);
  	display.drawBitmap(xx, yy, epd_bitmap_UVMAlto, 64, 64, 1);
  	display.setCursor(0,0);
   
  }else if (sensorValue >= 1079 & sensorValue <= 1169) {
    sensorUV = 10;
    // mostra o valor do UV no display
		display.setTextSize(2,2);
  	display.setCursor(14,50);
  	display.println("U.V");
		display.setTextSize(4,4);
  	display.setCursor(20,15);
  	display.println(sensorUV);
    				
		// mostra a figura Nivel UV
		int xx=65; //posio da figura
  	int yy=2;
  	int tt=0;
  	display.setTextColor(WHITE);
  	display.setTextColor(WHITE);
  	display.setCursor(0,0);
  	display.drawBitmap(xx, yy, epd_bitmap_UVMAlto, 64, 64, 1);
  	display.setCursor(0,0);
  
  }else if (sensorValue >= 1170) {
    sensorUV = 11;
    // mostra o valor do UV no display
		display.setTextSize(2,2);
  	display.setCursor(14,50);
  	display.println("U.V");
		display.setTextSize(4,4);
  	display.setCursor(20,15);
  	display.println(sensorUV);
    				
		// mostra a figura Nivel UV
		int xx=65; //posio da figura
  	int yy=2;
  	int tt=0;
  	display.setTextColor(WHITE);
  	display.setTextColor(WHITE);
  	display.setCursor(0,0);
  	display.drawBitmap(xx, yy, epd_bitmap_UVExtremo, 64, 64, 1);
  	display.setCursor(0,0);
  }
	CargaBat();
	display.display();
}	

void CargaBat(){ //Mostra a carga da Bateria na tela
	
	int raw = analogRead(VBAT_PIN);
  float voltage = (raw / 4095.0) * 3.3; // Considerando divisor que reduz de 3V para 3.3V ADC
  float percentage = constrain((voltage - VBAT_MIN) / (VBAT_MAX - VBAT_MIN) * 100.0, 0, 100);
	  
  display.setTextSize(1,1);
  display.setCursor(50,1);
  display.print(voltage, 1);
  display.print("V");
  display.setCursor(5,1);
  display.print(percentage, 0);
  display.print("%");

	drawBatteryIcon(percentage);

  display.display();
 

}

void drawBatteryIcon(float percent) { // Desenha cone da bateria baseado no percentual
  
	int x = 30;
  int y = 1;
  int width = 15;
  int height = 7;

  // Borda da bateria
  display.drawRect(x, y, width, height, SSD1306_WHITE);
  display.drawRect(x + width, y + 2, 2, 3, SSD1306_WHITE); //terminal da bateria.
  /*
  display.drawRect(x, y, largura, altura, cor)
  x + width  coordenada horizontal (posio do canto superior esquerdo do retngulo). 
  Isso indica que o retngulo ser desenhado aps uma largura anterior (width), ou seja,  direita de algum objeto.
  y + 2  coordenada vertical (posio do canto superior do retngulo), deslocada 2 pixels para baixo em relao ao ponto y.
  2  largura do retngulo (2 pixels).
  3  altura do retngulo (3 pixels).
  SSD1306_WHITE  cor do contorno do retngulo (branco, ou "ligado", pois a tela  monocromtica).
  */
  
  // Nveis de carga (dividido em 4)
  int fillWidth = map(percent, 0, 100, 0, width - 2);
  if (fillWidth > 0) {
    display.fillRect(x + 1, y + 1, fillWidth, height - 2, SSD1306_WHITE);
  }
}

medTPU.ino

Arduino
This function measures temperature, humidity, and local atmospheric pressure. The information is displayed as shown in the attached image.
The Esp32 reads the information directly from the BME280 sensor.
It should be noted that using this information, the user can anticipate the arrival of rain or storms. A gradual drop in atmospheric pressure can be a sign that a cold front or storm is approaching. This, combined with rising temperatures, increases water evaporation, which can lead to higher humidity and an increased likelihood of rain. To accurately predict rain, it must be accompanied by other signals, such as cloud formation, wind, etc. However, the device is very useful, especially on trails in areas with dense vegetation.
/* Funo de Medida de Temperatura, Presso e Umidade*/

void medTPU(){
  
  display.clearDisplay();

  // Leitura da Temperatura 
  display.setTextSize(1,2);
  display.setCursor(5,5);
  display.print("Temperatura: ");
  display.print(bme.readTemperature(),0);
  display.println(" C");
    
  // Leitura de Umidade 
  display.setCursor(5,25);
  display.print("Umidade Ar: ");
  display.print(bme.readHumidity(),0);
  display.println(" %");

  // Leitura da Presso atmosfrica
  display.setCursor(5,45);
  display.print("Press Atm: ");
  display.print((bme.readPressure() / 100.0F),0); //Leitura de Presso
  display.print(" Pa"); //Pascal

  display.display();
}

DataHora.ino

Arduino
The DateTime function provides information captured by the GPS module.
This information includes:
a) Greenwich Meridian Time, which is converted to a local date and the day of the week is also calculated. The calculations for the local date and days of the week are described in the .INO file, but basically, the longitude is divided by 15 degrees. Every 15 degrees from Greenwich Mean Time (GMT) is 1 hour ahead or behind. Leap years are also considered in the calculation. The days of the week depend on the date and are described in Portuguese.
b) Greenwich Meridian Time, converted to local time, is displayed in hours, minutes, and seconds. It is also calculated by observing the 15 degrees of longitude per hour.
c) The number of connected satellites is shown in the upper right corner by a satellite icon and a quantitative number. If there is no connection with at least 3 satellites, the message "No GPS Connection" will appear in Portuguese, or the information will be reset.
/*Menu Data e Hora*/

void DataHora(){
  
  display.clearDisplay();
  
  if(gps.time.isValid()){
    
    //Recebe dados e transforma
          
    HH = gps.time.hour();
    MM = gps.time.minute();
    Seg = gps.time.second();
    
    Dia = gps.date.day();
    Mes = gps.date.month();
    Ano = gps.date.year();

    satelites = gps.satellites.value();
         
    //Calculo da hora local
    longit = gps.location.lng(); //atravez da longitude determinamos a hora local
    HLT = round(longit/15); // Fator de converso da longitude em horas. A cada 15 graus de longitude, equivale a 1 hora. Nesse caso, arredondado.
    HL = HH + HLT; //A hora local  o valor da hora de Greenwich somado ou diminuido do fator de converso.
    if ((HLT<0) && (HH>=0) && (HL<=0)){ // calculos de horas a partir de 0 horas. quando o fator de converso  negativo.
      hora1 = HH + 24;
      HL = hora1 + HLT;
    }
    // Formata a hora e o minuto para exibir com dois dgitos
    String HLFormat = (HL < 10 ? "0" : "") + String(HL);
    String MMFormat = (MM < 10 ? "0" : "") + String(MM);
    String SegFormat = (Seg < 10 ? "0" : "") + String(Seg);

    //Calculo da data local
    if(((HLT<0)&&(HH>=HL))||((HLT>0)&&(HH<=HL))){
      DL = (Dia);
      Mes2 = Mes;
      Ano2 = Ano;
    }
    if((HLT<0)&&(HH<HL)){ //GMT(-)
      DL = Dia-1;
      if((DL==0)&&((Mes==5)||(Mes==7)||
        (Mes==10)||(Mes==12))){
        DL = 30;
        Mes2 = Mes-1;
      }
      if((DL==0)&&((Mes==2)||(Mes==4)||(Mes==6)||(Mes==8)||(Mes==9)||(Mes==11))){
        DL = 31;
        Mes2 = Mes-1;
      }
      if((DL==0)&&(Mes==1)){
        DL = 31;
        Mes2 = Mes-1;
        if(Mes2==0){
          Mes2 = 12;
          Ano2 = Ano-1; 
        }
      }
      if((DL==0) && ((Mes==3)&&((Ano%4)==0)&&((Ano%100)!=0)||((Ano%400)==0))){
        DL = 29;  //ano bissexto
        Mes2 = Mes-1;
      } else if((DL==0) && (Mes==3)){
          DL = 28;
          Mes2 = Mes-1;
        }
    }
    if((HLT>0)&&(HH>HL)){ //GMT(+)
      DL = Dia+1;
      if((DL==32)&&((Mes==1)||(Mes==3)||(Mes==5)||(Mes==7)||(Mes==8)||(Mes==10)||(Mes==12))){
        DL = 1;
        Mes2 = Mes+1;
        if(Mes2>12){
          Mes2 = 1;
          Ano2 = Ano+1;
        }
      }
      if((DL==31)&&((Mes==4)||(Mes==6)||(Mes==9)||(Mes==11))){
        DL = 1;
        Mes2 = Mes+1;        
      }
      if(((DL==30)||(DL==29)) && (Mes==2)){
        DL = 1;  //ano bissexto
        Mes2 = Mes+1;
      } 
    }
    
    //Calculo do dia da semana
    char DSe;
    int Ano3 = Ano2+2000;
    if(Mes2 == 1){
      Mes2 = 13;
      Ano3 = Ano3-1;
    }
    if(Mes2 == 2){
      Mes2 = 14;
      Ano3 = Ano3-1;
    }
    k = DL+2*Mes2+(3*(Mes2+1)/5)+Ano3+(Ano3/4)-(Ano3/100)+(Ano3/400)+2;
    kr = k%7;
            
    //Mostra a quantidade de satlites conectados
    int x1=100; //posio da figura
    int y1=1;
    int t1=0;
    // 'Recebendo', 20x20px
    const unsigned char epd_bitmap_Recebendo [] PROGMEM = {
	  0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x0f, 
	  0x00, 0x00, 0x07, 0x80, 0x00, 0x03, 0xd8, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x78, 0x00, 0x0f, 0xf0, 
	  0x00, 0x00, 0xcc, 0x00, 0x0e, 0x5e, 0x00, 0x08, 0x4f, 0x00, 0x05, 0x47, 0x80, 0x03, 0x43, 0xc0, 
	  0x00, 0x01, 0xc0, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };
    display.setTextColor(WHITE);
    display.setTextColor(WHITE);
    display.setCursor(0,0);
    display.drawBitmap(x1, y1, epd_bitmap_Recebendo, 20, 20, 1); //Desenha a figura de entrada
    display.setTextSize(1);
    display.setCursor(115,1);
    display.print(satelites); //imprime a quantidade de satlites
    
    //Cabealho
    display.setCursor(5,5);
    display.setTextSize(1,1);
    display.print("HORA/DATA");

    //Hora
    display.setCursor(20,19);
    display.setTextSize(2,3);
    display.print(HLFormat);
    display.print(":");
    display.print(MMFormat);
    display.print(":");
    display.print(SegFormat);
    
    //Data
    display.setCursor(10,47);
    display.setTextSize(1,2);
    display.print(DL);
    display.print("/");
    display.print(Mes2);
    display.print("/");
    display.print(Ano2);
    
    //Dia da semana
    display.setCursor(80,47);
    display.setTextSize(1,2);
    if(kr == 0){
      display.print("SABADO");
    }else if(kr == 1){
      display.print("DOMINGO");
    }else if(kr == 2){
      display.print("SEGUNDA");
    }else if(kr == 3){
      display.print("TERCA");
    }else if(kr == 4){
      display.print("QUARTA");
    }else if(kr == 5){
      display.print("QUINTA");
    }else if(kr == 6){
      display.print("SEXTA");
    }
  } else {
    display.clearDisplay();
    display.setTextSize(1,2);
    display.setCursor(20,10);
    display.print("Sem Conexao GPS");
    display.setCursor(20,30);
    display.print("Para Data/Hora");
  }
  display.display();

}

GPS.ino

Arduino
The GPS function provides the device's latitude, longitude, and altitude in meters.
The function takes the values directly from the GPS module and adds a negative sign if the latitude or longitude is west of the Greenwich meridian. The function then displays a letter representing the cardinal points.
The number of connected satellites is displayed in the upper right corner with a satellite icon and a quantitative number. If there is no connection to at least three satellites, the message "No GPS Connection" appears.
/* Funo GPS */

void GPS(){
  
  display.clearDisplay();

  if(gps.location.isValid()){
    
    latitude = float(gps.location.lat());
    longitude = float(gps.location.lng());
    altitude = float(gps.altitude.meters());
    satelites = gps.satellites.value();

    //Cabealho
    display.setCursor(5,3);
    display.setTextSize(1,1);
    display.print("GPS");

    //Mostra a quantidade de satlites conectados
    int x1=100; //posio da figura
    int y1=1;
    int t1=0;
    // 'Recebendo', 20x20px
    const unsigned char epd_bitmap_Recebendo [] PROGMEM = {
	  0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x0f, 
	  0x00, 0x00, 0x07, 0x80, 0x00, 0x03, 0xd8, 0x00, 0x01, 0xfc, 0x00, 0x00, 0x78, 0x00, 0x0f, 0xf0, 
	  0x00, 0x00, 0xcc, 0x00, 0x0e, 0x5e, 0x00, 0x08, 0x4f, 0x00, 0x05, 0x47, 0x80, 0x03, 0x43, 0xc0, 
	  0x00, 0x01, 0xc0, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };
    display.setTextColor(WHITE);
    display.setTextColor(WHITE);
    display.setCursor(0,0);
    display.drawBitmap(x1, y1, epd_bitmap_Recebendo, 20, 20, 1); //Desenha a figura de entrada
    display.setTextSize(1);
    display.setCursor(115,1);
    display.print(satelites); //imprime a quantidade de satlites
    
    //Mostra a Latitude
    display.setTextSize(1,2);
    display.setCursor(15,13);
    display.print("Lat: ");
    display.println(latitude, 3);
    if(latitude < 0){
      display.setCursor(90,13);
      display.print("S");
    }else{
      display.setCursor(90,13);
      display.print("N");
    }
    
    //Mostra a longitude   
    display.setCursor(15,30);
    display.print("Lon: ");
    display.println(longitude, 3);
    if(longitude < 0){
      display.setCursor(90,30);
      display.print("O");
    }else{
      display.setCursor(90,30);
      display.print("L");
    }
    
    //Mostra a Altitude
    display.setCursor(15,47);
    display.print("Alt: ");
    display.print(altitude,0);
    display.println(" m");

  } else { //Sem Conexo GPS
    display.clearDisplay();
    display.setTextSize(1,2);
    display.setCursor(20,10);
    display.println("Sem Conexao GPS");
    display.setCursor(20,30);
    display.print("Para GPS");
  }
  display.display();

}

Credits

Armando Leonardo
4 projects • 5 followers
I have electronics and computer as a hobby. I like to build and create things as well as solve logic problems

Comments