Hey,
I am trying to send int type data through MODBUS with arduino uno acting as the master and a slave MODBUS simulator on my PC. Communication is working but the data i am sending is not right. Even though the value of temp1, temp2, etc is correct, it is not being sent correctly. Any suggestions or advice would be really helpful
Below is the code
#include <ModbusRtu.h>
//#include <SimpleModbusMaster.h>
//#include <ModbusRTUMaster.h>
//#include<RS485.h>
//#include <ArduinoModbus.h>
//#include <ArduinoRS485.h>
#include <Timer.h>
#include <Event.h>
#include<ezButton.h>
//Pin definitions
#define PowerOnOffButtonPin 3
#define StatusLED1 4
#define StatusLED2 5
#define StatusLED3 6
#define StatusLED4 7
#define StatusLED5 8
#define T1 A0
#define T2 A1
#define T3 A2
#define T4 A3
#define T5 A4
#define T6 A5
#define T7 A6
#define T8 A7
// Definitions for temperature
#define T_REF 25.0
#define DEG_K 273.16
#define THERM_BETA 3435.0
#define c1 1.009249522e-03
#define c2 2.378405444e-04
#define c3 2.019202697e-07
#define SERIES_RESISTOR 21020
//different MODBUS libraries to use
#define MODBUS_1 1 // include ModbusRtu.h
#define MODBUS_2 0 // include SimpleModbusMaster.h
#define MODBUS_3 0 // include ModbusRTUMaster.h and RS485.h
#define MODBUS_4 0 //include ArduinoModbus.h and ArduinoRS485.h
#if MODBUS_1 || MODBUS_2 || MODBUS_3 || MODBUS_4
#define AUX_ADDRESS 0
#define BMS_ADDRESS 0x31
#define AUX_STATE_VARIABLES_REGISTER 0x31
#define AUX_SYSTEM_STATUS_REGISTER 0x032
#define AUX_DISCHARGE_ONOFF_REGISTER 0x33
#define AUX_TEMP_1_REGISTER 0x35
#define AUX_TEMP_2_REGISTER 0x37
#define AUX_TEMP_3_REGISTER 0x39
#define AUX_TEMP_4_REGISTER 0x3B
#define AUX_TEMP_5_REGISTER 0x3D
#define AUX_TEMP_6_REGISTER 0x3F
#define AUX_TEMP_7_REGISTER 0x41
#define AUX_TEMP_8_REGISTER 0x43
#define TOTAL_NO_OF_REGISTERS 11
#define RS485_TX_EN_PIN 2
#define baud 19200
#endif
#if MODBUS_2
#define timeout 1000
#define polling 200 // the scan rate
#define retry_count 10
enum
{
PACKET1,
PACKET2,
TOTAL_NO_OF_PACKETS
};
Packet packets[TOTAL_NO_OF_PACKETS];
//Master register array
unsigned int regs[TOTAL_NO_OF_REGISTERS];
#endif
#if MODBUS_3
ModbusRTUMaster master(RS485);
#endif
const int shortPressTime = 800; //max time considered for a short press
const int longPressTime = 3000; //min time considered for a long press
int buttonLastState = LOW;
int buttonCurrentState;
unsigned long pressedTime = 0;
unsigned long releasedTime = 0;
float soc;
float temp1,temp2,temp3,temp4,temp5,temp6,temp7,temp8;
float V1,V2,V3,V4,V5,V6,V7,V8;
int R1,R2,R3,R4,R5,R6,R7,R8;
int tempSensorValue1,tempSensorValue2,tempSensorValue3,tempSensorValue4,tempSensorValue5,tempSensorValue6,tempSensorValue7,tempSensorValue8;
//float c1 = 1.009249522e-03, c2 = 2.378405444e-04, c3 = 2.019202697e-07;
bool isCharging = false; // is true if pack is charging(Ich > 0 )
bool dischargeMosfetStatus = false; // is true if discharge MOSFET is ON
ezButton powerOnOffSwitch(PowerOnOffButtonPin);
Timer secondsTimer;
#if MODBUS_1
Modbus master(AUX_ADDRESS, Serial, RS485_TX_EN_PIN);
//uint16_t modbusData[16];
uint16_t state[TOTAL_NO_OF_REGISTERS] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B};
uint8_t u8state;
uint8_t u8query;
modbus_t telegram[TOTAL_NO_OF_REGISTERS];
unsigned long u32wait;
#endif
#if MODBUS_4
uint16_t state[TOTAL_NO_OF_REGISTERS] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B};
#endif
/****************************** Function Declarations ***********************/
void interruptRoutine();
void showSoC();
void showChargingStatus();
void calculateTemperatures();
void serialFlush();
void modbus_setup();
void modbusLoop();
/****************************** Main Function Definitions ***********************/
void setup() {
Serial.begin(baud);
pinMode(StatusLED1,OUTPUT);
pinMode(StatusLED2,OUTPUT);
pinMode(StatusLED3,OUTPUT);
pinMode(StatusLED4,OUTPUT);
pinMode(StatusLED5,OUTPUT);
pinMode(PowerOnOffButtonPin, INPUT_PULLUP);
powerOnOffSwitch.setDebounceTime(50);
//attachInterrupt(digitalPinToInterrupt(PowerOnOffButtonPin),interruptRoutine,FALLING);
modbus_setup();
}
void loop() {
//modbusLoop();
//modbus_update();
powerOnOffSwitch.loop();
secondsTimer.update();
//buttonCurrentState = digitalRead(PowerOnOffButtonPin);
if(!isCharging)
{
if(powerOnOffSwitch.isPressed()) // button is pressed
{
pressedTime = millis();
}
else if(powerOnOffSwitch.isReleased()) // button is released
{
releasedTime = millis();
long pressDuration = releasedTime - pressedTime;
if( pressDuration < shortPressTime )
{
soc = 88.43;
showSoC();
delay(100);
Serial.println("A short press is detected");
}
if( pressDuration > longPressTime )
{
Serial.println("A long press is detected");
state[AUX_DISCHARGE_ONOFF_REGISTER] = true;
if(dischargeMosfetStatus)
{
//Serial.println("A long press is detected");
secondsTimer.oscillate(StatusLED5,1000, LOW, 3);
secondsTimer.oscillate(StatusLED1,1000, LOW, 3);
delay(100);
}
}
}
}
modbusLoop();
//analog read for thermistor temperature readings
tempSensorValue1 = analogRead(T1);
tempSensorValue2 = analogRead(T2);
tempSensorValue3 = analogRead(T3);
tempSensorValue4 = analogRead(T4);
tempSensorValue5 = analogRead(T5);
tempSensorValue6 = analogRead(T6);
tempSensorValue7 = analogRead(T7);
tempSensorValue8 = analogRead(T8);
calculateTemperatures();
//Serial.print("Temp4 :");
//Serial.println(temp4);
delay(150);
//modbusData[4] = (int)temp4;
// #if MODBUS_1
// state[AUX_TEMP_1_REGISTER] = (int)temp1;
// state[AUX_TEMP_2_REGISTER] = (int)temp2;
// state[AUX_TEMP_3_REGISTER] = (int)temp3;
// state[AUX_TEMP_4_REGISTER] = (int)temp4;
// state[AUX_TEMP_5_REGISTER] = (int)temp5;
// state[AUX_TEMP_6_REGISTER] = (int)temp6;
// state[AUX_TEMP_7_REGISTER] = (int)temp7;
// state[AUX_TEMP_8_REGISTER] = (int)temp8;
// #endif
//Serial.println(state[AUX_TEMP_4_REGISTER]);
delay(50);
//Serial.println(state[AUX_TEMP_3TO4_REGISTER]);
if(isCharging)
{
soc = 72;
showChargingStatus();
}
//buttonLastState = buttonCurrentState;
serialFlush();
}
void interruptRoutine()
{
}
void showSoC()
{
if(soc >= 90.0)
{
digitalWrite(StatusLED5,HIGH);
digitalWrite(StatusLED4,HIGH);
digitalWrite(StatusLED3,HIGH);
digitalWrite(StatusLED2,HIGH);
digitalWrite(StatusLED1,HIGH);
}
else if(soc < 90.0 && soc >= 70.0)
{
digitalWrite(StatusLED5,LOW);
digitalWrite(StatusLED4,HIGH);
digitalWrite(StatusLED3,HIGH);
digitalWrite(StatusLED2,HIGH);
digitalWrite(StatusLED1,HIGH);
}
else if(soc< 70.0 && soc >= 50.0)
{
digitalWrite(StatusLED5,LOW);
digitalWrite(StatusLED4,LOW);
digitalWrite(StatusLED3,HIGH);
digitalWrite(StatusLED2,HIGH);
digitalWrite(StatusLED1,HIGH);
}
else if(soc< 50.0 && soc >= 30.0)
{
digitalWrite(StatusLED5,LOW);
digitalWrite(StatusLED4,LOW);
digitalWrite(StatusLED3,LOW);
digitalWrite(StatusLED2,HIGH);
digitalWrite(StatusLED1,HIGH);
}
else if(soc < 30.0 && soc >= 10.0)
{
digitalWrite(StatusLED5,LOW);
digitalWrite(StatusLED4,LOW);
digitalWrite(StatusLED3,LOW);
digitalWrite(StatusLED2,LOW);
digitalWrite(StatusLED1,HIGH);
}
else if(soc < 10.0)
{
digitalWrite(StatusLED5,LOW);
digitalWrite(StatusLED4,LOW);
digitalWrite(StatusLED3,LOW);
digitalWrite(StatusLED2,LOW);
digitalWrite(StatusLED1,LOW);
}
delay(1000);
digitalWrite(StatusLED5,LOW);
digitalWrite(StatusLED4,LOW);
digitalWrite(StatusLED3,LOW);
digitalWrite(StatusLED2,LOW);
digitalWrite(StatusLED1,LOW);
}
void showChargingStatus()
{
if(isCharging)
{
if(soc>0.0 && soc <= 30.0)
{
digitalWrite(StatusLED1,HIGH);
delay(250);
digitalWrite(StatusLED1,LOW);
digitalWrite(StatusLED2,LOW);
digitalWrite(StatusLED3,LOW);
digitalWrite(StatusLED4,LOW);
digitalWrite(StatusLED5,LOW);
}
else if (soc > 30.0 && soc <= 50.0)
{
digitalWrite(StatusLED1,HIGH);
digitalWrite(StatusLED2,HIGH);
delay(250);
digitalWrite(StatusLED2,LOW);
digitalWrite(StatusLED3,LOW);
digitalWrite(StatusLED4,LOW);
digitalWrite(StatusLED5,LOW);
}
else if (soc > 50.0 && soc <= 70)
{
digitalWrite(StatusLED1,HIGH);
digitalWrite(StatusLED2,HIGH);
digitalWrite(StatusLED3,HIGH);
delay(250);
digitalWrite(StatusLED3,LOW);
digitalWrite(StatusLED4,LOW);
digitalWrite(StatusLED5,LOW);
}
else if(soc > 70.0 && soc <= 90.0)
{
digitalWrite(StatusLED1,HIGH);
digitalWrite(StatusLED2,HIGH);
digitalWrite(StatusLED3,HIGH);
digitalWrite(StatusLED4,HIGH);
delay(250);
digitalWrite(StatusLED4,LOW);
digitalWrite(StatusLED5,LOW);
}
else if( soc > 90.0 && soc < 100.0)
{
digitalWrite(StatusLED1,HIGH);
digitalWrite(StatusLED2,HIGH);
digitalWrite(StatusLED3,HIGH);
digitalWrite(StatusLED4,HIGH);
digitalWrite(StatusLED5,HIGH);
delay(250);
digitalWrite(StatusLED5,LOW);
}
else if (soc == 100.0)
{
digitalWrite(StatusLED1,HIGH);
digitalWrite(StatusLED2,HIGH);
digitalWrite(StatusLED3,HIGH);
digitalWrite(StatusLED4,HIGH);
digitalWrite(StatusLED5,HIGH);
}
}
}
void calculateTemperatures()
{
R1 = SERIES_RESISTOR *(1024.0 / float(tempSensorValue1) - 1.0);
R2 = SERIES_RESISTOR *(1024.0 / float(tempSensorValue2) - 1.0);
R3 = SERIES_RESISTOR *(1024.0 / float(tempSensorValue3) - 1.0);
R4 = SERIES_RESISTOR *(1024.0 / float(tempSensorValue4) - 1.0);
R5 = SERIES_RESISTOR *(1024.0 / float(tempSensorValue5) - 1.0);
R6 = SERIES_RESISTOR *(1024.0 / float(tempSensorValue6) - 1.0);
R7 = SERIES_RESISTOR *(1024.0 / float(tempSensorValue7) - 1.0);
R8 = SERIES_RESISTOR *(1024.0 / float(tempSensorValue8) - 1.0);
temp1 = (1.0 / (c1 + c2*log(R1) + c3*log(R1)*log(R1)*log(R1))) - DEG_K;
temp2 = (1.0 / (c1 + c2*log(R2) + c3*log(R2)*log(R2)*log(R2))) - DEG_K;
temp3 = (1.0 / (c1 + c2*log(R3) + c3*log(R3)*log(R3)*log(R3))) - DEG_K;
temp4 = (1.0 / (c1 + c2*log(R4) + c3*log(R4)*log(R4)*log(R4))) - DEG_K;
temp5 = (1.0 / (c1 + c2*log(R5) + c3*log(R5)*log(R5)*log(R5))) - DEG_K;
temp6 = (1.0 / (c1 + c2*log(R6) + c3*log(R6)*log(R6)*log(R6))) - DEG_K;
temp7 = (1.0 / (c1 + c2*log(R7) + c3*log(R7)*log(R7)*log(R7))) - DEG_K;
temp8 = (1.0 / (c1 + c2*log(R8) + c3*log(R8)*log(R8)*log(R8))) - DEG_K;
}
void serialFlush()
{
while(Serial.available()>0)
char t = Serial.read();
}
void modbus_setup()
{
#if MODBUS_1
// state[AUX_STATE_VARIABLES_REGISTER] = 0;
// state[AUX_SYSTEM_STATUS_REGISTER] = 0;
// state[AUX_DISCHARGE_ONOFF_REGISTER] = 0;
// state[AUX_TEMP_1TO2_REGISTER] = 0;
// state[AUX_TEMP_3TO4_REGISTER] = 0;
// state[AUX_TEMP_5TO6_REGISTER] = 0;
// state[AUX_TEMP_7TO8_REGISTER] = 0;
telegram[0].u8id = BMS_ADDRESS; // slave address
telegram[0].u8fct = 4; // function code (this one is registers read)
telegram[0].u16RegAdd = 0; // start address in slave
telegram[0].u16CoilsNo = 4; // number of elements (coils or registers) to read
telegram[0].au16reg = state[AUX_STATE_VARIABLES_REGISTER]; // pointer to a memory array in the Arduino
telegram[1].u8id = BMS_ADDRESS; // slave address
telegram[1].u8fct = 4; // function code (this one is registers read)
telegram[1].u16RegAdd = 0; // start address in slave
telegram[1].u16CoilsNo = 4; // number of elements (coils or registers) to read
telegram[1].au16reg = state[AUX_SYSTEM_STATUS_REGISTER]; // pointer to a memory array in the Arduino
telegram[2].u8id = BMS_ADDRESS; // slave address
telegram[2].u8fct = 6; // function code (this one is registers read)
telegram[2].u16RegAdd = 0; // start address in slave
telegram[2].u16CoilsNo = 1; // number of elements (coils or registers) to read
telegram[2].au16reg = state[AUX_DISCHARGE_ONOFF_REGISTER]; // pointer to a memory array in the Arduino
telegram[3].u8id = BMS_ADDRESS; // slave address
telegram[3].u8fct = 6; // function code (this one is single coil write)
telegram[3].u16RegAdd = 1; // start address in slave
telegram[3].u16CoilsNo = 1; // number of elements (coils or registers) to write
telegram[3].au16reg = state[AUX_TEMP_1_REGISTER]; // pointer to a memory array in the Arduino
telegram[4].u8id = BMS_ADDRESS; // slave address
telegram[4].u8fct = 6; // function code (this one is single coil write)
telegram[4].u16RegAdd = 2; // start address in slave
telegram[4].u16CoilsNo = 1; // number of elements (coils or registers) to write
telegram[4].au16reg = state[AUX_TEMP_2_REGISTER]; // pointer to a memory array in the Arduino
telegram[5].u8id = BMS_ADDRESS; // slave address
telegram[5].u8fct = 6; // function code (this one is single coil write)
telegram[5].u16RegAdd = 3; // start address in slave
telegram[5].u16CoilsNo = 1; // number of elements (coils or registers) to write
telegram[5].au16reg = state[AUX_TEMP_3_REGISTER]; // pointer to a memory array in the Arduino
telegram[6].u8id = BMS_ADDRESS; // slave address
telegram[6].u8fct = 6; // function code (this one is single coil write)
telegram[6].u16RegAdd = 4; // start address in slave
telegram[6].u16CoilsNo = 1; // number of elements (coils or registers) to write
telegram[6].au16reg = state[AUX_TEMP_4_REGISTER]; // pointer to a memory array in the Arduino
telegram[7].u8id = BMS_ADDRESS; // slave address
telegram[7].u8fct = 6; // function code (this one is single coil write)
telegram[7].u16RegAdd = 5; // start address in slave
telegram[7].u16CoilsNo = 1; // number of elements (coils or registers) to write
telegram[7].au16reg = state[AUX_TEMP_5_REGISTER]; // pointer to a memory array in the Arduino
telegram[8].u8id = BMS_ADDRESS; // slave address
telegram[8].u8fct = 6; // function code (this one is single coil write)
telegram[8].u16RegAdd = 6; // start address in slave
telegram[8].u16CoilsNo = 1; // number of elements (coils or registers) to write
telegram[8].au16reg = state[AUX_TEMP_6_REGISTER]; // pointer to a memory array in the Arduino
telegram[9].u8id = BMS_ADDRESS; // slave address
telegram[9].u8fct = 6; // function code (this one is registers read)
telegram[9].u16RegAdd = 7; // start address in slave
telegram[9].u16CoilsNo = 1; // number of elements (coils or registers) to write
telegram[9].au16reg = state[AUX_TEMP_7_REGISTER]; // pointer to a memory array in the Arduino
// telegram 10: write a single coil
telegram[10].u8id = BMS_ADDRESS; // slave address
telegram[10].u8fct = 6; // function code (this one is write a single register)
telegram[10].u16RegAdd = 8; // start address in slave
telegram[10].u16CoilsNo = 1; // number of elements (coils or registers) to write
telegram[10].au16reg = state[AUX_TEMP_8_REGISTER]; // pointer to a memory array in the Arduino
master.start();
master.setTimeOut( 5000 ); // if there is no answer in 5000 ms, roll over
u32wait = millis() + 1000;
u8state = u8query = 0;
#endif
#if MODBUS_2
// Initialize each packet: packet, slave-id, function, start of slave index, number of regs, start of master index
modbus_construct(&packets[PACKET1], BMS_ADDRESS, READ_HOLDING_REGISTERS, 0,TOTAL_NO_OF_REGISTERS, 0);
modbus_construct(&packets[PACKET2], BMS_ADDRESS, PRESET_MULTIPLE_REGISTERS, 1, TOTAL_NO_OF_REGISTERS, 0);
modbus_configure(&Serial, baud, SERIAL_8N1, timeout, polling, retry_count,RS485_TX_EN_PIN, packets, TOTAL_NO_OF_PACKETS, regs);
#endif
#if MODBUS_4
pinMode(RS485_TX_EN_PIN, OUTPUT);
ModbusRTUServer.begin(BMS_ADDRESS, baud);
ModbusRTUServer.configureHoldingRegisters(0x61, TOTAL_NO_OF_REGISTERS);
ModbusRTUServer.configureInputRegisters(0x61, TOTAL_NO_OF_REGISTERS);
#endif
}
void modbusLoop()
{
#if MODBUS_2
modbus_update();
#endif
#if MODBUS_1
switch( u8state ) {
case 0:
if (millis() > u32wait) u8state++; // wait state
break;
case 1:
master.query( telegram[u8query] ); // send query (only once)
u8state++;
u8query++;
if (u8query > TOTAL_NO_OF_REGISTERS) u8query = 0;
break;
case 2:
//Serial.println(state[AUX_TEMP_4_REGISTER]);
master.poll(); // check incoming messages
if (master.getState() == COM_IDLE) {
u8state = 0;
u32wait = millis() + 1000;
}
break;
state[AUX_TEMP_1_REGISTER] = (int)temp1;
state[AUX_TEMP_2_REGISTER] = (int)temp2;
state[AUX_TEMP_3_REGISTER] = (int)temp3;
state[AUX_TEMP_4_REGISTER] = (int)temp4;
state[AUX_TEMP_5_REGISTER] = (int)temp5;
state[AUX_TEMP_6_REGISTER] = (int)temp6;
state[AUX_TEMP_7_REGISTER] = (int)temp7;
state[AUX_TEMP_8_REGISTER] = (int)temp8;
}
#endif
#if MODBUS_4
ModbusRTUServer.poll();
state[AUX_TEMP_1_REGISTER] = (int)temp1;
state[AUX_TEMP_2_REGISTER] = (int)temp2;
state[AUX_TEMP_3_REGISTER] = (int)temp3;
state[AUX_TEMP_4_REGISTER] = (int)temp4;
state[AUX_TEMP_5_REGISTER] = (int)temp5;
state[AUX_TEMP_6_REGISTER] = (int)temp6;
state[AUX_TEMP_7_REGISTER] = (int)temp7;
state[AUX_TEMP_8_REGISTER] = (int)temp8;
digitalWrite(RS485_TX_EN_PIN, HIGH);
delay(10);
ModbusRTUServer.holdingRegisterWrite(0x01, state[AUX_TEMP_1_REGISTER]);
ModbusRTUServer.holdingRegisterWrite(0x02, state[AUX_TEMP_2_REGISTER]);
ModbusRTUServer.holdingRegisterWrite(0x03, state[AUX_TEMP_3_REGISTER]);
ModbusRTUServer.holdingRegisterWrite(0x04, state[AUX_TEMP_4_REGISTER]);
ModbusRTUServer.holdingRegisterWrite(0x05, state[AUX_TEMP_5_REGISTER]);
ModbusRTUServer.holdingRegisterWrite(0x06, state[AUX_TEMP_6_REGISTER]);
ModbusRTUServer.holdingRegisterWrite(0x07, state[AUX_TEMP_7_REGISTER]);
ModbusRTUServer.holdingRegisterWrite(0x08, state[AUX_TEMP_8_REGISTER]);
for (int i = 0; i < TOTAL_NO_OF_REGISTERS; i++)
{
long holdingRegisterValue = ModbusRTUServer.holdingRegisterRead(i);
ModbusRTUServer.inputRegisterWrite(i, holdingRegisterValue);
}
#endif
}