Hi
I need some help to convert this code so it can handle two or more slaves on the Kamstrup Modbus network.
Status on the code/projekt:
- Layout, see attached image.
- Code "master _v91" can read and print, on LCD, from SDM 1 and 2. It can also at te same time read and print value one and two from slave 3 om the Kamstrup network.
Code in the Modbus Master _v91.
#include <SPI.h>
#include <Wire.h>
#include <SoftwareSerial.h>
#include <SDM630KAM382.h>
#include <LiquidCrystal_I2C.h>
#include <ModbusRtu.h>
SoftwareSerial swSerSDM(6, 7);
SDM sdm(swSerSDM, 9600, 5);
#define TXEN 4
// data array for modbus network sharing
uint16_t au16data[16];
uint8_t u8state;
volatile unsigned long counter = 0;
volatile unsigned long lastImpulse = 0;
volatile unsigned long diffImpulse = 0;
float currentWatt = 0;
float LcdcurrentWatt = 0;
float RD_S_ID3_VAL1_1 = 0;
volatile unsigned long counter2 = 0;
volatile unsigned long lastImpulse2 = 0;
volatile unsigned long diffImpulse2 = 0;
float currentWatt2 = 0;
float LcdcurrentWatt2 = 0;
float RD_S_ID3_VAL2_1 = 0;
LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
Modbus master(0,0,TXEN);
modbus_t telegram;
unsigned long u32wait;
void setup() {
sdm.begin();
master.begin( 19200 );
master.setTimeOut( 2000 );
u32wait = millis() + 1000;
u8state = 0;
lcd.begin(20,4);
lcd.setCursor(6,0);
lcd.print("Home");
lcd.setCursor(4,1);
lcd.print("Power");
lcd.setCursor(2,2);
lcd.print("BY: Mr.Y");
lcd.setCursor(0,3);
lcd.print("--------------------");
delay(5000);
lcd.clear();
}
void loop() {
switch( u8state ) {
case 0:
if (millis() > u32wait) u8state++; // wait state
break;
case 1:
telegram.u8id = 3; // slave address
telegram.u8fct = 4; // function code
telegram.u16RegAdd = 1; // start address in slave
telegram.u16CoilsNo = 2; // number of elements (coils or registers) to read
telegram.au16reg = au16data; // pointer to a memory array in the Arduino
RD_S_ID3_VAL1_1 = au16data[0];
RD_S_ID3_VAL2_1 = au16data[1];
master.query( telegram ); // send query (only once)
u8state++;
break;
case 2:
master.poll(); // check incoming messages
if (master.getState() == COM_IDLE) {
u8state = 0;
u32wait = millis() + 100;
}
break;
}
lcd.setCursor(0,0);
lcd.print("KamEL-1(W):");
lcd.setCursor(11,0);
lcd.print(RD_S_ID3_VAL1_1);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("KamEL-2(W):");
lcd.setCursor(11,1);
lcd.print(RD_S_ID3_VAL2_1);
lcd.print(" ");
lcd.setCursor(0,2);
lcd.print ("SDM-ID1(W):");
lcd.setCursor(11,2);
lcd.print(sdm.readVal(SDM630_POWERTOTAL, 0x01), 2);
lcd.print(" ");
lcd.setCursor(0,3);
lcd.print ("SDM-ID2(W):");
lcd.setCursor(11,3);
lcd.print(sdm.readVal(SDM630_POWERTOTAL, 0x02), 2);
lcd.print(" ");
}
I have tried my self but no luck. Here is my contribution.
#include <SPI.h>
#include <Wire.h>
#include <SoftwareSerial.h>
#include <SDM630KAM382.h>
#include <LiquidCrystal_I2C.h>
#include <ModbusRtu.h>
SoftwareSerial swSerSDM(6, 7);
SDM sdm(swSerSDM, 9600, 5);
#define TXEN 4
// data array for modbus network sharing
uint16_t au16data[4];
uint16_t au16data2[4];
uint8_t u8state;
uint8_t u8query;
volatile unsigned long counter = 0;
volatile unsigned long lastImpulse = 0;
volatile unsigned long diffImpulse = 0;
float currentWatt = 0;
float LcdcurrentWatt = 0;
float RD_S_ID3_VAL1_1 = 0;
float RD_S_ID4_VAL1_1 = 0;
volatile unsigned long counter2 = 0;
volatile unsigned long lastImpulse2 = 0;
volatile unsigned long diffImpulse2 = 0;
float currentWatt2 = 0;
float LcdcurrentWatt2 = 0;
float RD_S_ID3_VAL2_1 = 0;
float RD_S_ID4_VAL2_1 = 0;
LiquidCrystal_I2C lcd(0x3f, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
Modbus master(0,0,TXEN);
modbus_t telegram[2];
unsigned long u32wait;
void setup() {
sdm.begin();
master.begin( 19200 );
master.setTimeOut( 5000 );
u32wait = millis() + 1000;
// u8state = 0;
u8state = u8query = 0;
lcd.begin(20,4);
lcd.setCursor(6,0);
lcd.print("Rekasta 8");
lcd.setCursor(4,1);
lcd.print("Energikollen");
lcd.setCursor(2,2);
lcd.print("Stefan Eriksson");
lcd.setCursor(0,3);
lcd.print("--------------------");
delay(5000);
lcd.clear();
telegram[0].u8id = 4; // slave address
telegram[0].u8fct = 4; // function code
telegram[0].u16RegAdd = 1; // start address in slave
telegram[0].u16CoilsNo = 2; // number of elements (coils or registers) to read
telegram[0].au16reg = au16data; // pointer to a memory array in the Arduino
telegram[1].u8id = 3; // slave address
telegram[1].u8fct = 4; // function code
telegram[1].u16RegAdd = 1; // start address in slave
telegram[1].u16CoilsNo = 2; // number of elements (coils or registers) to read
telegram[1].au16reg = au16data2; // pointer to a memory array in the Arduino
}
void loop() {
switch( u8state ) {
case 0:
if (millis() > u32wait) u8state++; // wait state
break;
case 1:
master.query( telegram[0] ); // send query (only once)
u8state++;
case 2:
if (millis() > u32wait) u8state++; // wait state
break;
case 3:
master.query( telegram[1] ); // send query (only once)
u8state++;
break;
case 4:
master.poll(); // check incoming messages
RD_S_ID3_VAL1_1 = au16data[1];
RD_S_ID3_VAL2_1 = au16data[0];
RD_S_ID4_VAL1_1 = au16data2[0];
RD_S_ID4_VAL2_1 = au16data2[1];
if (master.getState() == COM_IDLE) {
u8state = 0;
u32wait = millis() + 100;
}
break;
}
lcd.setCursor(0,0);
lcd.print("KamEL-1(W):");
lcd.setCursor(11,0);
lcd.print(RD_S_ID3_VAL2_1);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("KamEL-4(W):");
lcd.setCursor(11,1);
lcd.print(RD_S_ID4_VAL2_1);
lcd.print(" ");
lcd.setCursor(0,2);
lcd.print ("SDM-ID1(W):");
lcd.setCursor(11,2);
lcd.print(sdm.readVal(SDM630_POWERTOTAL, 0x01), 2);
lcd.print(" ");
lcd.setCursor(0,3);
lcd.print ("SDM-ID2(W):");
lcd.setCursor(11,3);
lcd.print(sdm.readVal(SDM630_POWERTOTAL, 0x02), 2);
lcd.print(" ");
}
Code for Modbus Slave 03 (_v6.1) and 04 (_v6.2).
See attached file.
Appreciate all suggestions for general improvements and the solution to my problem reading from several Modbus slaves, on the Kamstrup Modbus network.
// Vind89
SDM630KAM382.zip (3.87 KB)
Modbus-Master-Slave-for-Arduino-master.zip (200 KB)
Slave_KAM382v61.ino (2.53 KB)
Slave_KAM382v62.ino (2.72 KB)