Está en la página 1de 30

PROYECTO FINAL

Internet de las cosas IoT

Máster Universitario en Electrónica y Telecomunicación Aplicadas

Curso 2020/2021

Alumno: Irene Merino Fernández

Profesor: Luis Hernández Acosta


ÍNDICE
Tabla de figuras ................................................................................................................ 2

1. Introducción.................................................................................................................. 3

2. Esquemas ...................................................................................................................... 5

3. Código ........................................................................................................................... 8

3.1 Arduino ................................................................................................................... 8

3.2 ESP32-CAM ........................................................................................................... 11

3.3 ESP32-MQTT-TEMP .............................................................................................. 18

3.4 ESP32-WebService ................................................................................................ 23

3.5 Raspberry Pi .......................................................................................................... 27

3.5.1 RPi_MQTT_Temperature............................................................................... 27

3.5.2 RPi_SERIAL_Capacity ..................................................................................... 29

3.5.3 RPi_Response ................................................................................................ 29

3.5.4 RPi_all.sh........................................................................................................ 30

Tabla de figuras
Figura 1. Sistema Arduino................................................................................................. 5
Figura 2. Sistema ESP32-CAM........................................................................................... 5
Figura 3. Sistema ESP32. ................................................................................................... 6
Figura 4. Sistema ESP32TTL LoRa OLED. ........................................................................... 6
Figura 5. Sistema Raspberry Pi. ........................................................................................ 7

2
1. Introducción
Para cerrar la asignatura, hemos realizado el proyecto final, que comprende desde
los conocimientos asimilados con Arduino, hasta Firebase, integrándolos en un sistema
de IoT.

En este documento se pretende recoger el trabajo realizado en el proyecto, dando


los esquemas realizados y el código implementado. Previo a esto, vamos a realizar una
descripción del sistema IoT implementado.

El sistema IoT cuenta con los siguientes elementos:

• Arduino UNO. Implementa un contador de personas usando ArduinoBlocks.


En él tenemos dos sensores de distancia, configurados para contar personas
al paso entre 20 y 40 cm. Además, cuenta con un led RGB, el cual se pondrá
rojo cuando el aforo está completo, y se mantendrá verde si aún hay espacio
disponible. También implementa un LCD que muestra el aforo máximo y el
aforo actual en tiempo real.
• ESP32-CAM. Implementa una cámara web usando lenguaje Arduino, a la cual
se accederá a través de la IP facilitada por la red en el momento de ejecución
del programa. Esta irá junto a un Arduino UNO, quien realizará las funciones
de programación y alimentación del módulo.
• ESP32-TTL LoRa OLED. Implementa un medidor de temperatura usando
lenguaje Arduino. Cuenta con una pantalla integrada en el chip que muestra
en tiempo real la temperatura de medida del sensor, y un mensaje que
permite o no el paso. Además, implementa comunicaciones MQTT para
enviar los datos a la Raspberry con el fin de trabajar con ellos en una base
de datos, y un pequeño servicio web que muestra un mensaje de
información sobre el sistema.
• ESP32. Implementa un dispensador de hidrogel electrónico. Cuenta con dos
sensores de agua, los cuales se colocarán en la mitad y parte inferior de un
bote de hidrogel, con el fin de saber aproximadamente qué niveles de
hidrogel tenemos. Además, cuenta con un relé y un motor, que dispensarán
el líquido. Finalmente, se implementa un servicio web, que cuenta con un
slider, el cual activa y desactiva el relé, y por lo tanto la dispensación.
También muestra el nivel de gel hidroalcohólico en tres rangos: 0% (vacío),
50-100% (entre vacío y medio lleno) y 100% (entre medio lleno y lleno).
• Raspberry Pi. Esta implementa varios ficheros utilizando un bash. En estos
archivos contamos, por un lado, con las comunicaciones seriales para utilizar
los datos del Arduino en la base de datos Firebase que hemos
implementado. Por otro lado, contamos con las comunicaciones MQTT con
el sensor de temperatura con el mismo fin de usar la base de datos.
Finalmente, contamos con la actuación de la Raspberry ante los datos de

3
temperatura, teniendo un led verde si la temperatura es adecuada, y un led
rojo si no lo es.

4
2. Esquemas

Figura 1. Sistema Arduino.

Figura 2. Sistema ESP32-CAM

5
Figura 3. Sistema ESP32.

Figura 4. Sistema ESP32TTL LoRa OLED.

6
Figura 5. Sistema Raspberry Pi.

7
3. Código
3.1 Arduino
/* ArduinoBlocks.com */

/* Project: Sensor presencia */

/* Author: Irene Merino Fernández */

#include <Wire.h>

#include "ABlocks_LiquidCrystal_I2C.h"

double full;

double now;

double prev;

double delay2;

LiquidCrystal_I2C lcd(0x27,16,2);

double fnc_ultrasonic_distance(int _t, int _e){

unsigned long dur=0;

digitalWrite(_t, LOW);

delayMicroseconds(5);

digitalWrite(_t, HIGH);

delayMicroseconds(10);

digitalWrite(_t, LOW);

dur = pulseIn(_e, HIGH, 18000);

return (dur/57);

void setup()

8
lcd.begin();lcd.noCursor();lcd.backlight();

Serial.begin(9600); Serial.flush(); while(Serial.available()>0)Serial.read();

pinMode(9, OUTPUT);

pinMode(10, OUTPUT);

pinMode(11, OUTPUT);

pinMode(4, OUTPUT);

pinMode(5, INPUT);

pinMode(2, OUTPUT);

pinMode(3, INPUT);

full = 100;

now = 0;

delay2 = 200;

prev = 0;

analogWrite(9,0);analogWrite(10,153);analogWrite(11,0);

void loop()

if ((prev != now)) {

Serial.println(now);

prev = now;

lcd.setCursor(0, 0);

lcd.print(String("Aforo:"));

9
lcd.setCursor(7, 0);

lcd.print((long)(now));

lcd.setCursor(0, 1);

lcd.print(String("Aforo max:"));

lcd.setCursor(11, 1);

lcd.print((long)(full));

if (((fnc_ultrasonic_distance(4,5) >= 20) && (fnc_ultrasonic_distance(4,5) <= 40))) {

if ((now < full)) {

lcd.clear();

analogWrite(9,255);analogWrite(10,255);analogWrite(11,255);

delay(delay2);

analogWrite(9,0);analogWrite(10,153);analogWrite(11,0);

now = (now + 1);

lcd.clear();

if ((now >= full)) {

lcd.clear();

lcd.setCursor(0, 1);

lcd.print(String("Aforo completo"));

analogWrite(9,255);analogWrite(10,255);analogWrite(11,255);

delay(delay2);

analogWrite(9,255);analogWrite(10,0);analogWrite(11,0);

lcd.clear();

10
}

if (((fnc_ultrasonic_distance(2,3) >= 20) && (fnc_ultrasonic_distance(2,3) <= 40))) {

if ((now <= full)) {

lcd.clear();

analogWrite(9,255);analogWrite(10,255);analogWrite(11,255);

delay(delay2);

analogWrite(9,51);analogWrite(10,204);analogWrite(11,0);

now = (now - 1);

if ((now <= 0)) {

lcd.clear();

analogWrite(9,255);analogWrite(10,255);analogWrite(11,255);

delay(delay2);

analogWrite(9,51);analogWrite(10,204);analogWrite(11,0);

now = 0;

3.2 ESP32-CAM
#include "esp_camera.h"

#include <WiFi.h>

#include "esp_timer.h"

#include "img_converters.h"

11
#include "Arduino.h"

#include "fb_gfx.h"

#include "soc/soc.h" //disable brownout problems

#include "soc/rtc_cntl_reg.h" //disable brownout problems

#include "esp_http_server.h"

//Replace with your network credentials

const char* ssid = "TP-LINK_IRENE";

const char* password = "030120161973";

#define PART_BOUNDARY "123456789000000000000987654321"

#define PWDN_GPIO_NUM 32

#define RESET_GPIO_NUM -1

#define XCLK_GPIO_NUM 0

#define SIOD_GPIO_NUM 26

#define SIOC_GPIO_NUM 27

#define Y9_GPIO_NUM 35

#define Y8_GPIO_NUM 34

#define Y7_GPIO_NUM 39

#define Y6_GPIO_NUM 36

#define Y5_GPIO_NUM 21

#define Y4_GPIO_NUM 19

#define Y3_GPIO_NUM 18

#define Y2_GPIO_NUM 5

#define VSYNC_GPIO_NUM 25

12
#define HREF_GPIO_NUM 23

#define PCLK_GPIO_NUM 22

static const char* _STREAM_CONTENT_TYPE = "multipart/x-mixed-replace;boundary="


PART_BOUNDARY;

static const char* _STREAM_BOUNDARY = "\r\n--" PART_BOUNDARY "\r\n";

static const char* _STREAM_PART = "Content-Type: image/jpeg\r\nContent-Length:


%u\r\n\r\n";

httpd_handle_t stream_httpd = NULL;

static esp_err_t stream_handler(httpd_req_t *req){

camera_fb_t * fb = NULL;

esp_err_t res = ESP_OK;

size_t _jpg_buf_len = 0;

uint8_t * _jpg_buf = NULL;

char * part_buf[64];

res = httpd_resp_set_type(req, _STREAM_CONTENT_TYPE);

if(res != ESP_OK){

return res;

while(true){

fb = esp_camera_fb_get();

if (!fb) {

Serial.println("Camera capture failed");

res = ESP_FAIL;

} else {

13
if(fb->width > 400){

if(fb->format != PIXFORMAT_JPEG){

bool jpeg_converted = frame2jpg(fb, 80, &_jpg_buf, &_jpg_buf_len);

esp_camera_fb_return(fb);

fb = NULL;

if(!jpeg_converted){

Serial.println("JPEG compression failed");

res = ESP_FAIL;

} else {

_jpg_buf_len = fb->len;

_jpg_buf = fb->buf;

if(res == ESP_OK){

size_t hlen = snprintf((char *)part_buf, 64, _STREAM_PART, _jpg_buf_len);

res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen);

if(res == ESP_OK){

res = httpd_resp_send_chunk(req, (const char *)_jpg_buf, _jpg_buf_len);

if(res == ESP_OK){

14
res = httpd_resp_send_chunk(req, _STREAM_BOUNDARY,
strlen(_STREAM_BOUNDARY));

if(fb){

esp_camera_fb_return(fb);

fb = NULL;

_jpg_buf = NULL;

} else if(_jpg_buf){

free(_jpg_buf);

_jpg_buf = NULL;

if(res != ESP_OK){

break;

//Serial.printf("MJPG: %uB\n",(uint32_t)(_jpg_buf_len));

return res;

void startCameraServer(){

httpd_config_t config = HTTPD_DEFAULT_CONFIG();

config.server_port = 80;

httpd_uri_t index_uri = {

.uri = "/",

15
.method = HTTP_GET,

.handler = stream_handler,

.user_ctx = NULL

};

//Serial.printf("Starting web server on port: '%d'\n", config.server_port);

if (httpd_start(&stream_httpd, &config) == ESP_OK) {

httpd_register_uri_handler(stream_httpd, &index_uri);

void setup() {

WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector

Serial.begin(115200);

Serial.setDebugOutput(false);

camera_config_t config;

config.ledc_channel = LEDC_CHANNEL_0;

config.ledc_timer = LEDC_TIMER_0;

config.pin_d0 = Y2_GPIO_NUM;

config.pin_d1 = Y3_GPIO_NUM;

config.pin_d2 = Y4_GPIO_NUM;

config.pin_d3 = Y5_GPIO_NUM;

config.pin_d4 = Y6_GPIO_NUM;

config.pin_d5 = Y7_GPIO_NUM;

config.pin_d6 = Y8_GPIO_NUM;

16
config.pin_d7 = Y9_GPIO_NUM;

config.pin_xclk = XCLK_GPIO_NUM;

config.pin_pclk = PCLK_GPIO_NUM;

config.pin_vsync = VSYNC_GPIO_NUM;

config.pin_href = HREF_GPIO_NUM;

config.pin_sscb_sda = SIOD_GPIO_NUM;

config.pin_sscb_scl = SIOC_GPIO_NUM;

config.pin_pwdn = PWDN_GPIO_NUM;

config.pin_reset = RESET_GPIO_NUM;

config.xclk_freq_hz = 20000000;

config.pixel_format = PIXFORMAT_JPEG;

if(psramFound()){

config.frame_size = FRAMESIZE_UXGA;

config.jpeg_quality = 10;

config.fb_count = 2;

} else {

config.frame_size = FRAMESIZE_SVGA;

config.jpeg_quality = 12;

config.fb_count = 1;

esp_err_t err = esp_camera_init(&config);

if (err != ESP_OK) {

Serial.printf("Camera init failed with error 0x%x", err);

17
return;

// Wi-Fi connection

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {

delay(500);

Serial.print(".");

Serial.println("");

Serial.println("WiFi connected");

Serial.print("Camera Stream Ready! Go to: http://");

Serial.print(WiFi.localIP());

// Start streaming web server

startCameraServer();

void loop() {

delay(1);

3.3 ESP32-MQTT-TEMP
#include <WiFi.h>

#include <PubSubClient.h>

#include <Wire.h>

#include <Adafruit_MLX90614.h>

#include <TFT_eSPI.h>

18
#include <SPI.h>

// Replace the next variables with your SSID/Password combination

const char* ssid = "TP-LINK_IRENE";

const char* password = "030120161973";

// Add your MQTT Broker IP address, example:

const char* mqtt_server = "192.168.1.190";

WiFiClient espClient;

PubSubClient client(espClient);

long lastMsg = 0;

char msg[50];

int value = 0;

Adafruit_MLX90614 mlx = Adafruit_MLX90614();

TFT_eSPI tft = TFT_eSPI();

void setup() {

Serial.begin(115200);

setup_wifi();

client.setServer(mqtt_server, 1883);

client.setCallback(callback);

tft.init();

tft.setRotation(1);

mlx.begin();

19
void setup_wifi() {

delay(10);

// We start by connecting to a WiFi network

Serial.println();

Serial.print("Connecting to ");

Serial.println(ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {

delay(500);

Serial.print(".");

Serial.println("");

Serial.println("WiFi connected");

Serial.println("IP address: ");

Serial.println(WiFi.localIP());

void callback(char* topic, byte* message, unsigned int length) {

Serial.print("Message arrived on topic: ");

Serial.print(topic);

Serial.print(". Message: ");

String messageTemp;

for (int i = 0; i < length; i++) {

20
Serial.print((char)message[i]);

messageTemp += (char)message[i];

Serial.println();

void reconnect() {

// Loop until we're reconnected

while (!client.connected()) {

Serial.print("Attempting MQTT connection...");

// Attempt to connect

if (client.connect("ESP32Client")) {

Serial.println("connected");

// Subscribe

client.subscribe("esp32/output");

} else {

Serial.print("failed, rc=");

Serial.print(client.state());

Serial.println(" try again in 5 seconds");

// Wait 5 seconds before retrying

delay(5000);

21
void loop() {

// Temperature in Celsius

float temperature = mlx.readObjectTempC();

if (!client.connected()) {

reconnect();

tft.fillScreen(TFT_BLACK);

tft.setTextColor(TFT_WHITE, TFT_BLACK);

tft.drawString("Temperature:", 1,0, 4);

if(temperature<38){

tft.setTextColor(TFT_GREEN, TFT_BLACK);

tft.drawFloat(temperature, 2, 0, 40, 4);

tft.drawString("Normal temperature", 1,70, 4);

tft.drawString("Access granted", 1,100, 4);

else{

tft.setTextColor(TFT_RED, TFT_BLACK);

tft.drawFloat(temperature, 2, 0, 40, 4);

tft.drawString("Temperature:",1,1,4);

tft.drawString("High temperature", 1,70, 4);

tft.drawString("Access denied", 1,100, 4);

delay(2000);

22
client.loop();

long now = millis();

if (now - lastMsg > 500) {

lastMsg = now;

// Convert the value to a char array

char tempString[8];

dtostrf(temperature, 1, 2, tempString);

Serial.print("Temperature: ");

Serial.println(tempString);

client.publish("esp32/temperature", tempString);

3.4 ESP32-WebService
try:

import usocket as socket

except:

import socket

from machine import Pin, ADC

import network

import esp

esp.osdebug(None)

import gc

gc.collect()

ssid = 'TP-LINK_IRENE'

23
password = '030120161973'

station = network.WLAN(network.STA_IF)

station.active(True)

station.connect(ssid, password)

while station.isconnected() == False:

pass

print('Connection successful')

print(station.ifconfig())

# ESP32 GPIO 26

relay = Pin(26, Pin.OUT)

adc0=ADC(Pin(36))

adc1=ADC(Pin(39))

state = 0

def web_page():

if relay.value() == 0:

relay_state = ''

else:

relay_state = 'checked'

if state == 0:

dispenser_state="EMPTY"

if state == 1:

dispenser_state=">50%"

24
if state == 2:

dispenser_state = "50%-100%"

html = """<html><head><meta name="viewport" content="width=device-width,


initial-scale=1"><style>

body{font-family:Arial; text-align: center; margin: 0px auto; padding-top:30px;}

.switch{position:relative;display:inline-block;width:120px;height:68px}.switch
input{display:none}

.slider{position:absolute;top:0;left:0;right:0;bottom:0;background-color:#ccc;border-
radius:34px}

.slider:before{position:absolute;content:"";height:52px;width:52px;left:8px;bottom:8p
x;background-color:#fff;-webkit-transition:.4s;transition:.4s;border-radius:68px}

input:checked+.slider{background-color:#2196F3}

input:checked+.slider:before{-webkit-transform:translateX(52px);-ms-
transform:translateX(52px);transform:translateX(52px)}

</style><script>function toggleCheckbox(element) { var xhr = new XMLHttpRequest();


if(element.checked){ xhr.open("GET", "/?relay=on", true); }

else { xhr.open("GET", "/?relay=off", true); } xhr.send(); }</script></head><body>

<h1>Hydrogel Dispenser</h1>

<p>Dispenser state: <strong>""" + dispenser_state + """</strong> </p>

<label class="switch"><input type="checkbox" onchange="toggleCheckbox(this)"


%s><span class="slider">

</span></label></body></html>""" % (relay_state)

return html

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

s.bind(('192.168.1.179', 80))

25
s.listen(5)

while True:

try:

if gc.mem_free() < 102000:

gc.collect()

conn, addr = s.accept()

conn.settimeout(3.0)

print('Got a connection from %s' % str(addr))

request = conn.recv(1024)

conn.settimeout(None)

request = str(request)

print('Content = %s' % request)

relay_on = request.find('/?relay=on')

relay_off = request.find('/?relay=off')

if relay_on == 6:

print('RELAY ON')

relay.value(1)

if relay_off == 6:

print('RELAY OFF')

relay.value(0)

level50 = adc0.read()

level0 = adc1.read()

if(level50 == 0 and level0 == 0):

26
state = 0

if(level50 != 0 and level0 == 0):

state = 1

if(level50 != 0 and level0 != 0):

state = 2

print(state)

response = web_page()

conn.send('HTTP/1.1 200 OK\n')

conn.send('Content-Type: text/html\n')

conn.send('Connection: close\n\n')

conn.sendall(response)

conn.close()

except OSError as e:

conn.close()

print('Connection closed')

3.5 Raspberry Pi
3.5.1 RPi_MQTT_Temperature
import paho.mqtt.client as mqtt

import json

from firebase import firebase

from time import sleep

import serial

27
firebase = firebase.FirebaseApplication('https://proyectofinaliot-f694d-default-
rtdb.firebaseio.com', None)

firebase.put("/", "temp", "0.00")

TOPIC = 'esp32/temperature'

#fr Callback fires when conected to MQTT broker.

def on_connect(client, userdata, flags, rc):

print('Connected with result code {0}'.format(rc))

# Subscribe (or renew if reconnect).

client.subscribe(TOPIC)

# Callback fires when a published message is received.

def on_message(client, userdata, msg):

temp = msg.payload.decode('utf-8')

print(msg.topic+" "+ str(temp))

if temp is not None:

firebase.put("/", "/temp", temp)

else:

print('Failed to get reading. Try again!')

client = mqtt.Client()

client.on_connect = on_connect # Specify on_connect callback

client.on_message = on_message # Specify on_message callback

client.connect('localhost', 1883, 60) # Connect to MQTT broker (also running on Pi)

try:

client.loop_forever()

except KeyboardInterrupt:

28
pass

finally:

pass

3.5.2 RPi_SERIAL_Capacity
import serial

from time import sleep

from firebase import firebase

ser = serial.Serial('/dev/ttyACM0', 9600)

firebase = firebase.FirebaseApplication('https://proyectofinaliot-f694d-default-
rtdb.firebaseio.com', None)

firebase.put("/", "capacity", "0.00")

while True:

cap = ser.readline()

cap_str = cap.decode('utf-8').replace(r"\r\n", "")

print("Arduino " + str(cap_str))

firebase.put("/", "/capacity", str(cap_str))

3.5.3 RPi_Response
import RPi.GPIO as GPIO

from firebase import firebase

from time import sleep

firebase = firebase.FirebaseApplication('https://proyectofinaliot-f694d-default-
rtdb.firebaseio.com', None)

GPIO.setmode(GPIO.BCM)

29
GPIO.setwarnings(False)

GPIO.setup(12, GPIO.OUT) #Rojo

GPIO.setup(18, GPIO.OUT) #Verde

try:

while True:

temp = firebase.get("/", "temp")

floatTemp = float(temp)

print(float(temp))

if(floatTemp < 38):

GPIO.output(18, GPIO.HIGH) #Verde

GPIO.output(12, GPIO.LOW) #Rojo

else:

GPIO.output(12, GPIO.HIGH) #Rojo

GPIO.output(18, GPIO.LOW) #Verde

except KeyboardInterrupt:

GPIO.cleanup()

3.5.4 RPi_all.sh
python3 RPi_SERIAL_Capacity.py $

python3 RPi_MQTT_Temperature.py $

python3 RPi_Response.py $

30

También podría gustarte