Data logging (with UltraSonic Sensor) on request

Hi all,

I am working on a rain water tank level project using a waterproof ultrasonic which is activated via a relay. I was wondering if it was possible to log the measurement only when the relay is turned on?

1 Like

The answer is, maybe :wink: What measurement, how are you logging the data, where is your code…

Ok here’s my code. basically i would like to achieve to have the relay activate at regular intervals and take a reading then upload that reading to blynk then i’ll be able to graph the readings. I can’t leave the ultrasonic on as the reading eventually return an error after a short period of time.

     #define BLYNK_PRINT Serial   
     #include <SPI.h>
     #include <Ethernet.h>
     #include <BlynkSimpleEsp8266.h>
     #include <ESP8266WiFi.h>
     #include <SimpleTimer.h>
     char auth[] = "*****";
     SimpleTimer timer;

     #define echoPin 13 // Echo Pin
     #define trigPin 15 // Trigger Pin

     long duration, distance; // Duration used to calculate distance

     int volume;
     int percent;
      
     void MeasureCm()
     {
       /* The following trigPin/echoPin cycle is used to determine the
      distance of the nearest object by bouncing soundwaves off of it. */ 
      
      digitalWrite(trigPin, LOW); 
      delayMicroseconds(2); 

      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10); 
      
      digitalWrite(trigPin, LOW);
      duration = pulseIn(echoPin, HIGH);
      
      //Calculate the distance (in cm) based on the speed of sound.
      distance = duration/58.2;

      Serial.print("Distance: ");
      Serial.println(distance);
     }

     void VolumeLitres()
     {
       if (distance > 27 ){
       volume = (10155055.310263-(distance*((3.14159265359*(126.5*126.5)))))/1000;
        Serial.print("Volume: ");
        Serial.println(volume);
       }
        else {
       volume = 9000;
       Serial.print("Volume: ");
       Serial.println(volume);
       }
      }

     void PercentFull()
      {
      percent = ((float)volume/9000)*100;

      Serial.print("Percent: ");
      Serial.println(percent);
      Serial.println();
      }

       
     void setup() {
      Serial.begin(115200);
      Blynk.begin(auth, "****", "*****");
       
      pinMode(trigPin, OUTPUT);
      pinMode(echoPin, INPUT);
      
      timer.setInterval(5000, MeasureCm);
      timer.setInterval(5000, VolumeLitres);
      timer.setInterval(5000, PercentFull);
     }

      BLYNK_READ(V8)
      {
      Blynk.virtualWrite(8,volume);// virtualpin 8 volume
      }

      BLYNK_READ(V9)
      {
      Blynk.virtualWrite(9,percent);// virtualpin 9 percent
      }


     void loop() {
       Blynk.run(); // Initiates Blynk
       timer.run(); // Initiates SimpleTimer
     }

I am guessing that the purpose of the relay is to supply and cut power to the sensors?

Since you already have the sensor function on a timer, simply add the relay command to power up the sensor at the beginning, take your readings, send data to app, another command to power down the sensor… wait and repeat on whatever schedule you need.

I’m a bit confused by the need for a relay. I’ve not actually used any ultrasonic distance measuring hardware, but I understand the principal.
I’d have expected the hardware to sit there and do nothing until you send a ping to the trigger pin, at which point it should give you back an echo reading.
If you’re saying that it doesn’t like being powered-up with no ping applied then maybe you should look at what’s causing that behaviour. Power supply issues maybe?
Also, I wouldn’t have thought that ultrasonics was the best technology to use in a water barrel where you’re likely to get echos.

Looking at your code, you’re using three different simple timers to call three functions which measure the distance, calculate the volume and calculate the percentage full. I’d just use one timer that calls the measure distance function, then call the calculate volume and calculate percentage functions from the measure distance function. I guess this could be why your system is failing after time, as simple timer is effectively trying to call all three functions at the same time, as they all have the same delay.

If you did use a relay, or possibly even a spare pin on your device that you set high to provide power to V-in on your ultrasonic sensor, then you may need to build-in a short power-up delay before triggering a ping. Not sure if that would cause Blynk issues in this situation, so you may need to use another simple timer for this delay.

Pete.

Thanks @Gunner & @PeteKnight for your input. Based on your advice I have modified the code slightly so now I have only one timer running. I have also used the Eventor widget and set it to turn on the ultrasonic sensor hourly for 10 seconds. The problem now is because I have included the ‘if’ statement when I turn off the sensor the reading reverts back to 9000 litres. Is there a statement I can include in the code to hold the current reading until the next hourly reading?

I have included the ‘if’ statement because when the water level comes within 25cm to the sensor I get false readings due to the design of the ultrasonic.

Any advice will be much appreciated.

    #define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
    #include <SPI.h>
    #include <Ethernet.h>
    #include <BlynkSimpleEsp8266.h>
    #include <ESP8266WiFi.h>
    #include <SimpleTimer.h>

    char auth[] = "****";

    SimpleTimer timer;

    #define echoPin 13 // Echo Pin
    #define trigPin 15 // Trigger Pin

    long duration, distance; // Duration used to calculate distance

    int volume;
    int percent;
     
    void MeasureCm()
    {
      /* The following trigPin/echoPin cycle is used to determine the
     distance of the nearest object by bouncing soundwaves off of it. */ 

     
     digitalWrite(trigPin, LOW); 
     delayMicroseconds(2); 

     digitalWrite(trigPin, HIGH);
     delayMicroseconds(10); 
     
     digitalWrite(trigPin, LOW);
     duration = pulseIn(echoPin, HIGH);
     
     //Calculate the distance (in cm) based on the speed of sound.
     distance = duration/58.2;

     Serial.print("Distance: ");
     Serial.println(distance);


    {
      if (distance > 27 ){
      volume = (10155055.310263-(distance*((3.14159265359*(126.5*126.5)))))/1000;
       Serial.print("Volume: ");
       Serial.println(volume);
      }
       else {
      volume = 9000;
      Serial.print("Volume: ");
      Serial.println(volume);
      }
      percent = ((float)volume/9000)*100;

     Serial.print("Percent: ");
     Serial.println(percent);
     Serial.println();
     }
    }


      
    void setup() {
     Serial.begin(115200);
     Blynk.begin(auth, "***", "***");
      
     pinMode(trigPin, OUTPUT);
     pinMode(echoPin, INPUT);
     
     timer.setInterval(1000, MeasureCm);
     }

     BLYNK_READ(V8)
     {
     Blynk.virtualWrite(8,volume);// virtualpin 8 volume
     }

     BLYNK_READ(V9)
     {
     Blynk.virtualWrite(9,percent);// virtualpin 9 percent
     }


    void loop() {
      Blynk.run(); // Initiates Blynk
      timer.run(); // Initiates SimpleTimer
    }

Based on some experimenting I have been running with the same sensor and code, I see that the Blynk connection or something seems to get messed up when the sensor scan runs for awhile… I think it is because running delayMicroseconds() somehow conflicts with Blynk’s timing in the background (I have noticed similar issue in the past with alternate servo control methods). That might? have been what was was causing your initial issues, not an overheated sensor.

You can try a couple of things…

A)
Set up a flag that goes HIGH when the relay turns the sensor online (flag = 1) and back to LOW when offline, then change your else to else if (flag == 1) to set default volume = 9000 if sensor is online and within that 25cm range

Followed by a final else that simply ends the loop, leaving the volume at the last valid reading.

I haven’t tested this code, but I think my logic is straight… so tweek it to fit :wink:

{
    if (distance > 27 and flag == 1) {
      volume = (10155055.310263 - (distance * ((3.14159265359 * (126.5 * 126.5))))) / 1000;
      Serial.print("Volume: ");
      Serial.println(volume);
    }
    else if (flag == 1) {
      volume = 9000;
      Serial.print("Volume: ");
      Serial.println(volume);
    }
    else {
      percent = ((float)volume / 9000) * 100;

      Serial.print("Percent: ");
      Serial.println(percent);
      Serial.println();
    }
  }

B)
Assuming my guess about the delayMicroseconds() conflict is correct, forgo the relay and change your timer to a few minutes or more, with a for loop that runs the sensor routine however many times you want (mindful of keeping the delay short enough to avoid disconnection), then averages the end result.

Again, slapped together but not tested…

void MeasureCm()
{
  for (int scan = 0; scan <= 1000; scan++) { // Loop sensor reads 1000 times
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);
    duration = pulseIn(echoPin, HIGH);
    //Calculate the distance (in cm) based on the speed of sound.
    int dirhold = dirhold + duration // total up readings
  }
  // Average out readings and Calculate the distance (in cm) 
  // based on the speed of sound.
  distance = ((dirhold / 1000) / 58.2 ) 
  Serial.print("Distance: ");
  Serial.println(distance);
  {
    if (distance > 27 ) {
      volume = (10155055.310263 - (distance * ((3.14159265359 * (126.5 * 126.5))))) / 1000;
      Serial.print("Volume: ");
      Serial.println(volume);
    }
    else {
      volume = 9000;
      Serial.print("Volume: ");
      Serial.println(volume);
    }
    percent = ((float)volume / 9000) * 100;

    Serial.print("Percent: ");
    Serial.println(percent);
    Serial.println();
  }
}

Thanks again @Gunner for your time for putting this code together. I will give it a go. Another weird thing that is happening is that my history graph isn’t holding data for the percentage value. Would you have any idea as to why?

Sorry, no. I haven’t played around with the History Graph enough to know.

Roger that. Cheers.