HI, I am trying different ways to limit values with rotary encoder menu. Ex.: temp max= 20 temp min = 0
I tried with constrain()...no results:
setting1 = constrain(setting1, 0, 20);
Also tried this, but I did not work or I put it at he wrong place un my code:
void limitSettingVal(int setting1){
if (Mode ==1){
if (setting1 < 0 ){
encoderPos = 20;
}
if (setting1 > 20) {
encoderPos = 0;
}
}
}
Here is the full code. the values I want to constrain are: setting1 and setting2
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Rotary encoder declarations
static int pinA = 2; // Our first hardware interrupt pin is digital pin 2
static int pinB = 3; // Our second hardware interrupt pin is digital pin 3
volatile byte aFlag = 0; // let's us know when we're expecting a rising edge on pinA to signal that the encoder has arrived at a detent
volatile byte bFlag = 0; // let's us know when we're expecting a rising edge on pinB to signal that the encoder has arrived at a detent (opposite direction to when aFlag is set)
volatile byte encoderPos = 0; //this variable stores our current value of encoder position. Change to int or uin16_t instead of byte if you want to record a larger range than 0-255
volatile byte oldEncPos = 0; //stores the last encoder position value so we can compare to the current reading and see if it has changed (so we know when to print to the serial monitor)
volatile byte reading = 0; //somewhere to store the direct values we read from our interrupt pins before checking to see if we have moved a whole detent
bool rising = true; //global variable for encoder interrupt routine
// Button reading, including debounce without delay function declarations
const byte buttonPin = 4; // this is the Arduino pin we are connecting the push button to
byte oldButtonState = HIGH; // assume switch open because of pull-up resistor
const unsigned long debounceTime = 10; // milliseconds
unsigned long buttonPressTime; // when the switch last changed state
boolean buttonPressed = 0; // a flag variable
// Menu and submenu/setting declarations
byte Mode = 0; // This is which menu mode we are in at any given time (top level or one of the submenus)
const int modeMax = 4; // This is the number of submenus/settings you want
const int tempMax = 20; //Temperature max dans setting1
const int tempMin = 0; //Temperature min dans setting1
const int humiMax = 99; //Humidite max dans setting2
const int humiMin = 35; //Humidite min dans setting2
byte setting1 = 0; // a variable which holds the value we set
byte setting2 = 0; // a variable which holds the value we set
byte setting3 = 0; // a variable which holds the value we set
byte setting4 = 0; // a variable which holds the value we set
int ledPin1 = 5;
int ledPin2 = 6;
/////
/* Note: you may wish to change setting etc to int, float or boolean to suit your application.
Remember to change "void setAdmin(byte name,*BYTE* setting)" to match and probably add some
"modeMax"-type overflow code in the "if(Mode == N && buttonPressed)" section*/
void setup() {
//Rotary encoder section of setup
pinMode(ledPin1, OUTPUT); //Del verte sur breadBoard
pinMode(ledPin2, OUTPUT); //Del verte sur breadBoard
pinMode(pinA, INPUT_PULLUP); // set pinA as an input, pulled HIGH to the logic voltage (5V or 3.3V for most cases)
pinMode(pinB, INPUT_PULLUP); // set pinB as an input, pulled HIGH to the logic voltage (5V or 3.3V for most cases)
//attachInterrupt(0,PinA,RISING); // set an interrupt on PinA, looking for a rising edge signal and executing the "PinA" Interrupt Service Routine (below)
//attachInterrupt(1,PinB,RISING); // set an interrupt on PinB, looking for a rising edge signal and executing the "PinB" Interrupt Service Routine (below)
//essaie attach interrupt furum
pinMode(pinA, INPUT_PULLUP);
pinMode(pinB, INPUT_PULLUP);
if (digitalRead(pinA)) {
attachInterrupt(0,PinA,FALLING);
attachInterrupt(1,PinB,FALLING);
rising = false;
}
else {
attachInterrupt(0,PinA,RISING);
attachInterrupt(1,PinB,RISING);
}
// button section of setup
pinMode (buttonPin, INPUT_PULLUP); // setup the button pin
// DEBUGGING section of setup
Serial.begin(9600); // DEBUGGING: opens serial port, sets data rate to 9600 bps
//démarre LCD
lcd.init(); // initialize the lcd
lcd.backlight();
//message power ''on'' sur LCD
lcd.setCursor(5,0); //Defining positon to write from first row, first column .
lcd.print("CHARCUPRO");
lcd.setCursor(3,2);
lcd.print("Version 1.1.1");
lcd.setCursor(0,2); //Second row, first column
lcd.print("");
delay(3000); //wait 8 sec
lcd.clear(); //clear the whole LCD
lcd.setCursor(1,1);
lcd.print("TEMP"); //text
//----------------------
lcd.setCursor(1,3);
lcd.print("HUMI"); //text
//----------------------
lcd.setCursor(12,1);
lcd.print("VENT"); //text
//----------------------
lcd.setCursor(12,3);
lcd.print("UV"); //text
//----------------------
lcd.setCursor(8,1);
lcd.print((char)223); //signe de degrees
//----------------------
lcd.setCursor(9,1);
lcd.print("C"); //signe de degrees
//----------------------
lcd.setCursor(9,3);
lcd.print("%"); //text
//----------------------
lcd.setCursor(17,1);
lcd.print("off"); //text
//----------------------
lcd.setCursor(17,3);
lcd.print("off"); //text
//----------------------
//lcd.setCursor(14,0);
//lcd.print("retour"); //text
//----------------------
//lcd.setCursor(0,0);
//lcd.print("Ajuster"); //text
//----------------------
}
//void printLCD(){
//These are the values which are not changing the operation
//}
void loop() {
rotaryMenu();
showSetting (setting1, setting2 );
//limitSettingVal(setting1);
// carry out other loop code here
}
////////****TOP ROTARY MENU*****////////
void rotaryMenu() { //This handles the bulk of the menu functions without needing to install/include/compile a menu library
//DEBUGGING: Rotary encoder update display if turned
if(oldEncPos != encoderPos) { // DEBUGGING
Serial.println(encoderPos);// DEBUGGING. Sometimes the serial monitor may show a value just outside modeMax due to this function. The menu shouldn't be affected.
oldEncPos = encoderPos;// DEBUGGING
}
// DEBUGGING
// Button reading with non-delay() debounce - thank you Nick Gammon!
byte buttonState = digitalRead (buttonPin); //toujours lire si bouton pesé ou pas
if (buttonState != oldButtonState){
if (millis () - buttonPressTime >= debounceTime){ // debounce
buttonPressTime = millis (); // when we closed the switch
oldButtonState = buttonState; // remember for next time
if (buttonState == LOW){
Serial.println ("Button was pressed"); // DEBUGGING: print that button has been closed
buttonPressed = 1;
}
else {
Serial.println ("Button opened"); // DEBUGGING: print that button has been opened
buttonPressed = 0;
}
} // end if debounce time up
} // end of button state change
//********** MODE MENU**********
//Main menu section
if (Mode == 0) {
if (encoderPos > (modeMax+10)) encoderPos = modeMax; // check if out of bounds below 0 and correct if we have
else if (encoderPos > modeMax) encoderPos = 0; // check we haven't gone out of bounds above modeMax and correct if we have
//fleche de curseur
switch(encoderPos){
case 0 : //MENU RETOUR
lcd.setCursor(0,1);lcd.print(" ");lcd.setCursor(0,3);lcd.print(" ");lcd.setCursor(11,1);
lcd.print(" ");lcd.setCursor(11,3);lcd.print(" ");lcd.setCursor(0,0);lcd.print("<<");
//delay(1000);lcd.setCursor(0,0);lcd.print(" ");delay(700);
break;
case 1:
lcd.setCursor(13,0);lcd.print(" ");lcd.setCursor(0,3);lcd.print(" ");lcd.setCursor(11,3);
lcd.print(" ");lcd.setCursor(11,1);lcd.print(" ");lcd.setCursor(0,1);lcd.print(">");
lcd.setCursor(0,0);lcd.print(" ");
break;
case 2:
lcd.setCursor(13,0);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(11,1);
lcd.print(" ");
lcd.setCursor(11,3);
lcd.print(" ");
lcd.setCursor(0,0);lcd.print(" ");
lcd.setCursor(0,3);
lcd.print(">");
break;
case 3:
lcd.setCursor(13,0);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(0,3);
lcd.print(" ");
lcd.setCursor(11,3);
lcd.print(" ");
lcd.setCursor(0,0);
lcd.print(" ");
lcd.setCursor(11,1);
lcd.print(">");
break;
case 4:
lcd.setCursor(13,0);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(0,3);
lcd.print(" ");
lcd.setCursor(11,1);
lcd.print(" ");
lcd.setCursor(0,0);
lcd.print(" ");
lcd.setCursor(11,3);
lcd.print(">");
break;
}
if (buttonPressed){
Mode = encoderPos; // set the Mode to the current value of input if button has been pressed
Serial.print("Mode selected: "); //DEBUGGING: print which mode has been selected
Serial.println(Mode); //DEBUGGING: print which mode has been selected
buttonPressed = 0; // reset the button status so one press results in one action
}
if (Mode == 1){
Serial.println("TEMP_Mode 1"); //DEBUGGING: print which mode has been selected
encoderPos = setting1; // start adjusting TEMP from last set point
}
if (Mode == 2) {
Serial.println("HUMID_Mode 2"); //DEBUGGING: print which mode has been selected
encoderPos = setting2; // start adjusting HUMIDITY from last set point
}
if (Mode == 3) {
Serial.println("FAN_Mode 3"); //DEBUGGING: print which mode has been selected
encoderPos = setting3; // start turning FAN on or off
}
if (Mode == 4) {
Serial.println("UV_Mode 4"); //DEBUGGING: print which mode has been selected
encoderPos = setting4; // start turning UV on or off
}
}
//**********SET SETTING VALUES**************
if (Mode == 1 && buttonPressed) {
setting1 = encoderPos; // record whatever value your encoder has been turned to, to setting 1
if(setting1 > 0){ //DEBUGGING
digitalWrite(5, HIGH);//DEBUGGING
}
if (setting1 == 0){ //DEBUGGING
digitalWrite(5,LOW);//DEBUGGING
}
lcd.setCursor(6,1);
lcd.print(" ");
lcd.setCursor(6,1);
lcd.print(setting1);
//remettre curseur
lcd.setCursor(0,1);
lcd.print(">");
setAdmin(1,setting1);
//code to do other things with setting1 here, perhaps update display
}
if (Mode == 2 && buttonPressed) {
setting2 = encoderPos; // record whatever value your encoder has been turned to, to setting 2
if (setting2 > 0){ //DEBUGGING
digitalWrite(6, HIGH);//DEBUGGING
}
if (setting2 == 0){ //DEBUGGING
digitalWrite(6,LOW);//DEBUGGING
}
lcd.setCursor(6,3);
lcd.print(" ");
lcd.setCursor(6,3);
lcd.print(setting2);
setAdmin(2,setting2);
//code to do other things with setting1 here, perhaps update display
}
if (Mode == 3 && buttonPressed){
setting3 = encoderPos; // record whatever value your encoder has been turned to, to setting 3
setAdmin(3,setting3);
//code to do other things with setting3 here, perhaps update display
}
if (Mode == 4 && buttonPressed){
setting3 = encoderPos; // record whatever value your encoder has been turned to, to setting 4
setAdmin(4,setting4);
//code to do other things with setting4 here, perhaps update display
}
}
//void limitSettingVal(int setting1){
//if (Mode ==1){
// if (setting1 < 0 ){
// encoderPos = 20;
// }
//if (setting1 > 20) {
// encoderPos = 0;
//}
//setting1 = constrain(setting1, 0, 20);
// }
//}
void showSetting (int setting1, int setting2 ) { //FONCTION AFFICHE VAL TEMPS REEL
if (Mode == 1) {
lcd.setCursor(6,1);
lcd.print(" ");
lcd.setCursor(6,1);
lcd.print(encoderPos);
delay(20);
}
if (Mode == 2) {
lcd.setCursor(6,3);
lcd.print(" ");
lcd.setCursor(6,3);
lcd.print(encoderPos);
delay(20);
}
}
// Carry out common activities each time a setting is changed
void setAdmin(byte name, byte setting){
Serial.print("Setting "); //DEBUGGING
Serial.print(name); //DEBUGGING
Serial.print(" = "); //DEBUGGING
Serial.println(setting);//DEBUGGING
encoderPos = Mode; // reorientate the menu index put 0 to go automatically to main menu
buttonPressed = 0; // reset the button status so one press results in one action
Mode = 0; // go back to top level of menu, now that we've set values
Serial.println("Main Menu"); //DEBUGGING
}
//Rotary encoder interrupt service routine for one encoder pin
void PinA(){
cli();
reading = PIND & 0xC;
if (rising) {
if(reading == B00001100 && aFlag) {
encoderPos --;
bFlag = 0;
aFlag = 0;
EICRA &= B11111010;
rising = false;
}
else if (reading == B00000100) bFlag = 1;
}
else {
if(reading == 0 && aFlag) {
encoderPos --;
bFlag = 0;
aFlag = 0;
EICRA |= B00000101;
rising = true;
}
else if (reading == B00001000) bFlag = 1;
}
sei();
}
void PinB(){
cli();
reading = PIND & 0xC;
if (rising) {
if (reading == B00001100 && bFlag) {
encoderPos ++;
bFlag = 0;
aFlag = 0;
EICRA &= B11111010;
rising = false;
}
else if (reading == B00001000) aFlag = 1;
}
else {
if (reading == 0 && bFlag) {
encoderPos ++;
bFlag = 0;
aFlag = 0;
EICRA |= B00000101;
rising = true;
}
else if (reading == B00000100) aFlag = 1;
}
sei();
}
// end of sketch!
