Does anybody know how to interface Grove RS 485 on arduino Mega
Can I use this PCB to send data to the motor driver via arduino similar as with MAX RS485
On Grove RS485 not existing DE and RE
Does anybody know how to interface Grove RS 485 on arduino Mega
Can I use this PCB to send data to the motor driver via arduino similar as with MAX RS485
On Grove RS485 not existing DE and RE
I've not used this particular board, but some RS485 modules that don't have /RE & DE have some sort of auto switching built in that switches the RS485 line driver from Rx to Tx and back again.
I had a quick look at the schematic for this one and I can't figure out how it switches into receive mode as it looks like both /RE and DE are pulled high all the time.
Looking at the connector on the left, you supply VCC & GND and your Tx + Rx serial data lines. If the code you have references RE & DE, then you could either comment that out or assign them to unused pins.
If I use standart example from library
/*
RS485_HalfDuplex.pde - example using ModbusMaster library to communicate
with EPSolar LS2024B controller using a half-duplex RS485 transceiver.
This example is tested against an EPSolar LS2024B solar charge controller.
See here for protocol specs:
http://www.solar-elektro.cz/data/dokumenty/1733_modbus_protocol.pdf
Library:: ModbusMaster
Author:: Marius Kintel <marius at kintel dot net>
Copyright:: 2009-2016 Doc Walker
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include <ModbusMaster.h>
/*!
We're using a MAX485-compatible RS485 Transceiver.
Rx/Tx is hooked up to the hardware serial port at 'Serial'.
The Data Enable and Receiver Enable pins are hooked up as follows:
*/
#define MAX485_DE 3
#define MAX485_RE_NEG 2
// instantiate ModbusMaster object
ModbusMaster node;
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);
node.postTransmission(postTransmission);
}
bool state = true;
void loop()
{
uint8_t result;
uint16_t data[6];
// Toggle the coil at address 0x0002 (Manual Load Control)
result = node.writeSingleCoil(0x0002, state);
state = !state;
// Read 16 registers starting at 0x3100)
result = node.readInputRegisters(0x3100, 16);
if (result == node.ku8MBSuccess)
{
Serial.print("Vbatt: ");
Serial.println(node.getResponseBuffer(0x04)/100.0f);
Serial.print("Vload: ");
Serial.println(node.getResponseBuffer(0xC0)/100.0f);
Serial.print("Pload: ");
Serial.println((node.getResponseBuffer(0x0D) +
node.getResponseBuffer(0x0E) << 16)/100.0f);
}
delay(1000);
}
What code can I expect ? )
Thanks
I have a similar module and they switch to TX driver when serial data is detected on the Arduino side. After TX transmission, it returns back to RX.
Great, can you share an example of code you have been used ?)
If your board is an auto switcher, then you can use any code unmodified, like you posted in #3. Just make sure that you aren't using the pins that are designated for RE & DE. If you are, then simply reassign to unused pins.
You don't need a special library for it
can you share some example ?
My existing project looks as it is
and Code
#include <ModbusMaster.h>
//RS485 //DI TX0 //DE pin3 //RE pin2//R0 RX0
//ENCODER
//RS485
#define MAX485_DE 3
#define MAX485_RE_NEG 2
// instantiate ModbusMaster object
ModbusMaster node;
void preTransmission() {digitalWrite(MAX485_RE_NEG, 1);digitalWrite(MAX485_DE, 1);}
void postTransmission() {digitalWrite(MAX485_RE_NEG, 0);digitalWrite(MAX485_DE, 0);}
uint8_t result,j;
uint16_t data[6];
//RS485
volatile unsigned int temp; //this variable will increase or decrease depending on the rotation of encoder
int counter = 0; // initial point of rotary encoder
int candleLenght = 1040; // Lenght -> signal for cutting candle
int RELAY1 = 8; // relay for something else
int x; // var for operate RELAY1 on/off
boolean runMotorOneTime = false; //for running motor once
unsigned long currentMillis;
//LED
const int ledPin40 = 40; //cut signal millis
const int ledPin41 = 41; //watchdog green
int ledState40 = HIGH; // ledState used to set the LED
int ledState41 = LOW; // ledState used to set the LED
long previousMillisWDOG = 0;
long watchDogInterval = 250;
long previousMillisCutLED = 250;
long CutLedInterval = 250;
int S1; //button status for candle L
int S2; //button status for candle L
int S3; //button status for candle L
void setup() {
//candle lenght buttons
pinMode(31, INPUT); //S1
pinMode(32, INPUT); //S2
pinMode(33, INPUT); //S3
//Encoder
pinMode(21, INPUT_PULLUP); // internal pullup input pin 21
pinMode(20, INPUT_PULLUP); // internal pullup input pin 20
//Setting up interrupt A rising pulse from encodenren activated ai0(). AttachInterrupt 2 is DigitalPin nr 20.
attachInterrupt(2, ai0, RISING); //0 & 1 taken by RS485
//B rising pulse from encodenren activated ai1(). AttachInterrupt 3 is DigitalPin nr 21.
attachInterrupt(3, ai1, RISING); //0 & 1 taken by RS485
//Encoder
//RS 485
pinMode(MAX485_RE_NEG, OUTPUT);
pinMode(MAX485_DE, OUTPUT);
// Init in receive mode
digitalWrite(MAX485_RE_NEG, 0);
digitalWrite(MAX485_DE, 0);
//RS 485
Serial.begin (9600);
Serial1.begin (38400);
Serial.println("Serail Ready");
pinMode(RELAY1, OUTPUT);
digitalWrite(RELAY1, HIGH); //RELAY 1 is OFF
// Modbus slave ID 1
node.begin(1, Serial1);
// Callbacks allow us to configure the RS485 transceiver correctly
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
writeMotorParams();
delay(1000);
readMotorParams();
// delay(500);
S1 = digitalRead(31);
S2 = digitalRead(32);
S3 = digitalRead(33);
}
void loop() {
currentMillis = millis();
runMotor();
//value of counter from encoder
// if( counter != temp ){
// //candleLenghtButton();
// temp = counter;
//
// //Serial.println (temp); //<-- if uncomment runMotor() not run at all, serial is buisy
// }
}
/*****************************************************************************
******* ANGLE ENCODER COLLECT DATA AND PASS FOR CUTTING SIGNAL *************
*****************************************************************************/
void ai0() {
if (digitalRead(21) == LOW) {
counter++;
//Serial.println(counter);
//if (counter % candleLenght == 0 ) { //activate cutCandle for RUN motor
if (counter % candyL(S1,S2,S3) == 0 ) { //activate cutCandle for RUN motor
x = !x;
cutCandle(x);//cut candle RUN motor + var y for relay to do something else
}
} else {
//counter--; //we do not want count anticlockwise
}
}
void ai1() {
if (digitalRead(20) == LOW) {
//counter--; //we do not want count anticlockwise
} else {
counter++;
// Serial.println(counter);
//if (counter % candleLenght == 0 ) { //activate cutCandle for RUN motor
if (counter % candyL(S1,S2,S3) == 0 ) { //activate cutCandle for RUN motor
x = !x;
cutCandle(x);//cut candle RUN motor + var y for relay to do something else
}
}
}
/*****************************************************************************
*************************** CUT CANDLE **************************************
*****************************************************************************/
int cutCandle(unsigned int x) {
if (x == 1) {
runMotorOneTime = false;
digitalWrite(RELAY1, HIGH); //relay for something else OFF
// Serial.println(currentTime);
//Serial.println("activate cutting solenoid OFF"); //<--lagging if uncomment
counter = 0;
}
if (x == 0) {
runMotorOneTime = false;
digitalWrite(RELAY1, LOW); //relay for something else ON
//Serial.println(currentTime);
//Serial.println("activate cutting solenoid ON"); //<--lagging if uncomment
counter = 0;
}
}
/*****************************************************************************
*************************** MOTOR DATA **************************************
*****************************************************************************/
void writeMotorParams() { //Setup the motor driver after hard reset
//308 = 0x0134 fan of driver 1off
//901 = 0x0385
//902 = 0x0386
//903 = 0x0387 RPM
result = node.writeSingleRegister(0x0004, 8); delay(50);
result = node.writeSingleRegister(0x0134, 1); delay(50);
result = node.writeSingleRegister(0x0385, 0); delay(50);
result = node.writeSingleRegister(0x0386, 1000); delay(50);
result = node.writeSingleRegister(0x0387, 300); delay(50);
}
void readMotorParams() {
result = node.readHoldingRegisters(0x0386, 1); // Control mode selection
if (result == node.ku8MBSuccess){
Serial.println("***SOME PARAMETER : ***" );
for (j = 0; j < 1; j++) {
data[j] = node.getResponseBuffer(j);
Serial.print("Control Mode selection P00.04 => "); Serial.print(j); Serial.println(data[j]);
}
}
}
void runMotor(){ //MOTOR ON
if (runMotorOneTime == false){
ledCutSignal();
ledWatchDog();
result = node.writeSingleRegister(0x0384, 1);
node.clearResponseBuffer();//if not clear can lagging
Serial1.flush();//if not clear can lagging
runMotorOneTime = true;//stop motor exit from method
Serial.println("MOTOR => CUT ON");
//Serial.println(millis());
//delay(25);
}
}
void ledWatchDog(){
if(currentMillis - previousMillisWDOG > watchDogInterval) {
// save the last time you blinked the LED
previousMillisWDOG = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState41 == LOW)
ledState41 = HIGH;
else
ledState41 = LOW;
// set the LED with the ledState of the variable:
digitalWrite(ledPin41, ledState41);
}
}
void ledCutSignal(){
if(currentMillis - previousMillisCutLED > CutLedInterval) {
// save the last time you blinked the LED
previousMillisCutLED = currentMillis;
// if the LED is off turn it on and vice-versa:
if (ledState40 == LOW)
ledState40 = HIGH;
else
ledState40 = LOW;
// set the LED with the ledState of the variable:
digitalWrite(ledPin40, ledState40);
}
}
/*****************************************************************************
*************************** CANDLE LENGHT ***********************************
*****************************************************************************/
int candyL(int s1, int s2, int s3 ){
long l;
if(s1 == 0 && s2 == 0 && s3 == 0) // 0-0-0
l = 1040;
else if(s1 == 1 && s2 == 0 && s3 == 0) // 1-0-0
l = 1140;
else if(s1 == 1 && s2 == 0 && s3 == 1) // 1-0-1
l = 1240;
else if(s1 == 1 && s2 == 1 && s3 == 0) // 1-1-0
l = 1340;
else if(s1 == 1 && s2 == 1 && s3 == 1) // 1-1-1
l = 1440;
else if(s1 == 0 && s2 == 1 && s3 == 1) // 0-1-1
l = 1540;
else if(s1 == 0 && s2 == 0 && s3 == 1) // 0-0-1
l = 1640;
else if (s1 == 0 && s2 == 1 && s3 == 0) // 0-1-0
l = 2000;
else
l = 1000;
return l;
}
/*****************************************************************************
*************************** CANDLE LENGHT ***********************************
*****************************************************************************/
Simple replacement Max RS485 to Grove RS485 dosent works, for some reason...
You might want to correct your hand drawn wiring diagram to get the 5V going to VCC on the RS485 module and run a GND to it as well.
As for why the Grove module doesn't work, I can't see from the schematics how it switches into receive mode. It must do but I can't see it....
Oh. sorry. wrong file (working, delete it)
This is a full diagram
I want to use Grove rs 485 in my configuration instead of Max rs485
But simple swap dosent helps......
Your RS485 wiring looks correct for a "normal" RS485 module.
Sorry to keep banging on about it but I can't see how the Grove module switches into receive mode as both /RE and DE are pulled high to +V. This is the relevant part of the schematic in case anybody else has an idea of why it's not working for you.
No problem with MAX RS 485
The problem comes up if I swap to grove-rs485, also I can see that on grove rs485 flickering only TX led, may be it is normal, I am using first time this pcb.
Have tried already 2 pcbs same issue, no any data passing to the motor driver...
Grove RS 485
That would tie in with the board being in permanent transmit mode due to /RE & DE being pulled high (according to the schematic). I must be missing something very obvious because controlling the direction of a half-duplex RS485 transceiver is such a basic thing, whether done automatically in electronics or manually through RE & DE pins.
Hopefully some other forum members like @pylon with more Modbus knowledge can shed some light on this issue and point out where we're going wrong, because it shouldn't be this hard to get RS485 working!
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.