Hi all,
since a few days I got stuck with my project.
What I am trying to achieve is the following:
Setup:
Arduino Nano 33 IOT
Node-Red
MS-SQL Server
Idea is to read Accelerometer Values from the Arduino with Node-Red Modbus requests. Afterwards they should be stored in the database.
Where I am having trouble with, is the conversion of the values since modbus is working with integer registers.
Arduino Code:
#include <Arduino_LSM6DS3.h>
#include <SPI.h>
#include <WiFiNINA.h> //
#include <ArduinoRS485.h> // ArduinoModbus depends on the ArduinoRS485 library
#include <ArduinoModbus.h>
#include "arduino_secrets.h"
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0; // your network key Index number (needed only for WEP)
const int ledPin = LED_BUILTIN;
int status = WL_IDLE_STATUS;
WiFiServer wifiServer(502);
ModbusTCPServer modbusTCPServer;
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial);
Serial.println("Modbus TCP Server IMU Value");
if (!IMU.begin()) {
Serial.println("Failed to initialize IMU!");
while (1);
}
Serial.print("Accelerometer sample rate = ");
Serial.print(IMU.accelerationSampleRate());
Serial.println(" Hz");
Serial.println();
Serial.println("Acceleration in g's");
Serial.println("X\tY\tZ");
// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(5000);
}
// you're connected now, so print out the status:
printWifiStatus();
// start the server
wifiServer.begin();
// start the Modbus TCP server
if (!modbusTCPServer.begin()) {
Serial.println("Failed to start Modbus TCP Server!");
while (1);
}
// configure the LED
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
// configure a single coil at address 100
//modbusTCPServer.configureCoils(100, 1);
modbusTCPServer.configureHoldingRegisters(0x01, 1);
}
void loop() {
// listen for incoming clients
WiFiClient client = wifiServer.available();
if (client) {
// a new client connected
Serial.println("new client");
// let the Modbus TCP accept the connection
modbusTCPServer.accept(client);
while (client.connected()) {
// poll for Modbus TCP requests, while client connected
modbusTCPServer.poll();
// update the LED
readIMUvalue();
}
Serial.println("client disconnected");
}
}
void readIMUvalue() {
// read the current value of the coil
float x, y, z;
uint16_t IMUValue ;
if (IMU.accelerationAvailable()) {
IMU.readAcceleration(x, y, z);
IMUValue = z ;
Serial.println(IMUValue);
}
modbusTCPServer.holdingRegisterWrite(0x01,IMUValue);
}
void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your WiFi shield's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
My Approach:
So the Arduino reads the IMU value as float in g's (for example: 0.79g). In order to convert the values I use uint16_t to store it in another variable. This value "IMUValue" is then used to write to the holding registers.
At the other end I setup node-red as following
[
{
"id": "21d7c6feb6ed492d",
"type": "modbus-read",
"z": "4e100d14e53b3afc",
"name": "Nano 33 IoTp",
"topic": "Analog Input",
"showStatusActivities": false,
"logIOActivities": false,
"showErrors": false,
"unitid": "1",
"dataType": "HoldingRegister",
"adr": "1",
"quantity": "1",
"rate": "500",
"rateUnit": "ms",
"delayOnStart": false,
"startDelayTime": "",
"server": "d6e277a1fd05509b",
"useIOFile": false,
"ioFile": "",
"useIOForPayload": false,
"emptyMsgOnFail": false,
"x": 170,
"y": 80,
"wires": [
[
"b3ed451bdca4e088"
],
[]
]
},
{
"id": "f008fd4bb8646cd1",
"type": "debug",
"z": "4e100d14e53b3afc",
"name": "debug 4",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 700,
"y": 80,
"wires": []
},
{
"id": "b3ed451bdca4e088",
"type": "buffer-maker",
"z": "4e100d14e53b3afc",
"name": "",
"specification": "spec",
"specificationType": "ui",
"items": [
{
"name": "item1",
"type": "floatle",
"length": 1,
"dataType": "msg",
"data": "payload"
}
],
"swap1": "swap16",
"swap2": "",
"swap3": "",
"swap1Type": "swap",
"swap2Type": "swap",
"swap3Type": "swap",
"msgProperty": "payload",
"msgPropertyType": "str",
"x": 450,
"y": 80,
"wires": [
[
"f008fd4bb8646cd1"
]
]
},
{
"id": "d6e277a1fd05509b",
"type": "modbus-client",
"name": "Arduino",
"clienttype": "tcp",
"bufferCommands": true,
"stateLogEnabled": true,
"queueLogEnabled": true,
"failureLogEnabled": true,
"tcpHost": "192.168.0.194",
"tcpPort": "502",
"tcpType": "DEFAULT",
"serialPort": "/dev/ttyUSB",
"serialType": "RTU-BUFFERD",
"serialBaudrate": "115200",
"serialDatabits": "8",
"serialStopbits": "1",
"serialParity": "none",
"serialConnectionDelay": "100",
"serialAsciiResponseStartDelimiter": "0x3A",
"unit_id": "1",
"commandDelay": "1",
"clientTimeout": "1000",
"reconnectOnTimeout": true,
"reconnectTimeout": "2000",
"parallelUnitIdsAllowed": true
}
]
What I now got as buffer is:
But what I would need at the end would be the decimal values again.
Maybe somebody has any advice where I left missing pices.
Thank you in advance!
Greetz ardakus