-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
29 changed files
with
2,266 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
name: cpp-linter | ||
|
||
on: | ||
push: | ||
paths-ignore: "doc/**" | ||
pull_request: | ||
paths-ignore: "doc/**" | ||
|
||
jobs: | ||
cpp-linter: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: cpp-linter/cpp-linter-action@master | ||
id: linter | ||
env: | ||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
with: | ||
style: file | ||
|
||
- name: Fail fast?! | ||
if: steps.linter.outputs.checks-failed > 0 | ||
run: | | ||
echo "Some files failed the linting checks!" | ||
# for actual deployment | ||
# run: exit 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Build results | ||
build/ | ||
|
||
# VSCode | ||
.vscode/ | ||
|
||
# Project | ||
sdkconfig |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
cmake_minimum_required(VERSION 3.16) | ||
|
||
include($ENV{IDF_PATH}/tools/cmake/project.cmake) | ||
project(esp32_wifi_onewire_mqtt) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,74 @@ | ||
# ESP32_WiFi_OneWire_MQTT | ||
[![GitHub](https://img.shields.io/github/license/VPavlusha/ESP32_WiFi_OneWire_MQTT?color=blue&label=License&logo=github)](LICENSE) | ||
[![cpp-linter](https://github.com/VPavlusha/ESP32_WiFi_OneWire_MQTT/actions/workflows/cpp-linter.yml/badge.svg)](https://github.com/VPavlusha/ESP32_WiFi_OneWire_MQTT/actions/workflows/cpp-linter.yml) | ||
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/VPavlusha/ESP32_WiFi_OneWire_MQTT?label=Release&logo=github)](https://github.com/VPavlusha/ESP32_WiFi_OneWire_MQTT/releases) | ||
[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://stand-with-ukraine.pp.ua) | ||
[![Made in Ukraine](https://img.shields.io/badge/Made_in-Ukraine-ffd700.svg?labelColor=0057b7)](https://stand-with-ukraine.pp.ua) | ||
--- | ||
|
||
# ESP32 Wi-Fi OneWire MQTT | ||
The ESP32 WiFi OneWire MQTT project is a simple way to read the data from DS18B20 temperature sensors connected to an ESP32 microcontroller, and send the data to an MQTT broker over Wi-Fi.<br/> | ||
Based on: https://github.com/espressif/esp-idf | ||
|
||
#### Table of Contents | ||
 [1. Features](#1-features) | ||
 [2. Monitor And Control Your Project](#2-monitor-and-control-your-project) | ||
 [3. Getting Started](#3-getting-started) | ||
 [4. Contributing](#4-contributing) | ||
 [5. License](#5-license) | ||
|
||
## 1. Features | ||
- ESP-IDF v5.0.2 | ||
- Reading temperature data from a DS18B20 sensor using the OneWire protocol. | ||
- Sending temperature data to an MQTT broker over Wi-Fi. | ||
- Easy-to-use API for customizing the firmware to meet your specific needs. | ||
- Used Wi-Fi, OneWire, DS18B20, MQTT technology. | ||
- Written in C language. | ||
- MIT License. | ||
|
||
## 2. Monitor And Control Your Project | ||
<img src="./doc/img/iot_onoff.png" alt="iot_onoff.png" width="250"/> | ||
|
||
You have the ability to monitor and control your Internet of Things (IoT) projects with some app like [IoT OnOff](https://www.iot-onoff.com/). | ||
|
||
## 3. Getting Started | ||
To get started with the ESP32 WiFi OneWire MQTT project, you'll need an ESP32 microcontroller, a DS18B20 temperature sensor, and access to an MQTT broker. You'll also need to install the ESP-IDF development framework. | ||
|
||
### 3.1 Clone the project repository: | ||
```C | ||
git clone https://github.com/VPavlusha/ESP32_WiFi_OneWire_MQTT.git | ||
``` | ||
### 3.2 Customize the firmware to match your Wi-Fi, DS18B20 and MQTT settings: | ||
- Edit the **main/Kconfig.projbuild** file with your Wi-Fi, DS18B20 and MQTT settings. | ||
|
||
The ESP32 WiFi OneWire MQTT firmware is designed to be easily customizable. You can use the provided API to change the MQTT topic, adjust the temperature DS18B20 port connections, Wi-Fi settings and more. | ||
|
||
### 3.3 Build the project: | ||
```C | ||
cd ESP32_WiFi_OneWire_MQTT | ||
idf.py build | ||
``` | ||
### 3.4 Flash onto your ESP32 microcontroller: | ||
```C | ||
idf.py -p PORT [-b BAUD] flash | ||
``` | ||
Replace PORT with your ESP32 board’s serial port name. | ||
You can also change the flasher baud rate by replacing BAUD with the baud rate you need. The default baud rate is 460800.<br/> | ||
### 3.5 Monitor the output: | ||
```C | ||
idf.py -p <PORT> monitor | ||
``` | ||
Do not forget to replace PORT with your serial port name. | ||
|
||
### 3.6 Check Wi-Fi network and MQTT broker: | ||
- Check the output on the serial monitor to verify that the ESP32 is connecting to your Wi-Fi network and MQTT broker. | ||
- Check your MQTT broker to verify that temperature data is being sent. | ||
|
||
More information how to build project: [ESP-IDF Programming Guide](https://docs.espressif.com/projects/esp-idf/en/v5.0.2/esp32/get-started/start-project.html). | ||
|
||
## 4. Contributing | ||
Contributions to the ESP32 WiFi OneWire MQTT project are welcome. If you find a bug or have a feature request, please submit an issue on the project's GitHub page. If you'd like to contribute code, please submit a pull request. | ||
|
||
## 5. License | ||
The ESP32_WiFi_OneWire_MQTT project is licensed under the MIT License. See the [MIT license] file for more information. | ||
|
||
[MIT license]: http://www.opensource.org/licenses/mit-license.html |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
idf_component_register(SRCS "onewire_bus_rmt.c" "onewire_bus.c" | ||
INCLUDE_DIRS "." | ||
PRIV_REQUIRES driver) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
| Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 | | ||
| ----------------- | ----- | -------- | -------- | -------- | | ||
|
||
# RMT Transmit & Receive Example -- 1-Wire bus | ||
|
||
(See the README.md file in the upper level 'examples' directory for more information about examples.) | ||
|
||
RMT peripheral has both transmit and receive channels. Connecting one transmit channel and one receive channel to the same GPIO and put the GPIO in open-drain mode can simulate bi-directional single wire protocols, such as [1-Wire protocol](https://www.maximintegrated.com/en/design/technical-documents/tutorials/1/1796.html). | ||
|
||
This example demonstrates how to use RMT to simulate 1-Wire bus and read temperatrue from [DS18B20](https://datasheets.maximintegrated.com/en/ds/DS18B20.pdf). | ||
|
||
## How to Use Example | ||
|
||
### Hardware Required | ||
|
||
* A development board with any supported Espressif SOC chip (see `Supported Targets` table above) | ||
* Several DS18B20 temperature sensors and a 4.7kohm pullup resistor | ||
|
||
Connection : | ||
|
||
``` | ||
┌──────────────────────────┐ | ||
│ 3.3V├───────┬─────────────┬──────────────────────┐ | ||
│ │ ┌┴┐ │VDD │VDD | ||
│ ESP32 Board │ 4.7k│ │ ┌──────┴──────┐ ┌──────┴──────┐ | ||
│ │ └┬┘ DQ│ │ DQ│ │ | ||
│ ONEWIRE_GPIO_PIN├───────┴──┬───┤ DS18B20 │ ┌───┤ DS18B20 │ ...... | ||
│ │ └───│-------------│────┴───│-------------│── | ||
│ │ └──────┬──────┘ └──────┬──────┘ | ||
│ │ │GND │GND | ||
│ GND├─────────────────────┴──────────────────────┘ | ||
└──────────────────────────┘ | ||
``` | ||
|
||
The GPIO number used in this example can be changed according to your board, by the macro `EXAMPLE_ONEWIRE_GPIO_PIN` defined in [onewire_ds18b20_example_main.c](main/onewire_ds18b20_example_main.c). | ||
|
||
*Note*: Parasite power mode is not supported currently by this example, you have to connect VDD pin to make DS18B20 functional. | ||
|
||
### Build and Flash | ||
|
||
Run `idf.py -p PORT flash monitor` to build, flash and monitor the project. | ||
|
||
(To exit the serial monitor, type ``Ctrl-]``.) | ||
|
||
See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html) for full steps to configure and use ESP-IDF to build projects. | ||
|
||
## Console Output | ||
|
||
If there are some DS18B20s on the bus: | ||
|
||
``` | ||
I (327) cpu_start: Starting scheduler on PRO CPU. | ||
I (0) cpu_start: Starting scheduler on APP CPU. | ||
I (338) gpio: GPIO[5]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 | ||
I (348) onewire_rmt: RMT Tx channel created for 1-wire bus | ||
I (358) gpio: GPIO[5]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0 | ||
I (358) onewire_rmt: RMT Rx channel created for 1-wire bus | ||
I (368) example: 1-wire bus installed | ||
I (418) example: found device with rom id 28FF30BE21170317 | ||
I (458) example: found device with rom id 28FF297E211703A1 | ||
I (498) example: found device with rom id 28FF6F7921170352 | ||
I (508) example: 3 devices found on 1-wire bus | ||
I (2518) example: temperature of device 28FF30BE21170317: 27.00C | ||
I (2528) example: temperature of device 28FF297E211703A1: 26.81C | ||
I (2538) example: temperature of device 28FF6F7921170352: 26.50C | ||
I (3548) example: temperature of device 28FF30BE21170317: 26.94C | ||
I (3558) example: temperature of device 28FF297E211703A1: 26.75C | ||
I (3568) example: temperature of device 28FF6F7921170352: 26.44C | ||
``` | ||
|
||
If there is no DS18B20 on the bus: | ||
|
||
``` | ||
I (327) cpu_start: Starting scheduler on PRO CPU. | ||
I (0) cpu_start: Starting scheduler on APP CPU. | ||
I (337) gpio: GPIO[5]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 | ||
I (347) onewire_rmt: RMT Tx channel created for 1-wire bus | ||
I (357) gpio: GPIO[5]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 1| Pulldown: 0| Intr:0 | ||
I (357) onewire_rmt: RMT Rx channel created for 1-wire bus | ||
I (367) example: 1-wire bus installed | ||
E (377) onewire_rmt: no device present on 1-wire bus | ||
I (377) example: 0 device found on 1-wire bus | ||
I (387) gpio: GPIO[5]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 | ||
I (397) gpio: GPIO[5]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 | ||
I (397) example: 1-wire bus deleted | ||
``` | ||
|
||
## Troubleshooting | ||
|
||
For any technical queries, please open an [issue] (https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
#include <string.h> | ||
#include "esp_check.h" | ||
#include "esp_log.h" | ||
#include "onewire_bus.h" | ||
|
||
static const char *TAG = "onewire"; | ||
|
||
struct onewire_rom_search_context_t { | ||
onewire_bus_handle_t bus_handle; | ||
|
||
uint8_t last_device_flag; | ||
uint16_t last_discrepancy; | ||
uint8_t rom_number[8]; | ||
}; | ||
|
||
// Algorithm inspired by https://www.maximintegrated.com/en/design/technical-documents/app-notes/1/187.html | ||
|
||
static const uint8_t dscrc_table[] = { | ||
0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, | ||
157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220, | ||
35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98, | ||
190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, | ||
70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7, | ||
219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154, | ||
101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36, | ||
248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185, | ||
140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, | ||
17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, | ||
175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, | ||
50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, | ||
202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139, | ||
87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, | ||
233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, | ||
116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53 | ||
}; | ||
|
||
uint8_t onewire_check_crc8(uint8_t *input, size_t input_size) | ||
{ | ||
uint8_t crc8 = 0; | ||
|
||
for (size_t i = 0; i < input_size; i ++) { | ||
crc8 = dscrc_table[crc8 ^ input[i]]; | ||
} | ||
|
||
return crc8; | ||
} | ||
|
||
esp_err_t onewire_rom_search_context_create(onewire_bus_handle_t handle, onewire_rom_search_context_handler_t *context_out) | ||
{ | ||
ESP_RETURN_ON_FALSE(handle, ESP_ERR_INVALID_ARG, TAG, "invalid 1-wire handle"); | ||
ESP_RETURN_ON_FALSE(context_out, ESP_ERR_INVALID_ARG, TAG, "invalid context handler pointer"); | ||
|
||
struct onewire_rom_search_context_t *context = calloc(1, sizeof(struct onewire_rom_search_context_t)); | ||
if (!context) { | ||
return ESP_ERR_NO_MEM; | ||
} | ||
|
||
context->bus_handle = handle; | ||
*context_out = context; | ||
|
||
return ESP_OK; | ||
} | ||
|
||
esp_err_t onewire_rom_search_context_delete(onewire_rom_search_context_handler_t context) | ||
{ | ||
ESP_RETURN_ON_FALSE(context, ESP_ERR_INVALID_ARG, TAG, "invalid context handler pointer"); | ||
|
||
free(context); | ||
|
||
return ESP_OK; | ||
} | ||
|
||
esp_err_t onewire_rom_search(onewire_rom_search_context_handler_t context) | ||
{ | ||
ESP_RETURN_ON_FALSE(context, ESP_ERR_INVALID_ARG, TAG, "invalid context handler pointer"); | ||
|
||
uint8_t last_zero = 0; | ||
|
||
if (!context->last_device_flag) { | ||
if (onewire_bus_reset(context->bus_handle) != ESP_OK) { // no device present | ||
return ESP_ERR_NOT_FOUND; | ||
} | ||
|
||
// send rom search command and start search algorithm | ||
ESP_RETURN_ON_ERROR(onewire_bus_write_bytes(context->bus_handle, (uint8_t[]){ONEWIRE_CMD_SEARCH_ROM}, 1), | ||
TAG, "error while sending search rom command"); | ||
|
||
for (uint16_t rom_bit_index = 0; rom_bit_index < 64; rom_bit_index ++) { | ||
uint8_t rom_byte_index = rom_bit_index / 8; | ||
uint8_t rom_bit_mask = 1 << (rom_bit_index % 8); // calculate byte index and bit mask in advance for convenience | ||
|
||
uint8_t rom_bit, rom_bit_complement; | ||
ESP_RETURN_ON_ERROR(onewire_bus_read_bit(context->bus_handle, &rom_bit), TAG, "error while reading rom bit"); // write 1 bit to read from the bus | ||
ESP_RETURN_ON_ERROR(onewire_bus_read_bit(context->bus_handle, &rom_bit_complement), | ||
TAG, "error while reading rom bit"); // read a bit and its complement | ||
|
||
uint8_t search_direction; | ||
if (rom_bit && rom_bit_complement) { // No devices participating in search. | ||
ESP_LOGE(TAG, "no devices participating in search"); | ||
return ESP_ERR_NOT_FOUND; | ||
} else { | ||
if (rom_bit != rom_bit_complement) { // There are only 0s or 1s in the bit of the participating ROM numbers. | ||
search_direction = rom_bit; // just go ahead | ||
} else { // There are both 0s and 1s in the current bit position of the participating ROM numbers. This is a discrepancy. | ||
if (rom_bit_index < context->last_discrepancy) { // current id bit is before the last discrepancy bit | ||
search_direction = (context->rom_number[rom_byte_index] & rom_bit_mask) ? 0x01 : 0x00; // follow previous way | ||
} else { | ||
search_direction = (rom_bit_index == context->last_discrepancy) ? 0x01 : 0x00; // search for 0 bit first | ||
} | ||
|
||
if (search_direction == 0) { // record zero's position in last zero | ||
last_zero = rom_bit_index; | ||
} | ||
} | ||
|
||
if (search_direction == 1) { // set corrsponding rom bit by serach direction | ||
context->rom_number[rom_byte_index] |= rom_bit_mask; | ||
} else { | ||
context->rom_number[rom_byte_index] &= ~rom_bit_mask; | ||
} | ||
|
||
ESP_RETURN_ON_ERROR(onewire_bus_write_bit(context->bus_handle, search_direction), | ||
TAG, "error while writing direction bit"); // set search direction | ||
} | ||
} | ||
} else { | ||
ESP_LOGD(TAG, "1-wire rom search finished"); | ||
return ESP_FAIL; | ||
} | ||
|
||
// if the search was successful | ||
context->last_discrepancy = last_zero; | ||
if (context->last_discrepancy == 0) { // last zero loops back to the first bit | ||
context->last_device_flag = true; | ||
} | ||
|
||
if (onewire_check_crc8(context->rom_number, 7) != context->rom_number[7]) { // check crc | ||
ESP_LOGE(TAG, "bad crc checksum of device with id " ONEWIRE_ROM_ID_STR, ONEWIRE_ROM_ID(context->rom_number)); | ||
return ESP_ERR_INVALID_CRC; | ||
} | ||
|
||
return ESP_OK; | ||
} | ||
|
||
esp_err_t onewire_rom_get_number(onewire_rom_search_context_handler_t context, uint8_t *rom_number_out) | ||
{ | ||
ESP_RETURN_ON_FALSE(context, ESP_ERR_INVALID_ARG, TAG, "invalid context pointer"); | ||
ESP_RETURN_ON_FALSE(rom_number_out, ESP_ERR_INVALID_ARG, TAG, "invalid rom_number pointer"); | ||
|
||
memcpy(rom_number_out, context->rom_number, sizeof(context->rom_number)); | ||
|
||
return ESP_OK; | ||
} |
Oops, something went wrong.