domingo, 27 de septiembre de 2026

Streamlit directories version 8°

 import streamlit as st

import time


# Configuración de la página

st.set_page_config(page_title="Smart System Monitor", layout="wide")


st.title("📡 Smart System Monitoring Dashboard")

st.write("Visualización en tiempo real de los módulos ESP32")


# --- DICCIONARIOS CON DATOS DE SENSORES ---

temp = {

    "ESP1": 21.5,

    "ESP2": None,  # Módulo con falla o desconectado

    "ESP3": 19.8

}


humid = {

    "ESP1": 65,

    "ESP2": 0,

    "ESP3": 58

}


weight = {

    "ESP1": 1.2,

    "ESP2": None,

    "ESP3": 1.5

}


# Botón para iniciar la simulación de lectura

if st.button("▶ Iniciar Lectura de Sensores"):

    

    # 1. VISUALIZACIÓN DE TEMPERATURA

    st.subheader("🌡️ Lecturas de Temperatura (°C)")

    cols_temp = st.columns(len(temp))

    

    for idx, (dispositivo, valor) in enumerate(temp.items()):

        with cols_temp[idx]:

            if valor is None:

                st.metric(label=dispositivo, value="Sin señal", delta="Error", delta_color="inverse")

            else:

                st.metric(label=dispositivo, value=f"{valor} °C")

            time.sleep(1)  # Pausa para simular carga progresiva


    # 2. VISUALIZACIÓN DE HUMEDAD

    st.subheader("💧 Lecturas de Humedad (%)")

    cols_humid = st.columns(len(humid))

    

    for idx, (dispositivo, valor) in enumerate(humid.items()):

        with cols_humid[idx]:

            if valor == 0 or valor is None:

                st.metric(label=dispositivo, value="0 %", delta="Falla Sensor", delta_color="inverse")

            else:

                st.metric(label=dispositivo, value=f"{valor} %")

            time.sleep(1)


    # 3. VISUALIZACIÓN DE PESO

    st.subheader("⚖️ Lecturas de Peso (kg)")

    cols_weight = st.columns(len(weight))

    

    for idx, (dispositivo, valor) in enumerate(weight.items()):

        with cols_weight[idx]:

            if valor is None:

                st.metric(label=dispositivo, value="N/A", delta="Offline", delta_color="inverse")

            else:

                st.metric(label=dispositivo, value=f"{valor} kg")

            time.sleep(1)


    st.success("✅ Monitoreo completado exitosamente.")

dictionaries.py

 import time

# ==========================================

# 1. DICTIONARIES WITH SENSOR DATA

# ==========================================

# Each key represents the ESP32 identifier

# and its value is the sensor reading.

temp = {

    "ESP1": 21.5,

    "ESP2": None,  # Simulates an error or device disconnection

    "ESP3": 19.8

}


humid = {

    "ESP1": 65,

    "ESP2": 0,     # Simulates a humidity reading failure

    "ESP3": 58

}


weight = {

    "ESP1": 1.2,

    "ESP2": None,  # Simulates missing weight reading

    "ESP3": 1.5

}

# ==========================================

# 2. CONTINUOUS DATA PRINTING ON CONSOLE

# ==========================================


# Temperature Readings

print("--- Temperature Readings (°C) ---")

for device, value in temp.items():

    print(f"Temperature at {device}: {value}°C")

    time.sleep(2)  # 2-second pause between each reading


# ==========================================

# 3. FINAL MESSAGE

# ==========================================

print("\nMonitoring completed.")

ACTIVITY CLASS

 

 AUTOMATED SYSTEMS 

Develop the following questions in your notebook.
  1. What is the topic of Week #7?

  2. What are the three evaluation pillars used to analyze prototypes?

  3. What does "Efficiency" measure in a prototype?

  4. What does "Precision" measure in a prototype?

  5. What does "Usefulness" mean in system design?

  6. Is a prototype successful if it works well but drains its battery in 1 hour?

  7. Why does a solar garden light have lower precision on cloudy days?

  8. Name the three subsystems evaluated in the Genius Solvers activity.

  9. In your own words: What makes a prototype "Useful" in a real-world ecosystem?

  10. What microcontroller and components are used to build the functional feeder prototype?

miércoles, 23 de septiembre de 2026

martes, 22 de septiembre de 2026

SENSOR TURBIDEZ

 #include <Wire.h>       // Library to communication I2C

#include <Adafruit_GFX.h>  //Library to control the OLED display
#include <Adafruit_SSD1306.h>  // Library to OLED SSD1306

#include <OneWire.h> //Library to communication with to the water temperature sensor DS18B20
#include <DallasTemperature.h> //Lybrary to control the water temperature sensor DS18B20

//Start the configurations of sensors and actuator
OneWire ourWire(4); //Indicate the pin 4 to ESP32 for reading of sensor DS18B20
DallasTemperature DS18B20(&ourWire); //Decalre the variable or object for the sensor.
Adafruit_SSD1306 display(128, 64, &Wire);

int sensorPin = 34;  // Pin of ESP32 for reading of the turbidity sensor.
int NTU; //Variable to save the turbidity
float temp; //Variable to save the water temperatura

void setup()
{
  Serial. begin(115200); // Start the serial monitor and the respective baudios.  
  Wire.begin();                                   //Start the communication I2C to the OLED  
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);     // Start the OLED and the direction 0x3C
  display.clearDisplay();                       // Clear the OLED
  DS18B20.begin(); //Start the water sensor DS18B20
}

void loop(){
Readturbidity ();     //Go to the function that read the turbidity
displayturbidity (); // Go to the fuction that show the NTU on the OLED
ReadTempWater ();     // Go to the function that read the water temperature
displayTempWater (); // Go to the function that show the water temperature on the OLED
}

void Readturbidity ()
{
  int reading = analogRead(sensorPin); // Save the analog value from the turbidity sensor
  float voltage = reading * (3.3 / 4095.0); // Scale the digital value to voltage 3.3V with the 12bits resolution
  // NTU(V)≈343.2V2−1446.2V+1523.6 This it the polynomial that represents the turbidity in the water
  NTU = (343.2*(voltage*voltage) - 1446.2*voltage + 1523.6); // Make the polynomial replacing the voltage
  if (NTU < 0) NTU = 0; // Avoid the negatives values
 
   // Show in the setrial monitor
  Serial.print("Pin Reading: "); Serial.print(reading);
  Serial.print("  Voltage: "); Serial.print(voltage);
  Serial.print(" V  NTU: "); Serial.print(NTU); Serial.print("\n");
  delay (2000);
}

void displayturbidity ()
{
  display.clearDisplay();
  display.setTextSize(1,2);
  display.setTextColor(WHITE);
  display.setCursor(34,2);
  display.println("Turbidity");
   display.setTextSize(3);
  display.setCursor(29,20);
  display.println(NTU);
  display.setTextSize(3);
  display.setCursor(32,44);
  display.println("NTU");
  display.display();
  delay(3000);
}

void ReadTempWater ()
{
DS18B20.requestTemperatures(); //Send the command to read the temperature
temp= DS18B20.getTempCByIndex(0); //Obtain the temperature in ºC
Serial.print("Temperature= ");
Serial.print(temp);
Serial.println(" °C");
delay(1000);
}


void displayTempWater ()
{
  display.clearDisplay();
  display.setTextSize(1,2);
  display.setTextColor(WHITE);
  display.setCursor(34,2);
  display.println("Temperature");
   display.setTextSize(3);
  display.setCursor(21,20);
  display.println(temp);
  display.setTextSize(1);
  display.setCursor(0,44);
  display.print((char)247); // degree symbol
  display.println("C Degree Celcius");
  display.display();
  delay(3000);
}

domingo, 20 de septiembre de 2026

CODE BACKGROUND

 import base64 with open("ENTER YOUR IMAGE", "rb") as file: imagen = base64.b64encode(file.read()).decode() st.markdown(f""" <style> .stApp {{ background-image: url("data:image/png;base64,{imagen}"); background-size: cover; background-position: center; }} </style> """, unsafe_allow_html=True)

REQUESTER WEEK 6 FORMATIVE ACTIVITY

from matplotlib import pyplot as plt

import requests

import streamlit as st

import time as time_module


# ESP32

ip = "Enter the IP provied for your teacher"

url = "http://" + ip + "/data.json"


# Get data

d = requests.get(url)

data = d.json()


timestamp = data["timestamp"]


sht = data["SHT"]

hc = data["HCSR04"]


temperature = sht["temperature"]

humidity = sht["humidity"]

distance = hc["distance"]



# Streamlit

st.title("ESP32 Sensor Dashboard")


tabs = ["?????????", "Temperature vs ????", "??????"]


tab1, tab2, ?????? = st.tabs(tabs)



with tab1:

    st.text("??????? over time")


    plt.xlabel("Time")

    ???????????("Temperature (°C)")

    plt.plot(timestamp, temperature)


    st.pyplot(plt.gcf())

    plt.close()



with tab2:

    st.text("Temperature vs ???????")


    plt.xlabel("Temperature (°C)")

    plt.ylabel("???????(%)")

    ????.scatter(temperature, humidity)


    st.pyplot(plt.gcf())

    plt.close()



with tab3:

    st.text("Distance over time")


    ??????????("Time")

    plt.ylabel("Distance (cm)")

    ??????.plot(timestamp, distance)


    st.pyplot(plt.gcf())

    ????????????



# Update every 2 seconds

time_module.sleep(2) 

st.rerun()


jueves, 17 de septiembre de 2026

DATA LOGGER

 #include <WiFi.h>

#include <HTTPClient.h>
#include <Wire.h>
#include "Adafruit_SHT31.h"

// ---------- Wi-Fi ----------
const char* ssid = "LEOMASTER";
const char* password = "123456789";

// ---------- Google Apps Script ----------
const char* scriptURL = "https://script.google.com/macros/s/AKfycbxqx832rkd68MmhMnbllSZFzFE7h5NBoRL1gofs88IVuYAPS3IsWSnvUgpg8VWy8Hgs/exec";

// ---------- SHT30 ----------
Adafruit_SHT31 sht30 = Adafruit_SHT31();

void setup() {

  Serial.begin(115200);
  Wire.begin(21, 22);

 
  if (!sht30.begin(0x44)) {
    Serial.println("SHT30 not found!");
    while (1);
  }

  Serial.println("SHT30 connected!");

  WiFi.begin(ssid, password);

  Serial.print("Connecting to Wi-Fi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println();
  Serial.println("Wi-Fi connected!");
  Serial.print("ESP32 IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  // Read temperature and humidity
  float temperature = sht30.readTemperature();
  float humidity = sht30.readHumidity();
  // Definimos el valor de AQI (Calidad del aire).
  int aqi = 45;
  // Check sensor data
  if (isnan(temperature) || isnan(humidity)) {
    Serial.println("Error reading SHT30");
    delay(5000);
    return;
  }
  // Show data in Serial Monitor
  Serial.println("----------------------------");
  Serial.print("Temperature: ");
  Serial.print(temperature);
  Serial.println(" °C");

  Serial.print("Humidity: ");
  Serial.print(humidity);
  Serial.println(" %");

  Serial.print("AQI: ");
  Serial.println(aqi);

  // Send data to Google Sheets using POST and JSON
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    // Iniciamos la conexión con la URL del script
    http.begin(scriptURL);
    // Indicamos que los datos se envían en formato JSON
    http.addHeader("Content-Type", "application/json");
    // Construimos el paquete JSON con las variables
    String httpRequestData = "{\"temperature\":" + String(temperature, 2) +
                             ",\"humidity\":" + String(humidity, 2) +
                             ",\"aqi\":" + String(aqi) + "}";

    Serial.println("Sending JSON data to Google Sheets...");
    // Enviamos la petición POST con los datos empaquetados
    int httpResponseCode = http.POST(httpRequestData);
    if (httpResponseCode > 0) {
      Serial.print("HTTP Response code: ");
      Serial.println(httpResponseCode);

      String response = http.getString();
      Serial.print("Server response: ");
      Serial.println(response);
    } else {
      Serial.print("Error sending data: ");
      Serial.println(httpResponseCode);
    }
    http.end();

  } else {
    Serial.println("Wi-Fi disconnected!");
  }
  delay(10000);
}

AppScript code

 function doPost(e) {

  // Obtiene la hoja de cálculo y la pestaña que están abiertas actualmente

  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();

 

  // Lee y abre el "paquete" de datos en formato JSON enviado por el ESP32

  var data = JSON.parse(e.postData.contents);

 

  // Obtiene la fecha y la hora exacta del momento en que llega el mensaje

  var date = new Date();

 

  // Extrae cada dato individual del paquete JSON

  var temperature = data.temperature;

  var humidity = data.humidity;

  var aqi = data.aqi;

 

  // Añade una nueva fila al final de la tabla con toda la información ordenada

  sheet.appendRow([date, temperature, humidity, aqi]);

 

  // Envía un mensaje de respuesta confirmando que todo salió bien

  return ContentService.createTextOutput('Success');

}

SENSOR TESTING

 #include <Wire.h>

#include <Adafruit_SHT31.h>

Adafruit_SHT31 sht30 = Adafruit_SHT31();

void setup() {
  Serial.begin(115200);

  if (!sht30.begin(0x44)) {
    Serial.println("SHT30 no encontrado");
    while (1);
  }

  Serial.println("SHT30 conectado correctamente");
}

void loop() {

  float temperatura = sht30.readTemperature();
  float humedad = sht30.readHumidity();

  Serial.print("Temperatura: ");
  Serial.print(temperatura);
  Serial.println(" °C");

  Serial.print("Humedad: ");
  Serial.print(humedad);
  Serial.println(" %");

  Serial.println("--------------------");

  delay(2000);
}

miércoles, 16 de septiembre de 2026

SUPPORT CASE C

// Definición de pines para los dos servomotores

const int PIN_SERVO_ARM1 = 14;

const int PIN_SERVO_ARM2 = 27;


// Creación de los objetos Servo

Servo plantServo1;

Servo plantServo2;


void setup() {

  // Asignación de temporizadores PWM para el ESP32

  ESP32PWM::allocateTimer(0);

  ESP32PWM::allocateTimer(1);


  // Vincular los servos a sus respectivos pines (500us a 2400us)

  plantServo1.attach(PIN_SERVO_ARM1, 500, 2400);

  plantServo2.attach(PIN_SERVO_ARM2, 500, 2400);


  // Posición inicial: Brazos replegados (0 grados)

  plantServo1.write(0);

  plantServo2.write(0);

  delay(1000); // Pausa de estabilización inicial

}


void loop() {

  // 1. Activar ambos servomotores simultáneamente a 90 grados

  plantServo1.write(90);

  plantServo2.write(90);


  // 2. Mantener la posición de riego durante 5 segundos

  delay(5000);


  // 3. Regresar ambos servos simultáneamente a 0 grados

  


  // Pausa entre ciclos de hidratación (ej. 10 segundos)

  

}

SUPPORT CASE B

??????


// Definición del pin de control del servomotor

const int PIN_SERVO_FILTER = 12;


// Creación del objeto Servo

Servo filterServo;


void setup() {

  // Asignación del temporizador PWM para el ESP32

  ESP32PWM::allocateTimer(0);


  // Vincular el servo al pin con ancho de pulso estándar (500us a 2400us)

  filterServo.attach(PIN_SERVO_FILTER, 500, 2400);


  // Posición inicial de la válvula: 0 grados

  filterServo.write(0);

  delay(1000); // Pausa de estabilización inicial

}


void loop() {

  int anguloActual = 0;


  // Secuencia de 3 incrementos graduales de 15 grados

  for (int i = 0; i < 3; i??) {

    anguloActual += 15;            // Paso 1: 15°, Paso 2: 30°, Paso 3: 45°

    filterServo.write(anguloActual);

    delay(2000);                   // Pausa de 2 segundos para estabilizar el flujo

  }


  // Regreso a la posición inicial (válvula cerrada)

  filterServo.???(0);

    ???                   // Pausa de 3 segundos

}

SUPPORT CASE A


???????????????

// Definición del pin de control del servomotor

const int PIN_SERVO_FEEDER = ??????????;


// Creación del objeto Servo

Servo feederServo;


void setup() {

  // Asignación de temporizador PWM para el ESP32

  ESP32PWM::allocateTimer(0);


  // Vincular el servo al pin con ancho de pulso estándar (500us a 2400us)

  feederServo.attach(PIN_SERVO_FEEDER, ?, ???);


  // Posición inicial: Compuerta completamente cerrada (0 grados)

  feederServo.write(0);

  delay(1000); // Pausa para estabilización inicial

}


void loop() {

  // 1. Abrir la compuerta a 90 grados

  feederServo.write(?);


  // 2. Mantener abierta la compuerta durante 2 ms

  delay(2);


  // 3. Regresar el servo a 0 grados para cerrar el paso de alimento

  feederServo.write(?);


  // Pausa de control entre ciclos de alimentación (ej. 5 segundos)

  delay(5000); 

}

CASES

 Case A: Food Feeder (Opening and Return)

Move the servomotor from 0 to 90 to open the feeding door. Hold the open position for 2 ms using delay(2). Return the servo immediately to 0 to close the food gate.

Case B: Foam Filter System (Gradual Flow Adjustment)

Advance the servo in 15 increments to gradually regulate the air or water valve. Pause for 2 seconds (delay(2000)) at each angle to stabilize the flow. Repeat this sequence 3 times 15, 30, and 45 before returning to the start position.

Case C: Plant Care Station (Synchronized Dual Arm)

Activate two servomotores simultaneously from 0 to 90 to position the watering nozzles over the plant. Hold the watering position for 5 seconds with delay(5000). Return both servos at the same time to 0 to complete the hydration cycle.

jueves, 10 de septiembre de 2026

CODE SERVO ANALISIS

 #include <ESP32Servo.h> // Para ESP32. Si usas Arduino Uno/Nano, cambia por: #include <Servo.h>


// Crear objetos Servo

Servo servo1;

Servo servo2;


// Asignación de pines

// ESP32: GPIO 18 y 19 | Arduino Uno/Nano: D9 y D10

const int PIN_SERVO1 = 18; 

const int PIN_SERVO2 = 19; 


void setup() {

  // Asignar los pines a cada servomotor

  servo1.attach(PIN_SERVO1);

  servo2.attach(PIN_SERVO2);


  // Posición inicial (0 grados)

  servo1.write(0);

  servo2.write(0);

  delay(1000);

}


void loop() {

  // Movimiento gradual de 0° a 180° (Servo 1 avanza, Servo 2 retrocede)

  for (int pos = 0; pos <= 180; pos += 1) {

    servo1.write(pos);        // Mueve Servo 1 de 0 a 180

    servo2.write(180 - pos);  // Mueve Servo 2 de 180 a 0

    delay(15);                // Velocidad del movimiento

  }


  delay(1000); // Pausa de 1 segundo en extremos


  // Movimiento de regreso de 180° a 0°

  for (int pos = 180; pos >= 0; pos -= 1) {

    servo1.write(pos);

    servo2.write(180 - pos);

    delay(15);

  }


  delay(1000);

}

EXAMPLE

import requests

import matplotlib.pyplot as plt

import matplotlib.image as mpimg

img = requests.get("https://picsum.photos/seed/67/200/300")

with open("image.jpg", "wb") as f: #Open file as write

f.write(img.content)

imagen = mpimg.imread("image.jpg")

plt.imshow(imagen)

plt.axis("off") # Quita las reglas y números de las orillas

plt.show() # Dibuja la imagen en la pestaña Plots

REQUESTER.PY

import requests

url="???/data.json"

d=requests.get(url)

data=d.json()

t=data["temperature"]

h=data["???"]

print(t)

print(h)

#plt.xlabel("Temperature (ºC)")

#plt.ylabel("Humidity (%)")

domingo, 6 de septiembre de 2026

formative 7 3p

 1. Learning Objective 

To understand the basic concept of a sensor and evaluate how a microcontroller (ESP32) receives physical environment variations and transforms them into readable text and numeric data in real time through the Wokwi Serial Monitor. 


2. Activity Instructions 

For this activity, the source code is already pre-loaded into the ESP32's memory. Your mission as a team is to assemble the hardware connections on the screen and analyze how the data travels. 


  1. -Open the Wokwi simulation platform. 

  1. -Click on the Add Component (+) button and add two elements to the workspace: an ---ESP32 DevKit v1 and a DHT22 (temperature and humidity sensor). 

  1. -Connect the wires using your mouse, linking the pins of both components exactly as --indicated in the Hardware Connection Map. 

  1. -Once the wiring is complete, press the green Start Simulation (Play) button. 

  1. -Open the Serial Monitor tab at the bottom of the interface, click directly on the DHT22 sensor to move its environment sliders, and complete this worksheet. 



Code Wokwi Formative Activity

https://blogleolozano.blogspot.com/2026/09/code-formative-activity-1.html


Put your wokwi excercise in the following link.

https://forms.gle/pcYiRHB71J8mzMg8A