Flow sensor library

@Clarke, you are not allocating enough space in you liters_S array. With %4.3f, that uses a minimum of 8 chars plus the null terminator. Make your array 20bytes in size to avoid problems and try again :smiley:

2 Likes

Anyone have advice for code to add to @peekay123 's code that will publish an event when certain conditions are met? Ideally, I’d like to publish an event when the water flow stays above a certain level for a certain amount of time. I know next to nothing about C++ and am trying to fumble through the basics. By the end of the project, I’d love to be able to log water usage too, but figured I’d try to get the events thing figured out first. Baby steps.

Any advice is appreciated!

@stringpark, what have you tried?

@peekay123 Well, I’m a little embarrassed to say, because I really have no idea what I’m doing. I tried adding the “if” statement below, but that doesn’t verify, so I must have formatted something wrong.

void loop()
{
  unsigned long t;
  static unsigned int pc;

  t = (millis() - oldTime);
  if(t >= 1000)    			// Only process counters once per second
  {
    //Read water sensor pulse count and process
    if (WaterPulseCount != 0)		// Do nothing if water is not flowing!
    {
      detachInterrupt (WATER_SENSOR_PIN);	// Disable water flow interrupt to read value
      //Calculate litres and adjust for 1 sec offset, if any
      liters = (WaterPulseCount / pulsesPerLiter) * (t / 1000);
      oldTime = millis();				// Reset base delay time
      pc = WaterPulseCount;
      WaterPulseCount = 0;			// Reset the water pulse counter
      attachInterrupt(WATER_SENSOR_PIN, WaterPulseCounter, FALLING);

      sprintf(liters_S, "%4.3f", liters);

      if(liters_S > .04)
      {
        Particle.publish("litersS",liters_S,60,PRIVATE);
      }

    }
  }
}

I’ve also tried adding the Particle.publish line below, just to see what would happen. It compiled, but I didn’t see anything in the cloud. Again, I’m pretty much clueless, sorry.

void setup()
{
  Serial.begin(9600); 

  Particle.variable("litersS", liters_S, STRING);
  Particle.publish("litersS",liters_S,60,PRIVATE);
  // Set Digital pin WATER_SENSOR_PINT to INPUT mode and set
  // interrupt vector (water flow sensor) for FALLING edge interrupt
  pinMode(WATER_SENSOR_PIN, INPUT);
  attachInterrupt(WATER_SENSOR_PIN, WaterPulseCounter, FALLING) ;
  oldTime = millis();
}

@stringpark, I suggest removing the underscore in the variable named liters_S, just to be safe. When you say you don’t “see anything in the cloud”, do you mean in the dashboard?

I believe the if you added should read if(liters > 0.04) since you want to evaluate the liters value, not the string of the litres value in liters_S.

:wink:

This (t / 1000) will most likely always be 1.0, since you are perforiming an integer division which will only ever return an integer even for 1999 / 1000 you'll only get 1.0 as result.
Similarly if WaterPulseCount and pulsePerLiter are integers, you'll only get integer results, losing all decimals.


When you say

Does this mean the code doesn't build?
If so, you should post the error messages to save us the need to search for the "offending" code line.

1 Like

@peekay123

When I remove the "_S" it won't compile. I get the following error:

peekay123.cpp: In function 'void loop()':

peekay123.cpp:68:50: error: no matching function for call to 'CloudClass::publish(const char [8], float&, int, const PublishFlag&)'
WaterPulseCount = 0; // Reset the water pulse counter
^

peekay123.cpp:68:50: note: candidates are:
In file included from ../wiring/inc/spark_wiring.h:48:0,
from ./inc/application.h:36,
from peekay123.cpp:5:
../wiring/inc/spark_wiring_cloud.h:222:17: note: bool CloudClass::publish(const char*, PublishFlag)
inline bool publish(const char eventName, PublishFlag eventType=PUBLIC)
^
../wiring/inc/spark_wiring_cloud.h:222:17: note: candidate expects 2 arguments, 4 provided
../wiring/inc/spark_wiring_cloud.h:227:17: note: bool CloudClass::publish(const char
, const char*, PublishFlag)
inline bool publish(const char eventName, const char eventData, PublishFlag eventType=PUBLIC)
^
../wiring/inc/spark_wiring_cloud.h:227:17: note: candidate expects 3 arguments, 4 provided
../wiring/inc/spark_wiring_cloud.h:232:17: note: bool CloudClass::publish(const char
, const char
, PublishFlag, PublishFlag)
inline bool publish(const char eventName, const char eventData, PublishFlag f1, PublishFlag f2)
^
../wiring/inc/spark_wiring_cloud.h:232:17: note: no known conversion for argument 2 from 'float' to 'const char
'
../wiring/inc/spark_wiring_cloud.h:238:17: note: bool CloudClass::publish(const char
, const char*, int, PublishFlag)
inline bool publish(const char *eventName, const char eventData, int ttl, PublishFlag eventType=PUBLIC)
^
../wiring/inc/spark_wiring_cloud.h:238:17: note: no known conversion for argument 2 from 'float' to 'const char
'
make[1]: *** [../build/target/user/platform-6peekay123.o] Error 1
make: *** [user] Error 2

 Error: Could not compile. Please review your code. 

Yes, by "cloud" I was referring to the Dashboard, Logs tab.

That worked! It allowed my "if" statement to compile. I'm still not seeing anything in the dashboard though. Here is what I have flashed right now.

/*
    Water flow sensor test sketch

*/


unsigned long oldTime;
volatile unsigned int WaterPulseCount = 0;

// conversion from pps to litres, plastic sensor (485 for metal)
const float pulsesPerLiter = 450;

// Spark Digial Pin D3 (D2 did not work)
#define WATER_SENSOR_PIN	D3	// Water sensor digital pin

// Define Spark variable - not sure "float" type works so define as INT
// so decimal is shifted left with * 100 (so xx.yy becomes xxyy)
float liters = 0;
char liters_S[6];

//-----------------------------------------------------------------------------
// Water Sensor interrupts
//-----------------------------------------------------------------------------
void WaterPulseCounter(void)
{
	// Increment the water pulse counter
	//detachInterrupt (WATER_SENSOR_PIN) ;
	WaterPulseCount++;
	//attachInterrupt(WATER_SENSOR_PIN, WaterPulseCounter, FALLING) ;
}


void setup()
{
 Serial.begin(9600);

   Particle.variable("litersS", liters_S, STRING);
  // Set Digital pin WATER_SENSOR_PINT to INPUT mode and set
  // interrupt vector (water flow sensor) for FALLING edge interrupt
  pinMode(WATER_SENSOR_PIN, INPUT);
  attachInterrupt(WATER_SENSOR_PIN, WaterPulseCounter, FALLING) ;
  oldTime = millis();
}


void loop()
{
  unsigned long t;
  static unsigned int pc;

  t = (millis() - oldTime);
  if(t >= 1000)    			// Only process counters once per second
  {
    //Read water sensor pulse count and process
    if (WaterPulseCount != 0)		// Do nothing if water is not flowing!
    {
    detachInterrupt (WATER_SENSOR_PIN);	// Disable water flow interrupt to read value
    //Calculate litres and adjust for 1 sec offset, if any
    liters = (WaterPulseCount / pulsesPerLiter) * (t / 1000);
    oldTime = millis();				// Reset base delay time
    pc = WaterPulseCount;
    WaterPulseCount = 0;			// Reset the water pulse counter
    attachInterrupt(WATER_SENSOR_PIN, WaterPulseCounter, FALLING);

    sprintf(liters_S, "%4.3f", liters);

    if(liters > 0.04)
    {Particle.publish("litersS",liters_S,60,PRIVATE);
    }

    }
  }
}

@ScruffR

Thanks! The reason I used "0.04" is because the output of the "Particle.variable" generally reads around 0.05-0.06 when the water is on. Do you suggest that I try "> 1" in my "if" statement?

You need to use a string as second parameter

Nope, since I couldn't see the declaration of pulsesPerLiter in your previous post, I assumed it to be int and hence you would not get 0.4 or any other floating point result, but with the full code above, that's settled.

1 Like

Finally figured out why I couldn’t see anything on the Dashboard. Turned out to be an Internet Explorer thing. Used Chrome and can see the liters value on the Dashboard just fine with the previously posted code. Whew, can finally move forward now! Now I just need an “if” statement that sets the condition of the liter value being greater than a certain value, but also throughout a certain period of time.

2 Likes