Go Down

Topic: problems interfacing with RS485 (Read 408 times) previous topic - next topic

frichsness

hello

i am new here and i don's have much knowledge in the area of programming (arduino's or anything else) but hopefully that will change :)

i have come across a Thies Clima ultrasonic wind sensor, and i would very much like to get that turned into part of a weather station. it uses RS485 MODBUS or thies interpretation to display wind speed, direction and temperature.

if i use the Thies software i can get the data in a serial monitor, by using an RS485 to USB converter. so i know i have the wirering ad the connection data correct.

the problem with that is that it is too limited, and i would like to get the data by using an Arduino so that in the long run i can add more sensors (pressure or rainfall) and possibly add it to a web server using a raspberry pi.

but my main problem is that i cannot seem to get any sketch that works, and every application of this RS485 seems to be a completely different code.

so i was hoping that one or more of you could help me out with the basics for a sketch. basically just setting the Arduino to master, reading the data and then displaying it in the serial monitor.

i have added a picture of the MODBUS settings for the unit and the manual for it.
i know how to work with the hardware, i just dont know how to make the code, once i have a code i can usualy see how it works. i just dont have the experience to write it from scratch :(

the unit is programmed up to start sending data as soon as it boots up, in MODBUS mode it sends a long string of HEX code, and in Thies mode it just sends 3 numbers on 1 line (speed, direction and temp)

i hope one of you can help me out with the basic code for getting data.

adwsystems

RS-485 is hardware. Modbus is Software. You can use Modbus with different hardware, you can use RS-485 with different softare (protocols). You need to be sure to combine, but not mix the two. You have Modbus over RS-485. Good.

Which Modbus? Modbus ASCII or Modbus RTU?

Which RS-485 hardware card do you have to put between the sensor and the Arduino? (ie., which break out board?)


frichsness

ohh sorry forgot to mention the hardware :)

i have Arduino nano and UNO here at the moment, along with MAX485 RS-485 Module
For the testing with a laptop i used an USB to RS485 converter'

the sensor is running MODBUS-RTU half duplex bus mode

adwsystems

I used the smarmengol library with much success. Have you tried this one?

With this library the program can function as master or slave (nice two-in-one feature so I don't have to have two libraries). The library and example do need to be reworked to fix the improper use of millis(), there is enough information around to search the fix. The examples are pretty good and overall I find it flexible enough.

frichsness

tried out the smarmengol library, but no luck

i tried a good selection of the sketches listed as excamples, but noone of them worked :(


this is the code i used that gave me the most response

but i just get squares and ?'s in the serial monitor

Code: [Select]

#include <ModbusRtu.h>

uint16_t au16data[16];
uint8_t u8state;

Modbus master(0,0,3); // this is master and RS-232 or USB-FTDI

modbus_t telegram;

unsigned long u32wait;

void setup() {
  master.begin( 9600 );
  master.setTimeOut( 2000 );
  u32wait = millis() + 1000;
  u8state = 0;
}

void loop() {
  switch( u8state ) {
  case 0:
    if (millis() > u32wait) u8state++;
    break;
  case 1:
    telegram.u8id = 10; // slave address
    telegram.u8fct = 3; // function code (this one is registers read)
    telegram.u16RegAdd = 1; // start address in slave
    telegram.u16CoilsNo = 4; // number of elements (coils or registers) to read
    telegram.au16reg = au16data; // pointer to a memory array in the Arduino

    master.query( telegram );
    u8state++;
    break;
  case 2:
    master.poll();
    if (master.getState() == COM_IDLE) {
      u8state = 0;
      u32wait = millis() + 100;
    }
    break;
  }
}

adwsystems

The serial monitor can only display alphanumeric ascii values. What you you think it will display when the value byte value '16' is sent? Since it is not ascii, it will display a square,?, or other garbage character.

Furthermore, the arduino is a master (per the program posted) and you are trying to read registers from the serial monitor. The serial monitor has no 'registers' for the master to read.

I think you need to (re)think your test setup and contemplate what each piece is doing and/or can do.

frichsness

The serial monitor can only display alphanumeric ascii values. What you you think it will display when the value byte value '16' is sent? Since it is not ascii, it will display a square,?, or other garbage character.

Furthermore, the arduino is a master (per the program posted) and you are trying to read registers from the serial monitor. The serial monitor has no 'registers' for the master to read.

I think you need to (re)think your test setup and contemplate what each piece is doing and/or can do.
hmmm okay

when i use the software from the manufacturer of the sensor i get a whole list of HEX "blocks" (like a mac adresse) and i was actualy assuming (apparently i was wrong) that i would receive the same in the serial monitor of the arduino. again i am no where close to being able to program much more than an on off switch on the arduino.

i assumed that there had to be a master somewhere ? is that wrong ?

from looking into the terminal monitor on the manufacturer software i get the following info

in what they call "thies interpreter"
Code: [Select]
20:19:02: 10TR2

20:19:02: 00.1 271 +24.0 5E*48

20:19:03: 10TR2

20:19:03: 00.1 282 +24.0 5E*44


in MODBUS RTU mode
Code: [Select]
20:19:40: 0A 04 88 B9 00 1C 0A FD  (MODBUS-REQUEST: SlaveAddr=0A FctCode=04 RegAddr=88B9 RegCnt=001C)

20:19:41: 0A 04 38 00 00 00 01 FF FF FF FF 00 00 09 F4 FF FF FF FF 00 00 00 F6 00 00 00 F2 FF FF FF FF FF FF FF FF 01 32 69 E5 00 00 01 63 00 00 00 5E 00 00 00 F1 00 03 99 47 00 00 00 00 DA FF  (MODBUS-RESPONSE: SlaveAddr=0A FctCode=04 ByteCnt=38 DecodedData=1, 4294967295, 2548, 4294967295, 246, 242, 4294967295, 4294967295, 20081125, 355, 94, 241, 235847, 0)
20:19:41: 0A 04 88 B9 00 1C 0A FD  (MODBUS-REQUEST: SlaveAddr=0A FctCode=04 RegAddr=88B9 RegCnt=001C)

20:19:42: 0A 04 38 00 00 00 01 FF FF FF FF 00 00 09 9F FF FF FF FF 00 00 00 F5 00 00 00 F2 FF FF FF FF FF FF FF FF 01 32 69 E5 00 00 01 64 00 00 00 5E 00 00 00 F1 00 03 9D 2F 00 00 00 00 5A B0  (MODBUS-RESPONSE: SlaveAddr=0A FctCode=04 ByteCnt=38 DecodedData=1, 4294967295, 2463, 4294967295, 245, 242, 4294967295, 4294967295, 20081125, 356, 94, 241, 236847, 0)


and at connect i get this info
Code: [Select]
Interpreter: THIES
baudrate    : 9600
Framing     : parity=N data=8 stop=1 rts=off dtr=off
ID             : 10

SW-VER     : 003.10
Art.-Nr.      : 4.3875.00.390

)
--------- COM4,9600,0,0,8,0,1,4294967295,0,100,0,100, ------------


but looking at it am i right in assuming that the first line is a request for data and then the second is the response (then repeated) ?

it would be easiest for me if i could read the Thies Interpreter directly, but i doubt i would be able to find anything that can read that since it seems fairly company specific.

so the MODBUS RTU have to do, but my main goal at the moment is just to get the arduino to send the request , read the data and write it in the serial monitor. that should be possible correct ?

any help is very much appreciated.

adwsystems

Should be. The data from the Thies Interpreter tells you exactly how to set up the request telegram and read the response telegram.

Serial port 0 on the UNO is also the port that communicates with the USB to the PC. You are asking it to do double duty. For projects like this, I highly suggest using an Arduino with at least two hardware serial ports. The MEGA has the advantage that the UNO shields will fit it. Then you can leave serial 0 available for sending ascii debug code to the serial monitor and use serial 1 or 2 for the RS-485.

frichsness

okay

so i will need to get a hold of a mega, is there any of the other boards that has multiple serial ports ?
i am mainly thinking space, since the MEGA is kinda big, and i would prefer it to be a small combined package.

since i have to go shopping again, i figured i might aswell get the optimal solution right off the bat.

adwsystems

A few

Arduino Product List

As I mentioned, the advantage to the MEGA is shields from the UNO will fit it. Not the same with the Micro and a few others.

frichsness

might be able to get a hold of a MEGA on sunday, then i can try to get on with this project :)
anything else you could recommend while i am in the shop ? :)

i have been searching around for more info on this line, i did notice something similar in some of the examples i have tried.

COM4,9600,0,0,8,0,1,4294967295,0,100,0,100,

but there seems to be a couple of things i cant find (or doesnt understand) but the first is the port obviosly, and the next would be baud rate and polarity.

but what about that long number 4294967295 ?

adwsystems

#11
Oct 05, 2018, 04:14 pm Last Edit: Oct 05, 2018, 04:17 pm by adwsystems
4294967295 is the max size for a long (0xFF FF FF FF). See the run of 4 FF?

Looks like all the data is of long data type.

Windows 10 has a nice calculator with a programmer mode to easily convert dec to hex.

FF FF FF FF
00 00 09 F4
FF FF FF FF
00 00 00 F6
00 00 00 F2
FF FF FF FF
FF FF FF FF
01 32 69 E5
00 00 01 63
00 00 00 5E
00 00 00 F1
00 03 99 47
00 00 00 00

is the data

4294967295,
2548,
4294967295,
246,
242,
4294967295,
4294967295,
20081125,
355,
94,
241,
235847,
0

frichsness

okay managed to get a hold of an arduino MEGA, and after alot of reading i think i am getting a better understanding of serial communication (thou still a long way to go i fear)

but i have borrowed a sketch from microcontroller-project.com for sending data to another Arduino and getting a reply. i was hoping to use it to tap into the Thies interpreter, since that is open with no password needed, just needed to send a "telegram"

if it is in this mode i should be able to send "10TR00002" and get a reply (at least that is how i read it in the manual) i have attached that part of the manual if anyone is interestet.

using the following code at the moment.
Code: [Select]
void setup() {
 
  Serial1.begin(9600);//Using Serial1 Port
  Serial.begin(9600);
  pinMode(8, OUTPUT);//DE/RE Controling pin of RS-485
}

void loop() {
  char getdata='m';

  digitalWrite(8,HIGH);//DE/RE=HIGH Transmit Enabled M1
  Serial1.print("10TR00002");

   
  digitalWrite(8,LOW);//DE/RE=LOW Receive Enabled M1
  delay(1000);
 
  if(Serial1.available()){ //If Serial Data is available
   
    while(Serial1.available() && getdata!='d')
    {
    getdata=Serial1.read();
    Serial.print(getdata);
    }
   
    Serial.println("1");
    }
  Serial.println("2");
  delay(1000);
}


MAX485 data pins connected to serial 1 ont he MEGA, with the send/recieve pins is connected to pin8

when running i get 1 and 2 in my serial monitor, but no data from the sensor.
if i disconnect the sensor i only get the 2, so in my mind it looks like the connection is there, i am just not sending the right codes, or not reading it right.

am i completely on the wrong track here ? i figured i would try to simplest for now, and see if i could avoid the modbus rtu, if it isnt needed.

the sensor is normaly working with this thies interpreter, connected to a PLC. and if i connect to it via Putty and type in 10TR2 i get a response with the data.

so what am i missing in the code ?


adwsystems

#13
Oct 09, 2018, 01:46 pm Last Edit: Oct 09, 2018, 01:53 pm by adwsystems
Code: [Select]
 digitalWrite(8,HIGH);//DE/RE=HIGH Transmit Enabled M1
  Serial1.print("10TR00002");

  
  digitalWrite(8,LOW);//DE/RE=LOW Receive Enabled M1


This assumes the Serial1.print() statement completes before it moves on to the digitalWrite statement. This is not true, therefore the DE/RE line switches mid-transmission.

You can't avoid Modbus RTU, completely, This is the language begin used over RS-485. You may find a way to work around having to use a modbus libary, but you can't avoid the fact it speaks using modbus RTU.

How many MAX485 boards do you have? If you purchased multiple, being the boards are half-duplex you can use two and not worry about the DE/RE pin. Connect one to each of the Rx and TX pins and hardwire the RE/DE pin to fix the polarity (Rx/Tx). then you don't have to worry about switching or timing. Once you have this working, then you can work to reduce to a single board.

frichsness

i have plenty of the MAX485 so that isnt a problem.

but the sensor is only half duplex, so i dont realy see how i could hook it up to 2, unless i could just loop the RX and TX wires to both modules, similar to a setup with 3 RS485 units on one line.

but maybe i should hook up another arduino instead of the sensor so i can see if the entire command is sent and received.

but a delay inbetween the serial1.print and switching to recieve makes sense, 100ms could maybe work.

i will try to look into it again tonight.

Go Up