trying to use SEN0492 Laser ranging sensor with a UNO R3 and RS485 shield
I am relatively new to Arduino sketching. I have successfully built ultrasonic JSN level sensors but have struggled with inconsistent results when used inside an outdoor frac tank. It appears to be due to the high temp and humidity in the afternoon sun condensing on the sensor.
I have also used RS485 to communicate the level readings long distance between 2 Arduino's using the RS485 shields. I then converted my tank sketch to use the SEN 0246 RS485 ultrasonic sensor, communicating to an UNO via the RS485 shield, but still experience inconsistent results.
I am now trying to convert the sketch I used for SEN0246 to be used with the SEN0492 laser sensor to see if that technology might perform better in this harsh environment. I really struggle with the Modbus protocol and cannot find any example code where someone has done a similar project with the UNO.
With only one serial port, my troubleshooting has been limited to modifying the code to display parameters on the LCD screen. I was able to verify that the sketch loads the modbus parameters into the array, and then writes them via serial connection to the RS485. I have also verified that there appears to be nothing returned on the serial port, because the sketch never enters the while loop for serial data. I suspect that I am not sending the proper protocol to the sensor, but my limited knowledge of Modbus leaves me scratching my head.
see attached sketch below, Any suggestions?
/**************************************************************************************************************
THIS SKETCH IS NON_FUNCTIONAL
*This code was originally written to test the range finder function of the URM08-RS485 Waterproof Sonar Range Finder
the original author : [email protected], date : 11.09.2017; version: 1.0
Code was Modified by SFH 6/22/23 to work on an arduino UNO R3 , using a RS485 shield and DFRobot SEN0492 sensor being
used to detect water level and calculate distance to water(gap). The readings are averaged and the result is
calculated and displayed in waterlevel in inches and gallons. simular code wos succesfully used with SEN0246 ultrasonic sensor
rs-485 shield https://www.dfrobot.com/product-1024.html
LCD shield https://www.robotshop.com/products/cytron-lcd-keypad-shield-arduino
SEN0492- laser sensor https://www.dfrobot.com/search-sen0492.html
external wiring via Screw shield https://www.robotshop.com/products/dfrobot-proto-screw-shield-assembled
**************************************************************************************************************/
//parameters to communicate via RS485 to the sensor
#define address 0x50 //Slave Address
#define function 0x03 //funtion Code
#define register_H 0x00 //Register Address High bit
#define register_L 0x34 //Register Address Low bit
#define length_H 0x00 //Read Length high bit
#define length_L 0x01 //Read Length low bit
#define CRC_H 0xC8 //CRC check High bit
#define CRC_L 0x45 //CRC check low bit
unsigned char CMD[8]={address,function,register_H,register_L,length_H,length_L,CRC_H,CRC_L}; //declare an array with 8 elements(plus null) to store the Distance measurement commands
//varible and array to recieve data from sensor
unsigned int Distance=0; // delare and set varible Distance to 0cm at start
unsigned char Rx_DATA[8]; //declare char Rx_Data array with 8 elements (plus one for the null)
//programming delays
int dt=1000; //a delay period before taking the next measurement
int setTime=100; // a delay used to allow serial coms to iniyialize
int wait = 200; // a delay to allow serial data to be returned
//median sorting parameters
#include "QuickStats.h"
int const numReadings = 14; //set the number of readings to include for statistical analysis
float med [numReadings]; //create an array to store 'numReadings' measurements that can then be sorted and use only the median data
QuickStats stats; //initialize an instance of this class
//varibles for water calulations
float convert = 0.393701; //conversion factor form cm to inches
float measure; //a float varible to store the calculated distance
long gallons; //declares the float varible gallons
long waterLevel; //declares waterLevel varible
int tankDepth = 104; //declares total tank depth varible
float gallonsPerInch = 202.38; //declares gallons per inch varible
#include <LiquidCrystal.h> //invokes the liquidCrystal library needed for the LCD display
int d4=4; //declares varible d4 (LCD d4 pin) to Arduino pin 4
int d5=5; //declares varible d5 (LCD d5 pin) to Arduino pin 5
int d6=6; //declares varible d6 (LCD d6 pin) to Arduino pin 6
int d7=7; //declares varible d7 (LCD d7 pin) to Arduino pin 7
int rs=8; //declares varible rs (LCD rs pin) to Arduino pin 8
int en=9; //declares varible en (LCD en pin) to Arduino pin 9
LiquidCrystal lcd (rs,en,d4,d5,d6,d7); //sets up LCD pins using the varibles declared above
void setup() {
Serial.begin(19200); //Communicate with module via Serial, set baud rate to 19200
delay(setTime);
lcd.begin(16,2); // starts the LCD, specifies columns and rows on the LCD
} //end of setup
void loop() {
int x = 0; // Declare and set varible x to 0
int i = 0; // Declare and set varible i to 0 at start(changed from unsigned char)
for (x=0;x<numReadings;x++){ //cycles through the for loop "numReading" times to store data in the median array for averaging
delay (wait); //wait for silent interval before sending request
//TX for loop
for(i=0;i<8;i++){ // cycles though the for loop 8 times to send all 8 portions of the command string
// Serial.write(CMD[i]); //sends the whole command string from the array to the sensor to return distance
}//end of transmit "for" loop
// RX data
delay(wait); //Wait for the end of distance measurement
i=0; //resets i to 0
while (Serial.available()){ //Read return data package (NOTE: Demo is just for your reference, the data package haven't be calibrated yet)
Rx_DATA[i++]=(Serial.read()); //reads each of the 8 packets and stores them in the Rx_Data array
//print functions inserted here verify that serial is not being recieved as the program never enters the while loop
} // end of recieve while loop
Distance=((Rx_DATA[3]<<8)|Rx_DATA[4]); //Get the distance data,(reads element 4(3), then shifts it left by 8, then does a bitwise OR with element 5(4))
//this math is way beyond my understanding
med[x] = Distance; //store each distance measuement in the 'med' array
} //end of median array "for" loop
Distance = (stats.average(med,numReadings)); //takes the average of 'numReading' in 'med' array
//calculations of water level gallons etc.
measure = Distance * convert; //convert cm distance to inches
waterLevel = tankDepth-measure; //calcualtes water level
gallons= waterLevel*gallonsPerInch; //calculates the total gallons
int level = int(waterLevel); //convert Float to integer
int gal = int(gallons); //convert Float to integer
int inch = int(measure); //convert Float to integer
//print results to LCD screen
lcd.clear(); //clears the LCD screen
lcd.setCursor(0,0); // sets cursor to top left of the screen
lcd.print(level); //prints the calculated inches of water
lcd.print(" In of ");
lcd.print(tankDepth); //prints the total tank depth
lcd.setCursor(0,1); // sets cursor to bottom left of the screen
lcd.print (gal);// prints the calculated gallons varible
lcd.print(" G ["); // prints text listed
lcd.print(inch); //prints the measured distance to water
lcd.print("]gap"); // prints text listed
delay(dt); //a delay period to allow last items displayed on LCD to be viewed without flicker
}
had to paste the working code in three separate comments;
/**************************************************************************************************************
*This code was originally written to test the range finder function of the URM08-RS485 Waterproof Sonar Range Finder
the original author : [email protected], date : 11.09.2017;
Code was Modified by SFH 8/15/23 to work on an arduino UNO R3 , using a RS485 shield and DFRobot SEN0492 laser sensor being
used to detect water level and calculate distance to water(gap). The readings are evaluated statistically averaging data and the result is
calculated and displayed in waterlevel in inches and gallons. simular code was succesfully used with SEN0246 ultrasonic sensor
RS-485 shield https://www.dfrobot.com/product-1024.html
LCD shield https://www.robotshop.com/products/cytron-lcd-keypad-shield-arduino
SEN0492- laser sensor https://www.dfrobot.com/search-sen0492.html
external wiring via Screw shield https://www.robotshop.com/products/dfrobot-proto-screw-shield-assembled
library quickstats that is used to evaluate the data https://github.com/dndubins/QuickStats
**************************************************************************************************************/
//parameters to communicate via RS485 to the sensor
#define address 0x50 //Slave Address
#define function 0x03 //funtion Code
#define register_H 0x00 //Register Address High bit
#define register_L 0x34 //Register Address Low bit
#define length_H 0x00 //Read Length high bit
#define length_L 0x01 //Read Length low bit
#define CRC_H 0xC8 //CRC check High bit
#define CRC_L 0x45 //CRC check low bit
unsigned char CMD[8]={address,function,register_H,register_L,length_H,length_L,CRC_H,CRC_L}; //declare an array with 8 elements(plus null) to store the Distance measurement commands
//varible and array to recieve data from sensor
unsigned int Distance=0; // delare and set varible Distance to 0 mm at start
unsigned char Rx_DATA[8]; //declare char Rx_Data array with 8 elements (plus one for the null)
//programming delays
int dt=30; //a delay period before taking the next measurement
int setTime=100; // a delay used to allow serial coms to iniyialize
int wait = 200; // a delay to allow serial data to be returned
//median sorting parameters
#include "QuickStats.h" //the library needed for statistical calculations
int const numReadings = 5; //set the number of readings to include for statistical analysis
float med [numReadings]; //create an array to store 'numReadings' measurements that can then be sorted and use only the median data
QuickStats stats; //initialize an instance of this class
Stan.Howe//varibles for water calulations
float convert = 25.4; //conversion factor from mm to inches
float measure; //a float varible to store the calculated distance
int calibrate = 1.0;// a caibration factor that can be used to fine tune the readings for accuracy
long gallons; //declares the float varible gallons to store calculated gallons in the tank
long waterLevel; //declares waterLevel varible to store the calculated water level
int tankDepth = 104; //declares total tank depth varible
float gallonsPerInch = 202.38; //declares gallons per inch varible
#include <LiquidCrystal.h> //invokes the liquidCrystal library needed for the LCD display
int d4=4; //declares varible d4 (LCD d4 pin) to Arduino pin 4
int d5=5; //declares varible d5 (LCD d5 pin) to Arduino pin 5
int d6=6; //declares varible d6 (LCD d6 pin) to Arduino pin 6
int d7=7; //declares varible d7 (LCD d7 pin) to Arduino pin 7
int rs=8; //declares varible rs (LCD rs pin) to Arduino pin 8
int en=9; //declares varible en (LCD en pin) to Arduino pin 9
LiquidCrystal lcd (rs,en,d4,d5,d6,d7); //sets up LCD pins using the varibles declared above
Stan.Howevoid setup() {
Serial.begin(115200); //Communicate with module via Serial, set baud rate to 115200
delay(setTime); //delay to allow serial coms to establish
lcd.begin(16,2); // starts the LCD, specifies columns and rows on the LCD
} //end of setup
void loop() {
int x = 0; // Declare and set varible x to 0
int i = 0; // Declare and set varible i to 0 at start(changed from unsigned char)
for (x=0;x<numReadings;x++){ //cycles through the "for" loop "numReading" times to store data in the median array for averaging
delay (wait); //wait for silent interval before sending request
//TX sub-"for" loop
for(i=0;i<8;i++){ // cycles though the for loop 8 times to send all 8 portions of the command string
Serial.write(CMD[i]); //sends each portion of the command string from the array to the sensor to return distance
}//end of transmit "for" loop
// RX data
delay(wait); //Wait for the end of distance measurement
i=0; //resets i to 0
while (Serial.available()){ //Read return data package
Rx_DATA[i++]=(Serial.read()); //reads each of the 8 packets and stores them in the Rx_Data array
} // end of recieve while loop
Stan.HoweDistance=((Rx_DATA[3]<<8)|Rx_DATA[4]); //Get the distance data,(reads element 4(3), then shifts it left by 8(multiplies by 256),
// then does a bitwise OR (it is really addition) with element 5(4))
med[x] = Distance; //store each distance measuement in the 'med' array
} //end of median array "for" loop
Distance = (stats.average(med,numReadings)); //takes the average of 'numReading' in 'med' array and stores it in the distance varible
//calculations of water level gallons etc.
measure = (Distance/convert)+calibrate; //convert mm distance to inches and calibrate the probe
int inch = round(measure); //convert Float to integer and round it off for display on LCD
waterLevel = tankDepth-inch; //calcualtes water level
gallons= waterLevel*gallonsPerInch; //calculates the total gallons
int level = int(waterLevel); //convert long to integer
int gal = int(gallons); //convert Float to integer
//print results to LCD screen
lcd.clear(); //clears the LCD screen
lcd.setCursor(0,0); // sets cursor to top left of the screen
lcd.print(level); //prints the calculated inches of water
lcd.print(" In of "); // prints text listed
lcd.print(tankDepth); //prints the total tank depth
lcd.setCursor(0,1); // sets cursor to bottom left of the screen
lcd.print (gal);// prints the calculated gallons varible
lcd.print(" G ["); // prints text listed
lcd.print(inch); //prints the measured distance to water
lcd.print("]gap"); // prints text listed
delay(dt); //a delay period to allow last items displayed on LCD to be viewed without flicker
}
Stan.HoweSOLVED
I had the wrong baud rate for this sensor. Have also calibrated my sensor based on testing (your mileage may vary). it wouldnt let me upload the new code- too many characters, ill try under a comment or two
/
Stan.HoweI had avoided those libraries in my sketch because they say they are not compatible with the Uno. But I gave your sketch a try anyway, and just a blank screen on the LCD.
thank you for trying
Stan.HoweHi!
pls try this code:
https://drive.google.com/file/d/14f1ELrnQ3wlZi4tULrVRWbt8kCTM3aDJ/view?usp=drive_link
It is recommended that you install related libraries in Arduino ide.
jenna