|
13 | 13 | #include "mbed_mem_trace.h" |
14 | 14 | #endif |
15 | 15 |
|
| 16 | +#if USE_MODBUS_SENSOR_MD02 |
| 17 | +# include <ArduinoRS485.h> |
| 18 | +# include <ArduinoModbus.h> |
| 19 | +#endif |
| 20 | + |
| 21 | +/************************************************************************************** |
| 22 | + * CONSTANTS |
| 23 | + **************************************************************************************/ |
| 24 | + |
| 25 | +#if USE_MODBUS_SENSOR_MD02 |
| 26 | +static unsigned int const MODBUS_BAUDRATE = 9600; |
| 27 | +static float const MODBUS_BIT_DURATION = 1.f / MODBUS_BAUDRATE; |
| 28 | +static float const MODBUS_PRE_DELAY_BR = MODBUS_BIT_DURATION * 9.6f * 3.5f * 1e6; |
| 29 | +static float const MODBUS_POST_DELAY_BR = MODBUS_BIT_DURATION * 9.6f * 3.5f * 1e6; |
| 30 | + |
| 31 | +static int const MODBUS_DEVICE_ID = 1; |
| 32 | +static int const MODBUS_DEVICE_TEMPERATURE_REGISTER = 0x0001; |
| 33 | +static int const MODBUS_DEVICE_HUMIDITY_REGISTER = 0x0002; |
| 34 | +#endif |
| 35 | + |
16 | 36 | /************************************************************************************** |
17 | 37 | * GLUE CODE |
18 | 38 | **************************************************************************************/ |
@@ -77,6 +97,9 @@ O1HeapInstance * o1heap_ins = nullptr; |
77 | 97 | rtos::Thread opc_ua_server_thread(osPriorityNormal, OPC_UA_SERVER_THREAD_STACK.size(), OPC_UA_SERVER_THREAD_STACK.data()); |
78 | 98 |
|
79 | 99 | opcua::ArduinoOpta::SharedPtr arduino_opta_opcua; |
| 100 | +#if USE_MODBUS_SENSOR_MD02 |
| 101 | +UA_NodeId modbus_md02_temperature_node_id; |
| 102 | +#endif |
80 | 103 |
|
81 | 104 | /************************************************************************************** |
82 | 105 | * DEFINES |
@@ -186,6 +209,16 @@ void setup() |
186 | 209 | //for (; !Serial && (millis() - start) < 1000; ) { } |
187 | 210 | while (!Serial) { } |
188 | 211 |
|
| 212 | +#if USE_MODBUS_SENSOR_MD02 |
| 213 | + RS485.setDelays(MODBUS_PRE_DELAY_BR, MODBUS_POST_DELAY_BR); |
| 214 | + if (!ModbusRTUClient.begin(MODBUS_BAUDRATE, SERIAL_8N1)) |
| 215 | + { |
| 216 | + Serial.println("Failed to start Modbus RTU Client!"); |
| 217 | + for (;;) { } |
| 218 | + } |
| 219 | + ModbusRTUClient.setTimeout(2 * 1000UL); /* 2 seconds. */ |
| 220 | +#endif |
| 221 | + |
189 | 222 | /* Initialize Ethernet interface and print obtained IP to Serial. */ |
190 | 223 | if (!Ethernet.begin()) { |
191 | 224 | Serial.println("\"Ethernet.begin()\" failed."); |
@@ -266,6 +299,54 @@ void setup() |
266 | 299 | arduino_opta_opcua->led_mgr()->add_led_output(opc_ua_server, "User LED", [](bool const value) { pinMode(LEDB, OUTPUT); digitalWrite(LEDB, value); }); |
267 | 300 | } |
268 | 301 |
|
| 302 | +#if USE_MODBUS_SENSOR_MD02 |
| 303 | + { |
| 304 | + UA_StatusCode rc = UA_STATUSCODE_GOOD; |
| 305 | + UA_ObjectAttributes oAttr = UA_ObjectAttributes_default; |
| 306 | + oAttr.displayName = UA_LOCALIZEDTEXT("en-US", "Modbus RS485 MD02 Sensor"); |
| 307 | + UA_NodeId modbus_md02_node_id; |
| 308 | + rc = UA_Server_addObjectNode(opc_ua_server, |
| 309 | + UA_NODEID_NULL, |
| 310 | + arduino_opta_opcua->node_id(), |
| 311 | + UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), |
| 312 | + UA_QUALIFIEDNAME(1, "ModbusRs485Md02"), |
| 313 | + UA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE), |
| 314 | + oAttr, |
| 315 | + NULL, |
| 316 | + &modbus_md02_node_id); |
| 317 | + if (UA_StatusCode_isBad(rc)) { |
| 318 | + UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Modbus MD02 Sensor: UA_Server_addObjectNode(...) failed with %s", UA_StatusCode_name(rc)); |
| 319 | + return; |
| 320 | + } |
| 321 | + |
| 322 | + UA_VariableAttributes temperature_value_attr = UA_VariableAttributes_default; |
| 323 | + |
| 324 | + /* Obtain the current value of the input pin. */ |
| 325 | + UA_Float temperature_value = 0.f; |
| 326 | + UA_Variant_setScalar(&temperature_value_attr.value, &temperature_value, &UA_TYPES[UA_TYPES_FLOAT]); |
| 327 | + |
| 328 | + temperature_value_attr.displayName = UA_LOCALIZEDTEXT("en-US", "Temperature / °C"); |
| 329 | + temperature_value_attr.dataType = UA_TYPES[UA_TYPES_FLOAT].typeId; |
| 330 | + temperature_value_attr.accessLevel = UA_ACCESSLEVELMASK_READ; |
| 331 | + |
| 332 | + /* Add the variable node. */ |
| 333 | + rc = UA_Server_addVariableNode(opc_ua_server, |
| 334 | + UA_NODEID_NULL, |
| 335 | + modbus_md02_node_id, |
| 336 | + UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), |
| 337 | + UA_QUALIFIEDNAME(1, "md02_temperature_deg"), |
| 338 | + UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), |
| 339 | + temperature_value_attr, |
| 340 | + NULL, |
| 341 | + &modbus_md02_temperature_node_id); |
| 342 | + if (UA_StatusCode_isBad(rc)) |
| 343 | + { |
| 344 | + UA_LOG_ERROR(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "Modbus MD02 Sensor: UA_Server_addVariableNode(...) failed with %s", UA_StatusCode_name(rc)); |
| 345 | + return; |
| 346 | + } |
| 347 | + } |
| 348 | +#endif |
| 349 | + |
269 | 350 | /* Print some threading related message. */ |
270 | 351 | UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, |
271 | 352 | "stack: size = %d | free = %d | used = %d | max = %d", |
@@ -314,4 +395,24 @@ void loop() |
314 | 395 | { |
315 | 396 | digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); |
316 | 397 | delay(500); |
| 398 | + |
| 399 | +#if USE_MODBUS_SENSOR_MD02 |
| 400 | + if (!ModbusRTUClient.requestFrom(MODBUS_DEVICE_ID, INPUT_REGISTERS, MODBUS_DEVICE_TEMPERATURE_REGISTER, 1)) { |
| 401 | + Serial.print("failed to read temperature register! "); |
| 402 | + Serial.println(ModbusRTUClient.lastError()); |
| 403 | + return; |
| 404 | + } |
| 405 | + if (ModbusRTUClient.available()) |
| 406 | + { |
| 407 | + int16_t const temperature_raw = ModbusRTUClient.read(); |
| 408 | + float const temperature_deg = temperature_raw / 100.f; |
| 409 | + Serial.println(temperature_deg); |
| 410 | + |
| 411 | + UA_Float temperature_deg_opcua_value = temperature_deg; |
| 412 | + UA_Variant temperature_deg_opcua_variant; |
| 413 | + UA_Variant_init(&temperature_deg_opcua_variant); |
| 414 | + UA_Variant_setScalar(&temperature_deg_opcua_variant, &temperature_deg_opcua_value, &UA_TYPES[UA_TYPES_FLOAT]); |
| 415 | + UA_Server_writeValue(opc_ua_server, modbus_md02_temperature_node_id, temperature_deg_opcua_variant); |
| 416 | + } |
| 417 | +#endif |
317 | 418 | } |
0 commit comments