From 203a4a006df48aea6fd67105b88cb0f3acb53095 Mon Sep 17 00:00:00 2001 From: Amaro Lopes Date: Wed, 11 Feb 2026 10:27:08 -0300 Subject: [PATCH] first commit --- .gitignore | 5 + .vscode/extensions.json | 10 + README.md | 0 chips/heartrate.chip.json | 19 ++ chips/heartrate.chip.wasm | Bin 0 -> 143190 bytes diagram.json | 188 ++++++++++++++++++ platformio.ini | 18 ++ src/main.ino | 402 ++++++++++++++++++++++++++++++++++++++ wokwi.toml | 13 ++ 9 files changed, 655 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/extensions.json create mode 100644 README.md create mode 100644 chips/heartrate.chip.json create mode 100755 chips/heartrate.chip.wasm create mode 100644 diagram.json create mode 100644 platformio.ini create mode 100644 src/main.ino create mode 100644 wokwi.toml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..080e70d --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ], + "unwantedRecommendations": [ + "ms-vscode.cpptools-extension-pack" + ] +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/chips/heartrate.chip.json b/chips/heartrate.chip.json new file mode 100644 index 0000000..a460a1b --- /dev/null +++ b/chips/heartrate.chip.json @@ -0,0 +1,19 @@ +{ + "name": "heartrate", + "author": "Amaro Lopes", + "pins": [ + "VCC", + "GND", + "BTN", + "OUT" + ], + "controls": [ + { + "id": "pulseValue", + "label": "Heart Rate", + "type": "slider", + "min": 40, + "max": 200 + } + ] +} \ No newline at end of file diff --git a/chips/heartrate.chip.wasm b/chips/heartrate.chip.wasm new file mode 100755 index 0000000000000000000000000000000000000000..f54c25bb173ce59bbf05b1f853a7df3df269ebc0 GIT binary patch literal 143190 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 literal 0 HcmV?d00001 diff --git a/diagram.json b/diagram.json new file mode 100644 index 0000000..d9665ff --- /dev/null +++ b/diagram.json @@ -0,0 +1,188 @@ +{ + "version": 1, + "author": "Amaro Lopes", + "editor": "wokwi", + "parts": [ + { + "type": "board-esp32-devkit-c-v4", + "id": "esp", + "top": 0, + "left": 0, + "attrs": {} + }, + { + "type": "chip-heartrate", + "id": "chip1", + "top": -114.18, + "left": -148.8, + "attrs": {} + }, + { + "type": "wokwi-resistor", + "id": "r1", + "top": -33.6, + "left": -67.75, + "rotate": 90, + "attrs": { + "value": "1000" + } + }, + { + "type": "wokwi-slide-switch", + "id": "sw1", + "top": -130, + "left": 127.9, + "attrs": {} + }, + { + "type": "wokwi-mpu6050", + "id": "imu1", + "top": 99.82, + "left": -199.28, + "attrs": {} + }, + { + "type": "wokwi-led", + "id": "led1", + "top": -32.4, + "left": 167, + "attrs": { + "color": "red" + } + } + ], + "connections": [ + [ + "esp:TX", + "$serialMonitor:RX", + "", + [] + ], + [ + "esp:RX", + "$serialMonitor:TX", + "", + [] + ], + [ + "esp:3V3", + "chip1:VCC", + "green", + [ + "h-187.01", + "v-134.4" + ] + ], + [ + "chip1:GND", + "esp:GND.2", + "black", + [ + "v28.8", + "h244.76" + ] + ], + [ + "r1:1", + "chip1:BTN", + "green", + [ + "h0" + ] + ], + [ + "r1:2", + "esp:3V3", + "green", + [ + "h0" + ] + ], + [ + "esp:35", + "chip1:OUT", + "green", + [ + "h-23.81", + "v-182.4" + ] + ], + [ + "sw1:1", + "chip1:BTN", + "green", + [ + "v0" + ] + ], + [ + "sw1:2", + "sw1:3", + "black", + [ + "v0" + ] + ], + [ + "sw1:3", + "esp:GND.2", + "black", + [ + "v0" + ] + ], + [ + "imu1:VCC", + "esp:3V3", + "red", + [ + "v0" + ] + ], + [ + "imu1:GND", + "esp:GND.2", + "black", + [ + "v-134.4", + "h28.88" + ] + ], + [ + "imu1:SCL", + "esp:22", + "green", + [ + "v9.6", + "h268.88", + "v-67.2" + ] + ], + [ + "imu1:SDA", + "esp:21", + "green", + [ + "v0" + ] + ], + [ + "esp:GND.2", + "led1:C", + "black", + [ + "v-19.2", + "h-4.76" + ] + ], + [ + "esp:17", + "led1:A", + "green", + [ + "h0" + ] + ] + ], + "dependencies": {} +} \ No newline at end of file diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..261c781 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,18 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:esp32] +platform = espressif32 +framework = arduino +board = esp32dev +lib_deps = + hwspeedy/DHT-Sensor + knolleary/PubSubClient + adafruit/Adafruit MPU6050@^2.2.8 diff --git a/src/main.ino b/src/main.ino new file mode 100644 index 0000000..a8ac417 --- /dev/null +++ b/src/main.ino @@ -0,0 +1,402 @@ +// ============================================================================ +// Sistema de monitoramento de cozinha com ESP32 +// Monitora temperatura, umidade e gás com detecção avançada de incêndio +// Envia dados via MQTT e controla coifa e ar-condicionado +// ============================================================================ + +// INCLUDES +#include +#include +#include // MQTT +#include // WiFi +#include + +// ============================================================================ +// DEFINES - Pinos GPIO +// ============================================================================ +#define PULSE_PIN 35 // Pin for the pulse sensor +#define LED_PIN 17 // Pin for the LED + +// ============================================================================ +// DEFINES - Configurações estáticas +// ============================================================================ +#define SAMPLE_PERIOD_MS 10 // 100 Hz +#define FILTER_ALPHA 0.9 + +#define TH_START 1.15 +#define TH_END 1.05 + +#define MIN_PEAK_AMPLITUDE 1.5 + +#define MIN_REP_TIME 800 +#define MAX_REP_TIME 5000 +// ============================================================================ +// ENUMS +// ============================================================================ +enum EstadoRepeticao { + OCIOSO, + DESCANSO, + SUBINDO, + DESCENDO +}; + +// ============================================================================ +// CONSTANTES - WiFi e MQTT +// ============================================================================ +const char* WIFI_SSID = "Wokwi-GUEST"; +const char* WIFI_PASSWORD = ""; +const char* MQTT_BROKER = "77.37.69.84"; +const int MQTT_PORT = 1883; +const char* MQTT_SUB_TOPICS[] = { + "academia/reps", + "academia/sets", + "academia/t_descanso" +}; +const char* MQTT_PUB_TOPIC = "academia"; +const int MQTT_SUB_COUNT = sizeof(MQTT_SUB_TOPICS) / sizeof(MQTT_SUB_TOPICS[0]); + +// ============================================================================ +// VARIÁVEIS GLOBAIS - Objetos +// ============================================================================ +WiFiClient espClient; +PubSubClient mqtt(espClient); +Adafruit_MPU6050 mpu; +sensors_event_t event; + +// ============================================================================ +// VARIÁVEIS GLOBAIS - Estado do sistema +// ============================================================================ + +EstadoRepeticao estado = OCIOSO; + +unsigned long ultimaAmostra = 0; + +unsigned long t_inicio = 0; +unsigned long t_pico = 0; +unsigned long t_fim = 0; +unsigned long t_descanso = 30; + +float aceleracaoFiltrada = 1.0; +float aceleracaoAnterior = 1.0; +float aceleracaoPico = 0; + +int repeticoes = 0; +int max_reps = 0; +int set = 0; +int sets = 0; + +// Frequência cardíaca (atual e agregados por repetição) +int frequenciaCardiacaAtual = 0; +unsigned long somaFrequenciaCardiaca = 0; +unsigned int contagemFrequenciaCardiaca = 0; + +// MQTT reconnect control +unsigned long ultimoMqttAttempt = 0; +const unsigned long MQTT_RECONNECT_INTERVAL_MS = 5000; + +// Buffer MQTT +char msg[256]; +char MQTT_CLIENTID[32]; + +// ============================================================================ +// FUNÇÕES AUXILIARES - Callbacks MQTT +// ============================================================================ +void mqttCallback(char* topic, byte* payload, unsigned int length) +{ + Serial.print("[MQTT] Mensagem em ["); + Serial.print(topic); + Serial.println("]"); + + // Copia payload para buffer null-terminated + char buf[64]; + int n = (length < (int)sizeof(buf) - 1) ? length : (int)sizeof(buf) - 1; + memcpy(buf, payload, n); + buf[n] = '\0'; + + Serial.print("[MQTT] payload: "); + Serial.println(buf); + + // Processa tópicos + if (strcmp(topic, "academia/reps") == 0) { + int v = atoi(buf); + if (!isnan(v)) { + Serial.print("[MQTT] reps = "); + Serial.println(v); + max_reps = v; + } + } else if (strcmp(topic, "academia/sets") == 0) { + int v = atoi(buf); + if (!isnan(v)) { + Serial.print("[MQTT] sets = "); + Serial.println(v); + sets = v; + } + } else if (strcmp(topic, "academia/t_descanso") == 0) { + int v = atoi(buf); + if (!isnan(v)) { + Serial.print("[MQTT] t_descanso = "); + Serial.println(v); + t_descanso = v; + } + } +} + +// ============================================================================ +// FUNÇÕES AUXILIARES - Conectividade +// ============================================================================ +// Conecta o ESP32 à rede WiFi +void connectWiFi() +{ + Serial.print("[WiFi] Conectando..."); + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); + int attempts = 0; + while (WiFi.status() != WL_CONNECTED && attempts < 20) { + delay(500); + Serial.print("."); + attempts++; + } + Serial.println("\r\n[WiFi] Conectado!"); +} + +// Inscreve em tópicos MQTT para receber atualizações de limiares +void mqttSubscribe() +{ + Serial.println("[MQTT] Conectado!"); + for (int i = 0; i < MQTT_SUB_COUNT; ++i) { + if (mqtt.subscribe(MQTT_SUB_TOPICS[i])) { + Serial.print("[MQTT] Tópico: "); + Serial.println(MQTT_SUB_TOPICS[i]); + } + } +} + +// Conecta ao broker MQTT +void connectMQTT() +{ + mqtt.setServer(MQTT_BROKER, MQTT_PORT); + mqtt.setCallback(mqttCallback); + + while (!mqtt.connected()) { + Serial.println("[MQTT] Conectando..."); + if (mqtt.connect(MQTT_CLIENTID)) { + mqttSubscribe(); + break; + } else { + Serial.print("[MQTT] Falha rc="); + Serial.println(mqtt.state()); + delay(2000); + } + } +} + +// ============================================================================ +// FUNÇÕES AUXILIARES - Sensores +// ============================================================================ +// Lê valores de aceleração do sensor MPU +void amostraMPU() +{ + sensors_event_t a, g, temp; + mpu.getEvent(&a, &g, &temp); + + float magnitudeAceleracao = sqrt( + a.acceleration.x * a.acceleration.x + + a.acceleration.y * a.acceleration.y + + a.acceleration.z * a.acceleration.z); + + float aceleracaoCorrigida = magnitudeAceleracao - 9.81; + + aceleracaoFiltrada = FILTER_ALPHA * aceleracaoFiltrada + (1.0 - FILTER_ALPHA) * aceleracaoCorrigida; + + detectarRepeticao(aceleracaoFiltrada); +} + +// ============================================================================ +// FUNÇÕES - Detecção de alarmes +// ============================================================================ +// Verifica qual alarme deve ser ativado baseado nos limites +void detectarRepeticao(float sinal) +{ + unsigned long agora = millis(); + + switch (estado) { + + case OCIOSO: + if (sinal > TH_START) { + t_inicio = agora; + aceleracaoPico = sinal; + estado = SUBINDO; + // Inicia acumulação de frequência cardíaca para esta repetição + somaFrequenciaCardiaca = 0; + contagemFrequenciaCardiaca = 0; + } + break; + + case SUBINDO: + if (sinal > aceleracaoPico) + aceleracaoPico = sinal; + + if (sinal < aceleracaoAnterior) { + t_pico = agora; + estado = DESCENDO; + } + break; + + case DESCENDO: + if (sinal < TH_END) { + t_fim = agora; + + analisarRepeticao(); + verificarSerie(); + } + break; + } + + // Se estamos no meio de uma repetição, acumula a frequência cardíaca atual + if (estado != OCIOSO) { + somaFrequenciaCardiaca += (unsigned long)frequenciaCardiacaAtual; + contagemFrequenciaCardiaca++; + } + + aceleracaoAnterior = sinal; +} + +void analisarRepeticao() +{ + unsigned long tempoTotal = t_fim - t_inicio; + unsigned long tempoSubida = t_pico - t_inicio; + unsigned long tempoDescida = t_fim - t_pico; + + bool ruim = false; + + Serial.print("Total: "); + Serial.print(tempoTotal); + Serial.print(" ms"); + + if (aceleracaoPico < MIN_PEAK_AMPLITUDE) { + Serial.print(" | Repetição parcial"); + ruim = true; + } + + if (tempoTotal < MIN_REP_TIME) { + Serial.print(" | Muito rápido"); + ruim = true; + } + + if (tempoTotal > MAX_REP_TIME) { + Serial.print(" | Muito lento"); + ruim = true; + } + + if (tempoDescida < tempoSubida * 0.6) { + Serial.print(" | Deixando cair o peso"); + ruim = true; + } + + if (!ruim) { + Serial.print(" | Boa repetição"); + repeticoes++; + Serial.print(" | Repetição "); + Serial.print(repeticoes); + } + // Calcula e mostra frequência cardíaca média durante a repetição + unsigned int fcMedia = 0; + if (contagemFrequenciaCardiaca > 0) { + fcMedia = (unsigned int)(somaFrequenciaCardiaca / contagemFrequenciaCardiaca); + Serial.print(" | FC média: "); + Serial.print(fcMedia); + Serial.print(" bpm"); + } + + // Zera agregados após uso + somaFrequenciaCardiaca = 0; + contagemFrequenciaCardiaca = 0; + + snprintf(msg, sizeof(msg), + "{\"fcm\": %d, \"reptime\": %d, \"timeup\": %d, \"timedown\": %d}", + fcMedia, tempoTotal, tempoSubida, tempoDescida); + + mqtt.publish(MQTT_PUB_TOPIC, msg); + + Serial.println(); +} + +void verificarSerie() +{ + if (repeticoes >= max_reps && max_reps > 0) { + Serial.println("[SÉRIE] Série finalizada, iniciando descanso..."); + repeticoes = 0; + estado = DESCANSO; + set++; + digitalWrite(LED_PIN, HIGH); + if (set >= sets && sets > 0) { + Serial.println("[TREINO] Treino finalizado, parabéns!"); + set = 0; + } + } else { + estado = OCIOSO; + } +} + +// ============================================================================ +// FUNÇÕES - Inicialização +// ============================================================================ +// Inicializa o ESP32 e configura os periféricos +void setup() +{ + Serial.begin(115200); + delay(100); + + Serial.println("\n[SETUP] Iniciando sistema..."); + + // Gera ID único MQTT + snprintf(MQTT_CLIENTID, sizeof(MQTT_CLIENTID), "esp32_%08X", + (uint32_t)(ESP.getEfuseMac() & 0xFFFFFFFF)); + + // Conecta + connectWiFi(); + connectMQTT(); + + while (!mpu.begin()) { + Serial.println("MPU6050 not connected!"); + delay(1000); + } + mpu.setAccelerometerRange(MPU6050_RANGE_4_G); + mpu.setGyroRange(MPU6050_RANGE_500_DEG); + mpu.setFilterBandwidth(MPU6050_BAND_21_HZ); + Serial.println("MPU6050 ready!"); + + pinMode(LED_PIN, OUTPUT); + digitalWrite(LED_PIN, LOW); + Serial.println("[SETUP] Pronto!\n"); +} + +// ============================================================================ +// LOOP PRINCIPAL +// ============================================================================ +// Loop principal - executa continuamente +void loop() +{ + if (!mqtt.connected()) { + connectMQTT(); + } + mqtt.loop(); + + if (millis() - ultimaAmostra >= SAMPLE_PERIOD_MS && estado != DESCANSO) { + // Verifica MQTT + + int16_t valorPulso = analogRead(PULSE_PIN); + + // Converter valorPulso para tensão + float tensao = valorPulso * (5.0 / 4095.0); + + // Atualiza frequência cardíaca atual (valor usado nas acumulações) + frequenciaCardiacaAtual = (int)((tensao / 3.3) * 675); + + ultimaAmostra += SAMPLE_PERIOD_MS; + amostraMPU(); + } else if (millis() - t_fim >= t_descanso * 100 && estado == DESCANSO) { + estado = OCIOSO; + digitalWrite(LED_PIN, LOW); + Serial.println("[DESCANSO] Descanso finalizado, pronto para próxima série."); + } +} \ No newline at end of file diff --git a/wokwi.toml b/wokwi.toml new file mode 100644 index 0000000..837c4d1 --- /dev/null +++ b/wokwi.toml @@ -0,0 +1,13 @@ +# Wokwi Configuration File +# Reference: https://docs.wokwi.com/vscode/project-config +[wokwi] +version = 1 +firmware = '.pio/build/esp32/firmware.bin' +elf = '.pio/build/esp32/firmware.elf' + +[[chip]] +name = 'heartrate' +binary = 'chips/heartrate.chip.wasm' + + +