adiciona podômetro e telinha
This commit is contained in:
220
diagram.json
220
diagram.json
@@ -3,186 +3,74 @@
|
|||||||
"author": "Amaro Lopes",
|
"author": "Amaro Lopes",
|
||||||
"editor": "wokwi",
|
"editor": "wokwi",
|
||||||
"parts": [
|
"parts": [
|
||||||
{
|
{ "type": "board-esp32-devkit-c-v4", "id": "esp", "top": 0, "left": 0, "attrs": {} },
|
||||||
"type": "board-esp32-devkit-c-v4",
|
{ "type": "chip-heartrate", "id": "chip1", "top": -114.18, "left": -148.8, "attrs": {} },
|
||||||
"id": "esp",
|
|
||||||
"top": 0,
|
|
||||||
"left": 0,
|
|
||||||
"attrs": {}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "chip-heartrate",
|
|
||||||
"id": "chip1",
|
|
||||||
"top": -114.18,
|
|
||||||
"left": -148.8,
|
|
||||||
"attrs": {}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "wokwi-resistor",
|
"type": "wokwi-resistor",
|
||||||
"id": "r1",
|
"id": "r1",
|
||||||
"top": -33.6,
|
"top": -33.6,
|
||||||
"left": -67.75,
|
"left": -67.75,
|
||||||
"rotate": 90,
|
"rotate": 90,
|
||||||
"attrs": {
|
"attrs": { "value": "1000" }
|
||||||
"value": "1000"
|
},
|
||||||
}
|
{ "type": "wokwi-slide-switch", "id": "sw1", "top": -130, "left": 127.9, "attrs": {} },
|
||||||
|
{ "type": "wokwi-mpu6050", "id": "imu1", "top": 167.02, "left": 175.12, "attrs": {} },
|
||||||
|
{ "type": "wokwi-led", "id": "led1", "top": -32.4, "left": 167, "attrs": { "color": "red" } },
|
||||||
|
{
|
||||||
|
"type": "wokwi-text",
|
||||||
|
"id": "text1",
|
||||||
|
"top": -163.2,
|
||||||
|
"left": 67.2,
|
||||||
|
"attrs": { "text": "devagar" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "wokwi-slide-switch",
|
"type": "wokwi-text",
|
||||||
"id": "sw1",
|
"id": "text2",
|
||||||
"top": -130,
|
"top": -163.2,
|
||||||
"left": 127.9,
|
"left": 153.6,
|
||||||
"attrs": {}
|
"attrs": { "text": "rápido" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "wokwi-mpu6050",
|
"type": "board-ssd1306",
|
||||||
"id": "imu1",
|
"id": "oled1",
|
||||||
"top": 99.82,
|
"top": 99.14,
|
||||||
"left": -199.28,
|
"left": 288.23,
|
||||||
"attrs": {}
|
"attrs": { "i2cAddress": "0x3c" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "wokwi-led",
|
"type": "wokwi-pushbutton",
|
||||||
"id": "led1",
|
"id": "btn1",
|
||||||
"top": -32.4,
|
"top": 111.8,
|
||||||
"left": 167,
|
"left": -144,
|
||||||
"attrs": {
|
"attrs": { "color": "green", "xray": "1" }
|
||||||
"color": "red"
|
},
|
||||||
}
|
{ "type": "wokwi-vcc", "id": "vcc1", "top": -37.64, "left": 326.4, "attrs": {} },
|
||||||
}
|
{ "type": "wokwi-vcc", "id": "vcc2", "top": -37.64, "left": -230.4, "attrs": {} }
|
||||||
],
|
],
|
||||||
"connections": [
|
"connections": [
|
||||||
[
|
[ "esp:TX", "$serialMonitor:RX", "", [] ],
|
||||||
"esp:TX",
|
[ "esp:RX", "$serialMonitor:TX", "", [] ],
|
||||||
"$serialMonitor:RX",
|
[ "esp:3V3", "chip1:VCC", "red", [ "h-187.01", "v-134.4" ] ],
|
||||||
"",
|
[ "chip1:GND", "esp:GND.2", "black", [ "v28.8", "h297.6", "v96" ] ],
|
||||||
[]
|
[ "r1:1", "chip1:BTN", "red", [ "h0" ] ],
|
||||||
],
|
[ "esp:35", "chip1:OUT", "green", [ "h-23.81", "v-182.4" ] ],
|
||||||
[
|
[ "sw1:1", "chip1:BTN", "green", [ "v0" ] ],
|
||||||
"esp:RX",
|
[ "sw1:2", "sw1:3", "black", [ "v0" ] ],
|
||||||
"$serialMonitor:TX",
|
[ "sw1:3", "esp:GND.2", "black", [ "v0" ] ],
|
||||||
"",
|
[ "imu1:SDA", "esp:21", "green", [ "v0" ] ],
|
||||||
[]
|
[ "esp:GND.2", "led1:C", "black", [ "h81.24" ] ],
|
||||||
],
|
[ "esp:17", "led1:A", "green", [ "h0" ] ],
|
||||||
[
|
[ "oled1:GND", "esp:GND.2", "black", [ "v0" ] ],
|
||||||
"esp:3V3",
|
[ "oled1:SCL", "esp:22", "green", [ "v0" ] ],
|
||||||
"chip1:VCC",
|
[ "esp:21", "oled1:SDA", "green", [ "h254.44" ] ],
|
||||||
"green",
|
[ "esp:3V3", "r1:2", "red", [ "h0" ] ],
|
||||||
[
|
[ "oled1:VCC", "vcc1:VCC", "red", [ "v0" ] ],
|
||||||
"h-187.01",
|
[ "vcc2:VCC", "esp:3V3", "red", [ "v0" ] ],
|
||||||
"v-134.4"
|
[ "imu1:SCL", "esp:22", "green", [ "v0" ] ],
|
||||||
]
|
[ "imu1:GND", "esp:GND.2", "black", [ "v0" ] ],
|
||||||
],
|
[ "imu1:VCC", "vcc1:VCC", "red", [ "v-153.6", "h86.48" ] ],
|
||||||
[
|
[ "btn1:1.r", "esp:25", "green", [ "v0" ] ],
|
||||||
"chip1:GND",
|
[ "esp:GND.1", "btn1:2.r", "black", [ "h0" ] ]
|
||||||
"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": {}
|
"dependencies": {}
|
||||||
}
|
}
|
||||||
@@ -16,3 +16,4 @@ lib_deps =
|
|||||||
hwspeedy/DHT-Sensor
|
hwspeedy/DHT-Sensor
|
||||||
knolleary/PubSubClient
|
knolleary/PubSubClient
|
||||||
adafruit/Adafruit MPU6050@^2.2.8
|
adafruit/Adafruit MPU6050@^2.2.8
|
||||||
|
arduinogetstarted/ezButton
|
||||||
|
|||||||
509
src/main.ino
509
src/main.ino
@@ -1,52 +1,88 @@
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Sistema de monitoramento de cozinha com ESP32
|
// Monitor de Repetições e Passos com ESP32
|
||||||
// Monitora temperatura, umidade e gás com detecção avançada de incêndio
|
// Monitora aceleração (MPU6050), frequência cardíaca (sensor de pulso)
|
||||||
// Envia dados via MQTT e controla coifa e ar-condicionado
|
// Exibe dados em OLED, envia via MQTT
|
||||||
|
// Modo Repetição: detecta exercícios com análise de tempo e intensidade
|
||||||
|
// Modo Pedômetro: conta passos baseado em aceleração
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
// INCLUDES
|
// INCLUDES
|
||||||
|
// ============================================================================
|
||||||
|
// Comunicação e rede
|
||||||
|
#include <WiFi.h>
|
||||||
|
#include <PubSubClient.h>
|
||||||
|
|
||||||
|
// Sensores e I2C
|
||||||
|
#include <Wire.h>
|
||||||
#include <Adafruit_MPU6050.h>
|
#include <Adafruit_MPU6050.h>
|
||||||
#include <Adafruit_Sensor.h>
|
#include <Adafruit_Sensor.h>
|
||||||
#include <PubSubClient.h> // MQTT
|
|
||||||
#include <WiFi.h> // WiFi
|
// Display
|
||||||
#include <Wire.h>
|
#include <Adafruit_GFX.h>
|
||||||
|
#include <Adafruit_SSD1306.h>
|
||||||
|
|
||||||
|
// Interface
|
||||||
|
#include <ezButton.h>
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// DEFINES - Pinos GPIO
|
// CONFIGURAÇÃO - Pinos GPIO
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
#define PULSE_PIN 35 // Pin for the pulse sensor
|
#define PULSE_PIN 35
|
||||||
#define LED_PIN 17 // Pin for the LED
|
#define LED_PIN 17
|
||||||
|
#define MODE_BUTTON_PIN 25
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// DEFINES - Configurações estáticas
|
// CONFIGURAÇÃO - Display OLED SSD1306
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
#define SAMPLE_PERIOD_MS 10 // 100 Hz
|
#define SCREEN_WIDTH 128 // Largura em pixels
|
||||||
#define FILTER_ALPHA 0.9
|
#define SCREEN_HEIGHT 64 // Altura em pixels
|
||||||
|
#define OLED_RESET -1 // Pin de reset (compartilhado)
|
||||||
|
#define SCREEN_ADDRESS 0x3C // Endereço I2C do display
|
||||||
|
|
||||||
#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
|
// CONFIGURAÇÃO - Algoritmo de Detecção de Repetições
|
||||||
|
// ============================================================================
|
||||||
|
#define SAMPLE_PERIOD_MS 10 // Período de amostragem em ms (100 Hz)
|
||||||
|
#define FILTER_ALPHA 0.9 // Fator de filtro exponencial (0-1)
|
||||||
|
#define ACCEL_REST_THRESHOLD 0.3 // Aceleração < 0.3 m/s² = repouso
|
||||||
|
#define ACCEL_ACTIVE_THRESHOLD 0.8// Aceleração > 0.8 m/s² = movimento ativo
|
||||||
|
#define MIN_PEAK_AMPLITUDE 1.5 // Amplitude mínima do pico em m/s²
|
||||||
|
#define MIN_REP_TIME 800 // Tempo mínimo de repetição em ms
|
||||||
|
#define MAX_REP_TIME 5000 // Tempo máximo de repetição em ms
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// CONFIGURAÇÃO - Pedômetro
|
||||||
|
// ============================================================================
|
||||||
|
#define STEP_ACCEL_THRESHOLD 0.8 // Limiar de aceleração para passo
|
||||||
|
#define STEP_DEBOUNCE_MS 200 // Tempo mínimo entre passos
|
||||||
|
#define BUTTON_DEBOUNCE_MS 50 // Debounce do botão
|
||||||
|
#define PEDOMETER_IDLE_TIMEOUT_MS 30000 // Timeout de inatividade (ms)
|
||||||
|
#define DISPLAY_UPDATE_INTERVAL_MS 100 // Limita display a 10 FPS
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// CONFIGURAÇÃO - WiFi e MQTT
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
#define WIFI_SSID "Wokwi-GUEST" // SSID da rede WiFi
|
||||||
|
#define WIFI_PASSWORD "" // Senha da rede WiFi
|
||||||
|
#define MQTT_BROKER "77.37.69.84" // Endereço do broker MQTT
|
||||||
|
#define MQTT_PORT 1883 // Porta MQTT padrão
|
||||||
|
#define MQTT_RECONNECT_INTERVAL_MS 5000 // Intervalo de reconexão
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// ENUMS - Estados do Sistema
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
enum EstadoRepeticao {
|
enum EstadoRepeticao {
|
||||||
OCIOSO,
|
OCIOSO,
|
||||||
DESCANSO,
|
|
||||||
SUBINDO,
|
SUBINDO,
|
||||||
DESCENDO
|
DESCENDO,
|
||||||
|
DESCANSO
|
||||||
};
|
};
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// CONSTANTES - WiFi e MQTT
|
// CONSTANTES - 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[] = {
|
const char* MQTT_SUB_TOPICS[] = {
|
||||||
"academia/reps",
|
"academia/reps",
|
||||||
"academia/sets",
|
"academia/sets",
|
||||||
@@ -56,203 +92,330 @@ const char* MQTT_PUB_TOPIC = "academia";
|
|||||||
const int MQTT_SUB_COUNT = sizeof(MQTT_SUB_TOPICS) / sizeof(MQTT_SUB_TOPICS[0]);
|
const int MQTT_SUB_COUNT = sizeof(MQTT_SUB_TOPICS) / sizeof(MQTT_SUB_TOPICS[0]);
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// VARIÁVEIS GLOBAIS - Objetos
|
// OBJETOS GLOBAIS
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
WiFiClient espClient;
|
WiFiClient espClient;
|
||||||
PubSubClient mqtt(espClient);
|
PubSubClient mqtt(espClient);
|
||||||
Adafruit_MPU6050 mpu;
|
Adafruit_MPU6050 mpu;
|
||||||
sensors_event_t event;
|
sensors_event_t event;
|
||||||
|
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
|
||||||
|
ezButton button(MODE_BUTTON_PIN);
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// VARIÁVEIS GLOBAIS - Estado do sistema
|
// VARIÁVEIS GLOBAIS - Estado Atual do Sistema
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
EstadoRepeticao estado = OCIOSO;
|
EstadoRepeticao estado = OCIOSO;
|
||||||
|
bool pedometroAtivo = false;
|
||||||
|
|
||||||
unsigned long ultimaAmostra = 0;
|
// ============================================================================
|
||||||
|
// VARIÁVEIS GLOBAIS - Leitura e Processamento de Sensores
|
||||||
unsigned long t_inicio = 0;
|
// ============================================================================
|
||||||
unsigned long t_pico = 0;
|
// Aceleração (MPU6050)
|
||||||
unsigned long t_fim = 0;
|
|
||||||
unsigned long t_descanso = 30;
|
|
||||||
|
|
||||||
float aceleracaoFiltrada = 1.0;
|
float aceleracaoFiltrada = 1.0;
|
||||||
float aceleracaoAnterior = 1.0;
|
float aceleracaoAnterior = 1.0;
|
||||||
float aceleracaoPico = 0;
|
float aceleracaoPico = 0;
|
||||||
|
unsigned long ultimaAmostra = 0;
|
||||||
|
|
||||||
|
// Frequência cardíaca (sensor de pulso)
|
||||||
|
int frequenciaCardiacaAtual = 0;
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// VARIÁVEIS GLOBAIS - Detecção de Repetições
|
||||||
|
// ============================================================================
|
||||||
|
unsigned long tInicio = 0;
|
||||||
|
unsigned long tPico = 0;
|
||||||
|
unsigned long tFim = 0;
|
||||||
|
unsigned long tDescanso = 30;
|
||||||
|
|
||||||
int repeticoes = 0;
|
int repeticoes = 0;
|
||||||
int max_reps = 0;
|
int maxRepeticoes = 0;
|
||||||
int set = 0;
|
int serie = 0;
|
||||||
int sets = 0;
|
int series = 0;
|
||||||
|
|
||||||
// Frequência cardíaca (atual e agregados por repetição)
|
// Agregação de frequência cardíaca por repetição
|
||||||
int frequenciaCardiacaAtual = 0;
|
|
||||||
unsigned long somaFrequenciaCardiaca = 0;
|
unsigned long somaFrequenciaCardiaca = 0;
|
||||||
unsigned int contagemFrequenciaCardiaca = 0;
|
unsigned int contagemFrequenciaCardiaca = 0;
|
||||||
|
|
||||||
// MQTT reconnect control
|
// ============================================================================
|
||||||
unsigned long ultimoMqttAttempt = 0;
|
// VARIÁVEIS GLOBAIS - Pedômetro
|
||||||
const unsigned long MQTT_RECONNECT_INTERVAL_MS = 5000;
|
// ============================================================================
|
||||||
|
long totalPassos = 0;
|
||||||
|
unsigned long ultimoTempoPassso = 0;
|
||||||
|
unsigned long ultimaAtividadePedometro = 0;
|
||||||
|
|
||||||
// Buffer MQTT
|
// ============================================================================
|
||||||
|
// VARIÁVEIS GLOBAIS - Comunicação MQTT
|
||||||
|
// ============================================================================
|
||||||
char msg[256];
|
char msg[256];
|
||||||
char MQTT_CLIENTID[32];
|
char MQTT_CLIENTID[32];
|
||||||
|
unsigned long ultimoMqttAttempt = 0;
|
||||||
|
unsigned long ultimoDisplayUpdate = 0;
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// FUNÇÕES AUXILIARES - Callbacks MQTT
|
// COMUNICAÇÃO - MQTT
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
void mqttCallback(char* topic, byte* payload, unsigned int length)
|
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];
|
char buf[64];
|
||||||
int n = (length < (int)sizeof(buf) - 1) ? length : (int)sizeof(buf) - 1;
|
int n = (length < (int)sizeof(buf) - 1) ? length : (int)sizeof(buf) - 1;
|
||||||
memcpy(buf, payload, n);
|
memcpy(buf, payload, n);
|
||||||
buf[n] = '\0';
|
buf[n] = '\0';
|
||||||
|
|
||||||
Serial.print("[MQTT] payload: ");
|
|
||||||
Serial.println(buf);
|
|
||||||
|
|
||||||
// Processa tópicos
|
|
||||||
if (strcmp(topic, "academia/reps") == 0) {
|
if (strcmp(topic, "academia/reps") == 0) {
|
||||||
int v = atoi(buf);
|
int valor = atoi(buf);
|
||||||
if (!isnan(v)) {
|
if (!isnan(valor)) {
|
||||||
Serial.print("[MQTT] reps = ");
|
maxRepeticoes = valor;
|
||||||
Serial.println(v);
|
|
||||||
max_reps = v;
|
|
||||||
}
|
}
|
||||||
} else if (strcmp(topic, "academia/sets") == 0) {
|
} else if (strcmp(topic, "academia/sets") == 0) {
|
||||||
int v = atoi(buf);
|
int valor = atoi(buf);
|
||||||
if (!isnan(v)) {
|
if (!isnan(valor)) {
|
||||||
Serial.print("[MQTT] sets = ");
|
series = valor;
|
||||||
Serial.println(v);
|
|
||||||
sets = v;
|
|
||||||
}
|
}
|
||||||
} else if (strcmp(topic, "academia/t_descanso") == 0) {
|
} else if (strcmp(topic, "academia/t_descanso") == 0) {
|
||||||
int v = atoi(buf);
|
int valor = atoi(buf);
|
||||||
if (!isnan(v)) {
|
if (!isnan(valor)) {
|
||||||
Serial.print("[MQTT] t_descanso = ");
|
tDescanso = valor;
|
||||||
Serial.println(v);
|
|
||||||
t_descanso = v;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// FUNÇÕES AUXILIARES - Conectividade
|
// CONECTIVIDADE - WiFi e MQTT
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Conecta o ESP32 à rede WiFi
|
|
||||||
void connectWiFi()
|
void connectWiFi()
|
||||||
{
|
{
|
||||||
Serial.print("[WiFi] Conectando...");
|
|
||||||
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
|
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
|
||||||
int attempts = 0;
|
int tentativas = 0;
|
||||||
while (WiFi.status() != WL_CONNECTED && attempts < 20) {
|
while (WiFi.status() != WL_CONNECTED && tentativas < 20) {
|
||||||
delay(500);
|
delay(500);
|
||||||
Serial.print(".");
|
tentativas++;
|
||||||
attempts++;
|
|
||||||
}
|
}
|
||||||
Serial.println("\r\n[WiFi] Conectado!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inscreve em tópicos MQTT para receber atualizações de limiares
|
|
||||||
void mqttSubscribe()
|
void mqttSubscribe()
|
||||||
{
|
{
|
||||||
Serial.println("[MQTT] Conectado!");
|
|
||||||
for (int i = 0; i < MQTT_SUB_COUNT; ++i) {
|
for (int i = 0; i < MQTT_SUB_COUNT; ++i) {
|
||||||
if (mqtt.subscribe(MQTT_SUB_TOPICS[i])) {
|
mqtt.subscribe(MQTT_SUB_TOPICS[i]);
|
||||||
Serial.print("[MQTT] Tópico: ");
|
|
||||||
Serial.println(MQTT_SUB_TOPICS[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Conecta ao broker MQTT
|
|
||||||
void connectMQTT()
|
void connectMQTT()
|
||||||
{
|
{
|
||||||
mqtt.setServer(MQTT_BROKER, MQTT_PORT);
|
mqtt.setServer(MQTT_BROKER, MQTT_PORT);
|
||||||
mqtt.setCallback(mqttCallback);
|
mqtt.setCallback(mqttCallback);
|
||||||
|
|
||||||
while (!mqtt.connected()) {
|
while (!mqtt.connected()) {
|
||||||
Serial.println("[MQTT] Conectando...");
|
|
||||||
if (mqtt.connect(MQTT_CLIENTID)) {
|
if (mqtt.connect(MQTT_CLIENTID)) {
|
||||||
mqttSubscribe();
|
mqttSubscribe();
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
Serial.print("[MQTT] Falha rc=");
|
|
||||||
Serial.println(mqtt.state());
|
|
||||||
delay(2000);
|
delay(2000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// FUNÇÕES AUXILIARES - Sensores
|
// INTERFACE - Display OLED
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Lê valores de aceleração do sensor MPU
|
|
||||||
|
void displayRepetitionStatus()
|
||||||
|
{
|
||||||
|
display.clearDisplay();
|
||||||
|
display.setTextSize(1);
|
||||||
|
display.setTextColor(SSD1306_WHITE);
|
||||||
|
display.setCursor(0, 0);
|
||||||
|
display.println("Modo Repeticao");
|
||||||
|
|
||||||
|
display.setTextSize(2);
|
||||||
|
display.setCursor(0, 15);
|
||||||
|
display.print("Reps: ");
|
||||||
|
display.println(repeticoes);
|
||||||
|
|
||||||
|
display.setCursor(0, 35);
|
||||||
|
display.print("Set: ");
|
||||||
|
display.print(serie);
|
||||||
|
display.print("/");
|
||||||
|
display.println(series);
|
||||||
|
|
||||||
|
display.setTextSize(1);
|
||||||
|
display.setCursor(0, 55);
|
||||||
|
display.print("FC: ");
|
||||||
|
display.print(frequenciaCardiacaAtual);
|
||||||
|
display.println(" bpm");
|
||||||
|
|
||||||
|
display.display();
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayPedometerStatus()
|
||||||
|
{
|
||||||
|
display.clearDisplay();
|
||||||
|
display.setTextSize(1);
|
||||||
|
display.setTextColor(SSD1306_WHITE);
|
||||||
|
display.setCursor(0, 0);
|
||||||
|
display.println("Modo Pedometro");
|
||||||
|
|
||||||
|
display.setTextSize(2);
|
||||||
|
display.setCursor(0, 20);
|
||||||
|
display.print("Passos: ");
|
||||||
|
display.println(totalPassos);
|
||||||
|
|
||||||
|
display.setTextSize(1);
|
||||||
|
display.setCursor(0, 55);
|
||||||
|
display.print("FC: ");
|
||||||
|
display.print(frequenciaCardiacaAtual);
|
||||||
|
display.println(" bpm");
|
||||||
|
|
||||||
|
display.display();
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayRestTimer()
|
||||||
|
{
|
||||||
|
display.clearDisplay();
|
||||||
|
display.setTextSize(1);
|
||||||
|
display.setTextColor(SSD1306_WHITE);
|
||||||
|
display.setCursor(0, 0);
|
||||||
|
display.println("DESCANSO");
|
||||||
|
|
||||||
|
unsigned long tempoDecorrido = (millis() - tFim) / 1000;
|
||||||
|
long tempoRestante = tDescanso - tempoDecorrido;
|
||||||
|
|
||||||
|
display.setTextSize(2);
|
||||||
|
display.setCursor(0, 20);
|
||||||
|
if (tempoRestante > 0) {
|
||||||
|
display.print("Restam: ");
|
||||||
|
display.println(tempoRestante);
|
||||||
|
} else {
|
||||||
|
display.println("PRONTO!");
|
||||||
|
}
|
||||||
|
|
||||||
|
display.setTextSize(1);
|
||||||
|
display.setCursor(0, 55);
|
||||||
|
display.print("FC: ");
|
||||||
|
display.print(frequenciaCardiacaAtual);
|
||||||
|
display.println(" bpm");
|
||||||
|
|
||||||
|
display.display();
|
||||||
|
}
|
||||||
|
|
||||||
|
void displayPedometerIdleScreen()
|
||||||
|
{
|
||||||
|
display.clearDisplay();
|
||||||
|
display.setTextSize(1);
|
||||||
|
display.setTextColor(SSD1306_WHITE);
|
||||||
|
display.setCursor(0, 0);
|
||||||
|
display.println("Pedometro OCIOSO");
|
||||||
|
|
||||||
|
display.setTextSize(2);
|
||||||
|
display.setCursor(0, 25);
|
||||||
|
display.println("Aguardando...");
|
||||||
|
|
||||||
|
display.setTextSize(1);
|
||||||
|
display.setCursor(0, 55);
|
||||||
|
display.print("FC: ");
|
||||||
|
display.print(frequenciaCardiacaAtual);
|
||||||
|
display.println(" bpm");
|
||||||
|
|
||||||
|
display.display();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// SENSORES - Leitura e Processamento
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
void amostraMPU()
|
void amostraMPU()
|
||||||
{
|
{
|
||||||
sensors_event_t a, g, temp;
|
sensors_event_t a, g, temp;
|
||||||
mpu.getEvent(&a, &g, &temp);
|
mpu.getEvent(&a, &g, &temp);
|
||||||
|
|
||||||
float magnitudeAceleracao = sqrt(
|
float magnitudeAceleracao = sqrt(
|
||||||
a.acceleration.x * a.acceleration.x
|
a.acceleration.x * a.acceleration.x +
|
||||||
+ a.acceleration.y * a.acceleration.y
|
a.acceleration.y * a.acceleration.y +
|
||||||
+ a.acceleration.z * a.acceleration.z);
|
a.acceleration.z * a.acceleration.z
|
||||||
|
);
|
||||||
|
|
||||||
float aceleracaoCorrigida = magnitudeAceleracao - 9.81;
|
float aceleracaoCorrigida = magnitudeAceleracao - 9.81;
|
||||||
|
aceleracaoFiltrada = FILTER_ALPHA * aceleracaoFiltrada +
|
||||||
|
(1.0 - FILTER_ALPHA) * aceleracaoCorrigida;
|
||||||
|
|
||||||
aceleracaoFiltrada = FILTER_ALPHA * aceleracaoFiltrada + (1.0 - FILTER_ALPHA) * aceleracaoCorrigida;
|
if (abs(aceleracaoFiltrada) > 0.1) {
|
||||||
|
ultimaAtividadePedometro = millis();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pedometroAtivo) {
|
||||||
detectarRepeticao(aceleracaoFiltrada);
|
detectarRepeticao(aceleracaoFiltrada);
|
||||||
|
} else {
|
||||||
|
detectaPasso(aceleracaoFiltrada);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void detectaPasso(float aceleracaoAtual)
|
||||||
|
{
|
||||||
|
unsigned long tempoAtual = millis();
|
||||||
|
|
||||||
|
if ((tempoAtual - ultimoTempoPassso) > STEP_DEBOUNCE_MS) {
|
||||||
|
if (aceleracaoAtual > STEP_ACCEL_THRESHOLD &&
|
||||||
|
aceleracaoAnterior < STEP_ACCEL_THRESHOLD) {
|
||||||
|
totalPassos++;
|
||||||
|
ultimoTempoPassso = tempoAtual;
|
||||||
|
ultimaAtividadePedometro = tempoAtual;
|
||||||
|
|
||||||
|
snprintf(msg, sizeof(msg),
|
||||||
|
"{\"passos\": %ld, \"fc\": %d}",
|
||||||
|
totalPassos, frequenciaCardiacaAtual);
|
||||||
|
mqtt.publish(MQTT_PUB_TOPIC, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aceleracaoAnterior = aceleracaoAtual;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// FUNÇÕES - Detecção de alarmes
|
// DETECÇÃO - Repetições
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Verifica qual alarme deve ser ativado baseado nos limites
|
|
||||||
void detectarRepeticao(float sinal)
|
void detectarRepeticao(float sinal)
|
||||||
{
|
{
|
||||||
unsigned long agora = millis();
|
unsigned long agora = millis();
|
||||||
|
|
||||||
switch (estado) {
|
switch (estado) {
|
||||||
|
|
||||||
case OCIOSO:
|
case OCIOSO:
|
||||||
if (sinal > TH_START) {
|
if (sinal > ACCEL_ACTIVE_THRESHOLD) {
|
||||||
t_inicio = agora;
|
tInicio = agora;
|
||||||
aceleracaoPico = sinal;
|
aceleracaoPico = sinal;
|
||||||
estado = SUBINDO;
|
estado = SUBINDO;
|
||||||
// Inicia acumulação de frequência cardíaca para esta repetição
|
|
||||||
somaFrequenciaCardiaca = 0;
|
somaFrequenciaCardiaca = 0;
|
||||||
contagemFrequenciaCardiaca = 0;
|
contagemFrequenciaCardiaca = 0;
|
||||||
|
digitalWrite(LED_PIN, HIGH);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SUBINDO:
|
case SUBINDO:
|
||||||
if (sinal > aceleracaoPico)
|
if (sinal > aceleracaoPico) {
|
||||||
aceleracaoPico = sinal;
|
aceleracaoPico = sinal;
|
||||||
|
}
|
||||||
|
|
||||||
if (sinal < aceleracaoAnterior) {
|
if (sinal < aceleracaoAnterior) {
|
||||||
t_pico = agora;
|
tPico = agora;
|
||||||
estado = DESCENDO;
|
estado = DESCENDO;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DESCENDO:
|
case DESCENDO:
|
||||||
if (sinal < TH_END) {
|
if (sinal < ACCEL_REST_THRESHOLD) {
|
||||||
t_fim = agora;
|
tFim = agora;
|
||||||
|
|
||||||
analisarRepeticao();
|
analisarRepeticao();
|
||||||
verificarSerie();
|
verificarSerie();
|
||||||
|
digitalWrite(LED_PIN, LOW);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DESCANSO:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Se estamos no meio de uma repetição, acumula a frequência cardíaca atual
|
if (estado != OCIOSO && estado != DESCANSO) {
|
||||||
if (estado != OCIOSO) {
|
|
||||||
somaFrequenciaCardiaca += (unsigned long)frequenciaCardiacaAtual;
|
somaFrequenciaCardiaca += (unsigned long)frequenciaCardiacaAtual;
|
||||||
contagemFrequenciaCardiaca++;
|
contagemFrequenciaCardiaca++;
|
||||||
}
|
}
|
||||||
@@ -262,52 +425,39 @@ void detectarRepeticao(float sinal)
|
|||||||
|
|
||||||
void analisarRepeticao()
|
void analisarRepeticao()
|
||||||
{
|
{
|
||||||
unsigned long tempoTotal = t_fim - t_inicio;
|
unsigned long tempoTotal = tFim - tInicio;
|
||||||
unsigned long tempoSubida = t_pico - t_inicio;
|
unsigned long tempoSubida = tPico - tInicio;
|
||||||
unsigned long tempoDescida = t_fim - t_pico;
|
unsigned long tempoDescida = tFim - tPico;
|
||||||
|
bool invalida = false;
|
||||||
bool ruim = false;
|
|
||||||
|
|
||||||
Serial.print("Total: ");
|
|
||||||
Serial.print(tempoTotal);
|
|
||||||
Serial.print(" ms");
|
|
||||||
|
|
||||||
if (aceleracaoPico < MIN_PEAK_AMPLITUDE) {
|
if (aceleracaoPico < MIN_PEAK_AMPLITUDE) {
|
||||||
Serial.print(" | Repetição parcial");
|
invalida = true;
|
||||||
ruim = true;
|
Serial.print(" Repetição parcial ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tempoTotal < MIN_REP_TIME) {
|
if (tempoTotal < MIN_REP_TIME) {
|
||||||
Serial.print(" | Muito rápido");
|
invalida = true;
|
||||||
ruim = true;
|
Serial.print(" Rápido demais ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tempoTotal > MAX_REP_TIME) {
|
if (tempoTotal > MAX_REP_TIME) {
|
||||||
Serial.print(" | Muito lento");
|
invalida = true;
|
||||||
ruim = true;
|
Serial.print(" Lento demais ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tempoDescida < tempoSubida * 0.6) {
|
if (tempoDescida < tempoSubida * 0.6) {
|
||||||
Serial.print(" | Deixando cair o peso");
|
invalida = true;
|
||||||
ruim = true;
|
Serial.print(" Deixando o peso cair ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ruim) {
|
if (!invalida) {
|
||||||
Serial.print(" | Boa repetição");
|
|
||||||
repeticoes++;
|
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;
|
unsigned int fcMedia = 0;
|
||||||
if (contagemFrequenciaCardiaca > 0) {
|
if (contagemFrequenciaCardiaca > 0) {
|
||||||
fcMedia = (unsigned int)(somaFrequenciaCardiaca / contagemFrequenciaCardiaca);
|
fcMedia = (unsigned int)(somaFrequenciaCardiaca / contagemFrequenciaCardiaca);
|
||||||
Serial.print(" | FC média: ");
|
|
||||||
Serial.print(fcMedia);
|
|
||||||
Serial.print(" bpm");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zera agregados após uso
|
|
||||||
somaFrequenciaCardiaca = 0;
|
somaFrequenciaCardiaca = 0;
|
||||||
contagemFrequenciaCardiaca = 0;
|
contagemFrequenciaCardiaca = 0;
|
||||||
|
|
||||||
@@ -316,21 +466,19 @@ void analisarRepeticao()
|
|||||||
fcMedia, tempoTotal, tempoSubida, tempoDescida);
|
fcMedia, tempoTotal, tempoSubida, tempoDescida);
|
||||||
|
|
||||||
mqtt.publish(MQTT_PUB_TOPIC, msg);
|
mqtt.publish(MQTT_PUB_TOPIC, msg);
|
||||||
|
|
||||||
Serial.println();
|
Serial.println();
|
||||||
}
|
}
|
||||||
|
|
||||||
void verificarSerie()
|
void verificarSerie()
|
||||||
{
|
{
|
||||||
if (repeticoes >= max_reps && max_reps > 0) {
|
if (repeticoes >= maxRepeticoes && maxRepeticoes > 0) {
|
||||||
Serial.println("[SÉRIE] Série finalizada, iniciando descanso...");
|
|
||||||
repeticoes = 0;
|
repeticoes = 0;
|
||||||
estado = DESCANSO;
|
estado = DESCANSO;
|
||||||
set++;
|
|
||||||
digitalWrite(LED_PIN, HIGH);
|
digitalWrite(LED_PIN, HIGH);
|
||||||
if (set >= sets && sets > 0) {
|
serie++;
|
||||||
Serial.println("[TREINO] Treino finalizado, parabéns!");
|
|
||||||
set = 0;
|
if (serie >= series && series > 0) {
|
||||||
|
serie = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
estado = OCIOSO;
|
estado = OCIOSO;
|
||||||
@@ -338,42 +486,45 @@ void verificarSerie()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// FUNÇÕES - Inicialização
|
// INICIALIZAÇÃO
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Inicializa o ESP32 e configura os periféricos
|
|
||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
delay(100);
|
delay(100);
|
||||||
|
|
||||||
Serial.println("\n[SETUP] Iniciando sistema...");
|
|
||||||
|
|
||||||
// Gera ID único MQTT
|
|
||||||
snprintf(MQTT_CLIENTID, sizeof(MQTT_CLIENTID), "esp32_%08X",
|
snprintf(MQTT_CLIENTID, sizeof(MQTT_CLIENTID), "esp32_%08X",
|
||||||
(uint32_t)(ESP.getEfuseMac() & 0xFFFFFFFF));
|
(uint32_t)(ESP.getEfuseMac() & 0xFFFFFFFF));
|
||||||
|
|
||||||
// Conecta
|
Wire.begin();
|
||||||
|
|
||||||
|
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
|
||||||
|
for (;;);
|
||||||
|
}
|
||||||
|
|
||||||
connectWiFi();
|
connectWiFi();
|
||||||
connectMQTT();
|
connectMQTT();
|
||||||
|
|
||||||
while (!mpu.begin()) {
|
while (!mpu.begin()) {
|
||||||
Serial.println("MPU6050 not connected!");
|
|
||||||
delay(1000);
|
delay(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
mpu.setAccelerometerRange(MPU6050_RANGE_4_G);
|
mpu.setAccelerometerRange(MPU6050_RANGE_4_G);
|
||||||
mpu.setGyroRange(MPU6050_RANGE_500_DEG);
|
mpu.setGyroRange(MPU6050_RANGE_500_DEG);
|
||||||
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
|
mpu.setFilterBandwidth(MPU6050_BAND_21_HZ);
|
||||||
Serial.println("MPU6050 ready!");
|
|
||||||
|
|
||||||
pinMode(LED_PIN, OUTPUT);
|
pinMode(LED_PIN, OUTPUT);
|
||||||
digitalWrite(LED_PIN, LOW);
|
digitalWrite(LED_PIN, LOW);
|
||||||
Serial.println("[SETUP] Pronto!\n");
|
|
||||||
|
pinMode(MODE_BUTTON_PIN, INPUT_PULLUP);
|
||||||
|
button.setDebounceTime(BUTTON_DEBOUNCE_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// LOOP PRINCIPAL
|
// LOOP PRINCIPAL
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Loop principal - executa continuamente
|
|
||||||
void loop()
|
void loop()
|
||||||
{
|
{
|
||||||
if (!mqtt.connected()) {
|
if (!mqtt.connected()) {
|
||||||
@@ -381,22 +532,58 @@ void loop()
|
|||||||
}
|
}
|
||||||
mqtt.loop();
|
mqtt.loop();
|
||||||
|
|
||||||
if (millis() - ultimaAmostra >= SAMPLE_PERIOD_MS && estado != DESCANSO) {
|
button.loop();
|
||||||
// Verifica MQTT
|
|
||||||
|
|
||||||
|
if (button.isPressed()) {
|
||||||
|
pedometroAtivo = !pedometroAtivo;
|
||||||
|
|
||||||
|
if (pedometroAtivo) {
|
||||||
|
totalPassos = 0;
|
||||||
|
ultimoTempoPassso = 0;
|
||||||
|
aceleracaoAnterior = 1.0;
|
||||||
|
ultimaAtividadePedometro = millis();
|
||||||
|
} else {
|
||||||
|
estado = OCIOSO;
|
||||||
|
repeticoes = 0;
|
||||||
|
serie = 0;
|
||||||
|
aceleracaoAnterior = 1.0;
|
||||||
|
somaFrequenciaCardiaca = 0;
|
||||||
|
contagemFrequenciaCardiaca = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
display.clearDisplay();
|
||||||
|
display.display();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (millis() - ultimaAmostra >= SAMPLE_PERIOD_MS) {
|
||||||
int16_t valorPulso = analogRead(PULSE_PIN);
|
int16_t valorPulso = analogRead(PULSE_PIN);
|
||||||
|
|
||||||
// Converter valorPulso para tensão
|
|
||||||
float tensao = valorPulso * (5.0 / 4095.0);
|
float tensao = valorPulso * (5.0 / 4095.0);
|
||||||
|
|
||||||
// Atualiza frequência cardíaca atual (valor usado nas acumulações)
|
|
||||||
frequenciaCardiacaAtual = (int)((tensao / 3.3) * 675);
|
frequenciaCardiacaAtual = (int)((tensao / 3.3) * 675);
|
||||||
|
|
||||||
ultimaAmostra += SAMPLE_PERIOD_MS;
|
|
||||||
amostraMPU();
|
amostraMPU();
|
||||||
} else if (millis() - t_fim >= t_descanso * 100 && estado == DESCANSO) {
|
ultimaAmostra += SAMPLE_PERIOD_MS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Atualizar display apenas a cada DISPLAY_UPDATE_INTERVAL_MS (100ms = 10 FPS)
|
||||||
|
if (millis() - ultimoDisplayUpdate >= DISPLAY_UPDATE_INTERVAL_MS) {
|
||||||
|
ultimoDisplayUpdate = millis();
|
||||||
|
|
||||||
|
if (estado == DESCANSO) {
|
||||||
|
displayRestTimer();
|
||||||
|
} else if (pedometroAtivo &&
|
||||||
|
(millis() - ultimaAtividadePedometro > PEDOMETER_IDLE_TIMEOUT_MS)) {
|
||||||
|
displayPedometerIdleScreen();
|
||||||
|
} else {
|
||||||
|
if (pedometroAtivo) {
|
||||||
|
displayPedometerStatus();
|
||||||
|
} else {
|
||||||
|
displayRepetitionStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (estado == DESCANSO && millis() - tFim >= tDescanso * 1000) {
|
||||||
estado = OCIOSO;
|
estado = OCIOSO;
|
||||||
digitalWrite(LED_PIN, LOW);
|
digitalWrite(LED_PIN, LOW);
|
||||||
Serial.println("[DESCANSO] Descanso finalizado, pronto para próxima série.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user