27 #include <libopencm3/stm32/rcc.h> 28 #include <libopencm3/stm32/gpio.h> 29 #include <libopencm3/stm32/usart.h> 30 #include <libopencm3/stm32/timer.h> 31 #include <libopencm3/cm3/nvic.h> 32 #include <libopencmsis/core_cm3.h> 40 #define SENSOR_SDM120_USART 3 47 #define SENSOR_SDM120_REDE_PORT B 48 #define SENSOR_SDM120_REDE_PIN 12 55 #define SENSOR_SDM120_TIMER 3 113 uint16_t crc = 0xffff;
114 for (uint8_t i=0; i<size; i++) {
115 crc ^= (uint16_t)
buffer[i];
116 for (uint8_t b=0; b<8; b++) {
118 crc = (crc>>1)^0xA001;
130 rcc_periph_clock_enable(RCC_AFIO);
185 if (
function!=0x03 &&
function!=0x04 &&
function!=0x10) {
196 uint8_t packet_size = 0;
197 packet[0] = meter_id;
198 packet[1] =
function;
199 packet[2] = address>>8;
203 if (
function==0x03 ||
function==0x04) {
205 }
else if (
function==0x10) {
208 uint8_t* data = (uint8_t*)&
value;
212 packet[10] = data[0];
215 uint16_t crc =
crc_modbus(packet, packet_size);
216 for (uint8_t i=0; i<packet_size; i++) {
239 if (
type>=SENSOR_SDM120_MEASUREMENT_MAX) {
247 if (
type>=SENSOR_SDM120_CONFIGURATION_MAX) {
255 if (
type>=SENSOR_SDM120_CONFIGURATION_MAX) {
263 float measurement = NAN;
276 measurement = INFINITY;
283 uint8_t* convert = (uint8_t*)&measurement;
294 measurement = INFINITY;
#define TIM_ISR(x)
get interrupt service routine for timer base on TIM identifier
sensor_sdm120_configuration_type_t
configuration types for electricity meter in 4xxx holding registers
static volatile uint8_t tx_used
number of byte to transmit
#define RCC_GPIO(x)
get RCC for GPIO based on GPIO identifier
float sensor_sdm120_measurement_decode(void)
decode received measurement
static volatile uint8_t rx_used
number of received data bytes in buffer
void sensor_sdm120_setup(uint32_t baudrate)
setup peripherals to communicate with electricity meter
enum sensor_pzem_measurement_type_t type
measurement type
silent time before sending data
library to query measurements from eastron SDM120-ModBus electricity meter (API)
#define USART_ISR(x)
get interrupt service routine for USART based on USART identifier
#define NVIC_TIM_IRQ(x)
get NVIC IRQ for timer base on TIM identifier
volatile bool sensor_sdm120_measurement_received
a measurement response has been received
sensor_sdm120_measurement_type_t
measurement types offered by electricity meter in 3xxx input registers
silent time after sending data
global definitions and methods (API)
static const uint16_t register_input[]
SDM120 3xxxx input register start addresses for the measurement types.
#define GPIO(x)
get GPIO based on GPIO identifier
static uint16_t crc_modbus(uint8_t *buffer, uint8_t size)
compute CRC for ModBus
#define SENSOR_SDM120_TIMER
timer number to count time
bool sensor_sdm120_measurement_request(uint8_t meter_id, enum sensor_sdm120_measurement_type_t type)
request measurement from electricity meter
#define RCC_TIM(x)
get RCC for timer based on TIM identifier
bool sensor_sdm120_configuration_request(uint8_t meter_id, enum sensor_sdm120_configuration_type_t type)
request configuration from electricity meter
#define SENSOR_SDM120_USART
USART peripheral.
#define USART_IRQ(x)
get NVIC IRQ for USART based on USART identifier
time to wait between messages
#define USART(x)
get USART based on USART identifier
#define USART_PORT(x)
get port for USART based on USART identifier
#define USART_PORT_RCC(x)
get RCC for USART port based on USART identifier
timeout_t
the ModBus timeouts to respect for sending messages
static uint8_t * buffer
input/output buffer for read/write commands/functions
static uint16_t timeout_times[TIMEOUT_MAX]
current timeout used
static uint8_t rx_buffer[9]
buffer for received response (ModBus response messages can be 2+256+2 long but we will only read up t...
static bool sensor_sdm120_transmit_request(uint8_t meter_id, uint8_t function, uint16_t address, float value)
send request to electricity meter
static const uint16_t register_holding[]
SDM120 4xxxx holding register start addresses for the configuration types.
static uint8_t tx_buffer[13]
buffer for request to transmit (ModBus request messages can be 7+256+2 long but we will only write up...
last element (useful to no the number of elements)
#define SENSOR_SDM120_REDE_PORT
GPIO port for RS-485 receiver and driver output enable signal.
#define LENGTH(x)
get the length of an array
union sensor_pzem_measurement_t::measurement_t value
measurement value
#define USART_RCC(x)
get RCC for USART based on USART identifier
#define TIM(x)
get TIM based on TIM identifier
#define USART_PIN_RX(x)
get receive pin for USART based on USART identifier
#define USART_PIN_TX(x)
get transmit pin for USART based on USART identifier
bool sensor_sdm120_configuration_set(uint8_t meter_id, enum sensor_sdm120_configuration_type_t type, float value)
set configuration in electricity meter
#define SENSOR_SDM120_REDE_PIN
GPIO pin for RS-485 receiver and driver output enable signal.
static enum timeout_t timeout
the current timeout used