Bonjour,
J'essaye de me programmer un compte pose pour ma chambre noire argentique (photo avec agrandisseur).
Pour mon besoin, j'ai donc :
- Un écran LCD I2C
- Un clavier 4x4
- Un sélecteur type potentiomètre
Sur mon afficheur LCD, j'affiche deux lignes :
- Nbr Etapes
- Nbr Secondes
Pour définir le nombre d'étapes et le nombre de seconde je souhaite les entrer via le clavier (j'arrive à faire le programme de 0 à 9 mais dès que je souhaite faire 10 ou plus ca coince :))
Pour changer de ligne j'utilise le sélecteur qui affiche un petit triangle.
J'ai trouvé un exemple de code pour mettre 2 digits, mais mon problème vient pour libérer la fonction une fois la valeur entrée et valider (par la touche #), en effet, je n'arrive plus à utiliser le sélecteur pour changer de ligne si j'utilise la fonction "getKeypadIntegerMulti"
Si vous pouvez me donner une piste pour libérer la fonction afin que le sélecteur passe à la ligne suivante.
Merci beaucoup
voici mon code dans son intégralité
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#define I2C_ADDR 0x27
LiquidCrystal_I2C lcd(0x27,20,4);
// This section sets up the rotary encoder on D2 and D3 with interrupts to minimise load. Potentially change the volatile data to byte to save space
static byte pinA = 2; // Our first hardware interrupt pin is digital pin 2
static byte pinB = 3; // Our second hardware interrupt pin is digital pin 3
static byte pinC = 4; // Rotary push button on pin 4
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 byte 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
int menuSelection = 0; //to detect which menu is selected. Do not let menuselection <= 0
byte menuSelectionState = HIGH; //to detect pushbutton on rotary, rotary is NC switch i.e. pressing the button equals to a LOW and not high
byte menuSelectionMode = 0; //determine if menu selection 0 (no changing) 1 (changing mode)
byte mainFunction = 10;
byte menuChangemode = 0;
const byte ROWS = 4;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] = {
{'1','4','7', '*'},
{'2','5','8', '0'},
{'3','6','9', '#'},
{'A','B','C', 'D'}
};
byte rowPins[ROWS] = {12, 11, 10, 9};
byte colPins[COLS] = {8, 7, 6, 5};
Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
char customKey = customKeypad.getKey();
long getKeypadIntegerMulti()
{
long value = 0;
long keyvalue;
int isnum;
int validation;
do
{
keyvalue = customKeypad.getKey();
isnum = (keyvalue >= '0' && keyvalue <= '9' || keyvalue == 'A' || keyvalue == 'B' || keyvalue == 'C' || keyvalue == 'D');
validation = (keyvalue == 'A' || keyvalue == 'B' || keyvalue == 'C' || keyvalue == 'D' );
if (isnum && !validation)
{
value = value * 10 + keyvalue - '0';
}
} while (isnum|| !keyvalue);
return value;
}
byte selectorL[8] = //icon creation for menu arrow pointing left
{
B00010,
B00110,
B01110,
B11110,
B01110,
B00110,
B00010,
B00000
};
byte selectorR[8] = //icon creation for menu arrow pointing right
{
B01000,
B01100,
B01110,
B01111,
B01110,
B01100,
B01000,
B00000
};
byte NbrEtape = 0 ;
byte NbrSec = 0 ;
String selectionEtape;
void setup() {
lcd.init();
lcd.setBacklight(HIGH);
lcd.home();
lcd.createChar(1,selectorL);
lcd.createChar(2,selectorR);
lcd.clear();
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)
pinMode(pinC, INPUT_PULLUP); // designate rotary encoder push button for pin change intterupt input
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)
}
void loop() {
lcd.setCursor(0,0);
lcd.print(F("Nbr Etapes : "));
lcd.setCursor(0,1);
lcd.print(F("Nbr secondes :"));
lcd.setCursor (17,menuSelection);
lcd.write(1); // Triangle postion 1 = pointe à gauche 2 = Pointe à droite
if (oldEncPos != encoderPos){ //Allows selection of editing with rotary selector
menuSelection = menuSelection + (encoderPos - oldEncPos);
if (menuSelection > 1){ //recheck if this is >3 is better or more accurate
menuSelection = 0;
}
if (menuSelection < 0){ //recheck if this is <1 is better or more accurate
menuSelection = 1;
}
oldEncPos = encoderPos;
lcd.clear();
}
if (menuSelection == 0){ //Change the number of steps - now maximum is 9 steps
int NbrEtape = getKeypadIntegerMulti();
lcd.setCursor(14,0);
lcd.print(NbrEtape);
//lcd.clear();
}
if (menuSelection == 1){ //Change the number of steps - now maximum is 9 steps
int NbrSec = getKeypadIntegerMulti();
lcd.setCursor(14,1);
lcd.print(NbrSec);
}
}
void PinA(){ //to monitor rotary position
cli(); //stop interrupts happening before we read pin values
reading = PIND & 0xC; // read all eight pin values then strip away all but pinA and pinB's values
if(reading == B00001100 && aFlag) { //check that we have both pins at detent (HIGH) and that we are expecting detent on this pin's rising edge
encoderPos --; //decrement the encoder's position count
bFlag = 0; //reset flags for the next turn
aFlag = 0; //reset flags for the next turn
}
else if (reading == B00000100) bFlag = 1; //signal that we're expecting pinB to signal the transition to detent from free rotation
sei(); //restart interrupts
}
void PinB(){ //to monitor rotary position2
cli(); //stop interrupts happening before we read pin values
reading = PIND & 0xC; //read all eight pin values then strip away all but pinA and pinB's values
if (reading == B00001100 && bFlag) { //check that we have both pins at detent (HIGH) and that we are expecting detent on this pin's rising edge
encoderPos ++; //increment the encoder's position count
bFlag = 0; //reset flags for the next turn
aFlag = 0; //reset flags for the next turn
}
else if (reading == B00001000) aFlag = 1; //signal that we're expecting pinA to signal the transition to detent from free rotation
sei(); //restart interrupts
}