frankensteins monster

This commit is contained in:
Conner 2024-10-14 00:31:33 +02:00
parent e3e1c4a5b9
commit 55102027c1
8 changed files with 603 additions and 8 deletions

View file

@ -0,0 +1,31 @@
# DS18B20 Component
Simple DS18B20 temperature sensor library for [ESP8266 RTOS SDK](https://github.com/espressif/ESP8266_RTOS_SDK) for reading Celsius temperature with different resolutions from singular device.
## Usage
```
// Create variable for handler
ds18b20_handler_t sensor;
// Check for any initialization failures
if (!ds18b20_init(&sensor, GPIO_NUM_12, TEMP_RES_12_BIT))
{
ESP_LOGE("TAG", "Failed to initalize DS18B20!");
return 0; // Exit
}
float temp = 0;
// Initalize conversion
ds18b20_convert_temp(&sensor);
// If you doesn't convert temperature you may read 85.0 Celsius,
// as it is default temperature set by DS18B20 if convert command wasn't issued.
temp = ds18b20_read_temp(&sensor); // Read temperature
// Print temperature with 4 decimal places
// (12 bit resolution measurement accuracy is 0.0625 Celsius)
ESP_LOGI("TAG", "Temperature = %.4f", temp);
```
> **_NOTE:_** If last statement doesn't print temperature you may have to disable Newlib nano in `menuconfig` of RTOS SDK.

View file

@ -0,0 +1,5 @@
#
# Component Makefile
#
COMPONENT_ADD_INCLUDEDIRS := .

View file

@ -0,0 +1,120 @@
#include "ds18b20.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
static const char* TAG_DS18B20 = "DS18B20";
static const uint16_t ds18b20_temp_conv_time[] = {94, 188, 375, 750}; // ms
static const uint16_t ds18b20_resolution_val[] = {0x1F, 0x3F, 0x5F, 0x7F};
uint8_t ds18b20_init(ds18b20_handler_t *device, gpio_num_t pin, ds18b20_temp_res_t resolution)
{
if (!device)
{
ESP_LOGW(TAG_DS18B20, "device is null!");
return 0;
}
if (!onewire_init(&device->bus, pin, NULL))
{
ESP_LOGW(TAG_DS18B20, "Failed to initialize onewire bus");
return 0;
}
device->res = resolution;
// Configure resolution
ds18b20_write_scratchpad(device);
ds18b20_read_scratchpad(device);
return 1;
}
void ds18b20_send_command(ds18b20_handler_t *device, ds18b20_commands_t command)
{
uint8_t payload = 0x0 ^ command;
onewire_write_byte(&device->bus, payload);
}
void ds18b20_convert_temp(ds18b20_handler_t *device)
{
onewire_reset(&device->bus);
onewire_send_command(&device->bus, _ROM_SKIP);
ds18b20_send_command(device, _CONVERT_T);
vTaskDelay(pdMS_TO_TICKS(ds18b20_temp_conv_time[device->res]));
}
void ds18b20_write_scratchpad(ds18b20_handler_t *device)
{
onewire_reset(&device->bus);
onewire_send_command(&device->bus, _ROM_SKIP);
ds18b20_send_command(device, _SCRATCH_WRITE);
// Th and Tl registers
onewire_write_byte(&device->bus, 0);
onewire_write_byte(&device->bus, 0);
// Resolution value
onewire_write_byte(&device->bus, ds18b20_resolution_val[device->res]);
}
void ds18b20_copy_scratchpad(ds18b20_handler_t *device)
{
onewire_reset(&device->bus);
onewire_send_command(&device->bus, _ROM_SKIP);
ds18b20_send_command(device, _SCRATCH_COPY);
}
void ds18b20_read_scratchpad(ds18b20_handler_t *device)
{
onewire_reset(&device->bus);
onewire_send_command(&device->bus, _ROM_SKIP);
ds18b20_send_command(device, _SCRATCH_READ);
uint8_t i;
for (i = 0; i < 9; i++)
{
device->scratchpad[i] = onewire_read_byte(&device->bus);
}
}
void ds18b20_print_scratchpad(ds18b20_handler_t *device)
{
uint8_t i;
for (i = 0; i < 9; i++)
{
printf("%x ", device->scratchpad[i]);
}
printf("\n");
}
float ds18b20_read_temp(ds18b20_handler_t *device)
{
ds18b20_read_scratchpad(device);
uint8_t sign = 0x0;
uint8_t lsb = device->scratchpad[0];
uint8_t mask = 0xFF << (TEMP_RES_12_BIT - device->res);
lsb &= mask; // Mask out last 3 bits accordingly
uint8_t msb = device->scratchpad[1];
sign = msb & 0x80;
int16_t temp = 0x0;
temp = lsb + (msb << 8);
if (sign)
{
temp = ~(-temp) + 1; // Convert signed two complement's
}
return temp / 16.0;
}

View file

@ -0,0 +1,97 @@
#ifndef DS18B20_H
#define DS18B20_H
#include "onewire.h"
typedef enum {
TEMP_RES_9_BIT = 0,
TEMP_RES_10_BIT = 1,
TEMP_RES_11_BIT = 2,
TEMP_RES_12_BIT = 3
} ds18b20_temp_res_t;
typedef enum {
_SCRATCH_WRITE = 0x4E,
_SCRATCH_READ = 0xBE,
_SCRATCH_COPY = 0x48,
_CONVERT_T = 0x44
} ds18b20_commands_t;
typedef uint8_t ds18b20_scratchpad_t[9];
typedef struct {
onewire_bus_handle_t bus;
ds18b20_temp_res_t res;
ds18b20_scratchpad_t scratchpad;
} ds18b20_handler_t;
/**
* @brief Initialize DS18B20
*
* @param device DS18B20 handler
* @param pin Data pin
* @param resolution Temperature resolution
*
* @retval 1: Success
* @retval 0: Incorrect pin or gpio configuration failed (Logs tells which happened)
*/
uint8_t ds18b20_init(ds18b20_handler_t *device, gpio_num_t pin, ds18b20_temp_res_t resolution);
/**
* @brief Send command to DS18B20
*
* @param device DS18B20 handler
* @param command Function command
*/
void ds18b20_send_command(ds18b20_handler_t *device, ds18b20_commands_t command);
/**
* @brief Write to scratchpad
*
* @param device DS18B20 handler
*/
void ds18b20_write_scratchpad(ds18b20_handler_t *device);
/**
* @brief Read from scratchpad
*
* @param device DS18B20 handler
*/
void ds18b20_read_scratchpad(ds18b20_handler_t *device);
/**
* @brief Copy to scratchpad
*
* @param device DS18B20 handler
*/
void ds18b20_copy_scratchpad(ds18b20_handler_t *device);
/**
* @brief Print scratchpad bytes
*
* @param device DS18B20 handler
*/
void ds18b20_print_scratchpad(ds18b20_handler_t *device);
/**
* @brief Initialize temperature conversion and wait for conversion
*
* Function sends CONV_T command and waits for X ms according to `ds18b20_temp_conv_time` static array
*
* @warning Should be called before `ds18b20_convert_temp()` function
*
* @param device DS18B20 handler
*/
void ds18b20_convert_temp(ds18b20_handler_t *device);
/**
* @brief Read temperature from scratchpad
*
* Function reads temperature from scratchpad and converts it to Celsius.
* @warning `ds18b20_convert_temp()` have to be called before for updated temperature.
*
* @param device DS18B20 handler
*/
float ds18b20_read_temp(ds18b20_handler_t *device);
#endif

View file

@ -0,0 +1,5 @@
#
# Component Makefile
#
COMPONENT_ADD_INCLUDEDIRS := .

View file

@ -0,0 +1,175 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "rom/ets_sys.h"
#include "onewire.h"
uint8_t onewire_configure_gpio(gpio_num_t pin, gpio_config_t *custom_config)
{
if (!GPIO_IS_VALID_GPIO(pin))
{
ESP_LOGE(TAG_ONEWIRE, "Provided pin is incorrect!");
return 0;
}
gpio_config_t config = {};
if (!custom_config)
{
config.intr_type = GPIO_INTR_DISABLE;
config.mode = GPIO_MODE_OUTPUT_OD;
config.pin_bit_mask = ((uint32_t) 1 << pin);
config.pull_down_en = 0;
config.pull_up_en = 0;
}
else
{
config = *custom_config;
}
if (gpio_config(&config) != ESP_OK)
{
return 0;
}
return 1;
}
uint8_t onewire_init(onewire_bus_handle_t *bus, gpio_num_t bus_pin, gpio_config_t *custom_config)
{
if (!bus)
{
ESP_LOGW(TAG_ONEWIRE, "bus is null! (onewire_init)");
return 0;
}
bus->pin = bus_pin;
bus->mutex = xSemaphoreCreateMutex();
// configure GPIO
if(!onewire_configure_gpio(bus_pin, custom_config))
{
return 0;
}
return 1;
}
uint8_t onewire_reset(onewire_bus_handle_t *bus)
{
uint8_t presence;
if (xSemaphoreTake(bus->mutex, _BLOCK_TIME))
{
gpio_set_level(bus->pin, 0); // Send reset pulse
ets_delay_us(_ONEWIRE_RESET_WAIT);
gpio_set_level(bus->pin, 1); // Leave floating
ets_delay_us(_ONEWIRE_PRESENCE_WAIT);
presence = !gpio_get_level(bus->pin);
xSemaphoreGive(bus->mutex);
}
else
{
ESP_LOGE(TAG_ONEWIRE, _SEMFAIL_MSG, "onewire_reset");
return -1;
}
ets_delay_us(_ONEWIRE_RESET_RECOVERY);
return presence;
}
void onewire_write_bit(onewire_bus_handle_t *bus, uint8_t bit)
{
if (xSemaphoreTake(bus->mutex, _BLOCK_TIME))
{
if (bit)
{
// Write 1
gpio_set_level(bus->pin, 0);
ets_delay_us(_ONEWIRE_WRITE1_LOW);
gpio_set_level(bus->pin, 1);
ets_delay_us(_ONEWIRE_WRITE1_WAIT);
}
else
{
// Write 0
gpio_set_level(bus->pin, 0);
ets_delay_us(_ONEWIRE_WRITE0_LOW);
gpio_set_level(bus->pin, 1);
ets_delay_us(_ONEWIRE_WRITE0_WAIT);
}
xSemaphoreGive(bus->mutex);
}
else
{
ESP_LOGE(TAG_ONEWIRE, _SEMFAIL_MSG, "onewire_write_bit");
}
}
uint8_t onewire_read_bit(onewire_bus_handle_t *bus)
{
uint8_t bit;
if (xSemaphoreTake(bus->mutex, _BLOCK_TIME))
{
gpio_set_level(bus->pin, 0);
ets_delay_us(_ONEWIRE_WRITE1_LOW);
gpio_set_level(bus->pin, 1);
ets_delay_us(_ONEWIRE_READ_WAIT);
bit = !gpio_get_level(bus->pin);
xSemaphoreGive(bus->mutex);
ets_delay_us(_ONEWIRE_READ_RECOVERY);
}
else
{
ESP_LOGE(TAG_ONEWIRE, _SEMFAIL_MSG, "onewire_read_bit");
return -1;
}
return bit;
}
void onewire_write_byte(onewire_bus_handle_t *bus, uint8_t byte)
{
uint8_t i;
for (i = 0; i < 8; i++)
{
onewire_write_bit(bus, (byte >> i) & 0x01);
}
}
uint8_t onewire_read_byte(onewire_bus_handle_t *bus)
{
uint8_t i;
uint8_t byte = 0x0;
for (i = 0; i < 8; i++)
{
byte |= (!onewire_read_bit(bus) << i);
}
return byte;
}
void onewire_send_command(onewire_bus_handle_t *bus, onewire_rom_commands_t command)
{
uint8_t payload = 0x0 ^ command;
onewire_write_byte(bus, payload);
}

View file

@ -0,0 +1,121 @@
#ifndef ONEWIRE_H
#define ONEWIRE_H
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "driver/gpio.h"
#include "esp_types.h"
#include "esp_err.h"
#define _ONEWIRE_WRITE1_LOW 6
#define _ONEWIRE_WRITE1_WAIT 64
#define _ONEWIRE_WRITE0_LOW 60
#define _ONEWIRE_WRITE0_WAIT 10
#define _ONEWIRE_READ_WAIT 9
#define _ONEWIRE_READ_RECOVERY 55
#define _ONEWIRE_RESET_WAIT 480
#define _ONEWIRE_PRESENCE_WAIT 70
#define _ONEWIRE_RESET_RECOVERY 410
#define _BLOCK_TIME pdMS_TO_TICKS(1000)
#define _SEMFAIL_MSG "Failed to obtain semaphore. (%s)"
static const char *TAG_ONEWIRE = "ONEWIRE";
typedef enum {
_ROM_READ = 0x33,
_ROM_SEARCH = 0xF0,
_ROM_MATCH = 0x55,
_ROM_SKIP = 0xCC
} onewire_rom_commands_t;
typedef struct {
gpio_num_t pin;
SemaphoreHandle_t mutex;
} onewire_bus_handle_t;
/**
* @brief Configure gpio pins for onewire communication
*
* Set `custom_config` to NULL for default config.
*
* @param pin Bus pin
* @param custom_config Custom gpio config
*
* @retval 1: Success
* @retval 0: Incorrect pin or gpio configuration failed (Logs tells which happened)
*/
uint8_t onewire_configure_gpio(gpio_num_t pin, gpio_config_t *custom_config);
/**
* @brief Initalize onewire bus
*
* Set `custom_config` to NULL for default config.
* @warning MUST be called before any other library function!
*
* @param bus Bus handle
* @param pin Bus pin
* @param custom_config Custom gpio config
*
* @retval 1: Success
* @retval 0: `bus` is NULL or gpio configuration failed (Logs tells which happened)
*/
uint8_t onewire_init(onewire_bus_handle_t *bus, gpio_num_t bus_pin, gpio_config_t *custom_config);
/**
* @brief Send reset pulse
*
* @param bus Bus handle
*
* @retval 1: Success (device sent presence pulse)
* @retval -1: Failed to obtain semaphore for gpio handling
* @retval 0: Device failed to return presence pulse
*/
uint8_t onewire_reset(onewire_bus_handle_t *bus);
/**
* @brief Write bit
*
* @param bus Bus handle
* @param bit Bit to send
*/
void onewire_write_bit(onewire_bus_handle_t *bus, uint8_t bit);
/**
* @brief Write byte
*
* @param bus Bus handle
* @param bit Byte to send
*/
void onewire_write_byte(onewire_bus_handle_t *bus, uint8_t byte);
/**
* @brief Read bit
*
* @param bus Bus handle
*
* @retval 1: Device returned 1
* @retval 0: Device returned 0
* @retval -1: Failed to obtain semaphore for gpio handling
*/
uint8_t onewire_read_bit(onewire_bus_handle_t *bus);
/**
* @brief Read bit
*
* @param bus Bus handle
*
* @return Byte returned by device
*/
uint8_t onewire_read_byte(onewire_bus_handle_t *bus);
/**
* @brief Send command to device
*
* @param bus Bus handle
* @param command Onewire rom command
*
*/
void onewire_send_command(onewire_bus_handle_t *bus, onewire_rom_commands_t command);
#endif

View file

@ -5,7 +5,7 @@
#include "lwip/sockets.h" #include "lwip/sockets.h"
#include <strings.h> #include <strings.h>
#define EXIT_NODE a // #define EXIT_NODE
#ifdef EXIT_NODE #ifdef EXIT_NODE
#define TAG "TCP" #define TAG "TCP"
@ -23,6 +23,7 @@ void zh_network_event_handler(void *arg, esp_event_base_t event_base, int32_t ev
uint8_t broadcast[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; uint8_t broadcast[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
uint8_t test[6] = {0x09, 0xF2, 0x69, 0x42, 0x11, 0xA9}; uint8_t test[6] = {0x09, 0xF2, 0x69, 0x42, 0x11, 0xA9};
uint8_t _self_mac[6] = {0};
typedef struct typedef struct
{ {
@ -51,6 +52,7 @@ void app_main(void)
wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT(); wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&wifi_init_config); esp_wifi_init(&wifi_init_config);
esp_wifi_set_mode(WIFI_MODE_STA); esp_wifi_set_mode(WIFI_MODE_STA);
esp_read_mac(_self_mac, WIFI_MODE_STA);
#ifdef EXIT_NODE #ifdef EXIT_NODE
wifi_config_t wifi_config = { wifi_config_t wifi_config = {
@ -107,10 +109,9 @@ void app_main(void)
for (;;) for (;;)
{ {
tcp_message_t packet; tcp_message_t packet;
memcpy(packet.mac, test, 6); memcpy(packet.mac, _self_mac, 6);
packet.battery_voltage = 3.3f; packet.battery_voltage = 3.3f packet.temperature = getTemp();
packet.temperature = 21.2f; packet.up_time = getUpTime();
packet.up_time = 213273948;
vTaskDelay(10000 / portTICK_PERIOD_MS); vTaskDelay(10000 / portTICK_PERIOD_MS);
zh_network_send(broadcast, (uint8_t *)&data, sizeof(data)); zh_network_send(broadcast, (uint8_t *)&data, sizeof(data));
int err = send(sock, (uint8_t *)&packet, sizeof(tcp_message_t), 0); int err = send(sock, (uint8_t *)&packet, sizeof(tcp_message_t), 0);
@ -147,8 +148,11 @@ void zh_network_event_handler(void *arg, esp_event_base_t event_base, int32_t ev
} }
#else #else
heap_caps_free(recv_data->data); heap_caps_free(recv_data->data);
// READ DATA sensor_message_t message = {0};
zh_network_send(recv_data->mac_addr, ) message.temperature = getTemp();
message.battery_voltage = 3.3f;
message.up_time = getUpTime();
zh_network_send(recv_data->mac_addr, (uint8_t *)&message, sizeof(message));
#endif #endif
case ZH_NETWORK_ON_SEND_EVENT:; case ZH_NETWORK_ON_SEND_EVENT:;
zh_network_event_on_send_t *send_data = event_data; zh_network_event_on_send_t *send_data = event_data;
@ -164,4 +168,41 @@ void zh_network_event_handler(void *arg, esp_event_base_t event_base, int32_t ev
default: default:
break; break;
} }
} }
// BoskoopBase
int getUpTime()
{
// Get system uptime in milliseconds
int uptime = (xTaskGetTickCount() * (1000 / configTICK_RATE_HZ));
return uptime;
}
float getTemp()
{
float temp = 0.0;
ds18b20_handler_t sensor;
// Initialize DS18B20 sensor
if (!ds18b20_init(&sensor, GPIO_NUM_2, TEMP_RES_12_BIT))
{
ESP_LOGE("DS18B20", "Failed to initialize DS18B20 sensor!");
return -1.0; // Indicate an error with a negative value
}
// Convert temperature
ds18b20_convert_temp(&sensor);
// Read the temperature
temp = ds18b20_read_temp(&sensor);
// Check if the temperature is within a reasonable range for DS18B20
if (temp < -55.0 || temp > 125.0)
{
ESP_LOGE("DS18B20", "Temperature reading out of range: %.2f", temp);
return -1.0; // Indicate invalid reading
}
return temp;
}