Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Sistema inteligente de monitorización de temperatura para escuelas: preciso, en tiempo real y seguro

Componentes y materiales

ComponenteCantidad
Pycom SiPy (Sigfox + WiFi/BLE)1
Raspberry Pi 3 Model B1
Arduino Nano R31
Conversor de nivel lógico bidireccional1
Módulo RFID RC522 (NFC)1
Sensor distancia Sharp GP2Y0A41SK0F (4-30 cm)1
Sensor temperatura IR MLX90614 (I2C)1
Pantalla LCD I2C 16x2 (DFRobot)1
LED genérico + resistencia 330Ω1
Buzzer1
Resistencias 330Ω (x2)2

Aplicaciones y servicios

Sobre el proyecto

Sistema inteligente de monitorización de temperatura para escuelas: preciso, en tiempo real y seguro

Planteamiento del problema

En Asia, por clima cálido y brotes como SARS (2003), los escolares deben medirse la temperatura cada trimestre. Cada alumno debe traer su termómetro digital, pero a menudo lo olvidan, pierden o rompen. No pueden compartirlos por higiene y algunos no pueden comprar uno nuevo. Además, el profesor debe introducir manualmente 40 temperaturas en base de datos: tarea tediosa y lenta.

La solución

Sistema inteligente de monitorización de temperatura para escuelas: preciso, en tiempo real y seguro

Sistema automático que mide temperatura a usuarios válidos (tarjeta RFID), almacena datos localmente (MySQL en Raspberry Pi) y en la nube (ThingSpeak vía Sigfox), y envía alerta por email si hay fiebre (>38°C). Cumple Objetivo de Desarrollo Sostenible: Salud y bienestar.

Funcionamiento: Raspberry Pi + Arduino

  1. Raspberry Pi ejecuta Python + MySQL. Al arrancar, crea BD y tablas si no existen.
  2. Espera datos por puerto serie del Arduino (handshaking).
  3. Al detectar tarjeta RFID, Arduino envía UID a Raspberry Pi.
  4. Raspberry Pi valida UID en BD. Si válido → responde con iniciales y userID; Arduino muestra "Welcome, [iniciales]" en LCD. Si no → "Error! Invalid User!".
  5. Arduino pide tomar temperatura. Sensor de distancia (Sharp) detecta presencia.
  6. Sensor IR MLX90614 mide temperatura frontal. Si está en rango 28-42°C, muestra en LCD y envía a Raspberry Pi (MySQL) y a SiPy (Sigfox → ThingSpeak).
  7. Handshaking bidireccional: ambas partes envían "READY"/"RECEIVED" para sincronizarse.
Sistema inteligente de monitorización de temperatura para escuelas: preciso, en tiempo real y seguro
Sistema inteligente de monitorización de temperatura para escuelas: preciso, en tiempo real y seguro

Funcionamiento: Sigfox (SiPy)

SiPy recibe por UART (pines P3/P4) el userID y temperatura (parte entera y decimal). Envía 3 bytes a backend Sigfox (RCZ4 Asia). El backend reenvía a ThingSpeak mediante callback HTTP.

Funcionamiento: Nube (ThingSpeak + IFTTT)

  1. Canal privado (SIGFOX) TEMPERATURE PRIVATE VIEWING recibe bytes crudos (userID, temp_entera, temp_decimal).
  2. MATLAB Analysis (disparado por React al insertar datos) combina parte entera+decimal, escribe en canal público (SIGFOX) TEMPERATURE PUBLIC VIEWING (userID, temperatura combinada).
  3. Si temperatura ≥ 38°C, MATLAB lanza Webhook IFTTT → email a profesores.
  4. Canal público muestra tabla autoactualizable (estilo Excel) para administración.
Sistema inteligente de monitorización de temperatura para escuelas: preciso, en tiempo real y seguro

1. Conexiones Arduino Nano

MóduloPines Arduino
RFID RC522SDA→D10, SCK→D13, MOSI→D11, MISO→D12, RST→D9, 3.3V, GND
LCD I2CSDA→A4, SCL→A5, 5V, GND
Sensor distancia SharpVCC→5V, GND, OUT→A0
BuzzerGND, OUT→D6
MLX90614SDA→A4, SCL→A5, 5V, GND
LEDCátodo→GND, Ánodo→D7

2. Configuración Raspberry Pi

  1. Instalar Raspbian (flashear imagen con balenaEtcher).
  2. Habilitar SSH/VNC en Raspberry Pi Configuration.
  3. (Opcional) IP estática eth0 editando /etc/dhcpcd.conf.

3. Base de datos MySQL (MariaDB)

sudo apt update && sudo apt upgrade
sudo apt install apache2
sudo apt install php php-mbstring
sudo apt install mariadb-server php-mysql
sudo mysql --user=root
# En consola MySQL:
DROP USER 'root'@'localhost';
CREATE USER 'root'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;
exit;
mysql --user=root --password=yourpassword
sudo apt install phpmyadmin
sudo phpenmod mysqli
sudo /etc/init.d/apache2 restart

Acceso a phpMyAdmin: https://IP_RASPBERRY/phpmyadmin

4. SiPy Expansion Board 2.0

  1. Insertar SiPy con botón de reset hacia USB.
  2. Actualizar firmware (herramienta Pycom) eligiendo región RCZ correcta.
  3. Instalar VS Code + extensión Pymakr + Node.js.
  4. Crear carpeta proyecto, archivo main.py, subir/ejecutar.
  5. Obtener Device ID y PAC con script:
from network import Sigfox
import binascii
sigfox = Sigfox(mode=Sigfox.SIGFOX, rcz=Sigfox.RCZ4)
print(binascii.hexlify(sigfox.id()))
print(binascii.hexlify(sigfox.pac()))
  1. Registrar en Sigfox Backend (elegir país, ingresar ID/PAC, crear cuenta).
  2. Probar envío: s.send(bytes([1,2,3,4,5,6,7,8,9,10,11,12])).

5. Configuración en la nube (ThingSpeak + IFTTT)

  1. Crear applet IFTTT: Webhooks (evento "fever") → Email (incluir {{Value1}}, {{Value2}}).
  2. Crear dos canales ThingSpeak: privado (recibe de Sigfox) y público (visualización).
  3. Configurar React en canal privado: al insertar datos en field3 (userID ≠ 0) → dispara MATLAB Analysis.
  4. MATLAB Analysis combina temperatura, escribe en canal público y si ≥38°C llama a Webhook IFTTT.
  5. Tabla HTML en canal público (solo vista privada) para análisis.

Colaboradores

Código

[C] ARDUINO NANO

/* 90% Aden (https://www.astero.me), 10% librerías open source */
#include <SPI.h>
#include <MFRC522.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <SoftwareSerial.h>
#include <Adafruit_MLX90614.h>

#define RST_PIN 9
#define SS_PIN 10
#define BUZZER_PIN 7
#define LED_PIN 6
#define dist_sensePin A0

MFRC522 mfrc522(SS_PIN, RST_PIN);
LiquidCrystal_I2C lcd(0x27, 16, 2);
Adafruit_MLX90614 mlx = Adafruit_MLX90614();
SoftwareSerial unoSerial(2, 3); // RX, TX para SiPy

boolean tapped = true;
boolean confirmation = false;

String GetUID() {
  String uid = "", uid_ns = "";
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    uid.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
    uid.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
  uid_ns.concat(uid.charAt(1)); uid_ns.concat(uid.charAt(2));
  uid_ns.concat(uid.charAt(4)); uid_ns.concat(uid.charAt(5));
  uid_ns.concat(uid.charAt(7)); uid_ns.concat(uid.charAt(8));
  uid_ns.concat(uid.charAt(10)); uid_ns.concat(uid.charAt(11));
  return uid_ns;
}

void setup() {
  Serial.begin(9600);
  while (!confirmation) { Serial.println("ARDUINO"); confirmation = Serial.readString() == "RAPI"; delay(1000); }
  SPI.begin(); mfrc522.PCD_Init(); mlx.begin(); unoSerial.begin(9600);
  pinMode(BUZZER_PIN, OUTPUT); pinMode(LED_PIN, OUTPUT);
  lcd.init(); lcd.backlight();
}

void loop() {
  boolean readySignal = Serial.readString() == "READY";
  if (readySignal) { tapped = true; Serial.println("RECEIVED"); }

  if (tapped) {
    digitalWrite(BUZZER_PIN, 0); digitalWrite(LED_PIN, 0); lcd.clear();
    lcd.setCursor(0,0); lcd.print(" Please tap");
    lcd.setCursor(0,1); lcd.print(" your card.");
    delay(500); tapped = false;
  } else {
    if (!mfrc522.PICC_IsNewCardPresent()) return;
    if (!mfrc522.PICC_ReadCardSerial()) return;
    String card_UID = GetUID(); card_UID.toUpperCase();
    Serial.print(card_UID); Serial.print("\n");

    String rawData = Serial.readString();
    int commaPos = rawData.indexOf(',');
    String userInitial = rawData.substring(0, commaPos);
    int userID = rawData.substring(commaPos + 1).toInt();
    lcd.clear();

    if (userID != 0 && userInitial != "0") {
      lcd.setCursor(0,0); lcd.print("Welcome, ");
      lcd.setCursor(0,1); lcd.print(userInitial);

      int dist_senseValue = analogRead(dist_sensePin);
      byte temp_Hbyte = 0, temp_Lbyte = 0;
      float meas_temp = 0.0;
      delay(2000);
      while ((dist_senseValue < 170) || (dist_senseValue > 200)) {
        dist_senseValue = analogRead(dist_sensePin);
        lcd.setCursor(0,0); lcd.print("Please take");
        lcd.setCursor(0,1); lcd.print("your temperature.");
      }
      digitalWrite(BUZZER_PIN, 1); digitalWrite(LED_PIN, 1); lcd.clear();
      meas_temp = (float)mlx.readObjectTempC();
      temp_Hbyte = floor(meas_temp);
      temp_Lbyte = (meas_temp - temp_Hbyte) * 100;

      String sMeasTemp = ""; sMeasTemp += userID; sMeasTemp += ","; sMeasTemp += temp_Hbyte; sMeasTemp += ","; sMeasTemp += temp_Lbyte;
      Serial.println("TEMP"); Serial.println(meas_temp);

      if (meas_temp >= 28 && meas_temp <= 42) {
        unoSerial.print(sMeasTemp);
        lcd.setCursor(0,0); lcd.print("Temperature: ");
        lcd.setCursor(0,1); lcd.print(" " + String(meas_temp));
      }
    } else {
      lcd.setCursor(0,0); lcd.print("Error!");
      lcd.setCursor(0,1); lcd.print("Invalid User.");
    }

    rawData = Serial.readString();
    commaPos = rawData.indexOf(',');
    userInitial = rawData.substring(0, commaPos);
    if (userInitial == "0") {
      lcd.clear(); lcd.setCursor(0,0); lcd.print("Error!");
      lcd.setCursor(0,1); lcd.print("Invalid Temperature.");
    }
    Serial.println("STANDBY"); delay(1000);
    mfrc522.PICC_HaltA(); mfrc522.PCD_StopCrypto1();
  }
}

[PYTHON] Raspberry Pi

''' Coded by Aden for Hackster.io Sigfox competition. https://www.astero.me '''
import mysql.connector, serial, os, time

def queryConnection():
    cursor = conn.cursor(buffered=True)
    cursor.execute("USE `" + databaseName + "`")
    return cursor

host = "localhost"; user = "root"; password = "password"; databaseName = "smartTemp"
conn = mysql.connector.connect(host=host, user=user, passwd=password)
comPort = 'ttyUSB0'; baudRate = 9600
ser = serial.Serial('/dev/' + comPort, baudRate, timeout=0)

print("Confirming USB Serial Port now, please wait")
connected = False
for x in range(2):
    time.sleep(2); ser.write("RAPI")
    if not connected:
        serialConfirmation = ser.readline().strip() == "ARDUINO"
        print(serialConfirmation)
        if not serialConfirmation: comPort = 'ttyUSB1'
        connected = True
    else: comPort = 'ttyUSB0'; connected = True
print(comPort)
ser = serial.Serial('/dev/' + comPort, baudRate)
print("COM PORT confirmed, using " + comPort)

countFile = open("count.txt", "a++")
tapRFID = False
cursor = queryConnection()

if os.stat("count.txt").st_size == 0:
    print("Count has not been set, setting to 1 now."); count = 1
else:
    for c in countFile: count = int(c)
    print("Count restored: " + str(count))

try:
    print("Creating " + databaseName + " database now..")
    cursor.execute("CREATE DATABASE " + databaseName)
    print("Database created.")
except mysql.connector.errors.DatabaseError:
    print(databaseName + " database already exists.")

cursor.execute("CREATE TABLE IF NOT EXISTS `userInfo` (id int, cardID VARCHAR(9), userID VARCHAR(4), userInitial VARCHAR(8))")
cursor.execute("CREATE TABLE IF NOT EXISTS `tempData` (id int, userID VARCHAR(4), dateMeas date, timeMeas time, tempMeasure decimal(5,2))")

while True:
    cursor = queryConnection()
    cardID = str(ser.readline().strip())
    cursor.execute("SELECT * FROM userInfo WHERE cardID = '" + cardID + "'")
    items = cursor.fetchone()
    if items:
        print(cardID)
        userID = str(items[2])
        userDetails = str(items[3] + ", " + items[2])
        currentDate = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())[0:10]
        currentTime = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime())[11:]
        print(items)
        ser.write(b'' + userDetails)
        countFile.close(); countFile = open("count.txt", 'w')
        tempSignal = False
        while not tempSignal:
            print("Getting Temperature")
            tempSignal = ser.readline().strip() == "TEMP"
            tempData = float(ser.readline().strip())
            print(tempData)
            if 28 <= tempData <= 42:
                cursor.execute("INSERT INTO `tempData`(`id`, `userID`, `dateMeas`, `timeMeas`, `tempMeasure`) VALUES (" + str(count) + ",'" + userID + "','" + currentDate + "','" + currentTime + "','" + str(tempData) + "')")
                conn.commit(); count += 1; countFile.write(str(count))
            else:
                ser.write(b'' + "0, 0")
    else:
        ser.write(b'' + ", 0"); print("Nothing found")

    readySignal = ser.readline().strip() == "STANDBY"
    while readySignal:
        ser.write(b'' + "READY"); print("sending")
        receivedSignal = ser.readline().strip() == "RECEIVED"
        if receivedSignal: readySignal = False; print("received")
    cursor.close(); conn.close()

[MicroPython] Sigfox (Pycom SiPy)

''' 100% Reginald '''
from machine import UART
from network import Sigfox
import binascii, socket, time, pycom, sys

pycom.heartbeat(False)
sigfox = Sigfox(mode=Sigfox.SIGFOX, rcz=Sigfox.RCZ4)
uart1 = UART(1, baudrate=9600)
uart1.init(9600, bits=8, parity=None, stop=1, pins=('P3','P4'), timeout_chars=20)

while True:
    try:
        recv = uart1.readline()
        if recv:
            print(binascii.hexlify(sigfox.id()))
            print(binascii.hexlify(sigfox.pac()))
            sk1 = socket.socket(socket.AF_SIGFOX, socket.SOCK_RAW)
            sk1.setblocking(False)
            sk1.setsockopt(socket.SOL_SIGFOX, socket.SO_RX, False)
            dataList = recv.decode("utf-8")
            print("dataList : %s" % dataList)
            split_val = dataList.split(",")
            userID = int(split_val[0])
            temp_H = int(split_val[1])
            temp_L = int(split_val[2])
            print("userID : %d temp_H : %d temp_L : %d" % (userID, temp_H, temp_L))
            bData = [userID, temp_H, temp_L]
            meas_temp = temp_H + (temp_L * 0.01)
            print("measure temperature : %.2f" % meas_temp)
            sk1.send(bytes(bData))
            sk1.close()
            time.sleep(5)
    except KeyboardInterrupt:
        sys.exit()

[ThingSpeak] MATLAB SCRIPT

%% Aden - Hackster.io Sigfox Competition
readChannelID = 870479;
webhookTrigger = 'https://maker.ifttt.com/trigger/student_fever/with/key/h10MdSGwjSPtZQ43wH-AgoiKI0pwaljBNnGUEu4Yecn';
readAPIKey = 'QGHINBPNJQKULBH2';
writeChannelID = 870482;
writeAPIKey = 'R6NJIM8NT5A42R9N';

wholeNumber = thingSpeakRead(readChannelID, 'ReadKey', readAPIKey, 'Fields', 1);
decimalNumber = thingSpeakRead(readChannelID, 'ReadKey', readAPIKey, 'Fields', 2)/100;
userID = thingSpeakRead(readChannelID, 'ReadKey', readAPIKey, 'Fields', 3);
display(wholeNumber, 'BEFORE')
analyzedData = wholeNumber + decimalNumber;
display(analyzedData, 'AFTER')
display(userID, 'USERID')
thingSpeakWrite(writeChannelID, 'Fields', [1,2], 'Values', {analyzedData, userID}, 'WriteKey', writeAPIKey)
if (analyzedData >= 38)
    webwrite(webhookTrigger, 'value1', analyzedData, 'value2', userID);
end

Esquemáticos

Sistema inteligente de monitorización de temperatura para escuelas: preciso, en tiempo real y seguro
Sistema inteligente de monitorización de temperatura para escuelas: preciso, en tiempo real y seguro
Sistema inteligente de monitorización de temperatura para escuelas: preciso, en tiempo real y seguro
Sistema inteligente de monitorización de temperatura para escuelas: preciso, en tiempo real y seguro
Sistema inteligente de monitorización de temperatura para escuelas: preciso, en tiempo real y seguro
Sistema inteligente de monitorización de temperatura para escuelas: preciso, en tiempo real y seguro
Sistema inteligente de monitorización de temperatura para escuelas: preciso, en tiempo real y seguro

Proceso de manufactura

  1. Monitorización profesional de temperatura con Raspberry Pi y DS18B20
  2. Monitorización precisa de temperatura en armario de servidores con Raspberry Pi
  3. Control de temperatura casero para cerveza: monitorizar y regular con Arduino
  4. Sensor K30 CO₂: Monitorización en tiempo real de la calidad del aire interior
  5. Persianas Inteligentes: Control Automático de Luz con Arduino y Energía Solar
  6. Puerta de control de temperatura sin contacto para detección rápida y precisa
  7. Arduino UNO + Shield WiFi: Visualización de Temperatura en Tiempo Real en Web vía Serial
  8. Librería Eficiente de Puerto I/O de 8 Bits para Arduino – Expande el Control Digital
  9. Guante Inteligente de Gestos a Texto para Lenguaje de Signos
  10. Health Band: Asistente Inteligente Vestible para Personas Mayores
  11. Agricultura Inteligente: Monitorización Integral IoT para Futuro Agrícola