Help with an RS485 setup

Hi all

I’m building my own simulator cockpit, and have got pretty far into the project already, as you can see from the photo of the dash panel. It is designed to run with the DCS World series simulation, and by using an output protocol called DCS Bios, it is possible to make the components interact with the game

Most of the physical gauges are represented, and actually work using stepper motors, LCD panels, MAX7219 controllers, all controlled by Arduino Nano’s. I have them working well individually, but of course like that they are connected up via USB. They all work, but connecting via USB is clearly not practical, as we are talking sixty USB devices. Also, when connecting multiple USB devices, often one or two of them don’t get recognised correctly, and so don’t function. By plugging into a different USB port you can get it to work, but you don’t want to mess around with that every time.

As a result the use of an RS485 network is recommended, and all my devices are built with wiring on the PCB and a socket for a MAX487 chip, and then by using an Arduino Mega as a master unit. It’s pretty simple, and using four wires (+5v, A, B, GND) and assigning an individual slave address to each Nano you can connect everything up on a type of ring main circuit.

So as I mentioned, I set out about nine months back when I started making this with the devices able to be RS485 enabled from the start. This is the master arduino Mega sketch

/*
Tell DCS-BIOS this is a RS-485 Master.
You will need to flash this to a Mega 2560.
*/
#define DCSBIOS_RS485_MASTER

/*
Define where the TX_ENABLE signals are connected.
You can connect up to three half-duplex RS-485 transceivers.

Arduino Pin RS-485 Transceiver Pin
TXn ------------------- DI (driver input)
RXn ------------------- RO (Receiver Output)
UARTn_TXENABLE_PIN ---- /RE, DE (active low receiver enable, driver enable)

If you have less than three transceivers connected, comment out the corresponding
#define UARTn_TEXENABLE_PIN lines for receivers that are not present.
*/
#define UART1_TXENABLE_PIN 2
//#define UART2_TXENABLE_PIN 3
//#define UART3_TXENABLE_PIN 4

#include “DcsBios.h”

void setup() {
DcsBios::setup();
}

void loop() {
DcsBios::loop();
}

I got off to a frustrating start when I just couldn’t get it working until I with the help of the guys on the DCS home cockpits forum established that the TX and RX on my Mega were actually marked the wrong way round. As I had ordered another Mega for use with one of the other parts of the sim I compared the two, and the original was incorrectly marked. Looking at the Arduino Mega master diagram showed me the original was the wrong one.

Once I got that right, I was able to get a device working and then another, and soon I had six gauges working correctly, all over RS485. They are all on one large engraved PCB, each with it’s own MAX487 chip, Nano and Stepper motor driver, and I was pretty pleased with myself.

So why am I seeking assistance from your good selves? Well, shortly after getting it to work, it started to stop working. You could not breathe on anything, if you looked at it in a funny way it stopped and had to be reset. It wasn’t that there was a particular connection that was weak (in fact I am making sure I use good quality 0.1" header pins and connections, and making PCB’s rather than wired connections) it was that you could not touch ANYTHING, wires, USB cable to the Mega, the gauge PCB, nothing.

Then it just stopped working altogether. As I mentioned, I hard wired most of it together, including making a shield with the MAX487 chip for the Mega, so that the only wires I have were the four wire connection between the Mega ‘shield’ and the gauge PCB, 5v supply to the gauge PCB for the Nanos, and 12v for the stepper motors.

I changed the Mega, I changed the MAX487 chips (all of them), the Nanos, the four wire connection, checked the 5v supply, nothing.

So I went back to basics, and got one device that I knew worked before, a new MAX487 chip for the slave, a new MAX487 chip and wired it to the mega, a new Nano board for the slave. Before fitting the MAX 487 chips I verified that the gauge was working properly via USB with the appropriate sketch, then inserted the MAX487 chip into the socket, got a new four wire lead to connect the MAX487 chips… and nothing.

I then tried it with a different Mega. Nothing. I bought those RS485 modules that have MAX487 chips on them and screw connections for the RS485 leads and header pins for the Mega and Nano.

Nothing. I literally cannot get one devise to work at all any more.

So right now I have a box full of MAX487 chips, another with those modules, two Megas, a load of Nanos and a 3/4 complete cockpit that I can’t get working together.

I can test the nanos in terms of loading sketches that run via USB, so can weed out any that have issues. I can test the Megas with sketches the same way. I don’t know how to verify the MAX487 chips or RS485 modules, although I still have some new ones so must assume that they are OK.

So as you can see I am totally mystified by all this. If I had never got it working I would assume that it was something I am doing wrong or mis understanding, but the fact that I had it working indicates I understood it correctly but have either introduced something into it or there is a failure of something I can’t find.

I have gone back to this numerous times with just one devise to see if I can get something to work, but I have failed.

Latterly I bought a TinySine RS232 / RS485 shield in order to exclude a variable from the system, namely the master RS485 connection to the Mega, however I don’t know despite a search how to modify the master sketch in order to get the simulation data to be transmitted over the TinySine RS485, so I was thinking that I could start there. If anyone can advise on this I would be grateful.

Additionally, I would appreciate any assistance you can give on my plight with the whole mess!

For reference, I am using Windows 10 on a PC running an Intel i7 CPU, and the protocol over which it is communicating with the components is DCS BIOS, the sim itself is DCS World

Here’s hoping that someone can help!

Cheers

Les

For the time being forget the TinySine board as you'll need to modify it to work with the Mega pin assignments.

The first step is to disconnect everything from the Mega except the USB connection to the computer and use an oscilloscope to see if any data is coming out of the Mega Tx1 pin.

If Tx1 shows activity then check to see if pin 2 is being driven whenever Tx1 is active.

Report your findings here.

Thanks for looking and replying. Unfortunately I don't have, or have access to an oscilloscope.

And just so I understand, the TinySine shield is designed for the Arduinos, and fits correctly, why would it need to be modified? If it's not useable so be it, but I would like to try and understand a bit more

Cheers!

Les

Lesthegringo:
And just so I understand, the TinySine shield is designed for the Arduinos, and fits correctly, why would it need to be modified? If it's not useable so be it, but I would like to try and understand a bit more

That shield connects to the Tx0/Rx0 pins which are connected to the microcontroller and the USB interface chip and therefore your computer. You cannot use Tx0/Rx0 for communication with the Nanos.

You need to:

  • Disconnect the Tx0/Rx0 shield pins and run wires to the Tx1/Rx1 pins as this is what the Mega uses for communication with the Nanos.
  • Alter the solder bridge to set the auto direction to manual.
  • Change UART1_TXENABLE_PIN to use pin 4 as that is what the shield uses.

You can buy an oscilloscope for well under a $100.

Ok, pretty big mods for that TinySine unit - I got it, more hassle to convert than to try and use. I'm OK with that.

As for the oscilloscope, and please don't take this the wrong way, as you are trying to help me - but wouldn't it be cheaper to buy a new Mega board? I wouldn't know how to use the oscilloscope and I could buy five Megas for the same price.

Cheers

Les

Well, despite it being cheaper than buying an oscilloscope, a replacement Mega has not solved the issue. In fact, even using literally a complete new set of hardware (Mega, Nano, RS485 modules, connector boards) this still does not function for even the simplest test.

I checked the wiring and connections at least seven times on what is a simple set of wiring - four wires between the RS485 modules, two wires from each RS485 module to 5v and GND on the Mega and Nano respectively, USB cable to Mega, 1 wire connecting Mega pin 2 to to pins DE and RE on the master RS485 module, 1 wire connecting Nano pin 2 to to pins DE and RE on the slave RS485 module, RO on master RS485 module to pin 19 on Mega, DI on master RS485 module to pin 18 on Mega, RO on slave RS485 module to pin RX on Nano, DI on slave RS485 module to pin TX on Nano, and a USB cable to connect to a USB charger for power for the Nano. And the 5v / GND / DSA / SCL connections for the LCD module, latterly replaced by an LED and switch to pins D13 and A0 plus GDN on the nano respectively for the test sketches.

For me, the hardware can't continually be defective out of the packet, and since the sketches I am running to test are standard test sketches that have worked for many people, I'm left thinking that maybe the hardware isn't the issue. I also had this running at one point, which indicates I am capable of wiring it correctly.

So is there something that can happen within windows, or within the USB connection that can interfere with the RS485 signal or transmission?

Cheers

Les

Are all the metal parts of your simulated cockpit connected together? And are they all connected to the Arduino ground and all the power supplies negative - terminals connected to the ground that all the rest is connected to?

Paul

Hi there, and thanks for looking at this.

Despite appearances, most of the sim is actually made from MDF, plywood and acrylic, with metal only being used for fixings and the like. As a result there is no need to ground anything other than the individual PCB's, which are all designed with a ground bus on them, and the nanos and other components use that.

However even when I try to build a test circuit on a wooden tray, connecting to the PC by USB cable and just has power supply input for the nano and has literally no physical connection to anything else, it still doesn't work. They are test sketches, test circuits, very similar to those you see in articles on instructables.

When I had the RS485 network running last year, I remember that there was a lot of flashing light activity on both the Mega and the Nanos. If my memory serves me correctly, the Mega TX and RX LED's would flash, and the Nano RX LED would flash. Now, all I get is the Mega RX LED flashing, but nothing else.

In the process of trying to get this working again, I have tried 3 Megas, 18 nanos, forty odd Max487 IC's and various RS485 modules - it is really likely are all defective? The 3 Megas were from 3 different sources, the Nanos are from different sources (four I think, and some are ATMega328P, some are ATMega168), the MAX487 chips are from at least three different sources.

There is only one part of the whole system that has not been swapped, and that is the PC. Due to the requirements of the Sim (DCS World) I have a dedicated stand-alone PC for this. This is what leads me to wonder if the problems are not to do with the mass of components listed above

Cheers

Les

From what you are describing, there looks to be way too many variables in trying to troubleshoot the problem. Are you able to get the master and just one slave working?

If you go back to absolute basics, can you modify the Arduino blink sketch to drive the RS485 line driver on the master. Make a simple sketch on the slave to read the RS485 line receiver and drive an LED. If that works, then you can have a bit of confidence that the "bus" is working.

I did find a guide to troubleshooting RS485 here that might point you in the right direction.

markd833:
From what you are describing, there looks to be way too many variables in trying to troubleshoot the problem. Are you able to get the master and just one slave working?

Nothing, not one single item - and I had multiple units functioning together in the past. Now I can't even get a simple test sketch working using one mega, one nano and two RS485 modules

markd833:
If you go back to absolute basics, can you modify the Arduino blink sketch to drive the RS485 line driver on the master. Make a simple sketch on the slave to read the RS485 line receiver and drive an LED. If that works, then you can have a bit of confidence that the "bus" is working.

If you can link me to a simple example blink sketch I will put it together and run it on a separate PC

markd833:
I did find a guide to troubleshooting RS485 here that might point you in the right direction.

I'll take a look and see , thanks for this

Cheers

Les

markd833 is just suggesting use the blink example that comes with the IDE. You'll need to hack it a bit to transmit 'H' and 'L' over the RS485. On the receiving end, read what you get and turn an LED on/off accordingly.

Nice looking cockpit - are you making a Warthog simulator?

In the Arduino IDE, have a look at File->Examples->01.Basics->Blink.

This might help you get going with the master (transmitter) side:

#define MAX487_DE_PIN  xx
#define MAX487_DI_PIN  xx
#define MAX487_RE_PIN  xx
#define MAX487_RO_PIN  xx

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);

  // initialise the RS485 line driver for transmission
  pinMode(MAX487_RE_PIN, OUTPUT);
  pinMode(MAX487_DE_PIN, OUTPUT);
  pinMode(MAX487_DI_PIN, OUTPUT);
  digitalWrite(MAX487_RE_PIN, HIGH);  // receiver off
  digitalWrite(MAX487_DE_PIN, HIGH);  // transmitter on
 
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  digitalWrite(MAX487_DI_PIN, HIGH);
  delay(1000);                       // wait for a second

  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  digitalWrite(MAX487_DI_PIN, LOW);
  delay(1000);                       // wait for a second
}

Replace the xx with the pin numbers on your Arduino board that you are using to connect to the DE, DI, RE & RO pins.

That should cause the master to drive the RS485 line with an alternating '1' and '0' at 1Hz.

You should be able to use a basic multimeter across the A & B outputs and see the voltage swing +ve and -ve as the 1's and 0's are output. If your multimeter is slow to respond, then increase the delays from 1000 (1 second) to 2000 (2 seconds).

Thanks, I get it now, and thanks for posting this

Yes, it's an A10C cockpit, to use with DCS World, as mentioned above. There's an open source system called DCS BIOS that has been developed by some guys, and it means you you can output all the data for gauges and LCD readouts etc. It's really well done, but the quantity of items you need an output for means that to try and use USB for them all is impractical, hence the need for this.

But, today I made a breakthrough, in that using a modified sketch I am able to control multiple steppers and hence gauges using one Mega board. If I really can get this to work with 6 or more stepper drivers, I may be able to sideline the need for RS485. I am still working on that and will feed back when I have progress.

However I do want to resolve the RS485 issue, as there are clear advantages to having it if I can use it, not least where units are ranged around where USB connections are more tricky

Thanks again for all the help guys!

Cheers

Glad you are making progress.

For the receiver, try something like this:

#define MAX487_DE_PIN  xx
#define MAX487_DI_PIN  xx
#define MAX487_RE_PIN  xx
#define MAX487_RO_PIN  xx

int rxState = 0; 

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);

  // initialise the RS485 line driver for transmission
  pinMode( MAX487_RE_PIN, OUTPUT);
  pinMode( MAX487_RO_PIN, INPUT);
  pinMode( MAX487_DE_PIN, OUTPUT);
  pinMode( MAX487_DI_PIN, OUTPUT);
  digitalWrite( MAX487_RE_PIN, LOW);   // receiver on
  digitalWrite( MAX487_DE_PIN, LOW);   // transmitter off
 
}

// the loop function runs over and over again forever
void loop() {
  // read the value on the RS485 receiver pin
  rxState = digitalRead(MAX487_RO_PIN);

  if (rxState == HIGH) {
    digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on
  } else {
    digitalWrite(LED_BUILTIN, LOW);   // turn the LED off
}

Replace the xx with the pin numbers on your Arduino board that you are using to connect to the DE, DI, RE & RO pins.

If you get it working with one slave, then put the same code into each slave one at a time and connect it to the RS485 bus. You should hopefully see a whole bunch of slaves blinking their LED at exactly the same time.

If it all suddenly stops working, then suspect the last device you connected.

markd833:
In the Arduino IDE, have a look at File->Examples->01.Basics->Blink.

This might help you get going with the master (transmitter) side:

#define MAX487_DE_PIN  xx

#define MAX487_DI_PIN  xx
#define MAX487_RE_PIN  xx
#define MAX487_RO_PIN  xx

// the setup function runs once when you press reset or power the board
void setup() {
 // initialize digital pin LED_BUILTIN as an output.
 pinMode(LED_BUILTIN, OUTPUT);

// initialise the RS485 line driver for transmission
 pinMode(MAX487_RE_PIN, OUTPUT);
 pinMode(MAX487_DE_PIN, OUTPUT);
 pinMode(MAX487_DI_PIN, OUTPUT);
 digitalWrite(MAX487_RE_PIN, HIGH);  // receiver off
 digitalWrite(MAX487_DE_PIN, HIGH);  // transmitter on

}

// the loop function runs over and over again forever
void loop() {
 digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
 digitalWrite(MAX487_DI_PIN, HIGH);
 delay(1000);                       // wait for a second

digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
 digitalWrite(MAX487_DI_PIN, LOW);
 delay(1000);                       // wait for a second
}




Replace the xx with the pin numbers on your Arduino board that you are using to connect to the DE, DI, RE & RO pins.

That should cause the master to drive the RS485 line with an alternating '1' and '0' at 1Hz.

You should be able to use a basic multimeter across the A & B outputs and see the voltage swing +ve and -ve as the 1's and 0's are output. If your multimeter is slow to respond, then increase the delays from 1000 (1 second) to 2000 (2 seconds).

I do have a question on this - all the diagrams have the DE and RE pins joined, should I still quote both pins?

Cheers

With the MAX487, you have the ability to individually turn on or off the transmitter or receiver using the DE and RE signals. If you are operating in half-duplex mode, so you are either transmitting or receiving (but not both at the same time), then the RE and DE signals can be connected together.

With that arrangement, the MAX487 is either in transmitting or receiving mode and you only need one wire to control the line drivers.

So, in the code examples, you can delete MAX487_RE_PIN & MAX487_DE_PIN and simply have MAX487_TXRX_PIN instead. You will still need to define this pin as an output and set it accordingly, HIGH for transmit and LOW for receive (I think I've got that the right way round).

The transmitter code will look something like this:

#define MAX487_TXRX_PIN  xx
#define MAX487_DI_PIN  xx
#define MAX487_RO_PIN  xx

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);

  // initialise the MAX487 line driver for transmission
  pinMode(MAX487_TXRX_PIN, OUTPUT);
  pinMode(MAX487_DI_PIN, OUTPUT);
  pinMode( MAX487_RO_PIN, INPUT);
  digitalWrite(MAX487_TXRX_PIN, HIGH);  // transmit mode 
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  digitalWrite(MAX487_DI_PIN, HIGH);
  delay(1000);                       // wait for a second

  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  digitalWrite(MAX487_DI_PIN, LOW);
  delay(1000);                       // wait for a second
}

And the receiver code will look something like this:

#define MAX487_TXRX_PIN  xx
#define MAX487_DI_PIN  xx
#define MAX487_RO_PIN  xx

int rxState = 0;

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);

  // initialise the MAX487 line driver for reception
  pinMode(MAX487_TXRX_PIN, OUTPUT);
  pinMode(MAX487_DI_PIN, OUTPUT);
  pinMode( MAX487_RO_PIN, INPUT);
  digitalWrite(MAX487_TXRX_PIN, LOW);  // receive mode 
 
}

// the loop function runs over and over again forever
void loop() {
  // read the value on the RS485 receiver pin
  rxState = digitalRead(MAX487_RO_PIN);

  if (rxState == HIGH) {
    digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on
  } else {
    digitalWrite(LED_BUILTIN, LOW);   // turn the LED off
}

I think I got all that right!

Another thought just occurred to me. If the setup did work and has now mysteriously completely failed, then there is the possibility that one of your MAX487 devices has a rogue DE pin that is switching the Tx line driver on effectively putting one of your devices in permanent transmit mode killing the whole 485 bus.

apologies for not getting back to you earlier - I still have to do the test sketch

However to answer the question above, I have tried multiple components at every step of the process, so it can't be one component.

Cheers

Les

All, understanding that this is an old post, I have finally solved the issue on this and wanted to share it to help others who may have had the same issue.

To recap, despite having the RS485 network working at one point, it suddenly stopped working and no attempts to resurrect it had any impact. However a couple of weeks ago someone who was working on the same type of setup as me mentioned that he had the same problem, and that by updating the Arduino bootloader, he suddenly got everything working again. Skeptical though I was, I knew it wouldn't do any harm so I uploaded the newest version of the Arduino IDE suite, reflashed the Mega and Nano with the same sketches and away it went, working fine. I used the same hardware and sketches as before with no changes, so for some reason something must have affected how the sketches were used by the Arduinos.

Anyway, maybe this helps someone, I know the issue cost me weeks of lost progress on my project

Cheers

Les