#include <stdio.h>
#include <math.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_rom_sys.h"
#define ONE_WIRE_PIN GPIO_NUM_4
#define LCD_RS GPIO_NUM_21
#define LCD_EN GPIO_NUM_22
#define LCD_D4 GPIO_NUM_18
#define LCD_D5 GPIO_NUM_19
#define LCD_D6 GPIO_NUM_23
#define LCD_D7 GPIO_NUM_5
static inline void oneWireLow(void)
{
gpio_set_direction(ONE_WIRE_PIN, GPIO_MODE_OUTPUT);
gpio_set_level(ONE_WIRE_PIN, 0);
}
static inline void oneWireRelease(void)
{
gpio_set_direction(ONE_WIRE_PIN, GPIO_MODE_INPUT);
}
bool oneWireReset(void)
{
oneWireLow();
esp_rom_delay_us(480);
oneWireRelease();
esp_rom_delay_us(70);
bool presence = (gpio_get_level(ONE_WIRE_PIN) == 0);
esp_rom_delay_us(410);
return presence;
}
void oneWireWriteBit(bool bit)
{
oneWireLow();
if (bit) {
esp_rom_delay_us(6);
oneWireRelease();
esp_rom_delay_us(64);
} else {
esp_rom_delay_us(60);
oneWireRelease();
esp_rom_delay_us(10);
}
}
bool oneWireReadBit(void)
{
oneWireLow();
esp_rom_delay_us(6);
oneWireRelease();
esp_rom_delay_us(9);
bool bit = gpio_get_level(ONE_WIRE_PIN);
esp_rom_delay_us(55);
return bit;
}
void oneWireWriteByte(uint8_t data)
{
for (int i = 0; i < 8; i++) {
oneWireWriteBit(data & 0x01);
data >>= 1;
}
}
uint8_t oneWireReadByte(void)
{
uint8_t data = 0;
for (int i = 0; i < 8; i++) {
if (oneWireReadBit()) {
data |= (1 << i);
}
}
return data;
}
float readDS18B20(void)
{
if (!oneWireReset()) return NAN;
oneWireWriteByte(0xCC);
oneWireWriteByte(0x44);
vTaskDelay(pdMS_TO_TICKS(750));
if (!oneWireReset()) return NAN;
oneWireWriteByte(0xCC);
oneWireWriteByte(0xBE);
uint8_t lsb = oneWireReadByte();
uint8_t msb = oneWireReadByte();
int16_t raw = (msb << 8) | lsb;
return raw / 16.0f;
}
static inline void delay_us(uint32_t us) { esp_rom_delay_us(us); }
static inline void delay_ms(uint32_t ms) { vTaskDelay(pdMS_TO_TICKS(ms)); }
static void lcd_pulse(void)
{
gpio_set_level(LCD_EN, 0);
delay_us(1);
gpio_set_level(LCD_EN, 1);
delay_us(1);
gpio_set_level(LCD_EN, 0);
delay_us(100);
}
static void lcd_write4(uint8_t v)
{
gpio_set_level(LCD_D4, (v >> 0) & 1);
gpio_set_level(LCD_D5, (v >> 1) & 1);
gpio_set_level(LCD_D6, (v >> 2) & 1);
gpio_set_level(LCD_D7, (v >> 3) & 1);
lcd_pulse();
}
static void lcd_send(uint8_t v, bool rs)
{
gpio_set_level(LCD_RS, rs);
lcd_write4(v >> 4);
lcd_write4(v & 0x0F);
}
static void lcd_cmd(uint8_t c) { lcd_send(c, false); }
static void lcd_char(char c) { lcd_send(c, true); }
static void lcd_clear(void)
{
lcd_cmd(0x01);
delay_ms(2);
}
static void lcd_cursor(uint8_t col, uint8_t row)
{
const uint8_t offs[] = {0x00, 0x40};
lcd_cmd(0x80 | (col + offs[row]));
}
static void lcd_print(const char *s)
{
while (*s) lcd_char(*s++);
}
static void lcd_init(void)
{
gpio_config_t io = {
.mode = GPIO_MODE_OUTPUT,
.pin_bit_mask = (1ULL<<LCD_RS)|(1ULL<<LCD_EN)|(1ULL<<LCD_D4)|
(1ULL<<LCD_D5)|(1ULL<<LCD_D6)|(1ULL<<LCD_D7)
};
gpio_config(&io);
delay_ms(50);
gpio_set_level(LCD_RS, 0);
gpio_set_level(LCD_EN, 0);
lcd_write4(0x03); delay_ms(5);
lcd_write4(0x03); delay_us(150);
lcd_write4(0x03);
lcd_write4(0x02);
lcd_cmd(0x28);
lcd_cmd(0x0C);
lcd_cmd(0x06);
lcd_clear();
}
void app_main(void)
{
gpio_set_pull_mode(ONE_WIRE_PIN, GPIO_PULLUP_ONLY);
lcd_init();
char buf[16];
while (1) {
float t = readDS18B20();
lcd_cursor(0, 0);
lcd_print("Temperature:");
lcd_cursor(0, 1);
if (isnan(t)) {
lcd_print("Sensor error ");
} else {
snprintf(buf, sizeof(buf), "%6.2f C", t);
lcd_print(buf);
}
vTaskDelay(pdMS_TO_TICKS(2000));
}
}