Bonjour,
Pour avoir plus de précision dans les calculs et profiter du 32 bits , j'ai fait une calculatrice à l'aide d'une nano 33 Ble. Pourquoi la nano 33 : car elle présente en ce qui concerne les GPIO les mêmes similitudes que la nano classique avec des caractéristiques supplémentaires comme par exemple la gestion du pullup interne pour A6 et A7. C'était donc ce qu'il y avait de plus simple pour moi d'autant plus que j'ai déjà travaillé sur une calculatrice à base de nano classique :
Calculatrice sur nano classique
Pour le montage : 19 boutons poussoirs raccordés entre GND et les entrées D0 à A3 et A6 à A7. Les entrées sont déclarées en INPUT_PULLUP mais D13 est exclu (en raison de sa liaison avec la LED_BUILTIN qui interdit le pull up interne) ainsi que A4 et A5 qui assurent la liaison I2C avec un écran LCD 2004.
Pour le code, un grand merci à dfgh (voir le lien plus haut) et surtout à JML qui brille par ses connaissances et compétences exceptionnelles, merci à lui en particulier pour la fonction « NombreChiffreAVir » qui retourne le nombre de chiffres après la virgule d’un nombre décimal si il y en a :
https://forum.arduino.cc/t/recuperer-le-nombre-de-chiffres-apres-la-virgule-dun-nombre-decimal/904164/17
Un grand merci également à tous les autres intervenants de ce forum.
J’ai rajouté une fonction Retour() qui efface le dernier caractère tapé et une fonction Replace() qui lorsqu’une opération est effectuée replace le résultat en haut de l'écran (puis le dernier opérateur est ajouté au dernier résultat).
Bon ce n’est pas un projet extraordinaire mais j’en suis fier quand même !
Si vous avez des remarques, je suis preneur car mon unique but est d’apprendre et de progresser.
Voici le code :
#include <avr/dtostrf.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
const byte bouton[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 };//nano 33
const char caractere[] = { '0','1','2','3','4','5','6','7','8','9','+','-','*','X','R','C','=','.','Y','Z','/','E'}; // X = D13 - Y = A4 - Z = A5
long decimal = 0;
double nbPrecedent = 0;
double nbActuel = 0;
boolean result = false;
char operateur;
char key;
char DernierChiffre[30]={0}; // Touche Retour
byte i=0; // Touche Retour
boolean operation = false; // Touche Retour
int NombreChiffreAVir (double ChiffreDec) { // retourne le nombre de chiffres après la vrigule d'un nombre décimal - précision sur 7 chiffres
int nb = 0;
char tmpBuffer[30];
char *recherchePoint = strchr(dtostrf(ChiffreDec, 0, 7, tmpBuffer), '.');
if (recherchePoint == nullptr) return 0;
for (int f = strlen(tmpBuffer) - 1; f >= 0; --f)
if (tmpBuffer[f] == '0') nb++;
else break;
return 7 - nb;
}
void setup() {
lcd.begin();
lcd.backlight();
lcd.print("By Philippe");
lcd.setCursor(0,1);
lcd.print("Version 2.0");
delay(1000);
lcd.clear();
// initialise le pull up interne pour D0 à D12 - A0 - A1 - A2 - A3 - A6 et A7 - A4 et A5 sont utilisés pour l'I2C de l'écran LCD
// exclu au passage D13 qui en raison de sa liaison avec la LED_BUILTIN interdit le pull up interne et externe
for (byte f = 0; f <= 21; f++)
{
if ((bouton[f] !=13) && (bouton[f] !=18) && (bouton[f] !=19))
{
pinMode(bouton[f], INPUT_PULLUP);
}
}
}
void loop() {
// affecte la touche pressée à la variable key puis l'affiche sur l'écran LCD
for (byte f = 0; f <= 21; f++)
{
if ((bouton[f] !=13) && (bouton[f] !=18) && (bouton[f] !=19) && (digitalRead(bouton[f]) == LOW))
{
key = caractere[f];
if ((key != 'C') && (key!= 'R') && (key!= 'E')) lcd.print(key);
delay(200);
while (digitalRead(bouton[f]) == LOW){;} //si le BP à été appuyé
}
}
if (key == 'E') {Retour();} // Touche Retour - efface le dernier caractère
if (key == 'C') {Efface();}
if (key == '.') {decimal = 10;}
if (key == '=') {calculs();}
if (key == 'R') {
operateur = key;
calculs();
}
for (byte f = 0; f <= 9; f++)
{
if (key == caractere[f])
{
if ( key >= '0' && key <= '9' )
{
if (decimal != 0)
{
nbActuel = ( nbActuel + (double( key - '0' ) / (decimal))) ;
decimal = decimal * 10;
DernierChiffre[i] = key ; // Touche Retour
i++; // Touche Retour
}
else
{
nbActuel = ( ( nbActuel * 10 ) + ( key - '0' ) ) ;
DernierChiffre[i] = key ; // Touche Retour
i++; // Touche Retour
}
key = '_';
}
}
if ( key == '+' || key == '-' || key == '*' || key == '/' )
{
operateur = key ;
if (result==true) Replace(),lcd.print(operateur),result=false; // ajoute le dernier opérateur au dernier résultat
nbPrecedent = nbActuel ;
key = '_';
nbActuel = 0;
decimal = 0;
operation = true;
i=0;
memset(DernierChiffre, 0,sizeof DernierChiffre); // Touche Retour
}
}
}
void Efface()
{
result = false;
decimal = 0;
nbActuel = 0;
nbPrecedent = 0;
lcd.clear();
key = '_';
i=0; // Touche Retour
memset(DernierChiffre, 0,sizeof DernierChiffre); // Touche Retour
operation = false;
}
void calculs()
{
if ( operateur == '+' ) nbActuel = nbPrecedent + nbActuel ;
if ( operateur == '-' ) nbActuel = nbPrecedent - nbActuel ;
if ( operateur == '*' ) nbActuel = nbPrecedent * nbActuel ;
if ( operateur == '/' ) nbActuel = nbPrecedent / nbActuel ;
if ( operateur == 'R' ) nbActuel = sqrt(nbActuel);
//decimal = 0; lcd.setCursor(0, 3); lcd.print ( nbActuel , 7 ) ;
decimal = 0; lcd.setCursor(0, 3); lcd.print ( nbActuel , NombreChiffreAVir (nbActuel) ) ;
key = '_';
decimal = 0;
nbPrecedent = 0;
result = true;
operation = false;
i=0;
memset(DernierChiffre, 0,sizeof DernierChiffre); // Touche Retour
}
void Replace() // si une opération a été effectuée (result==true), replace le résultat en haut de l'écran
{
decimal=0;
nbPrecedent = 0;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(nbActuel,NombreChiffreAVir (nbActuel));
}
void Retour() // efface dernier caractere
{
if ((decimal != 0) && (NombreChiffreAVir (nbActuel)!=0) && (operation==false)){
decimal = decimal /10;
nbActuel = nbActuel * (decimal);
nbActuel = (nbActuel - (DernierChiffre[i-1] - '0'))/(decimal);
lcd.clear();
i--;
lcd.setCursor(0, 0);
lcd.print(nbActuel,NombreChiffreAVir (nbActuel));
key = '_';
}
if ((decimal != 0) && (NombreChiffreAVir (nbActuel)!=0) && (operation==true)){
decimal = decimal /10;
nbActuel = nbActuel * (decimal);
nbActuel = (nbActuel - (DernierChiffre[i-1] - '0'))/(decimal);
lcd.clear();
i--;
lcd.setCursor(0, 0);
lcd.print(nbPrecedent,NombreChiffreAVir (nbPrecedent));
lcd.print(operateur);
if ((nbActuel !=0) && (i>0)) lcd.print(nbActuel,NombreChiffreAVir (nbActuel));
key = '_';
}
if ((decimal == 0) && (i>0) && (operation==false) ) {
nbActuel = ( (( nbActuel ) - ( DernierChiffre[i-1] - '0' ))/10 ) ;
if (i>0) i--;
lcd.clear();
lcd.setCursor(0, 0);
if ((nbActuel !=0) && (i>0)) lcd.print(nbActuel,0);
key = '_';
}
else if ((decimal == 0) && (i>0) && (operation==true)) {
nbActuel = ( (( nbActuel ) - ( DernierChiffre[i-1] - '0' ))/10 ) ;
if (i>0) i--;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(nbPrecedent,NombreChiffreAVir(nbPrecedent));
lcd.print(operateur);
if ((nbActuel !=0) && (i>0)) lcd.print(nbActuel,0);
key = '_';
}
}
Merci.