TFMini from Sparkfun

I am having some difficulty getting the TFMini to initiate. The Arduino library got ported over by me and wants to use SoftwareSerial. Would there be any alternative solutions? Thanks

edit: fixed spelling errors

@Allan, use Serial1 instead! One simple trick is to do this in your code (I used the example in this case):

#include <SoftwareSerial.h>  <---- comment this out

SoftwareSerial mySerial(10, 11);  <--- comment this out also

#define mySerial  Serial1    <---- Add this right after the SoftwareSerial line you commented out

The reset of the code and library should stay the same. Note that I haven’t tested this so you are the pioneer here :wink:

2 Likes

That worked thank you!!!

1 Like

Another issue I have ran into is utilizing an averaging method with the sensor. My code is below. It will give me a reading but it’s an incorrect one and does not update. any thoughts? Thanks

P.S. I don’t know how to do the fancy thing of putting the code in a grey box sorry.

//  Averaging Data from Sensor
    double readDistance(){

    char result = tfmini.getRecentSignalStrength();
    if (result >= 0)

    {

  // subtract the last reading:
  total = total - readings[readIndex];

  // read from the sensor:
  readings[readIndex] = tfmini.Distance[0].Distance;

  // add the reading to the total:
  total = total + readings[readIndex];

  // advance to the next position in the array:
  readIndex = readIndex + 1;

 // if we're at the end of the array...
  if (readIndex >= numReadings) {

    // ...wrap around to the beginning:
    readIndex = 0;

  }

  // calculate the average:
  average = total / numReadings;

Why is your result of type character?
What is this Distance[0] doing there?
Also if you want to call a function, your function call would usually finish with a set of parentheses.

like

 readings[readIndex] = tfmini.getDistance();

Without seeing your whole code, this is all rather confusing :confused:

I have no clue lol. Here is the rest of the code. It is rather messy because I’m pretty new to programming. Also
I tried getting ride of the fluff so there might be some stuff missing. Thanks!

#include <PowerShield.h>
#include "TFMini.h"
include <OneWire.h>
#include <Adafruit_RGBLCDShield.h>
#include <Adafruit_LiquidCrystal.h>

// Hardware Define
#define maxDistance 2000  // Min 30 - Max 2000 in mm
#define mySerial  Serial1 

//Averaging
// Define the number of samples to keep track of.  The higher the number,
// the more the readings will be smoothed, but the slower the output will
// respond to the input.  Using a constant rather than a normal variable lets
// use this value to determine the size of the readings array.
const int numReadings = 40;

int readings[numReadings];      // the readings from the analog input
int readIndex = 0;              // the index of the current reading
int total = 0;                  // the running total
int average = 0;                // the average

int PrevKey = 0;
unsigned char ErrorCount = 0;

PowerShield batteryMonitor;

//Set this to avoid having the device try to connect to the cloud
SYSTEM_THREAD(ENABLED);

//Initalize lcd class from adafruit
LiquidCrystal lcd(0);

//ParticleSoftSerial mySerial(39, 38);
TFMini tfmini;

Timer lcdtimer(17, updateLCDfun);
Timer timeout(5000, updateToMain, true); //5 second timer for returning to main screen when in submenu

struct levelValues{
    double shutdown;
    double alert;
};

bool updateLCD = false;
bool goToMain = false;
bool sec20time = false;
levelValues levels;
    
//  Averaging Data from Sensor
    double readDistance(){
//  unsigned int Distance = 0;
//  unsigned int Amplitude = 0;

    char result = tfmini.getRecentSignalStrength(); // Leddar1.getDetections();
    if (result >= 0)
    {
  // subtract the last reading:
  total = total - readings[readIndex];

  // read from the sensor:
  readings[readIndex] = tfmini.Distance[0].Distance;

  // add the reading to the total:
  total = total + readings[readIndex];

  // advance to the next position in the array:
  readIndex = readIndex + 1;

 // if we're at the end of the array...
  if (readIndex >= numReadings) {

    // ...wrap around to the beginning:
    readIndex = 0;
  }

  // calculate the average:
  average = total / numReadings;
  
    double feet = (average/304.8);
    double level = (36 - feet);                                                  
    double volume = (7.065 * level);                                               
    double gallons = (volume * 7.48);
    
    return(gallons);
    delay(1);  
    }
}

void updateLCDfun(){
    updateLCD = true;
}

void updateToMain(){
    goToMain = true;
}

void timerCallback();
void stimerCallback();//Forward declaration of timer callback function

Timer myTimer(600000, timerCallback); //Declare/define the software timer
Timer mysTimer(1200, stimerCallback); //Declare/define the software timer

void timerCallback(){
  myTimer.stop();
}

void stimerCallback(){
  mysTimer.stop();
}

void setup() {
   mySerial.begin(TFMINI_BAUDRATE);

  // Step 3: Initialize the TF Mini sensor
    tfmini.begin(&mySerial);    
    Serial1.begin(115200);
                
    Serial1.println("Serial Initalized!");
    
    //I2C Stuff
    lcd.begin(16, 2);
    Serial1.println("LCD Initalized!");
    
    Serial1.println("Rangefinder Initalized!");
    
    //Start Up Screen
    lcd.print("  Let's Get To");
    lcd.setCursor(0,1);
    lcd.print("      Work!");
    delay(1500);
    lcd.noAutoscroll();
    lcd.clear();
    lcd.home();
    
    lcdtimer.start();
    myTimer.start();
    mysTimer.start();
    Serial1.println("Setup done");
    
    Serial1.print("Shutdown: ");
    Serial1.println(levels.shutdown);
    Serial1.print("Alert: ");
    Serial1.println(levels.alert);
    }
}

void loop() {    
    static char curState = 0;
    static char nxState = 0;
    unsigned long now = millis();
    double gallons = readDistance();

   // Read the volatge of the LiPo
    float cellVoltage = batteryMonitor.getVCell();

    // Read the State of Charge of the LiPo
    float stateOfCharge = batteryMonitor.getSoC();                                              
                                            
    curState = nxState;
   
    switch (curState){
        case 0:             
            //Home screen 
            if (updateLCD) {
                updateLCD = false;
                lcd.home();
                lcd.print("   DOLI v2.8");
                lcd.setCursor(0,1);
                lcd.printf("Level:%.0f", gallons);                  
                lcd.print("gal                      ");
                }       	        
            }
        }
    }
}

I took the liberty to reformat, remove the automatic comments and some superfluous empty lines - but haven’t changed anyting in your code.

Then to the code:
Change char result to uint result just to avoid confusion.
Also your double readDistance() is not returning anything when if (result >= 0) is not satisfied. You need to add a return statement that throws back some error value for that case. For that case you may also want to add some Serial.print() statements to support debugging.
You also seem to be mixing mySerial and Serial1 but due to #define mySerial Serial1 both are exactly the same. As I guess mySerial is meant to communicate with TFMini I doubt your Serial1.print() statements would be appreciated by that. You may want to change these to Serial.print() instead.
And as said before readings[readIndex] = tfmini.Distance[0].Distance; should rather be readings[readIndex] = tfmini.getDistance();
Remove these unused timers myTimer and mysTimer() and everything in connection with them - they are good for nothing.

And more as a style than a programming advice: Correct the indendation of your code. This makes reading/understanding the code a lot easier.

I tried everything to no avail. So I reverted back to the Arduino example but I am still only receiving the max value. I went over my wiring and all appears correct. Here is the code.

// This #include statement was automatically added by the Particle IDE.
#include <PowerShield.h>

// This #include statement was automatically added by the Particle IDE.
#include "TFMini.h"

// This #include statement was automatically added by the Particle IDE.
#include <OneWire.h>

// This #include statement was automatically added by the Particle IDE.
#include <Debounce.h>

// This #include statement was automatically added by the Particle IDE.
#include <Adafruit_RGBLCDShield.h>

// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>

// This #include statement was automatically added by the Particle IDE.
#include <Adafruit_LiquidCrystal.h>

// Setup software serial port
//SoftwareSerial mySerial(10, 11); // Uno RX (TFMINI TX), Uno TX (TFMINI RX)

TFMini tfmini;
//#define mySerial Serial1

//Set this to avoid having the device try to connect to the cloud
SYSTEM_THREAD(ENABLED);

//Initalize lcd class from adafruit
LiquidCrystal lcd(0);

bool updateLCD = false;

void setup() {

// Step 1: Initialize hardware serial port (serial debug port)
Serial1.begin(115200);

// wait for serial port to connect. Needed for native USB port only
// while (!Serial1);

Serial1.println ("Initializing...");

// Step 2: Initialize the data rate for the SoftwareSerial port
Serial1.begin(TFMINI_BAUDRATE);

// Step 3: Initialize the TF Mini sensor
tfmini.begin(&Serial);
lcd.begin(16, 2);

}

void loop() {

// Take one TF Mini distance measurement
uint16_t dist = tfmini.getDistance();
uint16_t strength = tfmini.getRecentSignalStrength();

// Display the measurement
Serial1.print(dist);
Serial1.print(" cm sigstr: ");
Serial1.println(strength);

lcd.print(dist);
lcd.print(" cm sigstr: ");
lcd.println(strength);

// Wait some short time before taking the next measurement
delay(25);

}

You are still mixing Serial and Serial1
Serial is the one you should use for your debug output while Serial1 is the one you should be using for communication with your RFMini.

That's what this meant

How have you wired the device?

LCD: I2C (SCL, SDA)
TFmini: Rx Tx
Both connected to 5vdc

I changed everything over to the correct serial names but still am not getting the correct reading. Could it be something in the .cpp / .h files?

Actually the connection has two ends, and to tell whether the wiring is correct both ends should be stated. And for completeness I assume GND connected commonly to all devices?
Does your LCD work as expected?

Can you repost the code - possibly without all these superfluous lines of

// This #include statement was automatically added by the Particle IDE.

They are just a distraction.

1 Like
SYSTEM_THREAD(ENABLED);

LiquidCrystal lcd(0);

TFMini tfmini;

void setup() {
     
  Serial.begin(115200);
     
  Serial.println ("Initializing...");

  Serial1.begin(TFMINI_BAUDRATE);

  tfmini.begin(&Serial1);
  lcd.begin(16, 2);
  
}

void loop() {

  uint16_t dist = tfmini.getDistance();
  uint16_t strength = tfmini.getRecentSignalStrength();

  Serial.print(dist);
  Serial.print(" cm      sigstr: ");
  Serial.println(strength);
  
  
  lcd.printf(" cm  ");
  lcd.print(dist);
  lcd.setCursor(0,1);
  lcd.printf(" sigstr ");
  lcd.print(strength);

  delay(25); 
  
}

The LCD works with other projects I am doing.

I got it working! Apparently any Serial messages, like for debugging, blocks communication with the TFMini. When I commented out all the “Serial.println” commands I receive a reading. I don’t understand why so I am hoping to learn from the experts :wink:

I do have another issue when using a Power Shield with the sensor. It again blocks out the reading from the TFMini. When I remove the Power Shield and change nothing else (wiring, code, ect) everything works fine. I am wondering if the above issue may be related to this one. However, I see the Power Shield only uses I2C not serial for fuel gauge communication. Any thoughts? Thanks!

Solved the problem. It was me, I was the problem :wink:
I had the RX and TX wired incorrectly. I am confused on how it worked without the Power Shield, none the less, it’s fixed. I have the TFMini library with a working example to upload for the open source cause but I do not know how to do that yet. Once I research it, Ill get it uploaded.