#include "wokwi-api.h" #include #include /* -------------------------------------------------- */ /* 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); }