Array in Case Statement - c++

I am having trouble using an array for case statement for my state machine. Most sites mention that an array cannot be used for case statements so i have been trying a work around for it but so far it has been unsuccessful. I would really appreciate any help or suggestions for this. For Clarification: I do not want to hard code the states, i am trying to make the program in such a way that if the user only changes the order in the fsm_state_array[] the program would execute in that order only without changing anything else in the void loop().
Here is what i have tried so far, i have used functions to hard code to check previous state, current state and next state when the user enters their sequence of states in an array , so in my code below the states should go from 0 --> 2 --> 3--> 1 , however , i get 0 --> 2 --> 1 --> 3. I know this problem can be easily solved if i just use the array in the case statement but the compiler gives me an error. I would really appreciate any help or suggestions for this.
My code is shown below :
//Objectives: Use input from laser to control pre-amp on adc. Multiplex the inputs on Pre-Amp
//Type: Pulse, Freq:20Hz (50ms), Amp:5.0 Vpp, Offset:500mV, Width = 100ns
//-----------------------PROJECT LIBRARIES----------------------------------
#include <Bounce2.h>
#include <Arduino.h>
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
//-----------------------DEFINES------------------------------------------
//Declare Laser Input Pin
#define LASER_PIN 2
//Declare Reset Pin
#define RESET_PIN 3
typedef enum {
STATE_0,
STATE_1,
STATE_2,
STATE_3
} fsm_state;
//User can change or remove states here
fsm_state fsm_state_Array[] = {STATE_0, STATE_2, STATE_3, STATE_1};
//*eNextstate controls on which state the program starts the state machine, default is STATE_00, Must be same value as Transition_State[0]
fsm_state eNextState = fsm_state_Array[0];
int Current_State = 0;
int Next_State = 0;
int Previous_State = 0;
// -------------------------CONSTANTS (won't change)-------------------------------------
const unsigned long period = 1000; //the value is a number of milliseconds
//-------------------------VARIABLES (will change)-------------------------------------
bool only_for_print = false;//used only for print state ments
int reset_switch = 1;//Start HIGH to avoid reset
int PulseCount = 0; //Pulse count from X-RAY
int Output = 0;//Switch state on the Pre-Amp
int wait = 0;//wait for pulses count
int N = 20;//no. of pulses to count before switching states
volatile int IRQcount = 0;
volatile boolean reset_flag = false;
unsigned long start_time = 0;
unsigned long current_time = 0;
//----------------------------USER DEFINED FUNCTIONS---------------------------------
void fsm();
void loop();
void setup();
void WDT_RESET();
void IRQcounter();
void CountPulses();
//-----------------------------DEBOUNCE FUNCTIONS---------------------------------------
//--------------------------------MAIN SETUP--------------------------------------
void setup()
{
Serial.begin(115200);
//Pin Setup
pinMode(LASER_PIN, INPUT_PULLUP);
pinMode(RESET_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(LASER_PIN), IRQcounter, RISING);//attach interrupt handler to laser input
attachInterrupt (digitalPinToInterrupt (RESET_PIN), RESET_ISR, FALLING); // attach interrupt handler to reset, wait for user press button or switch
start_time = millis(); //initial start time
sei();//Turn on Interrupts
WaitForPulses();//Waits to detect 20 pulses
}
//--------------------------------MAIN LOOP----------------------------------
void loop()
{
current_time = millis();
fsm();//State machine
}
//--------------------------------PULSE COUNT FUNCTION--------------------------------------------
void CountPulses()
{
// current_time = millis();
if ((current_time - start_time) >= period)
{
start_time = current_time;
cli();//disable interrupts
PulseCount = IRQcount;
IRQcount = 0;
Serial.print(F("Pulse Count is = "));
Serial.println(PulseCount);
sei();//enable interrupts
}
}
//--------------------------------STATE MACHINE FUNCTION--------------------------------------------
void fsm()
{
switch (eNextState)
{
case STATE_0:
/////////Print Statement only for debugging//////////
while (only_for_print == false)
{
Serial.println("The state is 0");
only_for_print = true;
}
///////// Count Pulses Setup /////////////////
Previous_State = fsm_state_Array[3];
Current_State= 0;
Next_State = fsm_state_Array[1];
current_time = millis();
CountPulses();
Output = 0;
if (PulseCount == N)
{
PulseCount = 0;//Reset Pulse Count
only_for_print = false; //used only for print statments
State_Check_0_to_1();//Move to next state
}
break;
case STATE_1:
/////////Print Statement only for debugging//////////
while (only_for_print == false)
{
Serial.println("The state is 1");
only_for_print = true;
}
///////// Count Pulses Setup /////////////////
Previous_State = fsm_state_Array[0];
Current_State= 1;
Next_State = fsm_state_Array[2];
current_time = millis();
CountPulses();
Output = 1;
if (PulseCount == N)
{
PulseCount = 0;//Reset Pulse Count
only_for_print = false; //used only for print statments
State_Check_1_to_2();//Move to next state
}
break;
case STATE_2:
/////////Print Statement only for debugging//////////
while (only_for_print == false)
{
Serial.println("The state is 2");
only_for_print = true;
}
///////// Count Pulses Setup /////////////////
Previous_State = fsm_state_Array[1];
Current_State= 2;
Next_State = fsm_state_Array[3];
current_time = millis();
CountPulses();
Output = 2;
if (PulseCount == N)
{
PulseCount = 0;//Reset Pulse Count
only_for_print = false; //used only for print statments
State_Check_2_to_3();//Move to next state
}
break;
case STATE_3:
/////////Print Statement only for debugging//////////
while (only_for_print == false)
{
Serial.println("The state is 3");
only_for_print = true;
}
///////// Count Pulses Setup /////////////////
Previous_State = fsm_state_Array[2];
Current_State= 3;
Next_State = fsm_state_Array[0];
current_time = millis();
CountPulses();
Output = 3;
if (PulseCount == N)
{
PulseCount = 0;//Reset Pulse Count
only_for_print = false; //used only for print statments
State_Check_3_to_0();//Move to next state
}
break;
}
}
//----------------------------------RESET SWITCH ISR-------------------------------------
void RESET_ISR()
{
reset_flag = true;
if (reset_flag == true)
{
// Serial.println("System will now Reset");// Only for debugging
reset_flag = false;//Reset reset switch flag
wdt_enable(WDTO_500MS);//Reset after 0.5 seconds
while (1)
{
// wdt_reset(); // uncomment to avoid reboot
}
}
}
//-----------------------PULSE COUNT ISR---------------------------------------
void IRQcounter()
{
IRQcount++;
}
//-----------------------WAIT FOR PULSES---------------------------------------
void WaitForPulses()
{
while (wait < 20)
{
if (bit_is_set(EIFR, INTF0))
{
Serial.println("Pulse is detected ");
wait++;
}
}
wait = 0;//reset
}
void State_Check_0_to_1()//Check values of state 0 before going to state 1
{
if(Previous_State == fsm_state_Array[3] && Current_State == 0 && Next_State == fsm_state_Array[1])
{
eNextState = Next_State;
}
}
void State_Check_1_to_2()//Check values of state 1 before going to state 2
{
if((Previous_State == fsm_state_Array[0]) && (Current_State == 1) && (Next_State == fsm_state_Array[2]))
{
eNextState = Next_State;
}
}
void State_Check_2_to_3()//Check values of state 2 before going to state 3
{
if((Previous_State == fsm_state_Array[1]) && (Current_State == 2) && (Next_State == fsm_state_Array[3]))
{
eNextState = Next_State;
}
}
void State_Check_3_to_0()//Check values of state 3 before going to state 0
{
if((Previous_State == fsm_state_Array[2]) && (Current_State == 3) && (Next_State == fsm_state_Array[0]))
{
eNextState = Next_State;
}
}
Here is what my serial monitor shows:
Pulse is detected
Pulse is detected
Pulse is detected
Pulse is detected
Pulse is detected
Pulse is detected
Pulse is detected
Pulse is detected
Pulse is detected
Pulse is detected
Pulse is detected
Pulse is detected
Pulse is detected
Pulse is detected
Pulse is detected
Pulse is detected
Pulse is detected
Pulse is detected
Pulse is detected
Pulse is detected
The state is 0 -----> State 0
Pulse Count is = 72
Pulse Count is = 19
Pulse Count is = 20
The state is 2 -----> State 2
Pulse Count is = 20
The state is 1 -----> State 1
Pulse Count is = 21
Pulse Count is = 19
Pulse Count is = 21
Pulse Count is = 19
Pulse Count is = 21
Pulse Count is = 19
Pulse Count is = 21
Pulse Count is = 19
Pulse Count is = 21
Pulse Count is = 20
The state is 3 -----> State 3
Pulse Count is = 20
The state is 0
Pulse Count is = 20
The state is 2
Pulse Count is = 20
The state is 1
Pulse Count is = 20
The state is 3
Seperate code to test out FSM with pointers as suggested in the comments:
typedef void (*current_state)();
void state0();
void state1();
void state2();
void state3();
current_state states[4]={&state0,&state2,&state3,&state1};
current_state next_state;
void setup()
{
Serial.begin(115200);
}
void loop()
{
current_state();
}
void state0()
{
next_state = states[1]; // No parenthesis!
Serial.println("I am in STATE 0");
}
void state1()
{
next_state = states[2]; // No parenthesis!
Serial.println("I am in STATE 1");
}
void state2()
{
next_state = states[3]; // No parenthesis!
Serial.println("I am in STATE 2");
}
void state3()
{
next_state = states[0]; // No parenthesis!
Serial.println("I am in STATE 3");
}

This code from handling of STATE_2
Next_State = fsm_state_Array[3];
sets Next_State to STATE_1 because the array is initalized as
fsm_state fsm_state_Array[] = {STATE_0, STATE_2, STATE_3, STATE_1};
That means...
fsm_state_Array[0] = STATE_0;
fsm_state_Array[1] = STATE_2;
fsm_state_Array[2] = STATE_3;
fsm_state_Array[3] = STATE_1; // This is the element used
To provide a more "dynamic" solution probably using function pointer for states works better that using a switch:
// Current state is just a apointer to a void function
// accepting no parameters
void (*current_state)();
// All states are just void functions accepting no parameters
void state1();
void state2();
...
// To set what is the next state you update current_state
void state1() {
...
current_state = state2; // No parenthesis!
}
// In the main handler you just call current_state
...
current_state(); // Do the state processing
If you want to perform a sequence of operations then using function pointers you can just keep an array of them and iterate over it:
void (*states[])() = {
state1,
state2,
state3,
...
NULL /// To mark the end of the sequence
};
then you can execute the steps in sequence with
void main() {
for(int i=0; states[i]; i++) {
states[i](); // Execute the step
}
}

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

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();
}```

Using a pointer to use a variable as *part* of a call to a class variable

I'm trying to use a pointer in a function argument to read a variable from a class, like this:
void Function(int (*Argument)) {
Variable = Object*Argument.ClassVariable;
}
Note: the reason I want to do this is so that I can set the value of a rotary encoder position equal to the value a class variable was previously at, prior to allowing the user to change that class variable value. This way, when the user cycles through the class variables to set them, the starting position for each variable is the saved value.
Class objects are named Object1, Object2, etc.
The variable I want to read from each object is named ClassVariable.
When I call the function, i will useFunction(ClassNumber);
If ClassNumber is 13 at the time the function is called, I want Variable to be made equal to Object13.ClassVariable
Is this possible?
Further Info:
The entire class is public.
Constructor for class objects (note, this is arduino, byte is 8-bit unsigned):
Modes(byte hue, byte sat, byte val, int del, bool hROal, bool hset, bool sset, bool vset, bool dset) {
hueVal = hue;
satVal = sat;
valVal = val;
delVal = del;
hueROallow = hROal;
hSet = hset;
sSet = sset;
vSet = vset;
dSet = dset;
}
Each class object is a separate 'mode' that the user can select. The Argument i intend using in the function is the 'mode number' currently selected.
FULL CODE (very much a work in progress)
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH1106.h>
const byte Button2 = 8;
const byte EncApin = 3; // EncApin **MUST BE interrupt**
const byte EncBpin = 4; // These are the three pins the encoder A/B & button are connected to
const byte EncButt = 2; //
static int8_t enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0}; // array to set encoder H/L sequence
byte encVal; // initialises reading from encoder
Adafruit_SH1106 display(0); // Initialise display? (On SPI OLED screens this sets the MOSI/CLK/DC/RST/CS pins)
int displayVal; // to store the current output value for display
String displayMode;
byte mode = 1; // set mode 0 at beginning
byte qtyModes = 3; // set number of modes that may be selected here
byte setMode = 1;
byte qtySetModes = 4; // set number of sub-modes for setting values
///// FUNCTION PROTOTYPES ///////// must be declared here to allow the class to use them
void EncReading();
void EncReadingRO();
////////////////////////////////////////////////////////
////////////// ******** CLASSES ********* //////////////
////////////////////////////////////////////////////////
class Modes {
public: // everything in the class below this will be available to the program outside of the class
// Class Member Variables
// These are initialized at startup
byte hueVal;
byte satVal;
byte valVal;
int delVal;
bool hueROallow;
bool hSet;
bool sSet;
bool vSet;
bool dSet;
byte CLdisplayVal;
String displayDesc;
// These maintain the current state
unsigned long prevMillis; // will store last time LED was updated
// Constructor - creates a Mode & initializes the member variables and state
// additional options for whether rollover of values allowed needed
Modes(byte hue, byte sat, byte val, int del, bool hROal, bool hset, bool sset, bool vset, bool dset) {
hueVal = hue;
satVal = sat;
valVal = val;
delVal = del;
hueROallow = hROal;
hSet = hset;
sSet = sset;
vSet = vset;
dSet = dset;
}
void Update() {
switch (setMode) {
case 1: // case 1 for hue update
if (hSet == 0) {
displayDesc = F(" HUE (FIXED)");
CLdisplayVal = hueVal;
break;
}
if (hueROallow == 1) EncReadingRO();
else EncReading();
hueVal = encVal;
CLdisplayVal = encVal;
displayDesc = F(" HUE");
break;
case 2: // saturation update
if (sSet == 0) {
displayDesc = F(" SATURATION (FIXED)");
CLdisplayVal = satVal;
break;
}
EncReading();
satVal = encVal;
CLdisplayVal = encVal;
displayDesc = F(" SATURATION");
break;
case 3: // value update
if (vSet == 0) {
displayDesc = F(" BRIGHTNESS (FIXED)");
CLdisplayVal = valVal;
break;
}
EncReading();
valVal = encVal;
CLdisplayVal = encVal;
displayDesc = F(" BRIGHTNESS");
break;
case 4: // delay update
if (dSet == 0) {
displayDesc = F(" TIMING (FIXED)");
CLdisplayVal = delVal;
break;
}
EncReading();
delVal = encVal;
CLdisplayVal = encVal;
displayDesc = F(" TIMING");
break;
}
displayReading();
}
void displayReading() {
unsigned long currMillis = millis(); // These four lines are to
static unsigned long prevMillis; // act as a delay, except
if (currMillis - prevMillis >= 100) { // without holding the execution // note: encoder reading sensitive to delal changes, 100 not bad
prevMillis = currMillis; // of other code
display.fillRect(39, 30, 54, 24, BLACK);
display.fillRect(0, 0, 128, 18, WHITE);
display.setTextSize(1);
display.setTextColor(BLACK);
display.setCursor(1,1);
display.println(displayMode);
display.setCursor(1,10);
display.println(displayDesc);
display.setTextSize(3);
display.setTextColor(WHITE);
display.setCursor(39,30);
display.println(CLdisplayVal);
display.display();
}
}
};
////////// Construct objects - this sets up the objects we want of the class 'Modes'
// Modes modex(Hue0-255, Sat0-255, Val0-255, Del0-255, Hue rollover0/1, Hue settable0/1, Sset0/1, Vset0/1, Dse0/1
Modes mode1(50, 100, 150, 100, 1, 1, 1, 1, 1); // object 'mode1', initializing with H50, S100, V150, D100, hue rollover & settable options ON
Modes mode2(55, 105, 155, 105, 0, 1, 1, 1, 1);
Modes mode3(63, 73, 83, 93, 0, 1, 1, 1, 1);
////////////////////////////////////////////////////////
////////// ******** SETUP / LOOP ********* /////////////
////////////////////////////////////////////////////////
void setup() {
Serial.begin(115200);
display.begin(SH1106_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3D (for the 128x64)
display.clearDisplay();
display.display();
pinMode(EncApin, INPUT_PULLUP); // Turn on internal pullup resistors for encoder pins & buttons
pinMode(EncBpin, INPUT_PULLUP);
pinMode(Button2, INPUT_PULLUP);
pinMode(EncButt, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(EncApin), read_encoder, CHANGE);
attachInterrupt(digitalPinToInterrupt(EncButt), encButtPress, FALLING);
pciSetup(Button2); // set up encApin for pin change interrupt
encVal = mode1.hueVal; // initialize the encoder to the mode1 setmode1 value
}
void loop() {
switch(mode) {
case 1:
displayMode = F("MODE:Call it anything");
mode1.Update();
// add call to the mode 1 LED display function here, using mode1.xyz variables
break;
case 2:
displayMode = F("MODE:Second");
mode2.Update();
// add call to the mode 2 LED display function here, using mode2.xyz variables
break;
case 3:
displayMode = F("MODE:Third");
mode3.Update();
// add call to the mode 2 LED display function here, using mode2.xyz variables
break;
}
Serial.print(F("Enc: "));
Serial.print(encVal);
Serial.print(F(" M1 H: "));
Serial.print(mode1.hueVal);
Serial.print(F(" S: "));
Serial.print(mode1.satVal);
Serial.print(F(" V: "));
Serial.print(mode1.valVal);
Serial.print(F(" D: "));
Serial.print(mode1.delVal);
Serial.print(F(" M2 H: "));
Serial.print(mode2.hueVal);
Serial.print(F(" S: "));
Serial.print(mode2.satVal);
Serial.print(F(" V: "));
Serial.print(mode2.valVal);
Serial.print(F(" D: "));
Serial.println(mode2.delVal);
// Serial.print(F("freeMemory()="));
// Serial.println(freeMemory());
}
////////////////////////////////////////////////////////
//////////// ******** FUNCTIONS ********* //////////////
////////////////////////////////////////////////////////
///// Function to set encVal, 0-255, NO rollover
void EncReading() {
int8_t encoderdata;
encoderdata = read_encoder(); // returns the +- value from the read_encoder function
if (encoderdata) { // if not equal to zero
if (encVal+encoderdata>255 || encVal+encoderdata<0); // these if/else statements clamp encVal to prevent byte rollover
else {
encVal += encoderdata;
} // end else
}
}
///// Function to set encVal, 0-255, WITH rollover
void EncReadingRO() {
int8_t encoderdata;
encoderdata = read_encoder(); // returns the +- value from the read_encoder function
if (encoderdata) { // if not equal to zero
encVal += encoderdata;
}
}
////////////////////////////////////////////////////////
//////////// ******** INTERRUPTS ********* /////////////
////////////////////////////////////////////////////////
/////// Pin Change Interrupt Setup Function /////////// called in void setup to set the selected pin as a PCI
void pciSetup(byte pin)
{
*digitalPinToPCMSK(pin) |= bit (digitalPinToPCMSKbit(pin)); // enable pin
PCIFR |= bit (digitalPinToPCICRbit(pin)); // clear any outstanding interrupt
PCICR |= bit (digitalPinToPCICRbit(pin)); // enable interrupt for the group
}
//////////// PCI Interrupt Sub Routines////////
// ISR (PCINT0_vect) is ISR for D8-13 // ISR (PCINT2_vect) is ISR for A0-5 // ISR (PCINT2_vect) is ISR for D0-7 //
ISR (PCINT0_vect) // handle pin change interrupt for D8 to D13 here, depending on which are set in void setup
{
if(digitalRead(Button2) == LOW)
buttonPress();
}
//////// Func for ENCODER button press ISR ****** CHANGE 'setMode' ***** ///////////////
void encButtPress() {
static unsigned long prevInterrTime = 0;
unsigned long interrTime = millis();
if (interrTime - prevInterrTime > 200) {
setMode++;
// *** ADD HERE *** need to set encVal to whatever the existing value is in the setMode being switched to
if (setMode > qtySetModes) setMode = 1;
prevInterrTime = interrTime;
setPrevEncVal(mode);
}
}
void setPrevEncVal(byte (*modeNum)) {
switch (setMode) {
case 1: encVal = mode&modeNum.hueVal; break;
case 2: encVal = mode1.satVal; break;
case 3: encVal = mode1.valVal; break;
case 4: encVal = mode1.delVal; break;
}
}
//////// Func for button press ISR ****** CHANGE 'mode' ***** ///////////////
void buttonPress() {
static unsigned long prevInterrTime = 0;
unsigned long interrTime = millis();
if (interrTime - prevInterrTime > 200) {
mode++; // increment 'mode'
setMode = 1; // reset 'setMode'
}
if (mode > qtyModes) mode = 1;
prevInterrTime = interrTime;
}
//////// Func for +1/-1 encoder reading ISR ///////
/* returns change in encoder state (-1,0,1) */
int8_t read_encoder() {
static uint8_t old_AB = 0;
old_AB <<= 2;
old_AB |= ((digitalRead(EncBpin))?(1<<1):0) | ((digitalRead(EncApin))?(1<<0):0);
return ( enc_states[( old_AB & 0x0f )]);
}
To answer the question:
You can't, because C++ is a compiled language, and as such, the names of the functions, objects and variables become meaningless (instead, they become just addresses)
For example, you may see in your code
int myVariable = 6;
but the compiler sees:
mov [6], [0x6874]
Read Compiled vs. Interpreted Languages for more reference.
[For your particular case]
You'll be better off if you use interfaces and a factory.
class Mode {
virtual int getAttribute() = 0;
}
class AMeaningfulName : public Mode {
int getAttribute() { return 1; }
}
class SelectAnotherMeaningfulNamePlease : public Mode {
int getAttribute() { return 2; }
}
class ModeFactory {
Mode getMode(int userSelectedMode) {
if (userSelectedMode == MODE_1) {
return new AMeaningfulMode();
} else if (userSelectedMode == MODE_2) {
return new SelectAnotherMeaningulNamePlease();
} else {
//send an exception so the user knows he selected something invalid
}
}
}
///now, in your main or elsewhere
ModeFactory factory = new ModeFactory();
Mode mode = factory.getMode(userSelectedValue);
int theAtttributeIWanted = mode.getAttribute();
Take a look at virtual functions
https://en.wikipedia.org/wiki/Virtual_function
And also at factory pattern
https://www.tutorialspoint.com/design_pattern/factory_pattern.htm