Arduino Programming adding milliseconds delay - c++

So I'm trying to create an energy meter device which will read power every minute and then send it every 5 minutes through a LoRa server, using an MKR 1300 arduino. The problem is that as of now the hardware is removing a few milliseconds on the delay and so the time in the server ends up being p.e:
10:50:30
10:50:30
10:50:30
... 2 hours later
10:50:29
10:50:29
...
10:49:59
The code looks like this:
#include <MKRWAN.h>
#include "EmonLib.h"
LoRaModem modem;
String appEui = "1234567891011121";
String appKey = "ffffffffffffffffffffffffffffffff";
EnergyMonitor emon1;
EnergyMonitor emon2;
EnergyMonitor emon3;
double totalWatt;
int time_running;
int sending;
int totalKW;
int DELAY = 60000; // millis
void setup() {
Serial.begin(115200);
if (!modem.begin(EU868)) {
Serial.println("Failed to start module");
while (1) {}
};
Serial.print("Your module version is: ");
Serial.println(modem.version());
Serial.print("Your device EUI is: ");
Serial.println(modem.deviceEUI());
Serial.println("Connecting");
int connected = modem.joinOTAA(appEui, appKey);
if (!connected) {
Serial.println("Something went wrong; are you indoor? Move near a window and retry");
while (1) {}
}
Serial.println("Connected");
modem.minPollInterval(60);
analogReadResolution(9);
emon1.current(1, 53);
emon2.current(2, 53);
emon3.current(3, 53);
time_running = 0;
randomSeed(analogRead(A4));
}
void loop() {
unsigned long StartTime = millis();
totalWatt = 0;
unsigned long delay_send = 0;
int sending = 0;
double Irms1 = emon1.calcIrms(600);
if (Irms1 < 0.3) Irms1 = 0;
double Watt1 = Irms1 * 230;
double Irms2 = emon2.calcIrms(600);
if (Irms2 < 0.3) Irms2 = 0;
double Watt2 = Irms2 * 230;
double Irms3 = emon3.calcIrms(600);
if (Irms3 < 0.3) Irms3 = 0;
double Watt3 = Irms3 * 230;
totalWatt = Watt1 + Watt2 + Watt3;
totalKW = totalKW + totalWatt/1000;
if (time_running == 5) { //15 para 15 mins
double IrmsTotal = Irms1 +Irms2 + Irms3;
String msg = "{\"id\":\"avac_aud1\",\"kW\":"+String(totalKW)+", \"current\":"+String(IrmsTotal)+"}";
int err;
modem.beginPacket();
modem.print(msg);
err = modem.endPacket(true);
if (err > 0) {
//message sent correctly
time_running = 0;
totalKW = 0;
} else {
Serial.println("ERR");
time_running = 0;
}
}
time_running = time_running + 1;
if ((millis() - StartTime) > DELAY){
delay(10);
return;
} else{
delay(DELAY-(millis() - StartTime));
return;
}
}
I tried adding a variable ARD_DELAY (not shown above) to the code that in that last delay would subtract 7 to 8 milliseconds to try and fix this, but apparently, it only made it worse (now it removes 1 second every 1 hours instead of 2 hours) so today I'll try to add those 7 to 8 millis and see if it works, but I would really like to know why the heck this is happening because from what I can see from my code the delay should always account for the processed time including the data sending time.

Question is, how precise is your clock at all...
Still, I personally would rather go with the following approach:
#define DELAY (5UL * 60UL * 1000UL) // or whatever is appropriate...
static unsigned long timestamp = millis();
if(millis() - timestamp > DELAY)
{
// adding a fix constant will prevent accumulating deviations over time
timestamp += DELAY;
// run the every-5-min task...
}
Edit: combined 1-min and 5-min task:
Variant 1:
#define DELAY_SHORT (1UL * 60UL * 1000UL)
#define DELAY_LONG (5UL * 60UL * 1000UL)
static unsigned long timestampS = millis();
static unsigned long timestampL = timestampS;
if(millis() - timestampS > DELAY_SHORT)
{
timestamp += DELAY_SHORT;
// run the every-1-min task...
}
if(millis() - timestampL > DELAY_LONG)
{
timestamp += DELAY_LONG;
// run the every-5-min task...
}
Variant 2:
#define DELAY_1M (1UL * 60UL * 1000UL)
static unsigned long timestamp = millis();
if(millis() - timestamp > DELAY)
{
// adding a fix constant will prevent accumulating deviations over time
timestamp += DELAY;
// run the every-1-min task...
static unsigned int counter = 0;
if(++counter == 5)
{
counter = 0;
// run the every-5-min task...
}
}

Instead of trying to measure a start time and adding delay depending on that, you could keep track of the timing for your next cycle.
unsigned long next_cycle = DELAY;
...
void loop() {
...
delay( next_cycle - millis() );
next_cycle += DELAY;
}
If you also want to adjust for any time the program spends on initialization or similar, you can next_cycle = millis() + DELAY; before you enter your loop.

Related

Update speed while going to position

Need to update potentiometer values all time not only once, try different ways but nothing works :(
I think that main problem is that this function while(digitalRead(gotoPositionAPin)); blocks
Now it's read value and save speed
workflow of code
press button right save position a
press button left save position b
update pot speed (set speed)
update pot acceleration (set accel)
press button go to position A (its going with previous set of speed and acceleration)
press button go to position B (its going with previous set of speed and acceleration)
#include <AccelStepper.h>
// Define some steppers and the pins the will use
AccelStepper stepper1(1, 12, 11);
#define stepsPerRev 1600
#define stepPin 12
#define dirPin 11
#define ledPin 13
#define rotateLeftPin 7
#define rotateRightPin 6
#define savePositionAPin 5
#define savePositionBPin 4
#define gotoPositionAPin 3
#define gotoPositionBPin 2
#define maxSpeedPin 0
#define accelPin 1
// Set this to zero if you don't want debug messages printed
#define printDebug 0
// These are the constants that define the speed associated with the MaxSpeed pot
#define MAX_STEPS_PER_SECOND 1000 // At 200 s/r and 1/8th microstepping, this will be 333 rev/minute
#define MIN_STEPS_PER_SECOND 27 // At 200 steps/rev and 1/8th microstepping, this will be 1 rev/minute
// Change this value to scale the acceleration pot's scaling factor
#define ACCEL_RATIO 1
int buttonState = 0;
int stepNumber = 0;
int curSpeed = 100;
int dir = 0;
int maxSpeed = 0;
int accel = 0;
long savedPosA = 0;
long savedPosB = 0;
int loopCtr = 0;
float fMaxSpeed = 0.0;
float fStepsPerSecond = 0.0;
void setup()
{
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
pinMode(ledPin, OUTPUT);
pinMode(rotateLeftPin, INPUT);
pinMode(rotateRightPin, INPUT);
pinMode(savePositionAPin, INPUT);
pinMode(savePositionBPin, INPUT);
pinMode(gotoPositionAPin, INPUT);
pinMode(gotoPositionBPin, INPUT);
if (printDebug)
{
// Initialize the Serial port
Serial.begin(9600);
}
// blink the LED:
blink(2);
stepper1.setMaxSpeed(800.0);
stepper1.setAcceleration(600.0);
// Grab both speed and accel before we start
maxSpeed = analogRead(maxSpeedPin);
// Do the math to scale the 0-1023 value (maxSpeed) to
// a range of MIN_STEPS_PER_SECOND to MAX_STEPS_PER_SECOND
fMaxSpeed = maxSpeed / 1023.0;
fStepsPerSecond = MIN_STEPS_PER_SECOND + (fMaxSpeed * (MAX_STEPS_PER_SECOND - MIN_STEPS_PER_SECOND));
if (fStepsPerSecond > 1000)
{
fStepsPerSecond = 1000;
}
accel = analogRead(accelPin)/ACCEL_RATIO;
}
void loop()
{
// First, we need to see if either rotate button is down. They always take precidence.
if(digitalRead(rotateLeftPin))
{
stepper1.setSpeed(-fStepsPerSecond);
while(digitalRead(rotateLeftPin))
{
CheckPots();
stepper1.runSpeed();
stepper1.setSpeed(-fStepsPerSecond);
}
}
else if (digitalRead(rotateRightPin))
{
stepper1.setSpeed(fStepsPerSecond);
while(digitalRead(rotateRightPin))
{
CheckPots();
stepper1.runSpeed();
stepper1.setSpeed(fStepsPerSecond);
}
}
// Go see if we need to update our analog conversions
CheckPots();
// Check to see if user is trying to save position A or B
if(digitalRead(savePositionAPin))
{
savedPosA = stepper1.currentPosition();
if (printDebug)
{
Serial.print("Saved A at :");
Serial.println(savedPosA);
}
while(digitalRead(savePositionAPin));
}
if(digitalRead(savePositionBPin))
{
savedPosB = stepper1.currentPosition();
if (printDebug)
{
Serial.print("Saved B at :");
Serial.println(savedPosB);
}
while(digitalRead(savePositionBPin));
}
// Check to see if the user wants to go to position A or B
if (digitalRead(gotoPositionAPin))
{
if (printDebug)
{
// Yup, let's go to position A
Serial.print("cur pos = ");
Serial.println(stepper1.currentPosition());
Serial.print("Going to A = ");
Serial.println(savedPosA);
Serial.print("Speed = ");
Serial.println(fStepsPerSecond);
Serial.print("Accel = ");
Serial.println(accel);
}
stepper1.setAcceleration(0);
stepper1.runToNewPosition(stepper1.currentPosition());
stepper1.setMaxSpeed(fStepsPerSecond);
stepper1.setAcceleration(accel);
stepper1.runToNewPosition(savedPosA);
if (printDebug)
{
Serial.print("new pos = ");
Serial.println(stepper1.currentPosition());
}
while(digitalRead(gotoPositionAPin));
}
else if (digitalRead(gotoPositionBPin))
{
// Yup, let's go to position B
if (printDebug)
{
Serial.print("cur pos = ");
Serial.println(stepper1.currentPosition());
Serial.print("Going to B = ");
Serial.println(savedPosB);
Serial.print("Speed = ");
Serial.println(fStepsPerSecond);
Serial.print("Accel = ");
Serial.println(accel);
}
stepper1.setAcceleration(0);
stepper1.runToNewPosition(stepper1.currentPosition());
stepper1.setMaxSpeed(fStepsPerSecond);
stepper1.setAcceleration(accel);
stepper1.runToNewPosition(savedPosB);
if (printDebug)
{
Serial.print("new pos = ");
Serial.println(stepper1.currentPosition());
}
while(digitalRead(gotoPositionBPin));
}
}
// Blink the reset LED:
void blink(int howManyTimes)
{
int i;
for (i=0; i < howManyTimes; i++)
{
digitalWrite(ledPin, HIGH);
delay(200);
digitalWrite(ledPin, LOW);
delay(200);
}
}
void CheckPots(void)
{
loopCtr++;
// Only read these once in a while because they take a LONG time
if (loopCtr == 100)
{
maxSpeed = analogRead(maxSpeedPin);
// Do the math to scale the 0-1023 value (maxSpeed) to
// a range of MIN_STEPS_PER_SECOND to MAX_STEPS_PER_SECOND
fMaxSpeed = maxSpeed / 1023.0;
fStepsPerSecond = MIN_STEPS_PER_SECOND + (fMaxSpeed * (MAX_STEPS_PER_SECOND - MIN_STEPS_PER_SECOND));
if (fStepsPerSecond > 1000)
{
fStepsPerSecond = 1000;
}
}
// Read in the acceleration analog value
// This needs to be scaled too, but to what?
if (loopCtr >= 200)
{
accel = analogRead(accelPin)/ACCEL_RATIO;
loopCtr = 0;
}
}
If you're looking into "continuous operation" but don't want to introduce interrupts into your code (which will have special requirements in and of itself) there are a couple of things you need to get rid of:
Endless loops like: while(digitalRead(savePositionAPin));
System waits like: delay(200); as in your blink()
and instead use state variables. State variables are more or less what the name says: variables that hold the state of something, so you know what value the button, or timer, or counter had last time.
So, instead of a while-loop waiting for a button to be released, just set a global or static boolean that knows what state you were in the last time loop() ran, so you don't trigger the button action again. You need one boolean flag for each button.
And instead of delays, either create a state variable that holds "passed time" which you can get from millis() for example. So don't wait but instead you should just check if a certain amount of time has passed so you can toggle the state of the LED.
Adding a blinking LED to loop() - (untested example):
#define LEDWAIT 300
unsigned long myTime = 0;
bool onoff = false;
loop()
{
if (myTime == 0)
myTime = millis();
if ((millis() - myTime) > LEDWAIT) {
digitalWrite(ledPin, onoff ? HIGH : LOW);
onoff = !onoff;
myTime = millis();
}
// do other things
}
It is not entirely clear to me what your program is supposed to do and what the error is, so please correct me if I am wrong: You want to update a value based on which button is pressed? What is your opinion on using interrupts for triggering the updates?
You may want to edit the formating of your question.

Arduino millis() print values one after other

I don't know if someone else asked this before.
I'm trying to print in Serial screen the number 1 - 6, ONE number every 5 seconds (I'm trying only with number 1 and number 2 for smaller and easier to undestand and modify code). I could use delay function, but i want to use millis function, because i don't want to block the code using delay in loop.
This code problem is a part of bigger project.
I tryied to print the numbers using different interval times (eventTime_1 and eventTime_2), but it didn't work.
The code is
/* Two independant timed evenets */
const unsigned long eventTime_1 = 1000; // interval in ms
const unsigned long eventTime_2 = 5000;
unsigned long previousTime_1 = 0;
unsigned long previousTime_2 = 0;
void setup() {
// To Do: Serial communication
Serial.begin(9600);
}
void loop() {
/* Updates frequently */
unsigned long currentTime = millis();
// To Do: Event 1 timing
/* This is event 1 stuff */
if ( currentTime - previousTime_1 >= eventTime_1 ) {
Serial.println (" 1 ");
// Serial.println(currentTime);
// Serial.println(previousTime_1);
/* Update the timing for the next event */
previousTime_1 = currentTime;
}
// To Do: Event 2 timing
/* This is event 2 stuff */
if (currentTime - previousTime_2 >= eventTime_2 ) {
Serial.println ("2");
// Serial.println( analogRead(tempSensor) );
/* Update the timing for the next event */
previousTime_2 = currentTime;
}
}
As a result, prints 5 times the number 1 and after 5 seconds 1 time the number 2.
This is what i ecpect:
12:16:53.212 -> 1
12:16:58.225 -> 2
12:17:03.233 -> 1
12:17:08.238 -> 2
12:17:13.203 -> 1
12:17:18.272 -> 2
This is the final working code. From this code you can print 1 and 2 alternating every X second (x depends from you, in eventTime = X ; In my code is 5000).
// To Do: Variables for Timed Events
/* Create timed evenets */
const unsigned long eventTime = 5000;
unsigned long previousTime = 0;
/* Create a flag */
boolean flag1 = false;
void setup() {
// To Do: Serial communication
Serial.begin(9600);
}
void loop() {
/* Updates frequently */
unsigned long currentTime = millis();
if (currentTime - previousTime >= eventTime ) {
if (flag1 == false) {
Serial.println("1");
flag1 = true;
}
else if (flag1 == true) {
Serial.println ("2");
flag1 = false;
}
/* Update the timing for the next event */
previousTime = currentTime;
}
}
And the results are:
15:32:46.342 -> 1
15:32:51.402 -> 2
15:32:56.327 -> 1
15:33:01.325 -> 2
15:33:06.328 -> 1
15:33:11.325 -> 2
15:33:16.327 -> 1

ON and OFF time control over 24 hour period in C, C++

Using c, c++ (mbed, Arduino, etc), Is there a trick up c's sleeve to be able to set an ON time and OFF time over a 24 hour period. For instance 'ON' at 20:00 hours and off at 06:30 hours following morning.
Timers are no good here if there is a nvic reset. If the device does fall over and restart's at say 23:40 hours, we still need to service that 20:00 to 06:30 time frame.
Stuck on the going past midnight.
I've got this far using seconds but not quite working, but I'm sure I'm barking up the wrong tree so I would appreciate some clever input here.
lockStatus = 1 is 'ON'
lockStatus = 0 is 'OFF'
void autoLOCK()
{
int hour_from, minute_from = 0;
int seconds_from = 0 ;
int hour_to, minute_to = 0;
int seconds_to = 0;
lockFrom = "20:00";
lockTo = "06:30";
if (sscanf(lockFrom, "%d:%d", &hour_from, &minute_from) >= 2)
{
seconds_from = (hour_from * 3600 + minute_from * 60);
}
if (sscanf(lockTo, "%d:%d", &hour_to, &minute_to) >= 2)
{
seconds_to = (hour_to * 3600 + minute_to * 60);
}
lockStatus = 0;
if (seconds_now >= seconds_from) {
lockStatus = 1;
}
if (seconds_from > seconds_to) {
lockStatus = 1;
}
if (seconds_now >= seconds_to && seconds_from >= seconds_to) {
lockStatus = 0;
}
Serial.printf("Lock Status: %d\n\n", lockStatus);
}

So i cant figure out how to send my GPS data to the IFTTT server

So im working on a project making a safety and monitoring system for a bike and im sending the monitored data to Blynk
which is working perfectly.
Im trying to send an SMS when a value is triggered ,I recieve the SMS through Clicksend
but i cant figure out how i can send my values to IFTTT so that it can write those in the Alert SMS
Here is the code:
#include <SoftwareSerial.h>
#include <RH_NRF24.h>
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <ESP8266HTTPClient.h>
char auth[] = "AUTH_ID";
char ssid[] = "SSID";
char pass[] = "PASS";
const char* iftttURL = "http://maker.ifttt.com/trigger/{event}/with/key/{key}";
BlynkTimer timer;
// Singleton instance of the radio driver
RH_NRF24 nrf24(2, 4); //D4,D2 on esp //nrf24L01
int led = 15; //D8 on esp
int acc;
int touch;
int headtemp;
static const int RXPin = 5, TXPin = 16; //D1,D2 on esp //gps
static const uint32_t GPSBaud = 9600;
// The TinyGPS++ object
TinyGPSPlus gps;
// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
float lati;
float lon;
const int analogInPin = A0; //Pt100 Bike Temp
const int SensorValueLow = 463;
const int SensorValueDiff = 36; // differance between high and low sensor value
const int TempValueDiff = 32; // differance between high and low Temp value
const int TempValueLow = 0;
int sensorValue = 0;
int Temp = 0;
// Calibration: // //RPM
const byte PulsesPerRevolution = 10; // Set how many pulses there are on each revolution. Default: 2.
const unsigned long ZeroTimeout = 100000; // For high response time, a good value would be 100000
// Calibration for smoothing RPM:
const byte numReadings = 2; // Number of samples for smoothing. The higher, the more smoothing, but it's going to
// Variables:
/////////////
unsigned long kmh;
int d=50.8; //diameter of wheel in cm
volatile unsigned long LastTimeWeMeasured; // Stores the last time we measured a pulse so we can calculate the period.
volatile unsigned long PeriodBetweenPulses = ZeroTimeout+1000; // Stores the period between pulses in microseconds.
volatile unsigned long PeriodAverage = ZeroTimeout+1000; // Stores the period between pulses in microseconds in total, if we are taking multiple pulses.
unsigned long FrequencyRaw; // Calculated frequency, based on the period. This has a lot of extra decimals without the decimal point.
unsigned long FrequencyReal; // Frequency without decimals.
unsigned long RPM; // Raw RPM without any processing.
unsigned int PulseCounter = 1; // Counts the amount of pulse readings we took so we can average multiple pulses before calculating the period.
unsigned long PeriodSum; // Stores the summation of all the periods to do the average.
unsigned long LastTimeCycleMeasure = LastTimeWeMeasured; // Stores the last time we measure a pulse in that cycle.
unsigned long CurrentMicros = micros(); // Stores the micros in that cycle.
unsigned int AmountOfReadings = 1;
unsigned int ZeroDebouncingExtra; // Stores the extra value added to the ZeroTimeout to debounce it.
// Variables for smoothing tachometer:
unsigned long readings[numReadings]; // The input.
unsigned long readIndex; // The index of the current reading.
unsigned long total; // The running total.
unsigned long average; // The RPM value after applying the smoothing.
void myTimerEvent()
{
// You can send any value at any time.
// Please don't send more that 10 values per second.
Blynk.virtualWrite(V1, average);
Blynk.virtualWrite(V2, kmh);
Blynk.virtualWrite(V3, Temp);
}
WidgetMap myMap(V5);
void setup()
{
Serial.begin(9600);
Blynk.begin(auth, ssid, pass);
timer.setInterval(1000L, myTimerEvent);
ss.begin(GPSBaud); //GPS
Serial.println(F("DeviceExample.ino"));
Serial.println(F("A simple demonstration of TinyGPS++ with an attached GPS module"));
Serial.print(F("Testing TinyGPS++ library v. ")); Serial.println(TinyGPSPlus::libraryVersion());
Serial.println(F("by Mikal Hart"));
Serial.println();
pinMode(led, OUTPUT); //D8 of node mcu //nrf24L01
Serial.begin(9600);
while (!Serial)
; // wait for serial port to connect. Needed for Leonardo only
if (!nrf24.init())
Serial.println("init failed");
// Defaults after init are 2.402 GHz (channel 2), 2Mbps, 0dBm
if (!nrf24.setChannel(1))
Serial.println("setChannel failed");
if (!nrf24.setRF(RH_NRF24::DataRate2Mbps, RH_NRF24::TransmitPower0dBm))
Serial.println("setRF failed");
attachInterrupt(digitalPinToInterrupt(0), Pulse_Event, RISING); //RPM // Enable interruption pin 2 when going from LOW to HIGH.
}
void loop()
{
Blynk.run();
timer.run();
smsonaccident();
while (ss.available() > 0) //GPS
if (gps.encode(ss.read()))
displayInfo(); //GPS function
if (millis() > 5000 && gps.charsProcessed() < 10)
{
Serial.println(F("No GPS detected: check wiring."));
while(true);
}
NRF24L01(); //NRF24L01 Function
BikeTemp(); //Bike Temprature Function
BikeRPM(); //Bike Wheel RPM
}
void NRF24L01()
{
if (nrf24.available()) //nrf24L01
{
// Should be a message for us now
uint8_t buf[RH_NRF24_MAX_MESSAGE_LEN];
uint8_t len = sizeof(buf);
if (nrf24.recv(buf, &len))
{
Serial.println("*****Got Signal*****");
acc = buf[0];
touch = buf[1];
Serial.print("Accelerometer State: ");
Serial.print(buf[0]);
Serial.print(" , Touch State: ");
Serial.print(buf[1]);
if(touch == 1 || acc ==1)
{digitalWrite(led,HIGH);}
else
{digitalWrite(led,LOW);}
}
}
}
void BikeTemp()
{
sensorValue = analogRead(analogInPin); //Pt100 BikeTemp
Temp = sensorValue-SensorValueLow;
Temp = Temp/SensorValueDiff;
Temp = Temp*TempValueDiff;
Temp = Temp+TempValueLow;
Serial.print("Temp= ");
Serial.println(Temp);
}
void BikeRPM()
{
LastTimeCycleMeasure = LastTimeWeMeasured; // RPM+Km/h
CurrentMicros = micros(); // Store the micros() in a variable.
if(CurrentMicros < LastTimeCycleMeasure)
{
LastTimeCycleMeasure = CurrentMicros;
}
// Calculate the frequency:
FrequencyRaw = 10000000000 / PeriodAverage; // Calculate the frequency using the period between pulses.
// Detect if pulses stopped or frequency is too low, so we can show 0 Frequency:
if(PeriodBetweenPulses > ZeroTimeout - ZeroDebouncingExtra || CurrentMicros - LastTimeCycleMeasure > ZeroTimeout - ZeroDebouncingExtra)
{ // If the pulses are too far apart that we reached the timeout for zero:
FrequencyRaw = 0; // Set frequency as 0.
ZeroDebouncingExtra = 2000; // Change the threshold a little so it doesn't bounce.
}
else
{
ZeroDebouncingExtra = 0; // Reset the threshold to the normal value so it doesn't bounce.
}
FrequencyReal = FrequencyRaw / 10000; // Get frequency without decimals.
// Calculate the RPM:
RPM = FrequencyRaw / PulsesPerRevolution * 60; // Frequency divided by amount of pulses per revolution multiply by
RPM = RPM / 10000; // Remove the decimals.
// Smoothing RPM:
total = total - readings[readIndex]; // Advance to the next position in the array.
readings[readIndex] = RPM; // Takes the value that we are going to smooth.
total = total + readings[readIndex]; // Add the reading to the total.
readIndex = readIndex + 1; // Advance to the next position in the array.
if (readIndex >= numReadings) // If we're at the end of the array:
{
readIndex = 0; // Reset array index.
}
// Calculate the average:
average = total / numReadings; // The average value it's the smoothed result.
kmh = d*average*0.001885; // calculate km/h ,where d(in cm) is diameter of wheel
Serial.print("RPM: ");
Serial.print(average);
Serial.print(" , KM/h: ");
Serial.println(kmh);
}
void displayInfo()
{
Serial.print(F("Location: "));
if (gps.location.isValid())
{
// Serial.print(gps.location.lat(), 6);
lati = gps.location.lat() ;
Serial.print(lati, 6);
Serial.print(F(","));
// Serial.print(gps.location.lng(), 6);
lon = gps.location.lng() ;
Serial.print(lon, 6);
}
else
{
Serial.print(F("Invalid"));
}
int index = 5;
myMap.location(index, lati, lon, "Bike location");
Serial.print(F(" Date/Time: "));
if (gps.date.isValid())
{
Serial.print(gps.date.day());
Serial.print(F("/"));
Serial.print(gps.date.month());
Serial.print(F("/"));
Serial.print(gps.date.year());
}
else
{
Serial.print(F("INVALID"));
}
Serial.print(F(" "));
if (gps.time.isValid())
{
if (gps.time.hour() < 10) Serial.print(F("0"));
Serial.print(gps.time.hour());
Serial.print(F(":"));
if (gps.time.minute() < 10) Serial.print(F("0"));
Serial.print(gps.time.minute());
Serial.print(F(":"));
if (gps.time.second() < 10) Serial.print(F("0"));
Serial.print(gps.time.second());
}
else
{
Serial.print(F("INVALID"));
}
Serial.println();
}
ICACHE_RAM_ATTR void Pulse_Event() //RPM Data // The interrupt runs this to calculate the period between pulses:
{
PeriodBetweenPulses = micros() - LastTimeWeMeasured; // Current "micros" minus the old "micros" when the last pulse happens.
LastTimeWeMeasured = micros(); // Stores the current micros so the next time we have a pulse we would have something to compare with.
if(PulseCounter >= AmountOfReadings) // If counter for amount of readings reach the set limit:
{
PeriodAverage = PeriodSum / AmountOfReadings; // Calculate the final period dividing the sum of all readings by the
PulseCounter = 1; // Reset the counter to start over. The reset value is 1 because its the minimum setting allowed (1 reading).
PeriodSum = PeriodBetweenPulses; // Reset PeriodSum to start a new averaging operation.
int RemapedAmountOfReadings = map(PeriodBetweenPulses, 40000, 5000, 1, 10); // Remap the period range to the reading range.
RemapedAmountOfReadings = constrain(RemapedAmountOfReadings, 1, 10); // Constrain the value so it doesn't go below or above the limits.
AmountOfReadings = RemapedAmountOfReadings; // Set amount of readings as the remaped value.
}
else
{
PulseCounter++; // Increase the counter for amount of readings by 1.
PeriodSum = PeriodSum + PeriodBetweenPulses; // Add the periods so later we can average.
}
}
void smsonaccident()
{
if (acc>=1) // You can write any condition to trigger e-mail sending
{
Serial.println("Alert!!! Accident Happens see location. "); // This can be seen in the Serial Monitor
HTTPClient http; // Declare an object of class HTTPClient
http.begin(iftttURL); // Specify request destination
int httpCode = http.GET(); // Send the request
Serial.println("Done");
if (httpCode > 0) {
String payload = http.getString(); // Get the request response payload
Serial.println(payload); // Print the response payload
}
http.end(); // Close connection
acc=0;
delay(10000); // delay for 5 min if accident happens
}
}
Now im trying to find a way so that i can send my GPS values to the "iftttURL" but whatever i try or whatever i know doesnt work
either the value just doesnt get recieved or if it does then the SMS fails to send as it cant validate the values
what do i need to add
or what do i need to change to send my GPS values "lati" and "lon" to my ifttt url where it can recognize it as values that i can put into the alert message

I want to connect two yf-s201 Waterflow sensors, one as inflow and other as a outflow using Nodemcu & blynk

This is mostly a copy-paste of the code I found on Google,
I want to make a project using 2 waterflow sensors in which inflow() which shows how many liters i have taken in and outflow() which shows how many liters flown out.
This is how far ive reached, Need help with the code please, I am not a advanced coder so descriptive code and support is HIGHLY appreciated.
also please see the maincode(), in that section i am trying to achieve a loop, i mean if sensor1 is high it should display sensor1(inflow()) output ,and if sensor 2 is high it should display sensor2(outflow()) output.
Problems faced: the output doesn't work when i call both the inflow() and outflow() together, one function works,(i think it has something to do with the Interrupt Pins of the board?).
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
char auth[] = "SECRET";
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "Wifi";
char pass[] = "password";
//byte statusLed = 13;
byte inFlowSensor = D2;
byte outFlowSensor= D3;
float calibrationFactor = 4.5;
BlynkTimer timer;
volatile byte pulseCount;
float inFlowRate; // V2 - inflowrate
float outFlowRate; // V4 - outFowRate
boolean sensorInput = 0;
unsigned int inFlowMilliLitres;
unsigned int outFlowMilliLitres;
unsigned long inTotalMilliLitres; // V1 - inTotalLitres
//unsigned long totalLitres;
unsigned long outTotalMilliLitres; // V3 - outTotalLitres
unsigned long oldTime;
BLYNK_CONNECTED() { // runs once at device startup, once connected to server.
Blynk.syncVirtual(V1); //gets last known value of V1 virtual pin
Blynk.syncVirtual(V3); //gets last known value of V4
}
BLYNK_WRITE(V1)
{
inTotalMilliLitres = param.asFloat();
}
BLYNK_WRITE(V2)
{
inFlowRate = param.asFloat();
}
BLYNK_WRITE(V3)
{
outTotalMilliLitres = param.asFloat();
}
BLYNK_WRITE(V4)
{
outFlowRate = param.asFloat();
}
BLYNK_WRITE(V5) { // reset all data with button in PUSH mode on virtual pin V4
int resetdata = param.asInt();
if (resetdata == 0) {
Serial.println("Clearing Data");
Blynk.virtualWrite(V1, 0);
Blynk.virtualWrite(V2, 0);
inFlowRate = 0;
outFlowRate = 0;
inFlowMilliLitres = 0;
outFlowMilliLitres = 0;
inTotalMilliLitres = 0;
outTotalMilliLitres = 0;
//totalLitres = 0;
//totalLitresold = 0;
}
}
ICACHE_RAM_ATTR void pulseCounter()
{
// Increment the pulse counter
pulseCount++;
}
void inflow()
{
if((millis() - oldTime) > 1000) // Only process counters once per second
{
detachInterrupt(inFlowSensor);
inFlowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
oldTime = millis();
inFlowMilliLitres = (inFlowRate / 60) * 1000;
// Add the millilitres passed in this second to the cumulative total
inTotalMilliLitres += inFlowMilliLitres;
unsigned int frac;
// Print the flow rate for this second in litres / minute
Serial.print("Flow rate: ");
Serial.print(int(inFlowRate)); // 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 = (inFlowRate - int(inFlowRate)) * 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 Fuel Flowing: "); // Output separator
Serial.print(inFlowMilliLitres);
Serial.print("mL/Sec");
// Print the cumulative total of litres flowed since starting
Serial.print(" Input Fuel Quantity: "); // Input separator
Serial.print(inTotalMilliLitres);
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(inFlowSensor, pulseCounter, FALLING);
}
}
void outflow()
{
if((millis() - oldTime) > 1000) // Only process counters once per second
{
detachInterrupt(outFlowSensor);
outFlowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
oldTime = millis();
outFlowMilliLitres = (outFlowRate / 60) * 1000;
// Add the millilitres passed in this second to the cumulative total
outTotalMilliLitres += outFlowMilliLitres;
unsigned int frac;
// Print the flow rate for this second in litres / minute
Serial.print("Flow rate: ");
Serial.print(int(outFlowRate)); // 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 = (outFlowRate - int(outFlowRate)) * 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 Fuel Flowing: "); // Output separator
Serial.print(outFlowMilliLitres);
Serial.print("mL/Sec");
// Print the cumulative total of litres flowed since starting
Serial.print(" Out Fuel Quantity: "); // Input separator
Serial.print(outTotalMilliLitres);
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(outFlowSensor, pulseCounter, FALLING);
}
}
void sendtoBlynk() // In this function we are sending values to blynk server
{
Blynk.virtualWrite(V2, inFlowRate);
Blynk.virtualWrite(V1, inTotalMilliLitres);
Blynk.virtualWrite(V4, outFlowRate);
Blynk.virtualWrite(V3, outTotalMilliLitres);
}
void setup()
{
Serial.begin(9600); //38400
Blynk.begin(auth,ssid,pass);
Serial.println("Setup Started");
pulseCount = 0;
inFlowRate = 0.0;
outFlowRate = 0.0;
inFlowMilliLitres = 0;
outFlowMilliLitres = 0;
inTotalMilliLitres = 0;
outTotalMilliLitres = 0;
oldTime = 0;
attachInterrupt(inFlowSensor, pulseCounter, FALLING);
//attachInterrupt(outFlowSensor, pulseCounter, FALLING);
timer.setInterval(10000L, sendtoBlynk);
}
void maincode(){
inflow();
//outflow();
}
/**
* program loop
*/
void loop(){
Blynk.run();
timer.run();
Serial.println("Timer and Blynk Started");
Serial.println(inFlowSensor);
Serial.println(outFlowSensor);
maincode();
}```