Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
Mohammed Adnan Khan
Created September 5, 2024

Thermo-Jacket

A temperature-controlled jacket for the physically challenged

IntermediateWork in progress31

Things used in this project

Story

Read more

Code

NRF52840 code

C/C++
#include <zephyr.h>
#include <device.h>
#include <drivers/gpio.h>
#include <drivers/pwm.h>
#include <drivers/sensor.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/gatt.h>

// GPIO and PWM Definitions for the Peltier Control
#define PELTIER_PIN DT_GPIO_PIN(DT_ALIAS(peltier), gpios)
#define PWM_DEV DT_PWMS_CTLR(DT_ALIAS(peltier))
#define PWM_CHANNEL DT_PWMS_CHANNEL(DT_ALIAS(peltier))

// Temperature sensor device name
#define TEMP_SENSOR_NAME "TEMP_SENSOR"

// Default baseline temperature in Celsius
static int baseline_temp = 25;

// PWM values for controlling Peltier power
#define MAX_PWM_VALUE 10000
#define MIN_PWM_VALUE 0

static struct device *pwm_dev;
static struct device *temp_sensor_dev;

// Bluetooth characteristic for baseline temperature setting
static uint8_t bt_baseline_temp = 25;

static ssize_t read_baseline_temp(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) {
    return bt_gatt_attr_read(conn, attr, buf, len, offset, &bt_baseline_temp, sizeof(bt_baseline_temp));
}

static ssize_t write_baseline_temp(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf, uint16_t len, uint16_t offset, uint8_t flags) {
    if (offset + len > sizeof(bt_baseline_temp)) {
        return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
    }

    memcpy(&bt_baseline_temp, buf, len);
    baseline_temp = bt_baseline_temp;  // Update baseline temperature
    return len;
}

// Bluetooth GATT service definition
BT_GATT_SERVICE_DEFINE(temp_svc,
    BT_GATT_PRIMARY_SERVICE(BT_UUID_DECLARE_16(0x1809)),
    BT_GATT_CHARACTERISTIC(BT_UUID_DECLARE_16(0x2A1C), BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
        BT_GATT_PERM_READ | BT_GATT_PERM_WRITE, read_baseline_temp, write_baseline_temp, &bt_baseline_temp)
);

// Function to control the Peltier device
void control_peltier(int current_temp, int baseline_temp) {
    uint32_t pwm_value;

    if (current_temp > baseline_temp) {
        // Cool down: activate Peltier
        pwm_value = (current_temp - baseline_temp) * 1000;  // Scale value for PWM
        pwm_value = pwm_value > MAX_PWM_VALUE ? MAX_PWM_VALUE : pwm_value;
    } else {
        // Turn off Peltier
        pwm_value = MIN_PWM_VALUE;
    }

    // Apply PWM to Peltier device
    pwm_pin_set_usec(pwm_dev, PWM_CHANNEL, MAX_PWM_VALUE, pwm_value, 0);
}

// Main function to initialize and control temperature
void main(void) {
    int ret;
    struct sensor_value temp_val;
    int current_temp;

    // Initialize the PWM device for Peltier control
    pwm_dev = device_get_binding(PWM_DEV);
    if (!pwm_dev) {
        printk("Failed to bind PWM device\n");
        return;
    }

    // Initialize the temperature sensor
    temp_sensor_dev = device_get_binding(TEMP_SENSOR_NAME);
    if (!temp_sensor_dev) {
        printk("Failed to bind temperature sensor\n");
        return;
    }

    // Enable Bluetooth
    ret = bt_enable(NULL);
    if (ret) {
        printk("Bluetooth init failed (err %d)\n", ret);
        return;
    }

    printk("Bluetooth initialized, baseline temp: %d°C\n", baseline_temp);

    // Main loop to monitor temperature and control Peltier
    while (1) {
        // Fetch temperature from the sensor
        ret = sensor_sample_fetch(temp_sensor_dev);
        if (ret) {
            printk("Failed to fetch temperature\n");
            continue;
        }

        ret = sensor_channel_get(temp_sensor_dev, SENSOR_CHAN_AMBIENT_TEMP, &temp_val);
        if (ret) {
            printk("Failed to get temperature\n");
            continue;
        }

        current_temp = sensor_value_to_double(&temp_val);
        printk("Current Temp: %d°C, Baseline Temp: %d°C\n", current_temp, baseline_temp);

        // Control the Peltier device based on the current and baseline temperature
        control_peltier(current_temp, baseline_temp);

        // Wait before the next iteration
        k_sleep(K_SECONDS(5));
    }
}

Credits

Mohammed Adnan Khan

Mohammed Adnan Khan

3 projects • 8 followers
Embedded systems engineer

Comments