rs485 protocol sound good?

I've started to play around with rs485 and I started with I guess the simplest way of doing it I can think of
im using max485, and may want to use multiple transcievers in the future but for now here's a what im trying, would this work across long distance?

int check = 0;
Void setup(){
serial.begin(9600);
pinMode(2,1);
pinMode(2,0);
//RE' and DE are connected to pin 2
//DIN connected to tx
//RO connected to rx
}

Void loop(){
//receiving end
if(serial.available() > 0){
int buf = serial.read();
if(buf == 127){check=1;}
if(buf == 128){check=0;}
if(check==1 && buf != 127){serial.print(char(buf));}
}

//sending end
delay(1000);
digitalWrite(2,1);
delay(1);
serial.write(127);
serial.print("hello");
serial.write(128);
Serial.flush();
delay(10);
digitalWrite(2,0);

srry for any typos I did this from memory on my phone, so may be som cap. Errors
I upload the sending code to one, then power that isolated only connected by the a/b pair to the one I upload the receiving end which I have plugged in my laptop with serial monitor open
This works but its only inches away, would this work say 100meters away with a twisted pair of a cat5e cable?
for two way communication I was thinking of one master would send out an address, listen for ack, ask for data, wait for data
Id have a simple timeout on the master if something goes wrong, and the address/ack/data payloads would begin/end in a special character

Other than would this work long distance, I noticed the serial.flush and delay was necessary to allow enough time to send the whole thing out before changing the enable pin and cutting anything off, is there a way I can tell if anything is in the outgoing buffer sorta like serial.available() returns incoming buffer?

srry for any typos I did this from memory on my phone, so may be som cap. Errors

When you post your real code, properly, we can evaluate it.

pinMode(2,1);
pinMode(2,0);

Make up your mind!

This works but its only inches away, would this work say 100meters away with a twisted pair of a cat5e cable?

Connect the two devices that are inches apart with 100 meters of cable, and see for yourself.

Wow, lol made that same pinmode typo in the code the first time i compiled it
that is my code tho,can't download off the pc without using a thumb drive to another computer with an sd slot to put it on my phones memory card and its small anyway I remembered it
I think I had a 2 more debugging statements by the 127&128 but same thing, I commented out send / receive part for each half
is this the normal method of using rs485? Just using a set baud rate like normal serial?
I tried this just to test the max485's I got off ebay, don't have an application yet just ideas, and I don't have 100 meters of cat5 unfortunately

winner10920:
I think I had a 2 more debugging statements by the 127&128 but same thing, I commented out send / receive part for each half is this the normal method of using rs485? Just using a set baud rate like normal serial?

Here's the problem. I don't understand the question.

This might help:

The question is will this code work without errors over 100m? I've reaad that wiki before and looked around but I haven't found any suggested protocols or how to really use rs485. I kinda assumed it worked like regular serial but assumptions aren't the best to go on sometimes
whenever I look online it says the protocol is up to the user since rs485 is only the physical aspect, idk if that meant serial protocol or something entirely different

And also the question about checking the output buffer is an important one

As has been mentioned we have no real code to evaluate and there's no point us wasting time with something typed up from memory.

That said, at 9600bps RS-485 will work just fine up to 4000' (1200m) and probably longer. So if you send it, they will receive it.

Also that said all serial comms is prone to errors so your "protocol" should have ways and means to detect and deal with them.


Rob

I kinda assumed it worked like regular serial

It does, either half- or full-duplex. In full-duplex mode your code is exactly the same as using serial over TTL or RS-232. Half-duplex is more complicated.

I look online it says the protocol is up to the user since rs485 is only the physical aspect

True.


Rob

That is the code tho, except minor capitalism needed, wasn't long just wanted to know if serial.flush worked that way I have it and if delays are needed

I noticed the serial.flush and delay was necessary to allow enough time to send the whole thing out before changing the enable pin and cutting anything off,

The flush() function does not wait for the last char to be transmitted, this is very bad design IMO and requires you to add a delay as you have found out.

is there a way I can tell if anything is in the outgoing buffer sorta like serial.available() returns incoming buffer?

You can test the TXCn bit in the UCSRnA register.

As presented I think your code will work, it's not very robust but for a quick test I think it's OK.


Rob

that will tell me when the buffers entirely empty?

flush() waits until the last character has been written into the UART Tx buffer register, at that point there is still two characters to be transmitted, one in the buffer and one in the Tx shift register. (unless the code is slow, in which case the Tx shift register may be empty)

The TXCn bit will be set when the shift reg is empty and there is nothing in the buffer, from the data sheet

• Bit 6 – TXCn: USART Transmit Complete
This flag bit is set when the entire frame in the Transmit Shift Register has been shifted out and
there are no new data currently present in the transmit buffer (UDRn). The TXCn Flag bit is automatically
cleared when a transmit complete interrupt is executed, or it can be cleared by writing
a one to its bit location. The TXCn Flag can generate a Transmit Complete interrupt (see
description of the TXCIEn bit).

So yes, testing that bit should tell you that all the data has gone.


Rob

I haven't played around with registers before, do I treat UCSRnA as a variable like this?

txEmpty = UCSRnA & 0x20;

Yep (although the bit mask is 0x40), except n should be a number. On the 328 the value is UCSR0A but I have tried that before in the Arduino IDE and it caused an "undefined" error. However

int txEmpty = _SFR_MEM8(0xC0) & 0x40;

works, so I don't know why UCSR0A doesn't as it is defined as such

#define UCSR0A _SFR_MEM8(0xC0)

It seems that the iom328p.h file is not included.

Also you should really use (1 << TXC0) instead of 0x40, but TXC0 is not defined as well.

Anyone know what's happening here? It's 1AM here and I won't be up long enough to figure it out.


Rob

Lol thought 6th bit as in 6th position from right instead of the counting the first as 0,
My guess is that UCSR0A is a local variable to something, but I haven't looked at it yet,
but for now ill replace my serial.flush witha flag using _SFR_MEM8(0xC0) & 0x40;

Don't make life too complicated:

  // wait for transmit buffer to empty
  while (!(UCSR0A & _BV (TXC0)))
    {}

Ok, it works just fine, I had the Leonardo board selected in the IDE :0

This compiles

void setup() {
    int txEmpty = UCSR0A  & (1 << TXC0); 
}

void loop() {}

So use a loop like Nick's example above.


Rob

What does the _BV do?

This:

#define _BV(bit) (1 << (bit))

It returns the n'th bit.

So, _BV (1) is 2, _BV (2) is 4, and so on.

It just saves you writing:

(1 << TXC0)

Instead you can write:

_BV (TXC0)

Ok, thanks that makes sense