Flow Meter help with reading data

MQTT connect failed, error 5

post the code you are using.

#define CAYENNE_DEBUG // Uncomment to show debug messages
#define CAYENNE_PRINT Serial // Comment this out to disable prints and save space
#include <CayenneMQTTEthernet.h>

// Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
char username = “xxxx”;
char password = “xxxx”;
char clientID = “xxxx”;

int mq3_analogPin = A0; // connected to the output pin of MQ3
byte red=4, green=5, yellow=6; // pins for leds
// remember 100 to 1000 ohm resistor in series with each LED

float alcohol = 0;
unsigned long lastMillis = 0;

void setup() {
Serial.begin(9600);
Cayenne.begin(“username”, “password”, “clientID”);
pinMode(red,OUTPUT);
pinMode(yellow,OUTPUT);
pinMode(green,OUTPUT);
Serial.print(“Alcohol value:”);
Serial.begin(9600); // open serial at 9600 bps
}

void loop() {
Cayenne.loop();
if (millis() - lastMillis > 10000) {
lastMillis = millis();
Cayenne.virtualWrite(0, alcohol,“voltage”, “V”);
}
int mq3_value = analogRead(mq3_analogPin);
float voltage = mq3_value* (5.0/1023.0);
Serial.print(“Alcohol value:”);
Serial.println(mq3_value);
Serial.print(“Voltage(V)”);
Serial.println(voltage);
if (mq3_value<400)
{
digitalWrite(green,HIGH);
delay(1000);
digitalWrite(green,LOW);
}
else if(mq3_value>900)
{
digitalWrite(red,HIGH);

delay(1000);
digitalWrite(red,LOW);

}
else
{
digitalWrite(yellow,HIGH);
delay(1000);
digitalWrite(yellow,LOW);
}
delay(100); //Just here to slow down the output.
}
// Default function for sending sensor data at intervals to Cayenne.
// You can also use functions for specific channels, e.g CAYENNE_OUT(1) for sending channel 1 data.
CAYENNE_OUT_DEFAULT()
{
// Write data to Cayenne here. This example just sends the current uptime in milliseconds on virtual channel 0.
Cayenne.virtualWrite(0, millis());
// Some examples of other functions you can use to send data.
Cayenne.celsiusWrite(1, 22.0);
Cayenne.luxWrite(2, 700);
Cayenne.virtualWrite(3, 50, TYPE_PROXIMITY, UNIT_CENTIMETER);
}

// Default function for processing actuator commands from the Cayenne Dashboard.
// You can also use functions for specific channels, e.g CAYENNE_IN(1) for channel 1 commands.
CAYENNE_IN_DEFAULT()
{
CAYENNE_LOG(“Channel %u, value %s”, request.channel, getValue.asString());
//Process message here. If there is an error set an error message using getValue.setError(), e.g getValue.setError(“Error message”);
}

before going further, add a new device and add your MQTT credential into this simple code.

// This example shows how to connect to Cayenne using an Ethernet W5100 shield and send/receive sample data.

#define CAYENNE_DEBUG
#define CAYENNE_PRINT Serial
#include <CayenneMQTTEthernet.h>

// Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
char username[] = "MQTT_USERNAME";
char password[] = "MQTT_PASSWORD";
char clientID[] = "CLIENT_ID";

unsigned long lastMillis = 0;

void setup() {
	Serial.begin(9600);
	Cayenne.begin(username, password, clientID);
}

void loop() {
	Cayenne.loop();

	//Publish data every 10 seconds (10000 milliseconds). Change this value to publish at a different interval.
	if(millis() - lastMillis > 10000) {
		lastMillis = millis();
		//Write data to Cayenne here. This example just sends the current uptime in milliseconds.
		Cayenne.virtualWrite(0, lastMillis);
		//Some examples of other functions you can use to send data.
		//Cayenne.celsiusWrite(1, 22.0);
		//Cayenne.luxWrite(2, 700);
		//Cayenne.virtualWrite(3, 50, TYPE_PROXIMITY, UNIT_CENTIMETER);
	}
}

sorry, im just a beginner. but what do you mean by “add new device” :sweat_smile:

have a look at this: Adding a New Device using MQTT
follow step 3 and add MQTT credential into the code i gave above.

ive tried the steps that you gave, but hmm there is still error

54%20PM

can you share the first few line of the serial monitor when the arduino is restarted.

35%20AM

Hi there,

Can you please help me convert the sketch into mqtt?

Joseph

which sketch are you referring to? there is a sketch in MQTT already.

The one that tad.dvor published at the beginning of the post.

It’s called sensor.txt

it is very simple as replacing old cayenne code with new new cayenne code.

/*
This example shows how to connect to Cayenne using an Ethernet W5100 shield and send/receive sample data.

The CayenneMQTT Library is required to run this sketch. If you have not already done so you can install it from the Arduino IDE Library Manager.

Steps:
1. Set the Cayenne authentication info to match the authentication info from the Dashboard.
2. Compile and upload the sketch.
3. A temporary widget will be automatically generated in the Cayenne Dashboard. To make the widget permanent click the plus sign on the widget.
*/

//#define CAYENNE_DEBUG       // Uncomment to show debug messages
#define CAYENNE_PRINT Serial  // Comment this out to disable prints and save space
#include <CayenneMQTTEthernet.h>

// Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
char username[] = "MQTT_USERNAME";
char password[] = "MQTT_PASSWORD";
char clientID[] = "CLIENT_ID";
byte statusLed    = 13;

byte sensorInterrupt = 0;  // 0 = digital pin 2
byte sensorPin       = 2;
// The hall-effect flow sensor outputs approximately 4.5 pulses per second per
// litre/minute of flow.
float calibrationFactor = 4.5;

volatile byte pulseCount;  

float flowRate;
unsigned int flowMilliLitres;
unsigned long totalMilliLitres;

unsigned long oldTime;

void setup() {
	Serial.begin(9600);
	Cayenne.begin(username, password, clientID);
  // Set up the status LED line as an output
  pinMode(statusLed, OUTPUT);
  digitalWrite(statusLed, HIGH);  // We have an active-low LED attached
  
  pinMode(sensorPin, INPUT);
  digitalWrite(sensorPin, HIGH);

  pulseCount        = 0;
  flowRate          = 0.0;
  flowMilliLitres   = 0;
  totalMilliLitres  = 0;
  oldTime           = 0;

  // The Hall-effect sensor is connected to pin 2 which uses interrupt 0.
  // Configured to trigger on a FALLING state change (transition from HIGH
  // state to LOW state)
  attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
}

void loop() {
	Cayenne.loop();
  if((millis() - oldTime) > 1000)    // Only process counters once per second
  { 
    // Disable the interrupt while calculating flow rate and sending the value to
    // the host
    detachInterrupt(sensorInterrupt);
        
    // Because this loop may not complete in exactly 1 second intervals we calculate
    // the number of milliseconds that have passed since the last execution and use
    // that to scale the output. We also apply the calibrationFactor to scale the output
    // based on the number of pulses per second per units of measure (litres/minute in
    // this case) coming from the sensor.
    flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
    
    // Note the time this processing pass was executed. Note that because we've
    // disabled interrupts the millis() function won't actually be incrementing right
    // at this point, but it will still return the value it was set to just before
    // interrupts went away.
    oldTime = millis();
    
    // Divide the flow rate in litres/minute by 60 to determine how many litres have
    // passed through the sensor in this 1 second interval, then multiply by 1000 to
    // convert to millilitres.
    flowMilliLitres = (flowRate / 60) * 1000;
    
    // Add the millilitres passed in this second to the cumulative total
    totalMilliLitres += flowMilliLitres;
      
    unsigned int frac;
    
    // Print the flow rate for this second in litres / minute
    Serial.print("Flow rate: ");
    Serial.print(int(flowRate));  // Print the integer part of the variable
    Serial.print(".");             // Print the decimal point
    // Determine the fractional part. The 10 multiplier gives us 1 decimal place.
    frac = (flowRate - int(flowRate)) * 10;
    Serial.print(frac, DEC) ;      // Print the fractional part of the variable
    Serial.print("L/min");
    // Print the number of litres flowed in this second
    Serial.print("  Current Liquid Flowing: ");             // Output separator
    Serial.print(flowMilliLitres);
    Serial.print("mL/Sec");

    // Print the cumulative total of litres flowed since starting
    Serial.print("  Output Liquid Quantity: ");             // Output separator
    Serial.print(totalMilliLitres);
    Serial.println("mL"); 

    // Reset the pulse counter so we can start incrementing again
    pulseCount = 0;
    
    // Enable the interrupt again now that we've finished sending output
    attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
  }
}

/*
Insterrupt Service Routine
 */
void pulseCounter()
{
  // Increment the pulse counter
  pulseCount++;
}

CAYENNE_OUT(V0)                                  //Flow rate:
{
  Cayenne.virtualWrite(V0, flowRate);
}

CAYENNE_OUT(V1)                                  //Current Liquid Flowing:
{
  Cayenne.virtualWrite(V1, flowMilliLitres);
}

CAYENNE_OUT(V2)                                  //Output Liquid Quantity:
{
  Cayenne.virtualWrite(V2, totalMilliLitres);
}

I keep on getting an error message while trying to upload. Any idea?

what error are you getting? can you share the error you are getting.

This work with ESP8266 07?
I can not connect via WiFi? Its possible?

i did not understand what you mean by above.

Hey guys, I know kind of old post but it is on topic so I didn’t want to start another one, specifically I disagree with disabling the interrupts while sending the data. In this use case the PPM of the sensor is really inconsequential (4.5/second) but in my case it is 400Hz since I am using a high precision flow sensor. What is exactly the reason one must disable interrupts while sending the data to Cayenne?

Why not prioritize the sensor interrupt so that it continues to increment the counter even while data is being sent to Cayenne?

void setup() {
  pinMode(3, INPUT_PULLDOWN);
  attachInterrupt(digitalPinToInterrupt(3), pulse, RISING);
  NVIC_SET_PRIORITY(IRQ_PORTA, 0);

This way not a single pulse will be missed and we would have high accuracy increment of the total volume of liquid passed through the sensor

~B

so does it work the way you want?