I've been having trouble with a mutator in my project. I've been doing some research and the most I could find was a solution using references (which I included in my code). However, this didn't work. My project is a dispenser for dog food, I'm using OOP where I have 3 classes. The main class, Menu class, and Switch class. Menu class is where I use the LCD screen and Switch class is where I define the functionality of the switches. I'm having trouble in Menu class where I have the function setMenu(Switch right); which is a menu where the user is supposed to set the times that is wanted to dispense food. The if loop that I'm using to send a message when the user wants to save time (with a long press) is staying true regardless of the mutator, therefore the message stays looped indefinitely. Why is the mutator not working?
Thanks so much in advance for your help
//Menu class
#include "Menu.h"
void Menu::setMenu(Switch right)
{
//initialize right switch
right.pressed();
//code for setMenu, not relevant to my issue
//save the time and send message
if (right.getLongState()) //getter
{
clearScreen(); //function to clear the screen
messageTime = millis() + 1500;
while (millis() < messageTime)
{
lcd.setCursor(0, 0);
lcd.print("Time Saved");
}
clearScreen();
right.setLongState(false); //mutator
}
}
//Switch class
#include "Switch.h"
//getter (accessor)
bool& Switch::getLongState() {
return longState;
}
//setter (mutator)
void Switch::setLongState(bool l)
{
longState = l;
return;
}
//function for the functionalities of the switches (short press, counter, and long press with debouncing)
void Switch::pressed()
{
byte reading = digitalRead(pin);
if (reading != lastState)
{
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay)
{
if (reading != currentState)
{
currentState = reading;
if (currentState)
{
pressedTime = millis();
isPressing = true;
isLongDetected = false;
}
else
{
isPressing = false;
releasedTime = millis();
long pressDuration = releasedTime - pressedTime;
if (pressDuration < shortPressTime)
{
Serial.println("Short press");
shortState = ! shortState;
count++;
if (count > 1)
count = 0;
}
}
}
}
if (isPressing == true && isLongDetected == false)
{
long pressDuration = millis() - pressedTime;
if (pressDuration > longPressTime)
{
Serial.println("Long press");
isLongDetected = true;
longState = ! longState;
}
}
lastState = reading;
}
I've never heard them called that but wikipedia says this:
In computer science, a mutator method is a method used to control changes to a variable. They are also widely known as setter methods. Often a setter is accompanied by a getter (also known as an accessor), which returns the value of the private member variable.
Why does getLongState return a reference, rather than just a value? It makes no sense, especially for a getter, whose sole purpose is to LIMIT access to the variable.
I think the problem is that your "Switch" object is being passed by value. That means it makes a copy of the object. You are setting a value in the copy, not in the original. Try:
void Menu::setMenu(Switch &right)
{
//initialize right switch
right.pressed();
The '&' in "Switch &right" makes it a 'pass by reference' argument and a pointer to the original object is passed. Then when you call "setLongState()" it will modify the original object and not just the copy that was passed.
SteveMann:
Very few Arduino users use classes overtly. (They are hidden behind the IDE).
Is this a school project?
Is there a reason you want to do this the hard way?
And, what the heck is a "mutator"? Is this a feature of C++ that has somehow escaped my five years experience programming Arduinos?
It is a school project, I am required to use OOP to add complexity
A mutator or setter is a function that can change the value of a private variable, just like an accessor or getter is a function used to get the value of a private variable.
johnwasser:
I think the problem is that your "Switch" object is being passed by value. That means it makes a copy of the object. You are setting a value in the copy, not in the original. Try:
void Menu::setMenu(Switch &right)
{
//initialize right switch
right.pressed();
The '&' in "Switch &right" makes it a 'pass by reference' argument and a pointer to the original object is passed. Then when you call "setLongState()" it will modify the original object and not just the copy that was passed.
Thanks, I tried that and it worked I was placing the & in the wrong function
jimLee:
WOW! What kind of teacher says things like this?
I'm thinking the reason for requiring the use of OOP programming techniques in a programming class assignment would be to teach OOP programming techniques. The "to add complexity" part is probably just Editorial Comment by @ferchi1809.