I want to send a data to stepper motor controller through Modbus. I am a complete beginner to the Modbus. I built a Modbus adapter based on the Max485 IC according to this website and using an Arduino UNO. The problem is that I don't know how to send the data. The data string is '01 06 00 43 00 01 B9 DE', where 01 is the device, 06 is the function, 00 43 is the command, and B9 DE is the checksum. This data string will configure one of the inputs of the stepper motor controller.
There is an example sketch on the above website. This is the code:
Do you think it would be possible to modify the sketch to send the above data string? For example, by a replacement of 'byte txData[100]' by the required data string?
The sketch, as I understand it, sends a byte of the data each 1 second, and switches to the "receive" mode automatically after each transmission through the interrupt routine.
I want to modify the sketch in such a way that it sends the data only once. Also, the data must be a 8-bit string that I wrote in my first message.
Your code really doesn't do any modbus communication and rs485 direction is left "one way". I'm on mobile at the moment, but you could have a look at some arduino modbus master libraries and other modbus topics on this forum.
Again, this is not my code. However, I think it should work. The RG pin of max485 is connected to Rx pin (pin 0), while DI pin is connected to the Tx pin(pin 1) of Arduino. Depending of the status of the pin 3 of Arduino, the mode of transmission could be chosen. In the loop() of the sketch, pin 3 is set to HIGH and the transmission starts. The byte of data is sent from Tx of Arduino through max485 to the slave. Immediately after that, pin 3 is set to LOW and the Arduino is switched to the receiving mode.
I modified the example sketch of ModbusMaster library and incorporated the functions to write a single register, as kmin suggested. here is the code:
//need to send the Modbus command "01 06 00 43 00 01 B9 DE"
#include <ModbusMaster.h>
#define MAX485_DE 3
#define MAX485_RE_NEG 2
// instantiate ModbusMaster object
ModbusMaster node;
uint16_t u16WriteAddress = 0x0043;
uint16_t u16WriteValue = 0x0001;
uint16_t u16WriteQty = 1;
void preTransmission()
{
digitalWrite(MAX485_RE_NEG, 1);
digitalWrite(MAX485_DE, 1);
}
void postTransmission()
{
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);
}
void setup()
{
pinMode(MAX485_RE_NEG, OUTPUT);
pinMode(MAX485_DE, OUTPUT);
// Init in receive mode
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);
// Modbus communication runs at 115200 baud
Serial.begin(115200);
// Modbus slave ID 1
node.begin(1, Serial);
// Callbacks allow us to configure the RS485 transceiver correctly
node.preTransmission(preTransmission); //since we are going to transmit
// node.postTransmission(postTransmission);
}
bool state = true;
void loop()
{
uint8_t result;
if (state == true) { //execute the function 'writeSingleRegister' only once
result = node.writeSingleRegister(u16WriteAddress, u16WriteValue);
state = !state;
}
}
Do you think this code will work? I am not sure that I understand the example sketch completely. What is the reason for toggling both the node.preTransmission(preTransmission) and the node.postTransmission(postTransmission) in the setup? I put the comment marks on node.postTransmission(postTransmission) because I am only going to transmit the data. Is it correct?
I GUESS you want to write that register ONCE and not over and over again.
So set the state to true if result was 0 (=OK)
if the result is != 0 it would be a good idea if you print the error code (in HEX) so you know what is happening on your modbus.
for debugging it would be easier if you could also use another Serial or a display to get some information from your program.
these function calls are to handover the callback function to the node object. They don't call preTransmission/postTransmission, it is just that the library knows later on what function to call before and after a transmission.
your schematic doesn't show that you have connected pin2.
Either correct your schematic or remove pin 2 relevant lines.