mirror of
https://gitlab.com/fabinfra/fabhardware/fabmeter.git
synced 2025-03-12 06:31:47 +01:00
Initial commit
This commit is contained in:
commit
0d603b7d26
101
.gitignore
vendored
Normal file
101
.gitignore
vendored
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
# Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode,c,c++
|
||||||
|
# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode,c,c++
|
||||||
|
|
||||||
|
### C ###
|
||||||
|
# Prerequisites
|
||||||
|
*.d
|
||||||
|
|
||||||
|
# Object files
|
||||||
|
*.o
|
||||||
|
*.ko
|
||||||
|
*.obj
|
||||||
|
*.elf
|
||||||
|
|
||||||
|
# Linker output
|
||||||
|
*.ilk
|
||||||
|
*.map
|
||||||
|
*.exp
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Libraries
|
||||||
|
*.lib
|
||||||
|
*.a
|
||||||
|
*.la
|
||||||
|
*.lo
|
||||||
|
|
||||||
|
# Shared objects (inc. Windows DLLs)
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.so.*
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
*.i*86
|
||||||
|
*.x86_64
|
||||||
|
*.hex
|
||||||
|
|
||||||
|
# Debug files
|
||||||
|
*.dSYM/
|
||||||
|
*.su
|
||||||
|
*.idb
|
||||||
|
*.pdb
|
||||||
|
|
||||||
|
# Kernel Module Compile Results
|
||||||
|
*.mod*
|
||||||
|
*.cmd
|
||||||
|
.tmp_versions/
|
||||||
|
modules.order
|
||||||
|
Module.symvers
|
||||||
|
Mkfile.old
|
||||||
|
dkms.conf
|
||||||
|
|
||||||
|
### C++ ###
|
||||||
|
# Prerequisites
|
||||||
|
|
||||||
|
# Compiled Object files
|
||||||
|
*.slo
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
|
||||||
|
# Compiled Dynamic libraries
|
||||||
|
|
||||||
|
# Fortran module files
|
||||||
|
*.mod
|
||||||
|
*.smod
|
||||||
|
|
||||||
|
# Compiled Static libraries
|
||||||
|
*.lai
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
|
||||||
|
### VisualStudioCode ###
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
!.vscode/*.code-snippets
|
||||||
|
|
||||||
|
# Local History for Visual Studio Code
|
||||||
|
.history/
|
||||||
|
|
||||||
|
# Built Visual Studio Code Extensions
|
||||||
|
*.vsix
|
||||||
|
|
||||||
|
### VisualStudioCode Patch ###
|
||||||
|
# Ignore all local history of files
|
||||||
|
.history
|
||||||
|
.ionide
|
||||||
|
|
||||||
|
# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,c,c++
|
||||||
|
|
||||||
|
build/
|
||||||
|
managed_components/
|
||||||
|
sdkconfig
|
||||||
|
sdkconfig.old
|
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"idf.adapterTargetName": "esp32c3",
|
||||||
|
"idf.flashType": "UART",
|
||||||
|
"idf.port": "/dev/cu.usbserial-1320"
|
||||||
|
}
|
8
CMakeLists.txt
Normal file
8
CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# For more information about build system see
|
||||||
|
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
|
||||||
|
# The following five lines of boilerplate have to be in your project's
|
||||||
|
# CMakeLists in this exact order for cmake to work correctly
|
||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
project(fabmeter)
|
51
dependencies.lock
Normal file
51
dependencies.lock
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
dependencies:
|
||||||
|
espressif/cbor:
|
||||||
|
component_hash: 440f4ee4504841cc9b4f3a8ef755776a612ac9dace355514c68b999868f990ff
|
||||||
|
source:
|
||||||
|
service_url: https://api.components.espressif.com/
|
||||||
|
type: service
|
||||||
|
version: 0.6.0~1
|
||||||
|
espressif/esp-modbus:
|
||||||
|
component_hash: a03225cc0775fb4f495ff1ca56a91d0b4d4f7ba9961838dee6b04476e71a5347
|
||||||
|
source:
|
||||||
|
service_url: https://api.components.espressif.com/
|
||||||
|
type: service
|
||||||
|
version: 1.0.11
|
||||||
|
espressif/esp_diag_data_store:
|
||||||
|
component_hash: 31f8e570af6186788e3130fc67c5391593f17ac3cbc761a8affc50510de7cdbe
|
||||||
|
source:
|
||||||
|
service_url: https://api.components.espressif.com/
|
||||||
|
type: service
|
||||||
|
version: 1.0.0
|
||||||
|
espressif/esp_diagnostics:
|
||||||
|
component_hash: 856abf2f06f5e43a52767e221a6ac2554c944f7708781156f939249491cea3f1
|
||||||
|
source:
|
||||||
|
service_url: https://api.components.espressif.com/
|
||||||
|
type: service
|
||||||
|
version: 1.0.0
|
||||||
|
espressif/esp_insights:
|
||||||
|
component_hash: 94ca222800cdb5abb4d68ef4e8f11c62c9d46614c63783e0d3e6fa15e248fc35
|
||||||
|
source:
|
||||||
|
service_url: https://api.components.espressif.com/
|
||||||
|
type: service
|
||||||
|
version: 1.0.0
|
||||||
|
espressif/led_strip:
|
||||||
|
component_hash: 1f8cc130ebd557fde64c02fe5fad0cb36d69947498c540ace6f425e1083d7773
|
||||||
|
source:
|
||||||
|
service_url: https://api.components.espressif.com/
|
||||||
|
type: service
|
||||||
|
version: 2.4.1
|
||||||
|
espressif/rmaker_common:
|
||||||
|
component_hash: 7b8398212884abfea6199430cb40162c501b93c0c26e0ae90bbe2a3d1112f2d0
|
||||||
|
source:
|
||||||
|
service_url: https://api.components.espressif.com/
|
||||||
|
type: service
|
||||||
|
version: 1.4.2
|
||||||
|
idf:
|
||||||
|
component_hash: null
|
||||||
|
source:
|
||||||
|
type: idf
|
||||||
|
version: 5.1.0
|
||||||
|
manifest_hash: de1b2f078e7c29abca615624a54fb96595c3dfdb9d0ecd691a3f119da081b339
|
||||||
|
target: esp32c3
|
||||||
|
version: 1.0.0
|
4
main/CMakeLists.txt
Normal file
4
main/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
idf_component_register(SRCS "modbus_params.c" "fabmeter.c" "initializers.c" "mqtt_event_handler.c" "net_event_handler.c"
|
||||||
|
INCLUDE_DIRS ".")
|
||||||
|
|
||||||
|
# component_compile_options(-Wno-error=format= -Wno-format)
|
171
main/Kconfig.projbuild
Normal file
171
main/Kconfig.projbuild
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
menu "FabMeter Configuration"
|
||||||
|
|
||||||
|
config FABMETER_ID
|
||||||
|
int "FabMeter ID"
|
||||||
|
default 1
|
||||||
|
help
|
||||||
|
Numerical ID of the FabLight device
|
||||||
|
|
||||||
|
config PIN_DEBUG_LED
|
||||||
|
int "Debug LED pin"
|
||||||
|
default 8
|
||||||
|
help
|
||||||
|
GPIO pin number for the debug LED
|
||||||
|
|
||||||
|
menu "WiFi"
|
||||||
|
|
||||||
|
config WIFI_SSID
|
||||||
|
string "WiFi SSID"
|
||||||
|
default "myssid"
|
||||||
|
help
|
||||||
|
SSID (network name) for the example to connect to.
|
||||||
|
|
||||||
|
config WIFI_PASSWORD
|
||||||
|
string "WiFi Password"
|
||||||
|
default "mypassword"
|
||||||
|
help
|
||||||
|
WiFi password (WPA or WPA2) for the example to use.
|
||||||
|
|
||||||
|
choice WIFI_SCAN_METHOD
|
||||||
|
prompt "scan method"
|
||||||
|
default WIFI_FAST_SCAN
|
||||||
|
help
|
||||||
|
scan method for the esp32 to use
|
||||||
|
|
||||||
|
config WIFI_FAST_SCAN
|
||||||
|
bool "fast"
|
||||||
|
config WIFI_ALL_CHANNEL_SCAN
|
||||||
|
bool "all"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
menu "MQTT"
|
||||||
|
config BROKER_URI
|
||||||
|
string "Broker URL"
|
||||||
|
default "mqtts://mqtt.eclipseprojects.io:8883"
|
||||||
|
help
|
||||||
|
URL of an mqtt broker which this example connects to.
|
||||||
|
|
||||||
|
config BROKER_CERTIFICATE_OVERRIDE
|
||||||
|
string "Broker certificate override"
|
||||||
|
default ""
|
||||||
|
help
|
||||||
|
Please leave empty if broker certificate included from a textfile; otherwise fill in a base64 part of PEM
|
||||||
|
format certificate
|
||||||
|
|
||||||
|
config BROKER_CERTIFICATE_OVERRIDDEN
|
||||||
|
bool
|
||||||
|
default y if BROKER_CERTIFICATE_OVERRIDE != ""
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
menu "Modbus Configuration"
|
||||||
|
|
||||||
|
orsource "$IDF_PATH/examples/common_components/env_caps/$IDF_TARGET/Kconfig.env_caps"
|
||||||
|
|
||||||
|
config MB_UART_PORT_ONE
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
depends on (ESP_CONSOLE_UART_NUM !=1) && (SOC_UART_NUM > 1)
|
||||||
|
|
||||||
|
config MB_UART_PORT_TWO
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
depends on (ESP_CONSOLE_UART_NUM !=2) && (SOC_UART_NUM > 2)
|
||||||
|
|
||||||
|
config MB_UART_PORT_NUM
|
||||||
|
int "UART port number"
|
||||||
|
range 0 2 if MB_UART_PORT_TWO
|
||||||
|
default 2 if MB_UART_PORT_TWO
|
||||||
|
range 0 1 if MB_UART_PORT_ONE
|
||||||
|
default 1 if MB_UART_PORT_ONE
|
||||||
|
help
|
||||||
|
UART communication port number for Modbus.
|
||||||
|
|
||||||
|
config MB_UART_BAUD_RATE
|
||||||
|
int "UART communication speed"
|
||||||
|
range 1200 115200
|
||||||
|
default 9600
|
||||||
|
help
|
||||||
|
UART communication speed for Modbus.
|
||||||
|
|
||||||
|
choice
|
||||||
|
prompt "UART parity"
|
||||||
|
default MB_UART_PARITY_DISABLE
|
||||||
|
help
|
||||||
|
UART parity for Modbus.
|
||||||
|
|
||||||
|
config MB_UART_PARITY_DISABLE
|
||||||
|
bool "None"
|
||||||
|
|
||||||
|
config MB_UART_PARITY_EVEN
|
||||||
|
bool "Even"
|
||||||
|
|
||||||
|
config MB_UART_PARITY_ODD
|
||||||
|
bool "Odd"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config MB_UART_PARITY
|
||||||
|
int
|
||||||
|
default 0 if MB_UART_PARITY_DISABLE
|
||||||
|
default 2 if MB_UART_PARITY_EVEN
|
||||||
|
default 3 if MB_UART_PARITY_ODD
|
||||||
|
|
||||||
|
config MB_UART_STOP_BITS
|
||||||
|
int "UART stop bits"
|
||||||
|
default 1
|
||||||
|
range 1 2
|
||||||
|
help
|
||||||
|
UART stop bits for Modbus.
|
||||||
|
|
||||||
|
config MB_UART_RXD
|
||||||
|
int "UART RXD pin number"
|
||||||
|
range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX
|
||||||
|
default 22 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32C6
|
||||||
|
default 8 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C3 ||\
|
||||||
|
IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32H2
|
||||||
|
help
|
||||||
|
GPIO number for UART RX pin. See UART documentation for more information
|
||||||
|
about available pin numbers for UART.
|
||||||
|
|
||||||
|
config MB_UART_TXD
|
||||||
|
int "UART TXD pin number"
|
||||||
|
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
|
||||||
|
default 23 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32C6
|
||||||
|
default 9 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C3 ||\
|
||||||
|
IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32H2
|
||||||
|
help
|
||||||
|
GPIO number for UART TX pin. See UART documentation for more information
|
||||||
|
about available pin numbers for UART.
|
||||||
|
|
||||||
|
config MB_UART_RTS
|
||||||
|
int "UART RTS pin number"
|
||||||
|
range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX
|
||||||
|
default 18 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32C6
|
||||||
|
default 10 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C3 ||\
|
||||||
|
IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32H2
|
||||||
|
help
|
||||||
|
GPIO number for UART RTS pin. This pin is connected to
|
||||||
|
~RE/DE pin of RS485 transceiver to switch direction.
|
||||||
|
See UART documentation for more information about available pin
|
||||||
|
numbers for UART.
|
||||||
|
|
||||||
|
choice MB_COMM_MODE
|
||||||
|
prompt "Modbus communication mode"
|
||||||
|
default MB_COMM_MODE_RTU if CONFIG_FMB_COMM_MODE_RTU_EN
|
||||||
|
help
|
||||||
|
Selection of Modbus communication mode option for Modbus.
|
||||||
|
|
||||||
|
config MB_COMM_MODE_RTU
|
||||||
|
bool "RTU mode"
|
||||||
|
depends on FMB_COMM_MODE_RTU_EN
|
||||||
|
|
||||||
|
config MB_COMM_MODE_ASCII
|
||||||
|
bool "ASCII mode"
|
||||||
|
depends on FMB_COMM_MODE_ASCII_EN
|
||||||
|
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
endmenu
|
315
main/fabmeter.c
Normal file
315
main/fabmeter.c
Normal file
@ -0,0 +1,315 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <esp_err.h>
|
||||||
|
#include <esp_wifi.h>
|
||||||
|
#include <esp_event.h>
|
||||||
|
#include <esp_log.h>
|
||||||
|
#include <nvs_flash.h>
|
||||||
|
#include <esp_crt_bundle.h>
|
||||||
|
#include <esp_insights.h>
|
||||||
|
#include <mqtt_client.h>
|
||||||
|
#include "modbus_params.h" // for modbus parameters structures
|
||||||
|
#include "mbcontroller.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "modbus_utils.h"
|
||||||
|
#include "mqtt_event_handler.h"
|
||||||
|
#include "net_event_handler.h"
|
||||||
|
#include "initializers.h"
|
||||||
|
|
||||||
|
#define ESP_INSIGHTS_AUTH_KEY "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYzI3N2M3NzUtZDNjNy00NjEzLWIwMzctYjYxZGVjNmUyMGRmIiwiaXNzIjoiZTMyMmI1OWMtNjNjYy00ZTQwLThlYTItNGU3NzY2NTQ1Y2NhIiwic3ViIjoiYjExZWMyZWEtZGE5Ni00ZTQyLWIzODktOWU2MGNlM2U3Y2ZkIiwiZXhwIjoyMDA1MDA0ODk0LCJpYXQiOjE2ODk2NDQ4OTR9.FOPLo6qvkVI5k0M0j8YWonc7jRrTc6wG1p0001awcC6bWEOIxoheY69ZXSbn94vFiCtLyWAJafce3QrLJWgW0THDxGZaUNrjijqLXdKie7qEOVinjsdwILomIMa_NpSVLwZimAkd6B_uw1hk5RqooW2JzJeLYLX5i7oUgSAwZgvjN_cfCS2emrSKpZXD-CaDlNMGjt97VXzj4UFuDsNCWLaW0gEr5RcMMnYFwSxkLgv1NOWGQKfm1mZCRA_swCyxvjX4UrjlWSQZemqiqBMgnW7sBAyG5-UFGu1Fc-MfBfoB9aGblPE7LDwMeT1jgJUaJ9puhDFMY-v4Ilw8jUttzA"
|
||||||
|
|
||||||
|
// The number of parameters that intended to be used in the particular control process
|
||||||
|
#define MASTER_MAX_CIDS num_device_parameters
|
||||||
|
|
||||||
|
// Number of reading of parameters from slave
|
||||||
|
#define MASTER_MAX_RETRY 300
|
||||||
|
|
||||||
|
// Timeout to update cid over Modbus
|
||||||
|
#define UPDATE_CIDS_TIMEOUT_MS (5000)
|
||||||
|
#define UPDATE_CIDS_TIMEOUT_TICS (UPDATE_CIDS_TIMEOUT_MS / portTICK_PERIOD_MS)
|
||||||
|
|
||||||
|
// Timeout between polls
|
||||||
|
#define POLL_TIMEOUT_MS (1)
|
||||||
|
#define POLL_TIMEOUT_TICS (POLL_TIMEOUT_MS / portTICK_PERIOD_MS)
|
||||||
|
|
||||||
|
|
||||||
|
static const char *TAG = "FABMETER";
|
||||||
|
|
||||||
|
// Enumeration of modbus device addresses accessed by master device
|
||||||
|
enum {
|
||||||
|
MB_DEVICE_ADDR1 = 1 // Only one slave device used for the test (add other slave addresses here)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Example Data (Object) Dictionary for Modbus parameters:
|
||||||
|
// The CID field in the table must be unique.
|
||||||
|
// Modbus Slave Addr field defines slave address of the device with correspond parameter.
|
||||||
|
// Modbus Reg Type - Type of Modbus register area (Holding register, Input Register and such).
|
||||||
|
// Reg Start field defines the start Modbus register number and Reg Size defines the number of registers for the characteristic accordingly.
|
||||||
|
// The Instance Offset defines offset in the appropriate parameter structure that will be used as instance to save parameter value.
|
||||||
|
// Data Type, Data Size specify type of the characteristic and its data size.
|
||||||
|
// Parameter Options field specifies the options that can be used to process parameter value (limits or masks).
|
||||||
|
// Access Mode - can be used to implement custom options for processing of characteristic (Read/Write restrictions, factory mode values and etc).
|
||||||
|
const mb_parameter_descriptor_t device_parameters[] = {
|
||||||
|
// { CID, Param Name, Units, Modbus Slave Addr, Modbus Reg Type, Reg Start, Reg Size, Instance Offset, Data Type, Data Size, Parameter Options, Access Mode}
|
||||||
|
{ CID_INP_U_L1N, STR("Phase 1 line to neutral"), STR("V"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0000, 2,
|
||||||
|
INPUT_OFFSET(voltage_L1N), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_U_L2N, STR("Phase 2 line to neutral"), STR("V"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0002, 2,
|
||||||
|
INPUT_OFFSET(voltage_L2N), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_U_L3N, STR("Phase 3 line to neutral"), STR("V"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0004, 2,
|
||||||
|
INPUT_OFFSET(voltage_L3N), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ},
|
||||||
|
{ CID_INP_I_L1, STR("Phase 1 current"), STR("A"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0006, 2,
|
||||||
|
INPUT_OFFSET(current_L1), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_I_L2, STR("Phase 2 current"), STR("A"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0008, 2,
|
||||||
|
INPUT_OFFSET(current_L2), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_I_L3, STR("Phase 3 current"), STR("A"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x000A, 2,
|
||||||
|
INPUT_OFFSET(current_L3), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_P_L1, STR("Phase 1 active power"), STR("W"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x000C, 2,
|
||||||
|
INPUT_OFFSET(active_power_L1), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_P_L2, STR("Phase 2 active power"), STR("W"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x000E, 2,
|
||||||
|
INPUT_OFFSET(active_power_L2), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_P_L3, STR("Phase 3 active power"), STR("W"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0010, 2,
|
||||||
|
INPUT_OFFSET(active_power_L3), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_S_L1, STR("Phase 1 apparent power"), STR("VA"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0012, 2,
|
||||||
|
INPUT_OFFSET(apparent_power_L1), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_S_L2, STR("Phase 2 apparent power"), STR("VA"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0014, 2,
|
||||||
|
INPUT_OFFSET(apparent_power_L2), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_S_L3, STR("Phase 3 apparent power"), STR("VA"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0016, 2,
|
||||||
|
INPUT_OFFSET(apparent_power_L3), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_Q_L1, STR("Phase 1 reactive power"), STR("VAR"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0018,
|
||||||
|
2, INPUT_OFFSET(reactive_power_L1), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_Q_L2, STR("Phase 2 reactive power"), STR("VAR"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x001A,
|
||||||
|
2, INPUT_OFFSET(reactive_power_L2), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_Q_L3, STR("Phase 3 reactive power"), STR("VAR"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x001C,
|
||||||
|
2, INPUT_OFFSET(reactive_power_L3), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_PF_L1, STR("Phase 1 power factor"), STR(""), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x001E, 2,
|
||||||
|
INPUT_OFFSET(power_factor_L1), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_PF_L2, STR("Phase 2 power factor"), STR(""), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0020, 2,
|
||||||
|
INPUT_OFFSET(power_factor_L2), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_PF_L3, STR("Phase 3 power factor"), STR(""), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0022, 2,
|
||||||
|
INPUT_OFFSET(power_factor_L3), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_U_LN_AVG, STR("Average line-to-neutral voltage"), STR("V"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x002A,
|
||||||
|
2, INPUT_OFFSET(voltage_avg_LN), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_I_L_AVG, STR("Average line current"), STR("A"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x002E,
|
||||||
|
2, INPUT_OFFSET(current_avg), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_I_SUM, STR("Sum of line currents"), STR("A"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0030,
|
||||||
|
2, INPUT_OFFSET(current_sum), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_P_SUM, STR("Total system power"), STR("W"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0034,
|
||||||
|
2, INPUT_OFFSET(active_power_sum), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_S_SUM, STR("Total system apparent power"), STR("VA"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0038,
|
||||||
|
2, INPUT_OFFSET(apparent_power_sum), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_Q_SUM, STR("Total system reactive power"), STR("VAR"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x003C,
|
||||||
|
2, INPUT_OFFSET(reactive_power_sum), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_PF_SUM, STR("Total system power factor"), STR(""), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x003E,
|
||||||
|
2, INPUT_OFFSET(power_factor_sum), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_FREQ, STR("Line frequency"), STR("Hz"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0046, 2,
|
||||||
|
INPUT_OFFSET(frequency), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_E_IMP, STR("Imported energy"), STR("kWh"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0048, 2,
|
||||||
|
INPUT_OFFSET(active_energy_import), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_E_EXP, STR("Exported energy"), STR("kWh"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x004A, 2,
|
||||||
|
INPUT_OFFSET(active_energy_export), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_U_L1L2, STR("Phase 1 to phase 2 voltage"), STR("V"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x004C,
|
||||||
|
2, INPUT_OFFSET(voltage_L1L2), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_U_L2L3, STR("Phase 2 to phase 3 voltage"), STR("V"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x004E,
|
||||||
|
2, INPUT_OFFSET(voltage_L2L3), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_U_L3L1, STR("Phase 3 to phase 1 voltage"), STR("V"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0050,
|
||||||
|
2, INPUT_OFFSET(voltage_L3L1), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_U_LL_AVG, STR("Average line-to-line voltage"), STR("V"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0052,
|
||||||
|
2, INPUT_OFFSET(voltage_avg_LL), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_I_N, STR("Neutral current"), STR("A"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0054,
|
||||||
|
2, INPUT_OFFSET(current_N), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_E_SUM, STR("Total Energy"), STR("kWh"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0156,
|
||||||
|
2, INPUT_OFFSET(active_energy_sum), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_Eq_SUM, STR("Total reactive Energy"), STR("kVARh"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0158,
|
||||||
|
2, INPUT_OFFSET(reactive_energy_sum), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_E_RESET_SUM, STR("resettable total energy"), STR("kWh"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0180,
|
||||||
|
2, INPUT_OFFSET(active_energy_resettable_sum), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_Eq_RESET_SUM, STR("resettable total reactive energy"), STR("kVARh"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0182,
|
||||||
|
2, INPUT_OFFSET(reactive_energy_resettable_sum), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_E_RESET_IMP, STR("resettable total imported energy"), STR("kWh"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0184,
|
||||||
|
2, INPUT_OFFSET(active_energy_import_resettable), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_E_RESET_EXP, STR("resettable total exported energy"), STR("kWh"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0186,
|
||||||
|
2, INPUT_OFFSET(active_energy_export_resettable), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_E_NET, STR("Net kWh (Import - Export)"), STR("kWh"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x018C,
|
||||||
|
2, INPUT_OFFSET(active_energy_net), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_P_IMP_SUM, STR("Total imported power"), STR("W"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0500,
|
||||||
|
2, INPUT_OFFSET(active_power_import_sum), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_INP_P_EXP_SUM, STR("Total exported power"), STR("W"), MB_DEVICE_ADDR1, MB_PARAM_INPUT, 0x0502,
|
||||||
|
2, INPUT_OFFSET(active_power_export_sum), PARAM_TYPE_FLOAT, 4, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_HLD_SYS_TYPE, STR("System Type"), STR(""), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 0x000A,
|
||||||
|
2, HOLD_OFFSET(sys_type), PARAM_TYPE_FLOAT, 4, OPTS( 1, 3, 0 ), PAR_PERMS_READ_WRITE },
|
||||||
|
{ CID_HLD_PULSE_WIDTH, STR("Pulse Width"), STR("ms"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 0x000C,
|
||||||
|
2, HOLD_OFFSET(pulse_width), PARAM_TYPE_FLOAT, 4, OPTS( 60, 200, 0 ), PAR_PERMS_READ_WRITE },
|
||||||
|
{ CID_HLD_KPPA, STR("Key Parameter Programming Authorization (KPPA)"), STR(""), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 0x000E,
|
||||||
|
2, HOLD_OFFSET(kppa), PARAM_TYPE_FLOAT, 4, OPTS( 0, 1, 0 ), PAR_PERMS_READ_WRITE },
|
||||||
|
{ CID_HLD_PARITY_AND_STOP, STR("Parity and stop bit"), STR(""), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 0x0012,
|
||||||
|
2, HOLD_OFFSET(kppa), PARAM_TYPE_FLOAT, 4, OPTS( 0, 3, 0 ), PAR_PERMS_READ_WRITE},
|
||||||
|
{ CID_HLD_MB_ADDR, STR("Modbus address"), STR(""), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 0x0014,
|
||||||
|
2, HOLD_OFFSET(modbus_addr), PARAM_TYPE_FLOAT, 4, OPTS( 1, 247, 0 ), PAR_PERMS_READ_WRITE },
|
||||||
|
{ CID_HLD_PULSE_CONST, STR("Pulse Constant"), STR(""), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 0x0016,
|
||||||
|
2, HOLD_OFFSET(pulse_const), PARAM_TYPE_FLOAT, 4, OPTS( 0, 3, 0 ), PAR_PERMS_READ_WRITE },
|
||||||
|
{ CID_HLD_PASSWD, STR("Password"), STR(""), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 0x0018,
|
||||||
|
2, HOLD_OFFSET(password), PARAM_TYPE_FLOAT, 4, OPTS( 0, 9999, 0 ), PAR_PERMS_READ_WRITE },
|
||||||
|
{ CID_HLD_BAUDRATE, STR("Baudrate"), STR(""), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 0x001C,
|
||||||
|
2, HOLD_OFFSET(baudrate), PARAM_TYPE_FLOAT, 4, OPTS( 0, 5, 0 ), PAR_PERMS_READ_WRITE },
|
||||||
|
{ CID_HLD_AUTO_SCROLL_TIME, STR("Auto Scroll Time"), STR("s"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 0x003A,
|
||||||
|
2, HOLD_OFFSET(auto_scroll_time), PARAM_TYPE_FLOAT, 4, OPTS( 0, 60, 0 ), PAR_PERMS_READ_WRITE },
|
||||||
|
{ CID_HLD_BACKLIGHT_TIME, STR("Backlight Time"), STR("min"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 0x003C,
|
||||||
|
2, HOLD_OFFSET(backlight_time), PARAM_TYPE_FLOAT, 4, OPTS( 0, 121, 0 ), PAR_PERMS_READ_WRITE },
|
||||||
|
{ CID_HLD_PULSE_1_E_TYPE, STR("Pulse 1 Energy Type"), STR(""), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 0x0056,
|
||||||
|
2, HOLD_OFFSET(pulse_1_energy_type), PARAM_TYPE_FLOAT, 4, OPTS( 0, 4, 0 ), PAR_PERMS_READ_WRITE },
|
||||||
|
{ CID_HLD_RST_HIST, STR("Reset historical data"), STR(""), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 0xF010,
|
||||||
|
1, HOLD_OFFSET(reset_history), PARAM_TYPE_U16, 2, OPTS( 0, 1, 0 ), PAR_PERMS_WRITE },
|
||||||
|
{ CID_HLD_SERIAL, STR("Serial number"), STR(""), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 0xFC00,
|
||||||
|
2, HOLD_OFFSET(serial_number), PARAM_TYPE_U16, 2, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_HLD_METER_TYPE, STR("Meter type"), STR(""), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 0xFC02,
|
||||||
|
1, HOLD_OFFSET(meter_type), PARAM_TYPE_U16, 2, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
{ CID_HLD_METER_FIRMWARE, STR("Firmware version"), STR(""), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 0xFC84,
|
||||||
|
1, HOLD_OFFSET(fw_version), PARAM_TYPE_U16, 2, OPTS( 0, 0, 0 ), PAR_PERMS_READ },
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Calculate number of parameters in the table
|
||||||
|
const uint16_t num_device_parameters = (sizeof(device_parameters)/sizeof(device_parameters[0]));
|
||||||
|
|
||||||
|
// User operation function to read slave values and check alarm
|
||||||
|
static void modbus_poller(void *arg)
|
||||||
|
{
|
||||||
|
esp_err_t err = ESP_OK;
|
||||||
|
uint32_t value = 0;
|
||||||
|
uint8_t type = 0;
|
||||||
|
const mb_parameter_descriptor_t* param_descriptor = NULL;
|
||||||
|
|
||||||
|
char topic[512];
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Start modbus poller");
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
// Read all found characteristics from slave(s)
|
||||||
|
for (uint16_t cid = 0; (err != ESP_ERR_NOT_FOUND) && cid < MASTER_MAX_CIDS; cid++)
|
||||||
|
{
|
||||||
|
// Get data from parameters description table
|
||||||
|
// and use this information to fill the characteristics description table
|
||||||
|
// and having all required fields in just one table
|
||||||
|
err = mbc_master_get_cid_info(cid, ¶m_descriptor);
|
||||||
|
if ((err != ESP_ERR_NOT_FOUND) && (param_descriptor != NULL)) {
|
||||||
|
void* temp_data_ptr = master_get_param_data(param_descriptor);
|
||||||
|
assert(temp_data_ptr);
|
||||||
|
type = param_descriptor->param_type;
|
||||||
|
extern esp_mqtt_client_handle_t mqtt_client;
|
||||||
|
err = mbc_master_get_parameter(cid, (char*)param_descriptor->param_key,
|
||||||
|
(uint8_t*)&value, &type);
|
||||||
|
if (err == ESP_OK) {
|
||||||
|
*(uint32_t*)temp_data_ptr = __beswap_32(value);
|
||||||
|
char payload[32];
|
||||||
|
|
||||||
|
switch (param_descriptor->param_type)
|
||||||
|
{
|
||||||
|
case PARAM_TYPE_FLOAT:
|
||||||
|
ESP_LOGI(TAG, "Characteristic #%d %s (%s) value = %f (0x%"PRIu32") read successful.",
|
||||||
|
param_descriptor->cid,
|
||||||
|
(char*)param_descriptor->param_key,
|
||||||
|
(char*)param_descriptor->param_units,
|
||||||
|
*(float*)temp_data_ptr,
|
||||||
|
*(uint32_t*)temp_data_ptr);
|
||||||
|
|
||||||
|
snprintf(topic, 512, "fabmeter/%05d/%s", CONFIG_FABMETER_ID, (char*)param_descriptor->param_key);
|
||||||
|
|
||||||
|
snprintf(payload, 32, "%f", *(float*)temp_data_ptr);
|
||||||
|
esp_mqtt_client_publish(mqtt_client, topic, payload, 0, 0, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PARAM_TYPE_U8:
|
||||||
|
ESP_LOGI(TAG, "Characteristic #%d %s value = 0x%"PRIu8" read successful.",
|
||||||
|
param_descriptor->cid,
|
||||||
|
(char*)param_descriptor->param_key,
|
||||||
|
*(uint8_t*)temp_data_ptr);
|
||||||
|
snprintf(topic, 512, "fabmeter/%05d/%s", CONFIG_FABMETER_ID, (char*)param_descriptor->param_key);
|
||||||
|
|
||||||
|
snprintf(payload, 32, "0x%"PRIu8"", *(uint8_t*)temp_data_ptr);
|
||||||
|
esp_mqtt_client_publish(mqtt_client, topic, payload, 0, 0, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PARAM_TYPE_U16:
|
||||||
|
ESP_LOGI(TAG, "Characteristic #%d %s value = 0x%"PRIu16" read successful.",
|
||||||
|
param_descriptor->cid,
|
||||||
|
(char*)param_descriptor->param_key,
|
||||||
|
*(uint16_t*)temp_data_ptr);
|
||||||
|
snprintf(topic, 512, "fabmeter/%05d/%s", CONFIG_FABMETER_ID, (char*)param_descriptor->param_key);
|
||||||
|
|
||||||
|
snprintf(payload, 32, "0x%"PRIu16"", *(uint16_t*)temp_data_ptr);
|
||||||
|
esp_mqtt_client_publish(mqtt_client, topic, payload, 0, 0, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PARAM_TYPE_U32:
|
||||||
|
ESP_LOGI(TAG, "Characteristic #%d %s value = 0x%"PRIu32" read successful.",
|
||||||
|
param_descriptor->cid,
|
||||||
|
(char*)param_descriptor->param_key,
|
||||||
|
*(uint32_t*)temp_data_ptr);
|
||||||
|
snprintf(topic, 512, "fabmeter/%05d/%s", CONFIG_FABMETER_ID, (char*)param_descriptor->param_key);
|
||||||
|
|
||||||
|
snprintf(payload, 32, "0x%"PRIu32"", *(uint32_t*)temp_data_ptr);
|
||||||
|
esp_mqtt_client_publish(mqtt_client, topic, payload, 0, 0, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PARAM_TYPE_ASCII:
|
||||||
|
ESP_LOGI(TAG, "Characteristic #%d %s value = %s read successful.",
|
||||||
|
param_descriptor->cid,
|
||||||
|
(char*)param_descriptor->param_key,
|
||||||
|
(char*)temp_data_ptr);
|
||||||
|
snprintf(topic, 512, "fabmeter/%05d/%s", CONFIG_FABMETER_ID, (char*)param_descriptor->param_key);
|
||||||
|
|
||||||
|
snprintf(payload, 32, "%s", (char*)temp_data_ptr);
|
||||||
|
esp_mqtt_client_publish(mqtt_client, topic, payload, 0, 0, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(TAG, "Characteristic #%d (%s) read fail, err = 0x%d (%s).",
|
||||||
|
param_descriptor->cid,
|
||||||
|
(char*)param_descriptor->param_key,
|
||||||
|
(int)err,
|
||||||
|
(char*)esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
vTaskDelay(POLL_TIMEOUT_TICS); // delay between cids
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vTaskDelay(UPDATE_CIDS_TIMEOUT_TICS); // delay between updates
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void app_main(void)
|
||||||
|
{
|
||||||
|
extern led_strip_handle_t debug_led;
|
||||||
|
|
||||||
|
esp_insights_config_t config = {
|
||||||
|
.log_type = ESP_DIAG_LOG_TYPE_ERROR,
|
||||||
|
.auth_key = ESP_INSIGHTS_AUTH_KEY,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Initialization of device peripheral and objects
|
||||||
|
init_led_strip();
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(led_strip_set_pixel(debug_led, 0, 0xFF, 0, 0));
|
||||||
|
ESP_ERROR_CHECK(led_strip_refresh(debug_led));
|
||||||
|
|
||||||
|
init_eventloop();
|
||||||
|
init_nvs();
|
||||||
|
init_wifi();
|
||||||
|
esp_insights_init(&config);
|
||||||
|
|
||||||
|
init_mqtt();
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(init_modbus(&device_parameters[0], num_device_parameters));
|
||||||
|
vTaskDelay(10);
|
||||||
|
|
||||||
|
modbus_poller(NULL);
|
||||||
|
}
|
19
main/idf_component.yml
Normal file
19
main/idf_component.yml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
## IDF Component Manager Manifest File
|
||||||
|
dependencies:
|
||||||
|
espressif/esp-modbus: "^1.0.11"
|
||||||
|
espressif/led_strip: "^2.3.1"
|
||||||
|
espressif/esp_insights: "^1.0.0"
|
||||||
|
## Required IDF version
|
||||||
|
idf:
|
||||||
|
version: ">=4.1.0"
|
||||||
|
# # Put list of dependencies here
|
||||||
|
# # For components maintained by Espressif:
|
||||||
|
# component: "~1.0.0"
|
||||||
|
# # For 3rd party components:
|
||||||
|
# username/component: ">=1.0.0,<2.0.0"
|
||||||
|
# username2/component2:
|
||||||
|
# version: "~1.0.0"
|
||||||
|
# # For transient dependencies `public` flag can be set.
|
||||||
|
# # `public` flag doesn't have an effect dependencies of the `main` component.
|
||||||
|
# # All dependencies of `main` are public by default.
|
||||||
|
# public: true
|
174
main/initializers.c
Normal file
174
main/initializers.c
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
#include <mbcontroller.h>
|
||||||
|
#include <led_strip.h>
|
||||||
|
#include <esp_event.h>
|
||||||
|
#include <esp_wifi.h>
|
||||||
|
#include <esp_crt_bundle.h>
|
||||||
|
#include <mqtt_client.h>
|
||||||
|
#include <nvs_flash.h>
|
||||||
|
|
||||||
|
#include "initializers.h"
|
||||||
|
#include "net_event_handler.h"
|
||||||
|
#include "mqtt_event_handler.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
#define LED_STRIP_RMT_RES_HZ (10 * 1000 * 1000)
|
||||||
|
|
||||||
|
char TAG[] = "initializers";
|
||||||
|
led_strip_handle_t debug_led;
|
||||||
|
esp_mqtt_client_handle_t mqtt_client;
|
||||||
|
|
||||||
|
// Modbus master initialization
|
||||||
|
esp_err_t init_modbus(const mb_parameter_descriptor_t* device_parameters, const uint16_t num_device_parameters)
|
||||||
|
{
|
||||||
|
// Initialize and start Modbus controller
|
||||||
|
mb_communication_info_t comm = {
|
||||||
|
.port = MB_PORT_NUM,
|
||||||
|
#if CONFIG_MB_COMM_MODE_ASCII
|
||||||
|
.mode = MB_MODE_ASCII,
|
||||||
|
#elif CONFIG_MB_COMM_MODE_RTU
|
||||||
|
.mode = MB_MODE_RTU,
|
||||||
|
#endif
|
||||||
|
.baudrate = MB_DEV_SPEED,
|
||||||
|
.parity = MB_PARITY
|
||||||
|
};
|
||||||
|
void* master_handler = NULL;
|
||||||
|
|
||||||
|
esp_err_t err = mbc_master_init(MB_PORT_SERIAL_MASTER, &master_handler);
|
||||||
|
MB_RETURN_ON_FALSE((master_handler != NULL), ESP_ERR_INVALID_STATE, TAG,
|
||||||
|
"mb controller initialization fail.");
|
||||||
|
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
|
||||||
|
"mb controller initialization fail, returns(0x%"PRIu32").",
|
||||||
|
(uint32_t)err);
|
||||||
|
err = mbc_master_setup((void*)&comm);
|
||||||
|
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
|
||||||
|
"mb controller setup fail, returns(0x%"PRIu32").",
|
||||||
|
(uint32_t)err);
|
||||||
|
|
||||||
|
// Set UART pin numbers
|
||||||
|
err = uart_set_pin(MB_PORT_NUM, CONFIG_MB_UART_TXD, CONFIG_MB_UART_RXD,
|
||||||
|
CONFIG_MB_UART_RTS, UART_PIN_NO_CHANGE);
|
||||||
|
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
|
||||||
|
"mb serial set pin failure, uart_set_pin() returned (0x%"PRIu32").", (uint32_t)err);
|
||||||
|
|
||||||
|
err = mbc_master_start();
|
||||||
|
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
|
||||||
|
"mb controller start fail, returns(0x%"PRIu32").",
|
||||||
|
(uint32_t)err);
|
||||||
|
|
||||||
|
// Set driver mode to Half Duplex
|
||||||
|
err = uart_set_mode(MB_PORT_NUM, UART_MODE_RS485_HALF_DUPLEX);
|
||||||
|
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
|
||||||
|
"mb serial set mode failure, uart_set_mode() returned (0x%"PRIu32").", (uint32_t)err);
|
||||||
|
|
||||||
|
// Set UART stop bits
|
||||||
|
err = uart_set_stop_bits(MB_PORT_NUM, MB_STOP_BITS);
|
||||||
|
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
|
||||||
|
"mb serial set stop bits failure, uart_set_stop_bits() returned (0x%"PRIu32").", (uint32_t)err);
|
||||||
|
|
||||||
|
vTaskDelay(5);
|
||||||
|
err = mbc_master_set_descriptor(device_parameters, num_device_parameters);
|
||||||
|
MB_RETURN_ON_FALSE((err == ESP_OK), ESP_ERR_INVALID_STATE, TAG,
|
||||||
|
"mb controller set descriptor fail, returns(0x%"PRIu32").",
|
||||||
|
(uint32_t)err);
|
||||||
|
ESP_LOGI(TAG, "Modbus master stack initialized...");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t init_led_strip() {
|
||||||
|
// LED strip general initialization, according to your led board design
|
||||||
|
led_strip_config_t debug_led_config = {
|
||||||
|
.strip_gpio_num = CONFIG_PIN_DEBUG_LED, // The GPIO that connected to the LED strip's data line
|
||||||
|
.max_leds = 1, // The number of LEDs in the strip,
|
||||||
|
.led_pixel_format = LED_PIXEL_FORMAT_GRB, // Pixel format of your LED strip
|
||||||
|
.led_model = LED_MODEL_WS2812, // LED strip model
|
||||||
|
.flags.invert_out = false, // whether to invert the output signal
|
||||||
|
};
|
||||||
|
|
||||||
|
// LED strip backend configuration: RMT
|
||||||
|
led_strip_rmt_config_t debug_led_rmt_config = {
|
||||||
|
.clk_src = RMT_CLK_SRC_DEFAULT, // different clock source can lead to different power consumption
|
||||||
|
.resolution_hz = LED_STRIP_RMT_RES_HZ, // RMT counter clock frequency
|
||||||
|
.flags.with_dma = false, // DMA feature is available on ESP target like ESP32-S3
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(led_strip_new_rmt_device(&debug_led_config, &debug_led_rmt_config, &debug_led));
|
||||||
|
ESP_LOGI("led", "Created LED strip object with RMT backend for debug LED");
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t init_eventloop() {
|
||||||
|
esp_err_t ret = esp_event_loop_create_default();
|
||||||
|
ESP_ERROR_CHECK(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t init_wifi() {
|
||||||
|
esp_err_t ret;
|
||||||
|
ret = esp_netif_init();
|
||||||
|
ESP_ERROR_CHECK(ret);
|
||||||
|
|
||||||
|
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
||||||
|
ret = esp_wifi_init(&cfg);
|
||||||
|
ESP_ERROR_CHECK(ret);
|
||||||
|
|
||||||
|
ret = esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &network_event_handler, NULL, NULL);
|
||||||
|
ESP_ERROR_CHECK(ret);
|
||||||
|
ret = esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &network_event_handler, NULL, NULL);
|
||||||
|
ESP_ERROR_CHECK(ret);
|
||||||
|
|
||||||
|
|
||||||
|
// Initialize default station as network interface instance (esp-netif)
|
||||||
|
esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
|
||||||
|
assert(sta_netif);
|
||||||
|
|
||||||
|
// Initialize and start WiFi
|
||||||
|
wifi_config_t wifi_config = {
|
||||||
|
.sta = {
|
||||||
|
.ssid = CONFIG_WIFI_SSID,
|
||||||
|
.password = CONFIG_WIFI_PASSWORD,
|
||||||
|
.scan_method = CONFIG_WIFI_FAST_SCAN ? WIFI_FAST_SCAN : WIFI_ALL_CHANNEL_SCAN,
|
||||||
|
.sort_method = WIFI_CONNECT_AP_BY_SIGNAL,
|
||||||
|
.threshold.rssi = -127,
|
||||||
|
.threshold.authmode = WIFI_AUTH_WPA2_PSK,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
ret = esp_wifi_set_mode(WIFI_MODE_STA);
|
||||||
|
ESP_ERROR_CHECK(ret);
|
||||||
|
ret = esp_wifi_set_config(WIFI_IF_STA, &wifi_config);
|
||||||
|
ESP_ERROR_CHECK(ret);
|
||||||
|
ret = esp_wifi_start();
|
||||||
|
ESP_ERROR_CHECK(ret);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t init_nvs() {
|
||||||
|
// Initialize NVS
|
||||||
|
esp_err_t ret = nvs_flash_init();
|
||||||
|
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||||
|
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||||
|
ret = nvs_flash_init();
|
||||||
|
}
|
||||||
|
ESP_ERROR_CHECK(ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t init_mqtt() {
|
||||||
|
esp_err_t ret;
|
||||||
|
const esp_mqtt_client_config_t mqtt_cfg = {
|
||||||
|
.broker = {
|
||||||
|
.address.uri = CONFIG_BROKER_URI,
|
||||||
|
.verification.crt_bundle_attach = esp_crt_bundle_attach
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
|
||||||
|
/* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */
|
||||||
|
ret = esp_mqtt_client_register_event(client, MQTT_EVENT_ANY, mqtt_event_handler, NULL);
|
||||||
|
ESP_ERROR_CHECK(ret);
|
||||||
|
ret = esp_mqtt_client_start(client);
|
||||||
|
ESP_ERROR_CHECK(ret);
|
||||||
|
|
||||||
|
mqtt_client = client;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
16
main/initializers.h
Normal file
16
main/initializers.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <esp_err.h>
|
||||||
|
#include "mbcontroller.h"
|
||||||
|
|
||||||
|
#define MB_PORT_NUM (CONFIG_MB_UART_PORT_NUM) // Number of UART port used for Modbus connection
|
||||||
|
#define MB_DEV_SPEED (CONFIG_MB_UART_BAUD_RATE) // The communication speed of the UART
|
||||||
|
#define MB_PARITY (CONFIG_MB_UART_PARITY) // Parity used for Modbus communication
|
||||||
|
#define MB_STOP_BITS (CONFIG_MB_UART_STOP_BITS) // Number of stop bits used for UART communication
|
||||||
|
|
||||||
|
esp_err_t init_modbus(const mb_parameter_descriptor_t* device_parameters, const uint16_t num_device_parameters);
|
||||||
|
esp_err_t init_led_strip();
|
||||||
|
esp_err_t init_eventloop();
|
||||||
|
esp_err_t init_wifi();
|
||||||
|
esp_err_t init_nvs();
|
||||||
|
esp_err_t init_mqtt();
|
21
main/modbus_params.c
Normal file
21
main/modbus_params.c
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2016-2021 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
/*=====================================================================================
|
||||||
|
* Description:
|
||||||
|
* C file to define parameter storage instances
|
||||||
|
*====================================================================================*/
|
||||||
|
#include "modbus_params.h"
|
||||||
|
|
||||||
|
// Here are the user defined instances for device parameters packed by 1 byte
|
||||||
|
// These are keep the values that can be accessed from Modbus master
|
||||||
|
holding_reg_params_t holding_reg_params = { 0 };
|
||||||
|
|
||||||
|
input_reg_params_t input_reg_params = { 0 };
|
||||||
|
|
||||||
|
coil_reg_params_t coil_reg_params = { 0 };
|
||||||
|
|
||||||
|
discrete_reg_params_t discrete_reg_params = { 0 };
|
||||||
|
|
179
main/modbus_params.h
Normal file
179
main/modbus_params.h
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2016-2021 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*=====================================================================================
|
||||||
|
* Description:
|
||||||
|
* The Modbus parameter structures used to define Modbus instances that
|
||||||
|
* can be addressed by Modbus protocol. Define these structures per your needs in
|
||||||
|
* your application. Below is just an example of possible parameters.
|
||||||
|
*====================================================================================*/
|
||||||
|
#ifndef _DEVICE_PARAMS
|
||||||
|
#define _DEVICE_PARAMS
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// This file defines structure of modbus parameters which reflect correspond modbus address space
|
||||||
|
// for each modbus register type (coils, discreet inputs, holding registers, input registers)
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t discrete_input0:1;
|
||||||
|
uint8_t discrete_input1:1;
|
||||||
|
uint8_t discrete_input2:1;
|
||||||
|
uint8_t discrete_input3:1;
|
||||||
|
uint8_t discrete_input4:1;
|
||||||
|
uint8_t discrete_input5:1;
|
||||||
|
uint8_t discrete_input6:1;
|
||||||
|
uint8_t discrete_input7:1;
|
||||||
|
uint8_t discrete_input_port1:8;
|
||||||
|
} discrete_reg_params_t;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint8_t coils_port0;
|
||||||
|
uint8_t coils_port1;
|
||||||
|
} coil_reg_params_t;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
float voltage_L1N; // 0
|
||||||
|
float voltage_L2N; // 2
|
||||||
|
float voltage_L3N; // 4
|
||||||
|
float current_L1; // 6
|
||||||
|
float current_L2; // 8
|
||||||
|
float current_L3; // 10
|
||||||
|
float active_power_L1; // 12
|
||||||
|
float active_power_L2; // 14
|
||||||
|
float active_power_L3; // 16
|
||||||
|
float apparent_power_L1; // 18
|
||||||
|
float apparent_power_L2; // 20
|
||||||
|
float apparent_power_L3; // 22
|
||||||
|
float reactive_power_L1; // 24
|
||||||
|
float reactive_power_L2; // 26
|
||||||
|
float reactive_power_L3; // 28
|
||||||
|
float power_factor_L1; // 30
|
||||||
|
float power_factor_L2; // 32
|
||||||
|
float power_factor_L3; // 34
|
||||||
|
float voltage_avg_LN; // 36
|
||||||
|
float current_avg; // 38
|
||||||
|
float current_sum; // 40
|
||||||
|
float active_power_sum; // 42
|
||||||
|
float apparent_power_sum; // 44
|
||||||
|
float reactive_power_sum; // 46
|
||||||
|
float power_factor_sum; // 48
|
||||||
|
float frequency; // 50
|
||||||
|
float active_energy_import; // 52
|
||||||
|
float active_energy_export; // 54
|
||||||
|
float voltage_L1L2; // 56
|
||||||
|
float voltage_L2L3; // 58
|
||||||
|
float voltage_L3L1; // 60
|
||||||
|
float voltage_avg_LL; // 62
|
||||||
|
float current_N; // 64
|
||||||
|
float active_energy_sum; // 66
|
||||||
|
float reactive_energy_sum; // 68
|
||||||
|
float active_energy_resettable_sum; // 70
|
||||||
|
float reactive_energy_resettable_sum; // 72
|
||||||
|
float active_energy_import_resettable; // 74
|
||||||
|
float active_energy_export_resettable; // 76
|
||||||
|
float active_energy_net; // 78
|
||||||
|
float active_power_import_sum; // 80
|
||||||
|
float active_power_export_sum; // 82
|
||||||
|
} input_reg_params_t;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
#pragma pack(push, 1)
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
float sys_type; // 0
|
||||||
|
float pulse_width; // 2
|
||||||
|
float kppa; // 4
|
||||||
|
float parrity_and_stop; // 6
|
||||||
|
float modbus_addr; // 8
|
||||||
|
float pulse_const; // 10
|
||||||
|
float password; // 12
|
||||||
|
float baudrate; // 14
|
||||||
|
float auto_scroll_time; // 16
|
||||||
|
float backlight_time; // 18
|
||||||
|
float pulse_1_energy_type; // 20
|
||||||
|
uint16_t reset_history; // 22
|
||||||
|
uint32_t serial_number; // 24
|
||||||
|
uint16_t meter_type; // 28
|
||||||
|
uint16_t fw_version; // 30
|
||||||
|
|
||||||
|
} holding_reg_params_t;
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
extern holding_reg_params_t holding_reg_params;
|
||||||
|
extern input_reg_params_t input_reg_params;
|
||||||
|
extern coil_reg_params_t coil_reg_params;
|
||||||
|
extern discrete_reg_params_t discrete_reg_params;
|
||||||
|
|
||||||
|
// Enumeration of all supported CIDs for device (used in parameter definition table)
|
||||||
|
enum {
|
||||||
|
CID_INP_U_L1N = 0, // Input voltage L1-N
|
||||||
|
CID_INP_U_L2N, // Input voltage L2-N
|
||||||
|
CID_INP_U_L3N, // Input voltage L3-N
|
||||||
|
CID_INP_I_L1, // Input current L1
|
||||||
|
CID_INP_I_L2, // Input current L2
|
||||||
|
CID_INP_I_L3, // Input current L3
|
||||||
|
CID_INP_P_L1, // Input active power L1
|
||||||
|
CID_INP_P_L2, // Input active power L2
|
||||||
|
CID_INP_P_L3, // Input active power L3
|
||||||
|
CID_INP_S_L1, // Input apparent power L1
|
||||||
|
CID_INP_S_L2, // Input apparent power L2
|
||||||
|
CID_INP_S_L3, // Input apparent power L3
|
||||||
|
CID_INP_Q_L1, // Input reactive power L1
|
||||||
|
CID_INP_Q_L2, // Input reactive power L2
|
||||||
|
CID_INP_Q_L3, // Input reactive power L3
|
||||||
|
CID_INP_PF_L1, // Input power factor L1
|
||||||
|
CID_INP_PF_L2, // Input power factor L2
|
||||||
|
CID_INP_PF_L3, // Input power factor L3
|
||||||
|
CID_INP_U_LN_AVG, // Input voltage L-N average
|
||||||
|
CID_INP_I_L_AVG, // Input current L average
|
||||||
|
CID_INP_I_SUM, // Input current sum
|
||||||
|
CID_INP_P_SUM, // Input active power sum
|
||||||
|
CID_INP_S_SUM, // Input apparent power sum
|
||||||
|
CID_INP_Q_SUM, // Input reactive power sum
|
||||||
|
CID_INP_PF_SUM, // Input power factor average
|
||||||
|
CID_INP_FREQ, // Input frequency
|
||||||
|
CID_INP_E_IMP, // Input energy import
|
||||||
|
CID_INP_E_EXP, // Input energy export
|
||||||
|
CID_INP_U_L1L2, // Input voltage L1-L2
|
||||||
|
CID_INP_U_L2L3, // Input voltage L2-L3
|
||||||
|
CID_INP_U_L3L1, // Input voltage L3-L1
|
||||||
|
CID_INP_U_LL_AVG, // Input voltage L-L average
|
||||||
|
CID_INP_I_N, // Input current N
|
||||||
|
CID_INP_E_SUM, // Input energy sum
|
||||||
|
CID_INP_Eq_SUM, // Input energy reactive sum
|
||||||
|
CID_INP_E_RESET_SUM, // Input resettable energy sum
|
||||||
|
CID_INP_Eq_RESET_SUM, // Input resettable reactive energy sum
|
||||||
|
CID_INP_E_RESET_IMP, // Input resettable energy import
|
||||||
|
CID_INP_E_RESET_EXP, // Input resettable energy export
|
||||||
|
CID_INP_E_NET, // Input net energy *import - export*
|
||||||
|
CID_INP_P_IMP_SUM, // Input power import sum
|
||||||
|
CID_INP_P_EXP_SUM, // Input power export sum
|
||||||
|
CID_HLD_SYS_TYPE, // System type (1 - Single phase, 3 - Three phase)
|
||||||
|
CID_HLD_PULSE_WIDTH, // Pulse width (60ms, 100ms, 200ms)
|
||||||
|
CID_HLD_KPPA, // Key Parameter Programming Authorization (0 - not authorized, 1 - authorized)
|
||||||
|
CID_HLD_PARITY_AND_STOP, // Parity and stop bits (0 - 1 stop bit, no parity, 1 - 1 stop bit, even parity, 2 - 1 stop bit, odd parity, 3 - 2 stop bits, no parity)
|
||||||
|
CID_HLD_MB_ADDR, // Modbus address (1-247)
|
||||||
|
CID_HLD_PULSE_CONST,// Pulse constant (0 - 1000 imp/kWh, 1 - 100 imp/kWh, 2 - 10 imp/kWh, 3 - 1 imp/kWh)
|
||||||
|
CID_HLD_PASSWD, // Password (0 - 9999, default 1000)
|
||||||
|
CID_HLD_BAUDRATE, // Baudrate (0 - 2400, 1 - 4800, 2 - 9600, 3 - 19200, 5 - 1200)
|
||||||
|
CID_HLD_AUTO_SCROLL_TIME, // Auto scroll time (0-60 - time in seconds)
|
||||||
|
CID_HLD_BACKLIGHT_TIME, // Backlight time (0-121, 0 - always on, 121, always off, 1-120 - time in seconds)
|
||||||
|
CID_HLD_PULSE_1_E_TYPE, // Pulse 1 energy type (1 - import, 2 - total, 3 - export)
|
||||||
|
CID_HLD_RST_HIST, // Reset history (0x0003 - reset energy info)
|
||||||
|
CID_HLD_SERIAL, // Serial number (uint32_t, read only)
|
||||||
|
CID_HLD_METER_TYPE, // Meter type (0x0089 - SDM72D-M-2, read only)
|
||||||
|
CID_HLD_METER_FIRMWARE // Meter firmware (Format XX.YY, XX = data[0], YY = data[1] , read only)
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // !defined(_DEVICE_PARAMS)
|
61
main/modbus_utils.h
Normal file
61
main/modbus_utils.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// The macro to get offset for parameter in the appropriate structure
|
||||||
|
#define HOLD_OFFSET(field) ((uint16_t)(offsetof(holding_reg_params_t, field) + 1))
|
||||||
|
#define INPUT_OFFSET(field) ((uint16_t)(offsetof(input_reg_params_t, field) + 1))
|
||||||
|
#define COIL_OFFSET(field) ((uint16_t)(offsetof(coil_reg_params_t, field) + 1))
|
||||||
|
// Discrete offset macro
|
||||||
|
#define DISCR_OFFSET(field) ((uint16_t)(offsetof(discrete_reg_params_t, field) + 1))
|
||||||
|
|
||||||
|
#define STR(fieldname) ((const char*)( fieldname ))
|
||||||
|
// Options can be used as bit masks or parameter limits
|
||||||
|
#define OPTS(min_val, max_val, step_val) { .opt1 = min_val, .opt2 = max_val, .opt3 = step_val }
|
||||||
|
|
||||||
|
// BigEndian 32bit swap
|
||||||
|
// just swap the two 16 bit registers since the two bytes in each
|
||||||
|
// register are already swapped (BigEndian) as per modbus standard.
|
||||||
|
# define __beswap_32(x) \
|
||||||
|
(__extension__ \
|
||||||
|
({ uint32_t __bsx = (x); \
|
||||||
|
((((__bsx) >> 16) & 0xffff) | (((__bsx) & 0xffff) << 16)); }))
|
||||||
|
|
||||||
|
// The function to get pointer to parameter storage (instance) according to parameter description table
|
||||||
|
static void* master_get_param_data(const mb_parameter_descriptor_t* param_descriptor)
|
||||||
|
{
|
||||||
|
assert(param_descriptor != NULL);
|
||||||
|
void* instance_ptr = NULL;
|
||||||
|
if (param_descriptor->param_offset != 0) {
|
||||||
|
switch(param_descriptor->mb_param_type)
|
||||||
|
{
|
||||||
|
case MB_PARAM_HOLDING:
|
||||||
|
instance_ptr = ((void*)&holding_reg_params + param_descriptor->param_offset - 1);
|
||||||
|
break;
|
||||||
|
case MB_PARAM_INPUT:
|
||||||
|
instance_ptr = ((void*)&input_reg_params + param_descriptor->param_offset - 1);
|
||||||
|
break;
|
||||||
|
case MB_PARAM_COIL:
|
||||||
|
instance_ptr = ((void*)&coil_reg_params + param_descriptor->param_offset - 1);
|
||||||
|
break;
|
||||||
|
case MB_PARAM_DISCRETE:
|
||||||
|
instance_ptr = ((void*)&discrete_reg_params + param_descriptor->param_offset - 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
instance_ptr = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ESP_LOGE("MB_UTILS", "Wrong parameter offset for CID #%d", param_descriptor->cid);
|
||||||
|
assert(instance_ptr != NULL);
|
||||||
|
}
|
||||||
|
return instance_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
79
main/mqtt_event_handler.c
Normal file
79
main/mqtt_event_handler.c
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#include "mqtt_event_handler.h"
|
||||||
|
#include <esp_log.h>
|
||||||
|
#include <mqtt_client.h>
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief Event handler registered to receive MQTT events
|
||||||
|
*
|
||||||
|
* This function is called by the MQTT client event loop.
|
||||||
|
*
|
||||||
|
* @param handler_args user data registered to the event.
|
||||||
|
* @param base Event base for the handler(always MQTT Base in this example).
|
||||||
|
* @param event_id The id for the received event.
|
||||||
|
* @param event_data The data for the event, esp_mqtt_event_handle_t.
|
||||||
|
*/
|
||||||
|
void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) {
|
||||||
|
ESP_LOGD("mqtt", "Event dispatched from event loop base=%s, event_id=%" PRIu32, base, event_id);
|
||||||
|
esp_mqtt_event_handle_t event = event_data;
|
||||||
|
esp_mqtt_client_handle_t client = event->client;
|
||||||
|
int msg_id;
|
||||||
|
switch ((esp_mqtt_event_id_t) event_id) {
|
||||||
|
case MQTT_EVENT_CONNECTED:
|
||||||
|
ESP_LOGI("mqtt", "MQTT_EVENT_CONNECTED");
|
||||||
|
|
||||||
|
char id[6] = "00000";
|
||||||
|
sprintf(id, "%05d", CONFIG_FABMETER_ID);
|
||||||
|
|
||||||
|
// Register Meter
|
||||||
|
msg_id = esp_mqtt_client_publish(client, "fabmeter", id, 0, 0, 0);
|
||||||
|
ESP_LOGI("mqtt", "sent publish successful, msg_id=%d", msg_id);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case MQTT_EVENT_DISCONNECTED:
|
||||||
|
ESP_LOGI("mqtt", "MQTT_EVENT_DISCONNECTED");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MQTT_EVENT_SUBSCRIBED:
|
||||||
|
ESP_LOGI("mqtt", "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
|
||||||
|
break;
|
||||||
|
case MQTT_EVENT_UNSUBSCRIBED:
|
||||||
|
ESP_LOGI("mqtt", "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
|
||||||
|
break;
|
||||||
|
case MQTT_EVENT_PUBLISHED:
|
||||||
|
ESP_LOGI("mqtt", "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
|
||||||
|
break;
|
||||||
|
case MQTT_EVENT_DATA:
|
||||||
|
ESP_LOGI("mqtt", "MQTT_EVENT_DATA");
|
||||||
|
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
|
||||||
|
printf("DATA=%.*s\r\n", event->data_len, event->data);
|
||||||
|
|
||||||
|
char* topic = strndup(event->topic, event->topic_len);
|
||||||
|
|
||||||
|
ESP_LOGI("mqtt", "TOPIC=%s", topic);
|
||||||
|
|
||||||
|
free(topic);
|
||||||
|
|
||||||
|
// if (ret != ESP_OK) {
|
||||||
|
// ESP_LOGE("mqtt", "Error handling MQTT command: %s", esp_err_to_name(ret));
|
||||||
|
// }
|
||||||
|
break;
|
||||||
|
case MQTT_EVENT_ERROR:
|
||||||
|
ESP_LOGE("mqtt", "MQTT_EVENT_ERROR");
|
||||||
|
if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
|
||||||
|
ESP_LOGE("mqtt", "Last error code reported from esp-tls: 0x%x",
|
||||||
|
event->error_handle->esp_tls_last_esp_err);
|
||||||
|
ESP_LOGE("mqtt", "Last tls stack error number: 0x%x", event->error_handle->esp_tls_stack_err);
|
||||||
|
ESP_LOGE("mqtt", "Last captured errno : %d (%s)", event->error_handle->esp_transport_sock_errno,
|
||||||
|
strerror(event->error_handle->esp_transport_sock_errno));
|
||||||
|
} else if (event->error_handle->error_type == MQTT_ERROR_TYPE_CONNECTION_REFUSED) {
|
||||||
|
ESP_LOGE("mqtt", "Connection refused error: 0x%x", event->error_handle->connect_return_code);
|
||||||
|
} else {
|
||||||
|
ESP_LOGW("mqtt", "Unknown error type: 0x%x", event->error_handle->error_type);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ESP_LOGI("mqtt", "Other event id:%d", event->event_id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
23
main/mqtt_event_handler.h
Normal file
23
main/mqtt_event_handler.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <esp_event.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @brief Event handler registered to receive MQTT events
|
||||||
|
*
|
||||||
|
* This function is called by the MQTT client event loop.
|
||||||
|
*
|
||||||
|
* @param handler_args user data registered to the event.
|
||||||
|
* @param base Event base for the handler(always MQTT Base in this example).
|
||||||
|
* @param event_id The id for the received event.
|
||||||
|
* @param event_data The data for the event, esp_mqtt_event_handle_t.
|
||||||
|
*/
|
||||||
|
void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
28
main/net_event_handler.c
Normal file
28
main/net_event_handler.c
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#include <esp_wifi.h>
|
||||||
|
#include <esp_event.h>
|
||||||
|
#include <esp_log.h>
|
||||||
|
#include <led_strip.h>
|
||||||
|
#include "net_event_handler.h"
|
||||||
|
|
||||||
|
|
||||||
|
extern led_strip_handle_t debug_led;
|
||||||
|
|
||||||
|
void network_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) {
|
||||||
|
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
|
||||||
|
ESP_ERROR_CHECK(led_strip_set_pixel(debug_led, 0, 0xFF, 0xFF, 0));
|
||||||
|
ESP_ERROR_CHECK(led_strip_refresh(debug_led));
|
||||||
|
esp_wifi_connect();
|
||||||
|
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
|
||||||
|
ESP_ERROR_CHECK(led_strip_set_pixel(debug_led, 0, 0xFF, 0xFF, 0));
|
||||||
|
ESP_ERROR_CHECK(led_strip_refresh(debug_led));
|
||||||
|
esp_wifi_connect();
|
||||||
|
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
||||||
|
ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data;
|
||||||
|
ESP_LOGI("network", "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
|
||||||
|
ESP_ERROR_CHECK(led_strip_set_pixel(debug_led, 0, 0, 0xFF, 0));
|
||||||
|
ESP_ERROR_CHECK(led_strip_refresh(debug_led));
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
|
ESP_ERROR_CHECK(led_strip_set_pixel(debug_led, 0, 0, 0, 0));
|
||||||
|
ESP_ERROR_CHECK(led_strip_refresh(debug_led));
|
||||||
|
}
|
||||||
|
}
|
14
main/net_event_handler.h
Normal file
14
main/net_event_handler.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <esp_event.h>
|
||||||
|
#include <led_strip.h>
|
||||||
|
|
||||||
|
void network_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user