Hi guys
I have a problem with using my Arduino MEGA with the RS485 Lib from Nick Gammon.
As long as i use a SoftwareSerial for the communication with the rs485 IC's all works fine.
But now i want to use the 3 Hardware Serials of the MEGA (Serial1, Serial2 and Serial3)
So I changed my code to work with the HardwareSerial Serial1. The problem is now, that i can just receive Data from the RS485 but nothing is sent to the RS485.
I allready tried it with the 2 mod's from Nick's Homepage
sendMsg (fWrite, msg, sizeof msg);
delayMicroseconds (660);
digitalWrite (ENABLE_PIN, LOW); // disable sending
and
digitalWrite (ENABLE_PIN, HIGH); // enable sending
sendMsg (fWrite, msg, sizeof msg);
while (!(UCSR0A & (1 << UDRE0))) // Wait for empty transmit buffer
UCSR0A |= 1 << TXC0; // mark transmission not complete
while (!(UCSR0A & (1 << TXC0))); // Wait for the transmission to complete
digitalWrite (ENABLE_PIN, LOW); // disable sending
But both of them didn't work.
Have anyone of you an idea what the problem could be?
Greets
Peter
Has nobody an idea for a solution?
That code refers to UART0, isn't Serial1 one on UART1?
Also I don't understand setting the TXC0 bit all the time, not saying it's wrong as I haven't had a good look at the data sheet but it seems strange.
Rob
Thanks for your input, Rob!
I also don't understand the function of this code-part. I have some experience in writing c/c++ but have no idea about manipulating the hardware registers.
But you're right, Serial1 should be UART1.
So would it be the right way if i write
digitalWrite (ENABLE_PIN, HIGH); // enable sending
sendMsg (fWrite, msg, sizeof msg);
while (!(UCSR1A & (1 << UDRE1))) // Wait for empty transmit buffer
UCSR1A |= 1 << TXC1; // mark transmission not complete
while (!(UCSR1A & (1 << TXC1))); // Wait for the transmission to complete
digitalWrite (ENABLE_PIN, LOW); // disable sending
Greets
Peter
I use RS485 a lot in my work. If you didn't already know, the main difference from RS232 from a software point of view is that RS485 is half duplex: you can be in transmit mode, or receive mode, but not both at the same time. Typically there's a pin that connects you to the RS485 transceiver that turns the transmit mode on or off (if the transmitter is off then you're in receive mode). The transceiver (or driver) is the chip that takes data from the UART and drives RS485 compatible voltages onto the wires.
What you don't want to do is turn off the transmitter while the UART is still transmitting, and you have to remember that the UART will still be shifting out the data in serial fashion for a significant time after it accepts that last character from you. Hence the loop which tests for tx idle before it turns off the transmitter. Another thing you can do is just delay for a couple of character times, but testing tx-idle is more efficient.
Thanks for your Reply DonMilne
Do you know if my changes in the previous code would be correct?
It's a bit frustrating that the most things of my sketch are working and i'm not able to change all the stuff from SoftwareSerial to a hardware port 
Greets
Peter
Your code looks right to me, except for two things. (1) I don't know why you're setting a transmitter status bit before waiting to complete. Normally you wait for tx holding reg empty, then for tx shift reg empty. The UART sets its own status bits. (2) You are using sizeof msg as the number of bytes to send. Is tht correct? Messages have a fixed length? Obviously I have no info on the protocol you're trying to implement.
I suggest you try a simple test: try sending an ASCII message to the Arduino serial monitor, over RS485 - I assume you have an RS485 adapter for the PC. If you can do that then you can stop worrying about low level comms mistakes and look for protocol mistakes.
First i have to tell you, that the rs485 library isn't mine. It's written bi Nick Gammon...
(1) Do you mean the command digitalWrite (ENABLE_PIN, HIGH); ?
This is to enable sending
(2) Yes, sizeof msg is used. The messages i d'like to send have different lengths, depends on how many commands (which Slave should change which port to which state...). The protocol i use is written by myself.
Unfortunately i don't have a RS485 adapter for my pc.
The strange thing is, that my sketches are working as long as i use the SoftwareSerial to connect the Arduino to the RS485 IC. But when i switch to a hardware Serial on the Arduino and change the code as in the sample from Nick, it wouldn't work any more.
If it's a help for you, here is the link to the page from Nick with the example for the RS485 library Gammon Forum : Electronics : Microprocessors : RS485 communications
Greets
Peter
According to Nick's documentation
The first loop waits for the hardware chip's buffer to empty, at the same time setting the "transmission not complete" flag.
But he doesn't explain why that flag needs to be set. It's not clear to me why you would do that but if his code works I won't argue 
sizeof msg is used. The messages i d'like to send have different lengths
I assume "msg" is pointer to a byte array. So sizeof will always give you the size of that pointer, IE 2, it does not give you the size of the array that's being pointed to.
Rob
I would say that, practically speaking, you can't do RS485 related cross development on a PC if the PC can't send and receive RS485. You need it for debugging and testing. USB-RS485 converters are readily available (e.g. on Amazon) and cheap, and will do you for many more projects in future. I would recommend the converters we use at work, but they're nothing special and probably cost more than you need.
someone83:
(1) Do you mean the command digitalWrite (ENABLE_PIN, HIGH); ?
No, I was referring to the setting of TXC1 prior to entering the wait loop. Looking at the data sheet I see that bit is indeed writable (it's a W1C type bit). I would expect that status bit to be self resetting when a new tx starts, but I guess what the code is doing is ok too. My own serial code on the AVR waits on UDREn, which is read only - my home AVR projects have not involved RS485 so far, and so have not needed to be so fussy about controlling the UART.
someone83:
(2) Yes, sizeof msg is used. The messages i d'like to send have different lengths
You don't seem to be catering for different lengths. Also I don't know what kind of structure "msg" is. If it's a struct then you'll be sending the structure size every time. And as Graynomad mentions, if msg in an array then you'll only be sending two bytes (sizeof ptr). In other words you may not have implemented the protocol correctly, there may be nothing wrong with the comms itself. That's what I had in mind when I suggested testing the comms separately.
Thanks again for your replies and sorry for my late response, i was very busy at work the last few days and so i didn't have time for working on this project...
@DonMilne: I will buy a RS485-USB converter soon, i think this would be a good part!
Meanwhile i tested the sketches from http://arduino-info.wikispaces.com/SoftwareSerialRS485Example and this works fine when i upload the master-sketch to my MEGA and change all the SoftwareSerial stuff in it to Serial 1 and upload the slave sketch to an Arduino Pro Mini.
I can send from the Mega single bytes and they are returned from the Pro Mini as they should.
So i think, the Serial Ports are working.
I attached 3 files to this post. The Master_working is my actual software which works fine (but isn't completed yet)
The Master_not_working is the version where i tried to communicate over Serial1. Here i see Data arriving at the serial monitor and also that something is been sent (i think it's commented out at the moment).
Sending happens in the function void senden()
The Slave is the file of one of my two slaves at the moment.
At the moment one slave is sending a command when a button is pushed (released), the master checks the command and sends a new command to the second slave (the attached file Slave). On this second slave i see the data incoming (on the serial monitor) from the first slave, but nothing comes in from the master.
I hope that my sketches can help you solving my problem.
Regards
Peter
Master_working.ino (12.1 KB)
Master_not_working.ino (12.4 KB)
Slave.ino (12.1 KB)
Is it the same slave code with both the working and non-working master modules?
Yes, the slave-code is allways the same.
Nothing jumps out at me in the code. "sizeof msg" is ok when msg is a statically initialized local.
This looks like one of those things that would probably take five minutes to debug if I was there. Or I could probably simulate what you're doing but that would be too much work when I have plenty unpaid projects of my own! I can only expand on what I already suggested: break the problem into simple parts and prove each part.
Incidentally, I was unfamiliar with Gammon's RS485 module, but I had a look in order to check your code. Clever, but highly inefficient. More than 50% of the bandwidth spent on error detection! And it's not as if you get forward error correction included for the cost. That seems unnecessary.