Calculatrice sur nano 33 Ble 32 bits

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.

Bonjour,

Dans mon code il y avait un bug :
Lorsqu'un nombre décimal était traité par la fonction retour, en cas de suppression de tout les chiffres après la virgule le nombre devenait un nombre entier mais il était toujours traité comme un nombre décimal :
Par exemple après suppression de tous les chiffres après la virgule du nombre 15.719 puis rajout des 3 derniers chiffres afin d'obtenir le nombre entier 15719 ==> 15719 + 1 était égal à 16.719 !

if (key == 'E') {
   {Retour();}  // Touche Retour - efface le dernier caractère
   if (NombreChiffreAVir (nbActuel) ==0) decimal=0; //  fixe bug decimal - entier
  }

l'ajout de cette ligne de code lorsque l'on appuie sur la touche retour fixe ce bug :

if (NombreChiffreAVir (nbActuel) ==0) decimal=0;

Voilà, c'est pour les débutants comme moi que ça intéresse si il y en a :smile: .

Bonne journée.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.