Hello everyone, I am having trouble getting the full range out of the ToFFuture XT-S1 ranging module. I can get to around 12000mm (39ft) without issue, but after that, the sensor jumps to over 65000mm (213ft). The documentation says the sensor should work out to 30m (98ft) which is significantly further than what I am getting. I guess the main thing I am unsure about is if there is anything in my code that is limiting the performance of the sensor.
Thank you in advance for your time!
Further Informaion:
I have tried the sensor both indoors and outdoors with the same results.
I am running the sensor via UART and it is connected to an Arduino Nano.
The output is sent to a 0.96" tft display (ST7735S).
I am unable to upload the product manual PDF for the sensor since I am a new user.
#include <Adafruit_GFX.h> // Core graphics library
#include <Adafruit_ST7735.h> // Hardware-specific library for ST7735
#include <SPI.h>
#include <ModbusMaster.h>
// Module connection pins
#define CLK 2
#define DIO 3
// TFT screen connection pins
#define TFT_CS 10
#define TFT_RST 8 // Or set to -1 and connect to Arduino RESET pin
#define TFT_DC 9
#define TFT_MOSI 11 // Data out
#define TFT_SCLK 13 // Clock out
// For ST7735-based displays, we will use this call
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCLK, TFT_RST);
float p = 3.1415926;
/************************* Kalman Filter *******************************/
bool filters_klm_on = true;
uint16_t klm_factor = 300;
uint16_t klm_threshold = 300;
int last_time = 0;
uint16_t last_distance = 0;
void doKlmFilter(uint16_t & distance)
{
if(filters_klm_on)
{
bool bfilterstart = false;
int currentTime = millis();
if(abs(currentTime - last_time)<300)//300ms
bfilterstart = true;
last_time = currentTime;
if((distance < 64000)&&(last_distance < 64000)&& bfilterstart)
{
int32_t diff = distance - last_distance;
if (abs(diff) < klm_threshold)
{
uint32_t result = 0;
result = (((distance * klm_factor) + (last_distance * (1000-klm_factor))) / 1000);
distance = result;
}
}
last_distance = distance;
}
}
/********************************************************/
ModbusMaster master;
void setup() {
Serial.begin(115200);// Serial Bitrate 115200
master.begin(1, Serial);// Default Modbus slave id is 1
tft.initR(INITR_MINI160x80_PLUGIN); // Init ST7735S mini display
uint16_t time = millis();
tft.fillScreen(ST77XX_BLACK);
time = millis() - time;
tft.setRotation(3);
tft.setTextSize(2);
tft.setCursor(0, 0);
tft.print("Mini Ranger"); //Product Name
tft.setCursor(0, 40);
tft.setTextSize(3);
}
// Initialize the device configuration
void recfgsensor()
{
// Set the current register to 0
master.writeSingleRegister(0, 0);
// Set the outgoing mode to 0x0001 for passive reception result mode
master.writeSingleRegister(61, 0x0001);// Direct reception
// Set the measurement cycle register to 200ms
master.writeSingleRegister(66, 200);// Measurement cycle 200ms
// Set the 3rd register to 0x0001: start measuring
master.writeSingleRegister(3, 0x0001);
// Set the 3rd register to 0x0002: stop measuring
// master.writeSingleRegister(3, register set to 0x0002);
}
bool checkConnect()
{
if (master.readInputRegisters(22, 4) == master.ku8MBSuccess)// Read 4 registers starting from position 22.
{
uint16_t data[4];
for (int i = 0; i < 4; i++)
{
data[i] = master.getResponseBuffer(i);
}
return true;
}
return false;
}
uint16_t timeout_count = 0;
bool isConneced = false;
void loop() {
int k;
uint8_t data1[] = { 0xff, 0xff, 0xff, 0xff};
uint8_t blank[] = { 0x00, 0x00, 0x00, 0x00};
uint8_t result;
uint8_t data[10];
int i=0;
if(isConneced == false)
{
if(checkConnect())
{
isConneced = true;
timeout_count = 0;
recfgsensor();
Serial.println("connected");
}
}else
{
if(Serial.available())
{
timeout_count = 0;
delay(1); // Delay 1 ms to wait for a frame of data to be received
while (Serial.available() > 0) {
char c = Serial.read();
if(i<9)
data[i]= c;
i++;
}
if (i >= 9)// If 9 bytes are received
{
uint16_t dist = (data[3]<<8)|data[4];
Serial.println(dist);
doKlmFilter(dist);
if(dist < 64000)
{
// Calculate display value in hundredths of feet
float displayValue = dist/304.8; //conversion from mm to ft.
// Write the value to the tft display.
tft.setTextColor(ST77XX_WHITE);
tft.print(displayValue);
tft.print(" ft");
delay(2000);
// Clear the value by overwriting in black and then resetting the cursor.
tft.setTextColor(ST77XX_BLACK);
tft.setCursor(0, 40);
tft.print(displayValue);
tft.print(" ft");
tft.setCursor(0, 40);
}else
{
// If the distance is over 64000 mm (209.97ft) display the error message.
tft.setTextColor(ST77XX_WHITE);
tft.print("Too Far");
delay(2000);
//Clear the error message and reset the cursor position.
tft.setTextColor(ST77XX_BLACK);
tft.setCursor(0, 40);
tft.print("Too Far");
tft.setCursor(0, 40);
}
}
}else{
timeout_count ++;
if(timeout_count > 20)// If no data is received for 2 seconds, it is considered that the device has been disconnected
{
timeout_count = 0;
isConneced = false;
Serial.println("Disconnect");
}
}
}
delay(10); // Delay 0.1s
}