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. 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 <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
#if MODBUS_1 || MODBUS_2 || MODBUS_3
#define AUX_ADDRESS 0
#define BMS_ADDRESS 0x31
#define AUX_STATE_VARIABLES_REGISTER 0x01
#define AUX_SYSTEM_STATUS_REGISTER 0x02
#define AUX_DISCHARGE_ONOFF_REGISTER 0x03
#define AUX_TEMP_1_REGISTER 0x04
#define AUX_TEMP_2_REGISTER 0x05
#define AUX_TEMP_3_REGISTER 0x06
#define AUX_TEMP_4_REGISTER 0x07
#define AUX_TEMP_5_REGISTER 0x08
#define AUX_TEMP_6_REGISTER 0x09
#define AUX_TEMP_7_REGISTER 0x0A
#define AUX_TEMP_8_REGISTER 0x0B
#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
/****************************** 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
}
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;
}
#endif
}
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. Any suggestions or advice would be really helpful Below is the code