#include <HX711.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#ifndef ARDUINO_CLOUD
#include <ESP32Servo.h>
#define PIN_SERVO 33
Servo servo1;
#else
#include "arduino_secrets.h"
#include <splash.h>
#include <Adafruit_GrayOLED.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>
#include "thingProperties.h"
#endif
// Definición de pines
#define PIN_IR 14
#define PIN_PULSOR 27
#define PIN_BUZZER 32
#define PIN_LED_RED 26
#define PIN_LED_GREEN 25
#define PIN_LM35 35
#define PIN_VSENSOR 34
// Configuración del ADC
#define ADC_VREF_mV 3300.0 // en milivoltios
#define ADC_RESOLUTION 4096.0
// Configuración del OLED
#define SCREEN_WIDTH 128 // ancho en píxeles
#define SCREEN_HEIGHT 64 // alto en píxeles
#define OLED_RESET -1 // pin de reset
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Configuración del HX711
const int LOADCELL_DOUT_PIN = 16;
const int LOADCELL_SCK_PIN = 4;
HX711 scale;
const int ESCALA = -435;
// Variables globales
const int lineH = 11;
bool IR_val = false;
bool prev_IR_val = false;
bool prev_btn_state = false;
bool curr_btn_state = false;
float curr_voltage = 0;
float R1 = 30000.0;
float R2 = 7500.0;
float weight = 0;
char buffers[5][30];
float getTemperature() {
int adcVal = analogRead(PIN_LM35);
float milliVolt = adcVal * (ADC_VREF_mV / ADC_RESOLUTION);
return milliVolt / 10; // Temperatura en °C
}
float getVoltage() {
int adcVal = analogRead(PIN_VSENSOR);
float voltage = adcVal * 3.3 * (R1 + R2) / (ADC_RESOLUTION * R2);
return voltage;
}
float getWeight() {
if (scale.is_ready()) {
Serial.print("HX711 reading: ");
return scale.get_units(10);
} else {
Serial.println("HX711 not found.");
return 0;
}
}
void servoWrite(int deg) {
#ifndef ARDUINO_CLOUD
servo1.write(deg);
#endif
}
void setBuzzer(bool on) {
digitalWrite(PIN_BUZZER, on ? HIGH : LOW);
}
void printOLED() {
display.clearDisplay();
for (int i = 0; i < 5; i++) {
display.setCursor(0, lineH * i);
display.print(buffers[i]);
}
display.display();
}
void setup() {
Serial.begin(9600);
scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
#ifndef ARDUINO_CLOUD
servo1.attach(PIN_SERVO);
#endif
scale.set_scale(ESCALA);
scale.tare(20);
delay(250);
pinMode(PIN_LED_RED, OUTPUT);
pinMode(PIN_LED_GREEN, OUTPUT);
pinMode(PIN_PULSOR, INPUT_PULLDOWN);
pinMode(PIN_IR, INPUT);
pinMode(PIN_BUZZER, OUTPUT);
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
while(true);
}
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(2);
display.setCursor(0, 0);
display.println("Iniciando...");
display.display();
digitalWrite(PIN_LED_RED, HIGH);
digitalWrite(PIN_LED_GREEN, LOW);
setBuzzer(true);
servoWrite(0);
delay(500);
digitalWrite(PIN_LED_GREEN, HIGH);
digitalWrite(PIN_LED_RED, LOW);
servoWrite(45);
delay(500);
digitalWrite(PIN_LED_RED, LOW);
digitalWrite(PIN_LED_GREEN, LOW);
servoWrite(180);
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
setBuzzer(false);
display.println("Sitema Listo");
display.display();
delay(1000);
}
void loop() {
display.setCursor(0, 0);
float temp = getTemperature();
IR_val = digitalRead(PIN_IR);
curr_btn_state = digitalRead(PIN_PULSOR);
curr_voltage = getVoltage();
bool presence = IR_val && !prev_IR_val;
servoWrite(180);
delay(300);
digitalWrite(PIN_LED_RED, HIGH);
digitalWrite(PIN_LED_GREEN, LOW);
setBuzzer(false);
#ifdef ARDUINO_CLOUD
ledVerde = false;
ledRojo = true;
#endif
Serial.print("Irval: ");
Serial.println(IR_val);
if (presence) {
// Animación de "Obteniendo peso"
const char* anim[] = {
"Obteniendo peso.",
"Obteniendo peso..",
"Obteniendo peso...",
"Obteniendo peso:"
};
for (int i = 0; i < 4; i++) {
strcpy(buffers[3], anim[i]);
printOLED();
delay(400);
}
weight = getWeight();
bool AlertOn = abs(weight) > 400;
digitalWrite(PIN_LED_GREEN, AlertOn);
digitalWrite(PIN_LED_RED, !AlertOn);
#ifdef ARDUINO_CLOUD
ledVerde = AlertOn;
ledRojo = !AlertOn;
#endif
setBuzzer(AlertOn);
if (AlertOn) {
servoWrite(0);
}
}
#ifdef ARDUINO_CLOUD
temperatura = temp;
peso = weight;
voltaje =curr_voltage;
ArduinoCloud.update();
#endif
// Actualización de la pantalla OLED
const char* labels[] = {
"Voltaje: %.2f",
"Temperatura: %.2f C",
"Presencia: %s",
"ÚltimoPeso: %.f g",
"GO?: %s"
};
sprintf(buffers[0], labels[0], curr_voltage);
sprintf(buffers[1], labels[1], temp);
sprintf(buffers[2], labels[2], IR_val ? "No" : "Si");
sprintf(buffers[3], labels[3], weight);
sprintf(buffers[4], labels[4], curr_btn_state ? "ok" : "no");
printOLED();
if (presence) {
strcpy(buffers[4], "Pulse para continuar:");
printOLED();
}
while (presence) {
curr_btn_state = digitalRead(PIN_PULSOR);
Serial.print("curr_btn_state: ");
Serial.println(curr_btn_state);
if (curr_btn_state && (curr_btn_state != prev_btn_state)) {
servoWrite(0);
delay(100);
break;
}
prev_btn_state = curr_btn_state;
Serial.print("Gstate: ");
Serial.println((int)0); // Gstate no se modifica, se imprime 0
}
prev_IR_val = IR_val;
delay(100);
}