I’ve a JMC iHSS86 servo stepper motor, how would I control it using the RS485 connection using the controllino. My connections are all correct but the motor shows no response. If someone could help me with an example code for running the motor it would be great. Get the manual of the motor here https://drive.google.com/file/d/1Ve7qNsAmmY-KWVpaJ64QSie0kB4v9OHZ/view?usp=drive_link
Wasted post.
Link needs registration to see the file.
Sorry, you may as well delete the post.
It looks like a stepper, you have to write the servo logic to integrate the encoder feedback.
Perhaps detail your connections here too.
The user manual / datasheet on the Sorotec website didn't mention RS485 from what I could see. There's information on an RS232 link - but that may be just for setting parameters.
I've updated the permission for the manual. The arduino connection is as follows, 5v,gnd, tx to pin 3 and rx to pin 4 and en to pin 5. The connection to the motor is as per the above datasheet, A, B and gnd. I'm using the rs485 breakout board. This motor has rs485 as well as CAN bus communication.
the manual you share does not related to a JMC iHSS86 stepper motor from what I could find after a quick search
if the link I shared (check the documentation tab there) is the same servo as you have then read up its user manual!
hope that helps....
The manual I provided is the right one. Its a mix of every motors they manufacture you have to go to the page where that particular motor is there. There are example hex code programs in there but when i apply it to my program nothing happens. Thats why I'm here.
please post the code you're using.
#include <Controllino.h>
#include <ModbusMaster.h>
// Initialize ModbusMaster instance
ModbusMaster node;
void setup() {
// Start serial communication for debugging
Serial.begin(9600);
// Initialize RS485 communication
Serial2.begin(9600, SERIAL_8N1); // RS485 communication on Serial2
// Set DE and RE pins for RS485 on Controllino Maxi
pinMode(CONTROLLINO_RS485_nRE, OUTPUT);
pinMode(CONTROLLINO_RS485_DE, OUTPUT);
// Enable RS485 Receive
digitalWrite(CONTROLLINO_RS485_nRE, LOW);
// Enable RS485 Transmit
digitalWrite(CONTROLLINO_RS485_DE, HIGH);
// Initialize Modbus communication to slave ID 1
node.begin(1, Serial2);
// Enable the drive
uint8_t result = node.writeSingleRegister(0x6040, 0x000F);
if (result != node.ku8MBSuccess) {
Serial.print("Failed to enable drive. Error code: ");
Serial.println(result);
} else {
Serial.println("Drive enabled successfully.");
}
}
void loop() {
uint8_t result;
uint16_t data[6]; // Array to store the register data
// Read registers starting at address 0x6041 (Controlword)
result = node.readHoldingRegisters(0x6041, 6);
if (result == node.ku8MBSuccess) {
for (uint8_t i = 0; i < 6; i++) {
data[i] = node.getResponseBuffer(i);
Serial.print("Register ");
Serial.print(0x6041 + i);
Serial.print(": ");
Serial.println(data[i], HEX);
}
} else {
Serial.print("Failed to read registers. Error code: ");
Serial.println(result);
}
delay(2000); // Delay 2 seconds between reads
}
This code just keeps giving no connection
if you're using node
to communicate over the rs-485 interface, how does is know which pins to use?
rs-485 is half-duplex, the TX cannot be enabled when receiving data.
I'm using the node to target the right motor, this motor can be daisy chained to 32 motors from one board.
are the pin #s hardcoded? do you understand what i'm asking?
Yes the controllino ports are hard coded for rs485 communication
You have two libraries for one task. Hard coded pins on controllino and soft coded on modbusmaster. I don't know controllino at all, but using both together sounds confusing.
If its a normal arduino uno and a rs485 bearkout board how would you do it?
Just with that modbusmaster code, for example. Define direction control pins, define serial2 pins, remove controllino.
What arduino board you have? Do you have multiple serial ports??
Edit: Uno.
So you don't even have serial2.
You need to use softwareserial (or use a board with multiple serials).
You have to set also correct parameters to enable RS485 communication and select baudrate. If you go with softwareserial, select slow baudrate, 2400 bps for example.
I've done that also, but still there is no output from the motor. But i used 9600 baudrate. I used the hex code from the manual still the motor does not move. This motor can be daisy chained from a single controller, so is it necessary to include the motor id? NB: I dont have the code right now, its on my friend's laptop.
You mean modbus slave id? Yes, it has to be correct. It was 1 on your code above.
Set those parameters, fix your code to use softwareserial and post that and your wiring, good quality images for example.
Only way you may find help here.
#include <SoftwareSerial.h>
// Define the pin used to control the direction
const int directionPin = 2;
// Define the pins for SoftwareSerial
const int rxPin = 10; // Receive pin (connect to RO on RS485 breakout)
const int txPin = 11; // Transmit pin (connect to DI on RS485 breakout)
// Create a SoftwareSerial instance
SoftwareSerial RS485(rxPin, txPin); // RX, TX
const byte slaveID = 0x01; // Assuming the Slave ID is 1
unsigned int calculateCRC(byte *array, int length) {
unsigned int crc = 0xFFFF;
for (int pos = 0; pos < length; pos++) {
crc ^= (unsigned int)array[pos]; // XOR byte into least sig. byte of crc
for (int i = 8; i != 0; i--) { // Loop over each bit
if ((crc & 0x0001) != 0) { // If the LSB is set
crc >>= 1; // Shift right and XOR 0xA001
crc ^= 0xA001;
}
else // Else just shift right
crc >>= 1;
}
}
return crc;
}
void appendCRC(byte *array, int length) {
unsigned int crc = calculateCRC(array, length);
array[length] = crc & 0xFF; // Lower byte
array[length + 1] = (crc >> 8) & 0xFF; // Higher byte
}
void setup() {
// Start the serial communication for debugging
Serial.begin(9600);
// Start the SoftwareSerial communication at the desired baud rate
RS485.begin(9600);
// Set the direction pin as output
pinMode(directionPin, OUTPUT);
}
void loop() {
// Prepare the Modbus-RTU request message
byte command[] = {
slaveID, // Slave ID (01)
0x10, // Function code (10 = Write Multiple Registers)
0x60, 0x40, // Starting Address (6040h)
0x00, 0x09, // Quantity of Registers (9 registers)
0x12, // Byte count (18 bytes)
// Data to write to the registers
0x00, 0x0F, // Controlword (6040h = 000F)
0x00, 0x01, // Modes of operation (6060h = 0001)
0x00, 0x00, 0x00, 0x64, // Profile velocity (6081h = 00000064)
0x00, 0x64, // Profile acceleration (6083h = 0064)
0x00, 0x64, // Profile deceleration (6084h = 0064)
0x00, 0x64, // Quick stop deceleration (6085h = 0064)
0x00, 0x03, 0x0D, 0x40, // Target position (607Ah = 00030D40)
0x00, 0x00 // CRC placeholders
};
// Calculate and append the correct CRC
appendCRC(command, sizeof(command) - 2);
// Enable transmission mode
digitalWrite(directionPin, HIGH);
// Send the command over RS485 using SoftwareSerial
RS485.write(command, sizeof(command));
// Wait for the transmission to complete
delay(10);
// Switch to receive mode
digitalWrite(directionPin, LOW);
// Wait for a response
delay(500);
// Example: Reading and printing the response if needed
if (RS485.available()) {
while (RS485.available()) {
byte response = RS485.read();
Serial.print(response, HEX);
Serial.print(" ");
}
Serial.println();
}
// Wait before sending the next command
delay(1000);
}
Im using an arduino uno and rs485 breakout board from sparkfun
This is the connection to the motor from the breakout board
rs485 board
arduino connection
Wiring looks matching your code. Are you powering rs-board 3.3V?
Did you set parameters for rs485 communication on your motor?? What baud rate?
What output you got on serial monitor with that code?
I've set every parameters according to the datasheet using the HISU (handheld intelligent setting unit) the baudrate is set to 9600 on the motor, there is no output from the motor as well as in the serial monitor