Teensy 4.1, Modbus RTU, Sparkfun BOB-10124

apaulisch

New member
I am building an ultrasonic wing instrument for my boat. The interface to the instrument is RS485. I can access and interact with the wind instrument with an RS485 USB dongle and my PC. So far so good.
I would now like to poll the same device with a Teensy 4.1. I have a Sparkfun BOB-10125 breakout board that is 3.3V powered. I'm using the Arduino 2.3.2 IDE, and the Teensyduino 1.59.
Downloaded and installed the ModbusArduino Library, and the Arduino RS485 library. Looked at the sample code for the Temperature Sesnsor. My requirements are almost identical, so I started with that.. I read through a bunch of posts on this forum but I'm still stumped on how to get the Serial1 hardware port to work, specifically I'm not sure where to connect the RTS bin on the BOB.. I tried pin 2 on the teensy, but that didn't work..
Teensy-bob10124 wiring.jpg


C++:
/*
  Modbus RTU Wind Sensor Sensor

  This sketch shows you how to interact with a Modbus RTU wind speed and direction sensor.
  It reads the speed and direction va;ues continuously and outputs them to the
  serial monitor.

  Based on teh sample temperature provided by
  by Riccardo Rizzo
*/

#include <ArduinoRS485.h>
#include <ArduinoModbus.h>


float windspeedms;
float winddirction;

void setup() {
  Serial.begin(9600);
  while (!Serial);

  Serial.println("Modbus Wind Sensor");
  Serial1.transmitterEnable(2);
  // start the Modbus RTU client
  if (!ModbusRTUClient.begin(9600)) {
    Serial.println("Failed to start Modbus RTU Client!");
    while (1);
  }
  Serial1.transmitterEnable(2);
}

void loop() {

  // send a Holding registers read request to (slave) id 1, for 2 registers
  if (!ModbusRTUClient.requestFrom(1, HOLDING_REGISTERS, 0x00, 2)) {
    Serial.print("failed to read registers! ");
    Serial.println(ModbusRTUClient.lastError());
  } else {
    // If the request succeeds, the sensor sends the readings, that are
    // stored in the holding registers. The read() method can be used to
    // get the raw temperature and the humidity values.
    short rawwindspeedms = ModbusRTUClient.read();
    short rawwinddirction = ModbusRTUClient.read();

    // To get the temperature in Celsius and the humidity reading as
    // a percentage, divide the raw value by 10.0.
    windspeedms = rawwindspeedms / 100.0;
    winddirction = rawwinddirction;
    Serial.println(windspeedms);
    Serial.println(winddirction);
  }

  delay(50);
}

I can see the transmit LED pulse on the BOB, but in the serial monitor I keep getting timeout errors..
Code:
Modbus Wind Sensor
failed to read registers! Connection timed out
failed to read registers! Connection timed out
failed to read registers! Connection timed out

Did I maybe get my RX/TX lines crossed? If anyone has the BOB-10125 working with their Teensy 4.1 any help would be appreciated..
 
OK, took me a while to figure out you meant BOB-10124... This board.
It is indeed not really clear from the schematic and silkscreen on the PCB but the RTS signal should be connected to pin 4 of J9:
1712512699737.png

The LED will be ON when transmitting and OFF while receiving.

Paul
 
Yep.. that's how I have it connected.. Pin 2 on the Teensy to the RTS on the BOB.. Serial1.transmitterEnable(2) seems to set it up correctly..
the I can see the LED on the BOB blinking when I transmit..
I just never seem to get anything back from the device.. (when I hook up the device to an RS485 to USB adapter on the PC it works great.. )..

For testing, I have the RS485 USB dongle on COM7, and the Teensy on COM8.. a nice twisted pair in between.. A to A, B to B.. Gnd, to GND.. I should be able to send anything, and something should arrive on the other end.. (never mind the MODBUS part, I'll settle for a single character :)
 
SOLVED: I got things working somewhat, but communications were very intermittent.. After repowering the Teensy, I'd get one or two clean transmissions and then a lot of garbage, or just 0x00's
If it worked intermittently it couldn't be the code, it had to be the circuit. I hooked up my scope, and sure enough there was all kinds of unstable noise on the A/B lines.. I added two 600 Ohm bias resistors.. (from A to 3,3v, and from B to GND).. that did the trick.. nice and stable now.. Now I can go back and fiddle with the software :)
If anyone else is working with a Teensy 4.1 and Sparkfun BOB-10124 RS485 breakout, remember to add bias resistors.. I also added a 120 Ohm terminator.. that one was fairly obvious.. Everything now works really well with the ModBus library..

Here is the code, in case anyone is interested..

C:
/*
  Modbus RTU Wind Sensor Sensor

  This sketch shows you how to interact with a Modbus RTU wind speed and direction sensor.
  It reads the speed and direction va;ues continuously and outputs them to the
  serial monitor.

  Based on teh sample temperature provided by
  by Riccardo Rizzo
*/

#include <ArduinoRS485.h>
#include <ArduinoModbus.h>

float windspeedms;
int winddirction;
float maxwindspeedms;
int windscale;

void setup() {
  Serial.begin(9600);
  while (!Serial);

  Serial.println("Modbus Wind Sensor");
 
  // start the Modbus RTU client
  if (!ModbusRTUClient.begin(9600,SERIAL_8N1)) {
    Serial.println("Failed to start Modbus RTU Client!");
    while (1);
  }
  Serial1.transmitterEnable(2);
  //Serial1.attachRts(2);
  delay(10);
}

void loop() {

  // send a Holding registers read request to (slave) id 1, for 2 registers
  if (!ModbusRTUClient.requestFrom(1, HOLDING_REGISTERS, 0x00, 4)) {
    Serial.print("failed to read registers! ");
    Serial.println(ModbusRTUClient.lastError());
  } else {
    // If the request succeeds, the sensor sends the readings, that are
    // stored in the holding registers. The read() method can be used to
    // get the raw temperature and the humidity values.
    short rawwindspeedms = ModbusRTUClient.read();
    short rawwinddirction = ModbusRTUClient.read();
    short rawmaxwindspeedms = ModbusRTUClient.read();
    short rawwindscale =  ModbusRTUClient.read();

    windspeedms = rawwindspeedms / 100.0;
    winddirction = rawwinddirction;
    maxwindspeedms = rawmaxwindspeedms / 100.0;
    windscale = rawwindscale;
    Serial.print("Windspeed: ");
    Serial.print(windspeedms);
    Serial.print("m/s   Direction: ");
    Serial.print(winddirction);
    Serial.print("deg   Max Windspeed: ");
    Serial.print(maxwindspeedms);
    Serial.print("m/s   Beauford Scale:");
    Serial.println(windscale);
  }
}
 
Art and Science of RS485 from Circuit Cellar Ink magazine way back in 1999 is always a good thing to read when starting out with RS485. Google usually turns up a link or two to a copy.

Some of the MAXIM chips have slightly altered input thresholds which make idle bias redundant. Although I still include it in some form.
 
Back
Top