WIP write multiple registers
This commit is contained in:
parent
12cd3df5a3
commit
0bfc93d3ea
@ -107,6 +107,7 @@ typedef enum {
|
||||
typedef enum {
|
||||
MODBUS_EXCEPTION_ILLEGAL_FUNCTION = 1,
|
||||
MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS = 2,
|
||||
MODBUS_EXCEPTION_ILLEGAL_REGISTER_QUANTITY = 2,
|
||||
MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE = 3,
|
||||
MODBUS_EXCEPTION_SLAVE_DEVICE_FAILURE = 4,
|
||||
MODBUS_EXCEPTION_ACKNOWLEDGE = 5,
|
||||
|
@ -291,6 +291,10 @@ int main(void)
|
||||
/* TODO: Process data and light a desired color of LED */
|
||||
/* TODO: Add hystheresis */
|
||||
|
||||
/* Reset the TIM21 Elapsed Period Flag */
|
||||
tim21_elapsed_period = 0;
|
||||
}
|
||||
/* TEST END */
|
||||
if (sensor_config.led_on) {
|
||||
if (CO2 <= sensor_config.led_co2_alert_limit1) {
|
||||
/* CO2 is OK -> GREEN */
|
||||
@ -315,11 +319,6 @@ int main(void)
|
||||
LL_GPIO_SetOutputPin(LED_G_GPIO_Port, LED_G_Pin);
|
||||
LL_GPIO_SetOutputPin(LED_B_GPIO_Port, LED_B_Pin);
|
||||
}
|
||||
|
||||
/* Reset the TIM21 Elapsed Period Flag */
|
||||
tim21_elapsed_period = 0;
|
||||
}
|
||||
/* TEST END */
|
||||
/* USER CODE END WHILE */
|
||||
|
||||
/* USER CODE BEGIN 3 */
|
||||
|
@ -58,6 +58,7 @@ int8_t modbus_copy_reply_to_buffer(uint8_t *buffer, uint8_t *msg_len, modbus_tra
|
||||
uint16_t crc16;
|
||||
uint8_t byte_count;
|
||||
|
||||
// TODO use relative indices (increments) instead of absolute
|
||||
buffer[0] = modbus_slave_address;
|
||||
buffer[1] = transaction->function_code;
|
||||
*msg_len = 5;
|
||||
@ -86,6 +87,13 @@ int8_t modbus_copy_reply_to_buffer(uint8_t *buffer, uint8_t *msg_len, modbus_tra
|
||||
buffer[5] = (uint8_t) transaction->holding_registers[0];
|
||||
*msg_len = 8;
|
||||
break;
|
||||
case MODBUS_WRITE_MULTIPLE_REGISTERS:
|
||||
buffer[2] = (uint8_t) (transaction->register_address >> 8);
|
||||
buffer[3] = (uint8_t) transaction->register_address;
|
||||
buffer[4] = (uint8_t) (transaction->register_count >> 8);
|
||||
buffer[5] = (uint8_t) transaction->register_count;
|
||||
*msg_len = 8;
|
||||
|
||||
}
|
||||
}
|
||||
crc16 = modbus_CRC16(buffer, *msg_len - 2); /* last two bytes is the checksum itself */
|
||||
@ -109,11 +117,18 @@ int8_t modbus_slave_set_address(uint8_t address)
|
||||
|
||||
int8_t modbus_slave_process_msg(const uint8_t *buffer, int len)
|
||||
{
|
||||
/*
|
||||
* TODO list:
|
||||
*
|
||||
* 1) check that errors and exceptions are handled according to Modbus_Application_Protocol_V1_1b.pdf
|
||||
* 2) buffer overflow prevention: for each function code, check that buffer is long enough
|
||||
*/
|
||||
/* transaction holds message context and content:
|
||||
* it wraps all necessary buffers and variables */
|
||||
modbus_transaction_t transaction;
|
||||
int8_t callback_result;
|
||||
uint8_t buffer_pos = 0;
|
||||
uint8_t byte_count;
|
||||
|
||||
if (len < MODBUS_MINIMAL_FRAME_LEN) {
|
||||
/* frame too short; return error */
|
||||
@ -188,11 +203,22 @@ int8_t modbus_slave_process_msg(const uint8_t *buffer, int len)
|
||||
return MODBUS_ERROR;
|
||||
}
|
||||
transaction.register_address = (buffer[buffer_pos++] << 8) | buffer[buffer_pos++];
|
||||
// TODO check length!
|
||||
if (flags & MODBUS_FLAG_WRITE) {
|
||||
if (flags & MODBUS_FLAG_SINGLE) {
|
||||
transaction.holding_registers[0] = (buffer[buffer_pos++] << 8) | buffer[buffer_pos++];
|
||||
} else {
|
||||
// write multiple register - TODO
|
||||
/* Write multiple registers */
|
||||
transaction.register_count = (buffer[buffer_pos++] << 8) | buffer[buffer_pos++];
|
||||
byte_count = buffer[buffer_pos++];
|
||||
if (transaction.register_count > 123 || 2*transaction.register_count != byte_count) {
|
||||
/* Max number of register is defined by Modbus_Application_Protocol_V1_1b, section 6.12 */
|
||||
transaction.exception.exception_code = MODBUS_EXCEPTION_ILLEGAL_REGISTER_QUANTITY;
|
||||
} else {
|
||||
for (uint8_t i = 0; i < transaction.register_count; i++) {
|
||||
transaction.holding_registers[i] = (buffer[buffer_pos++] << 8) | buffer[buffer_pos++];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
transaction.register_count = (buffer[buffer_pos++] << 8) | buffer[buffer_pos++];
|
||||
|
41
tests/write_multiple_holding_registers_test.py
Executable file
41
tests/write_multiple_holding_registers_test.py
Executable file
@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env python3
|
||||
from time import sleep
|
||||
from sys import exit
|
||||
import minimalmodbus
|
||||
import serial
|
||||
|
||||
slave_address = 254
|
||||
instrument = minimalmodbus.Instrument('/dev/ttyUSB0', slave_address, close_port_after_each_call=True) # port name, slave address (in decimal)
|
||||
|
||||
instrument.serial.baudrate = 19200
|
||||
instrument.serial.bytesize = 8
|
||||
instrument.serial.parity = serial.PARITY_EVEN
|
||||
instrument.serial.stopbits = 1
|
||||
instrument.serial.timeout = 0.05 # seconds
|
||||
instrument.mode = minimalmodbus.MODE_RTU # rtu or ascii mode
|
||||
instrument.clear_buffers_before_each_transaction = True
|
||||
|
||||
# holding register numbers
|
||||
LED_on_register = 0
|
||||
LED_brightness_register = 1
|
||||
LED_smooth_register = 2
|
||||
CO2_alert_limit_1_register = 3
|
||||
CO2_alert_limit_2_register = 4
|
||||
SCD4x_temperature_offset_register = 5
|
||||
MODBUS_address_register = 6
|
||||
baudrate_register = 7
|
||||
# values
|
||||
LED_on = 1
|
||||
LED_brightness = 100
|
||||
LED_smooth = 0
|
||||
CO2_alert_limit_1 = 1000
|
||||
CO2_alert_limit_2 = 2000
|
||||
SCD4x_temperature_offset = 0
|
||||
MODBUS_address = 254
|
||||
baudrate = 0
|
||||
registers = [LED_on, LED_brightness, LED_smooth, CO2_alert_limit_1, CO2_alert_limit_2, SCD4x_temperature_offset, MODBUS_address, baudrate]
|
||||
# write to holding registers
|
||||
print('---- Writing to multiple holding registers ----')
|
||||
instrument.write_registers(LED_on_register, registers)
|
||||
print('---- DONE ----')
|
||||
exit(0)
|
Loading…
Reference in New Issue
Block a user