2

I would like to introduce myself as a student from Czech Republic. I'm currently I'm working on a Meteostation project.

I've got Arduino set up, with plenty of weather sensors, as well as WH1080 sensors connected.

Right now, I'm only able to read the data via serial port on computer with Arduino IDE or show it on my 20*4 display.

Because of the distance between source of data and recipient of data, wireless data transfer is unsuitable for my application.

I found these MAX 485 modules on eBay for cheap:

max485 module

I quickly got 2 pieces, as well as 5v-3.3v logic level shifter, as I was concerned about different logics on Raspi. I don't know much about Raspi and their pins, as the only thing I ever used with them was DS3231 real time clock module.

Now, the thing I'm trying to achieve is this - I want to be running a bunch of sensors at roof of our house, and have the Arduino send the data to Raspi over the rs485 (on request? as the sensor loop would be like 10-15min so maybe communicate on interrupt?)

What I'm planning to do with the data on the raspi would be running a software like WeeWx or wfrog to process them and possibly render a local website, that I could make public as port forwarding (I have public IP).

However, there are few questions I have, hopefully its not too much to ask

  1. How would the wiring look like? I was unable to find any dumb-proof tutorial online, as I don't know whether or how to use the logic level shifter.

  2. If I can read the data over serial port, would it be just a plain text (as shown on PC in Arduino ide serial monitor), or has each value its address that I could then easily accessing to a variable then being used to process the weather data?

  3. If I'm completely wrong in something, or there's some completely different way how these things are being done by more experienced people, I'd love to hear some suggestions.

Thanks in advance for any kind of response, as this is at the moment causing me headaches, as I'm unable to do this on my own. I don't expect anyone to do all the work for me, maybe just point me in the right direction.

5
  • My mind boggled a bit reading your question. Maybe this page about RS485 will help you get started.
    – Nick Gammon
    Jan 31, 2016 at 3:42
  • You didn't get any answers when you asked the same question on raspberrypi.stackexchange.com because the question is too broad.
    – Milliways
    Jan 31, 2016 at 7:45
  • 2
    I also were a beginner (umm, in the previous century, literally). I found it is more rewarding to start with projects which have up to one unknown part, since that is something one can learn. However starting a project as a beginner with so many unknown factors can hardly lead to a success.
    – Gee Bee
    Mar 17, 2016 at 21:45
  • May I ask: what makes you think the range is too extended for wireless links, but not for RS485? Given an appropriate transmitter and antenna combination, wireless links can extend over miles inbetween nodes.
    – sekdiy
    Apr 17, 2016 at 10:03
  • @Martin K, have any of these answers helped you?
    – Paul
    Aug 16, 2016 at 11:59

2 Answers 2

5

How would the wiring look like? I was unable to find any dumb-proof tutorial online.

I found this tutorial to be pretty usefull.

There really isn't much to it, I suggest trying a short range before going full range. It's a "half duplex bus system" the ends of the bus should have a "end termination resistor", usually 120Ohms, between the A and B signal. Since it's half duplex, the Pi and Arduino can't talk at the same time. You'll have to pull the DE and RE pins high when you want to transmit (and keep them low for receiving).

Basic sketch would be something like:

#define TXEnablePin 13

void setup(){
  Serial.setup(9600);
  pinMode(TXEnablePin,OUTPUT);
}

void loop(){
  String data = "";
  Unsigned int sensorValue1 = Sensor.getValue();
  Unsigned int sensorValue2 = Sensor.getValue();
  data += str(sensorValue1) + ":" + str(sensorValue2) + ";\r\n";
  send(data);
  delay(10000);
}

void send(String data){
  digitalWrite(TXEnablePin,HIGH);
  delay(1);
  Serial.send(data);
  Serial.flush();//Wait for everything to be transmitted, before disabling transmitter.
  digitalWrite(TXEnablePin,LOW);
}

I don't know whether or how to use the logic level shifter.

These things are pretty straight forward. You should actually be able to figure it out yourself (given you have the power of the internet).

LV to 3.3V of Pi GND to GND of Pi GND to GND of Arduino HV to 5V of Arduino

Then, whatever 5V signal you want to connect to HVx and whatever 3.3V signal you want to connect to LVx

Example:
Arduino-TX -> HV1
Arduino-RX -> HV2
Pi-TX -> LV2
Pi-RX -> LV1

enter image description here

If I can read the data over serial port, would it be just a plain text (as shown on PC in Arduino ide serial monitor), or has each value its address that I could then easily accessing to a variable then being used to process the weather data?

It would be ASCII (plain text) if you send strings. You could make different types of requests.

Like; If you send: "Temperature" to the Arduino, it will respond with: "TEMP:10" or something.

But the easiest thing would be to send all values of all sensors in a combined string every 10 seconds or so. And let the Raspberry Pi unpack that string.

If I'm completely wrong in something, or there's some completely different way how these things are being done by more experienced people, I'd love to hear some suggestions.

I think it's pretty good that you actually already know of the existence of RS485 and why you'd want to use it.

But I also feel that you feel a little uncomfortable with the project as it is. It's important to handle problems one by one, to avoid getting overrun by problems. Try to make it working over (short) USB first. Then try a short RS485 link and eventually try a long RS485 link. You can then more easily spot where the problem is. Use facts from multiple tutorials, to boost the confidence you have in the system ;). It may just work if you wire it as said. If it doesn't work, you can always post a question.

If possible, it may also be worthwhile to follow some tutorials on Arduino (get a starter kit and book with tutorial projects?). Within these tutorials they give examples of problems and show what there is to solve them. Without throwing yourself into a dark pit of a project.

2
  • Friend, i try same method (like your) but not working (about of digitalWrite(TXEnablePin,LOW);)! Auto-Direction is best idea, use an 74HC14 IC with an Capacitor (capacitor == Serial.flush()). Communication never allowed an internal delay, cos missing bits or skip bits position.
    – dsgdfg
    Dec 6, 2018 at 8:54
  • I succeeded at about 500kbit speed with hardware delay(PCI-RS232).
    – dsgdfg
    Dec 6, 2018 at 8:58
2

Ok, one simple step which might help you to get going.

The no-brainer

There is an RS232 link between your Arduino and the PC. (Of course, it might not be a real RS232, it can be the USB, and over the USB the PC sees the arduino as a serial port what you can write from Arduino. So far so good.

You can easily extend the USB with passive expansion cords, as well as with active USB expansion cords, easily getting an extra 30m. Of course it is not an RS485, but comes at no further thinking.

The RS485

RS485 is basically a clever variant of a serial port, which allows you sending your data over up to 1.5km twisted wire pair.

  • get an USB-RS485 adapter for your PC or Raspberry side. These are widely available, e.g. http://usb-rs485.eu/?cms=eu85xl&gclid=CjwKEAjwq6m3BRCP7IfMq6Oo9gESJACRc0bNkhzTSQU3wUW_5tebRZDD-zAqflcvcFOq9V8nmZIlRhoCvyPw_wcB
  • get an RS485 driver chip such as MAX485 (I prefer LTC485, that works straight from 5V, costs like 1 EUR) for your Arduino side.
  • you'll need two ardino pins - serial read and write, therefore you may prefer an Arduio supporting also Serial1 - so a TxD and RxD wire from the board. When you write to this serial port instead of Serial, the data comes out from the TxD pin of the Ardino panel, instead of going to the PC via the USB.
  • now, if you can have a simplex system - i.e. only Arduino talks to the PC or Raspberry - then it makes your life a lot easier. Then you only need the TxD from the Arduino, and connect it to the DI of the RS485 driver chip. Connect RE and DE and connect both of them to 5V. That's all.
  • if you want a two direction communication between the Arduino and PC, that makes things a bit more complicated. RS485 is a half-duplex thing, so your Arduino needs to control when it wants to talk to the line or listen. For that you need a separate pin to be connected to RE and DE together. Put it to 1 to write, 0 to read from the RS485 lines. Note that Arduino is having write buffers, so it will be a little tricky to know exactly when to switch back to listening after writing. Solving this properly worths of a separate question :)
  • connect A of the MAX485/LTC485 to the A of the USB RS485 interface. Connect B to B. Now you're almost there... Connect also GND of the Arduino to the GND of the RS485 interface. (Although you can see many examples on the net of using only two wires, A and B, in the real life you either need a common GND, or an additional overvoltage protection circuit made of four zener diodes to have it running well forever.)
    • you're advised of using a twisted pair wire for A and B. This is not a requirement though, you can go well with any wires. One of my friend used a garden fence made of metal as A, and the soil as B, which worked well for 50 meters :) However for 1.5Mbit, 1km you definitely need a twisted pair
    • Note that if you go with long wires (over 50 meter) and higher speed (over 9600 bps), you need to have line-terminator resistors. This means a simple 120 ohm resistor connected between A and B on the PC side. Another 120 ohm resistor to be connected at A and B on the MAX 485 side - so the two farthest end of the long communication wire.

Now the software side:

  • The USB RS485 interface will look like just a regular serial port for the PC (e.g. COM9) or Raspberry. So you can read and write the RS485 bus just like a standard com port.
  • On the Arduino side, you can use the Serial1 (or equal) to write data out to the MAX485, which drives the wires.
  • I suggest again to start with a simplex system, i.e. Arduino only writes data, the PC just reads data.
  • Note that you have to use exactly the same bit rate on Arduino as well as on the PC side. Watch out when you open up the terminal.
1
  • you may prefer an Arduino supporting also Serial1”: This is only needed if you want to keep Serial for debugging. Otherwise there is no problem in using Serial for the RS-485 link: the data goes both to the USB link and the TX pin on the board. “it will be a little tricky to know exactly when to switch back to listening after writing”: That's what Serial.flush() is for. It does get tricky if you want to do it non-blocking: I would test UCSR0A & _BV(TXC0). Jun 16, 2016 at 12:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.