TroubleshootingArduino

trying to use SEN0492 Laser ranging sensor with a UNO R3 and RS485 shield

userHead Stan.Howe 2023-06-28 18:54:27 446 Views7 Replies

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

 

}

2023-08-17 02:45:05

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

userHeadPic Stan.Howe
2023-08-17 02:44:01

//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

userHeadPic Stan.Howe
2023-08-17 02:43:52

void 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

userHeadPic Stan.Howe
2023-08-17 02:42:12

   Distance=((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

 

}

userHeadPic Stan.Howe
2023-08-16 03:51:31

SOLVED

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

 

 

 

/

userHeadPic Stan.Howe
2023-06-29 20:35:10

I 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

userHeadPic Stan.Howe
2023-06-29 18:08:14

Hi!

 

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.

userHeadPic jenna