adiciona monitor cardíaco
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
*/*.wasm
|
||||||
|
*/wokwi-api.h
|
||||||
75
heart_rate/Makefile
Normal file
75
heart_rate/Makefile
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
# Wokwi Custom Chip Makefile
|
||||||
|
# Generated by wokwi-cli
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# make - Build the chip
|
||||||
|
# make clean - Remove build artifacts
|
||||||
|
# make wokwi-api.h - Download the Wokwi API header
|
||||||
|
#
|
||||||
|
# Requirements:
|
||||||
|
# - WASI-SDK (https://github.com/WebAssembly/wasi-sdk)
|
||||||
|
# - Set WASI_SDK_PATH environment variable or install to ~/.wokwi/wasi-sdk
|
||||||
|
#
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
CHIP_NAME ?= heartrate.chip
|
||||||
|
SOURCES ?= main.c
|
||||||
|
OUTPUT ?= $(CHIP_NAME).wasm
|
||||||
|
|
||||||
|
# WASI-SDK paths
|
||||||
|
WASI_SDK_PATH ?= /l/disk0/alopes/.wokwi/wasi-sdk
|
||||||
|
WASI_SDK_VERSION ?= 25
|
||||||
|
|
||||||
|
# Compiler settings
|
||||||
|
CC = $(WASI_SDK_PATH)/bin/clang
|
||||||
|
SYSROOT = $(WASI_SDK_PATH)/share/wasi-sysroot
|
||||||
|
|
||||||
|
# Compilation flags
|
||||||
|
CFLAGS = --target=wasm32-wasi \
|
||||||
|
--sysroot=$(SYSROOT) \
|
||||||
|
-nostartfiles \
|
||||||
|
-I. \
|
||||||
|
-O2
|
||||||
|
|
||||||
|
LDFLAGS = -Wl,--no-entry \
|
||||||
|
-Wl,--import-memory \
|
||||||
|
-Wl,--export-table
|
||||||
|
|
||||||
|
# Default target
|
||||||
|
all: check-sdk wokwi-api.h $(OUTPUT)
|
||||||
|
|
||||||
|
# Build the WASM file
|
||||||
|
$(OUTPUT): $(SOURCES) wokwi-api.h
|
||||||
|
@echo "Compiling $(CHIP_NAME)..."
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(SOURCES)
|
||||||
|
@echo "Success! Output: $@ ($$(du -h $@ | cut -f1))"
|
||||||
|
|
||||||
|
# Check WASI-SDK is available
|
||||||
|
check-sdk:
|
||||||
|
@if [ ! -d "$(WASI_SDK_PATH)" ]; then \
|
||||||
|
echo "Error: WASI-SDK not found at $(WASI_SDK_PATH)"; \
|
||||||
|
echo ""; \
|
||||||
|
echo "Install WASI-SDK:"; \
|
||||||
|
echo " Option 1: Run 'wokwi-cli chip compile' once to auto-install"; \
|
||||||
|
echo " Option 2: Download from https://github.com/WebAssembly/wasi-sdk/releases"; \
|
||||||
|
echo " Option 3: Set WASI_SDK_PATH environment variable"; \
|
||||||
|
exit 1; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Download wokwi-api.h if not present
|
||||||
|
wokwi-api.h:
|
||||||
|
@if [ ! -f wokwi-api.h ]; then \
|
||||||
|
echo "Downloading wokwi-api.h..."; \
|
||||||
|
curl -sL "https://wokwi.com/api/chips/wokwi-api.h" -o wokwi-api.h; \
|
||||||
|
echo "Downloaded wokwi-api.h"; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Clean build artifacts
|
||||||
|
clean:
|
||||||
|
rm -f $(OUTPUT)
|
||||||
|
|
||||||
|
# Clean everything including downloaded files
|
||||||
|
distclean: clean
|
||||||
|
rm -f wokwi-api.h
|
||||||
|
|
||||||
|
.PHONY: all check-sdk clean distclean
|
||||||
11
heart_rate/heartrate.chip.json
Normal file
11
heart_rate/heartrate.chip.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "heartrate",
|
||||||
|
"author": "Amaro Lopes",
|
||||||
|
"pins": [
|
||||||
|
"VCC",
|
||||||
|
"GND",
|
||||||
|
"BTN",
|
||||||
|
"OUT"
|
||||||
|
],
|
||||||
|
"controls": []
|
||||||
|
}
|
||||||
119
heart_rate/main.c
Normal file
119
heart_rate/main.c
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
|
||||||
|
#include "wokwi-api.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* -------------------------------------------------- */
|
||||||
|
/* States */
|
||||||
|
|
||||||
|
typedef enum { STATE_NORMAL, STATE_RISING, STATE_FALLING } hr_state_t;
|
||||||
|
|
||||||
|
typedef enum { STATE_SLOW = 0, STATE_FAST = 1 } hr_speed_t;
|
||||||
|
|
||||||
|
/* -------------------------------------------------- */
|
||||||
|
/* Chip state */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
pin_t out_pin;
|
||||||
|
pin_t btn_pin;
|
||||||
|
|
||||||
|
float bpm;
|
||||||
|
int last_target;
|
||||||
|
|
||||||
|
hr_state_t state;
|
||||||
|
hr_speed_t speed;
|
||||||
|
|
||||||
|
int pulseValue;
|
||||||
|
|
||||||
|
timer_t update_timer;
|
||||||
|
} chip_state_t;
|
||||||
|
|
||||||
|
/* -------------------------------------------------- */
|
||||||
|
/* Output mapping */
|
||||||
|
|
||||||
|
static void update_output_voltage(chip_state_t *chip) {
|
||||||
|
float volts = (chip->bpm * 3.3f) / 675.0f;
|
||||||
|
|
||||||
|
if (volts < 0.0f)
|
||||||
|
volts = 0.0f;
|
||||||
|
if (volts > 3.3f)
|
||||||
|
volts = 3.3f;
|
||||||
|
|
||||||
|
pin_dac_write(chip->out_pin, volts);
|
||||||
|
|
||||||
|
printf("BPM: %.1f | Voltage: %.3fV\n", chip->bpm, volts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------- */
|
||||||
|
/* Main update loop */
|
||||||
|
|
||||||
|
static void update_cb(void *user_data) {
|
||||||
|
chip_state_t *chip = user_data;
|
||||||
|
|
||||||
|
int target = attr_read(chip->pulseValue);
|
||||||
|
|
||||||
|
/* Read pull-down switch: LOW=SLOW, HIGH=FAST */
|
||||||
|
chip->speed = pin_read(chip->btn_pin) ? STATE_FAST : STATE_SLOW;
|
||||||
|
|
||||||
|
/* Detect target change and re-evaluate direction */
|
||||||
|
if (target != chip->last_target) {
|
||||||
|
if (chip->bpm < target) {
|
||||||
|
chip->state = STATE_RISING;
|
||||||
|
} else if (chip->bpm > target) {
|
||||||
|
chip->state = STATE_FALLING;
|
||||||
|
} else {
|
||||||
|
chip->state = STATE_NORMAL;
|
||||||
|
}
|
||||||
|
chip->last_target = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Step size */
|
||||||
|
float step = (chip->speed == STATE_FAST) ? 2.0f : 0.5f;
|
||||||
|
|
||||||
|
/* Rising */
|
||||||
|
if (chip->state == STATE_RISING) {
|
||||||
|
chip->bpm += step;
|
||||||
|
if (chip->bpm >= target) {
|
||||||
|
chip->bpm = target;
|
||||||
|
chip->state = STATE_NORMAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Falling */
|
||||||
|
if (chip->state == STATE_FALLING) {
|
||||||
|
chip->bpm -= step;
|
||||||
|
if (chip->bpm <= target) {
|
||||||
|
chip->bpm = target;
|
||||||
|
chip->state = STATE_NORMAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
update_output_voltage(chip);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------- */
|
||||||
|
/* Init */
|
||||||
|
|
||||||
|
void chip_init(void) {
|
||||||
|
printf("Heart Rate chip init\n");
|
||||||
|
|
||||||
|
chip_state_t *chip = calloc(1, sizeof(chip_state_t));
|
||||||
|
|
||||||
|
/* Attribute: target BPM */
|
||||||
|
chip->pulseValue = attr_init("pulseValue", 100);
|
||||||
|
|
||||||
|
chip->bpm = 100.0f;
|
||||||
|
chip->last_target = 100;
|
||||||
|
chip->state = STATE_NORMAL;
|
||||||
|
chip->speed = STATE_SLOW;
|
||||||
|
|
||||||
|
chip->out_pin = pin_init("OUT", ANALOG);
|
||||||
|
chip->btn_pin = pin_init("BTN", INPUT); // pull-down switch
|
||||||
|
|
||||||
|
timer_config_t update_cfg = {.callback = update_cb, .user_data = chip};
|
||||||
|
|
||||||
|
chip->update_timer = timer_init(&update_cfg);
|
||||||
|
|
||||||
|
/* 50 ms update rate */
|
||||||
|
timer_start(chip->update_timer, 50000, true);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user