Go Down

Topic: Contapezzi con display 7 segment (Read 2368 times) previous topic - next topic

Flavi71

Nov 11, 2018, 02:03 am Last Edit: Nov 11, 2018, 09:27 am by Flavi71
Salve a tutti, devo costruire un contapezzi manuale, il circuito è molto semplice, ogni volta che premo un pulsante mi va ad aumentare di una unità la variabile buttonPushCounter e il risultato viene visualizzato su un display a 7 segmenti (il modello che ho disponibile è quello in foto allegata). Un secondo pulsante mi va ad azzerare il contatore e pulisce il display.

Il tutto funziona col monitor seriale, ma se collego il display visualizzo solo le cifre da 1 a 9 poi le lettere da "a" a F poi si ferma. Io ho la necessità di arrivare a contare fino a 90, ma non so come "dire" al display di visualizzare le 2 cifre del contatore.

Ho studiato il funzionamento su Playground, https://playground.arduino.cc/Main/LedControl#Seg7Control
e credo che necessiti usare la funzione

Code: [Select]

void printNumber(int v) {
    int ones;
    int tens;
    int hundreds;
    boolean negative;
[code]

ma non riesco a capirne il funzionamento. Chiedo qualche suggerimento, non la soluzione, voglio arrivarci da solo  :D

Questo è il codice del contapezzi che ho provato.

[code]

 //State change detection (edge detection)
//We always have to include the library
#include "LedControl.h"

/*
 Now we need a LedControl to work with.
 pin 12 is connected to the DataIn
 pin 11 is connected to the CLK
 pin 10 is connected to LOAD
 We have only a single MAX72XX.
 */
LedControl lc=LedControl(12,11,10,1);

/*  The circuit:
 - buttonpin attached to pin 2 from +5V
 - buttonreset attached to pin 4 from +5V
 - 10 kilohm resistor attached to pin 2&4 from ground
*/
// this constant won't change:
const int  buttonPin = 2;// the pin that the pushbutton is attached to
const int  buttonReset = 4;// the pin that the buttonreset is attached to

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

void setup(){
  /*
   The MAX72XX is in power-saving mode on startup,
   we have to do a wakeup call
   */
  lc.shutdown(0,false);
  /* Set the brightness to a medium values */
  lc.setIntensity(0,8);
  /* and clear the display */
  lc.clearDisplay(0);

  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  pinMode(buttonReset, INPUT);
}

void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      buttonPushCounter++;
      lc.setDigit(0,0,buttonPushCounter,false);
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;

  // if the buttonreset is pressed reset the buttonpushcounter
  if  (digitalRead(buttonReset) == HIGH){
      (buttonPushCounter = 0);
       lc.clearDisplay(0);
    }
  }
[/code]
[/code]

torn24

#1
Nov 11, 2018, 10:23 am Last Edit: Nov 11, 2018, 10:37 am by torn24
Ciao! Premettiamo che stai usando una libreria, il display si potrebbe controllare anche senza librerie ma sarebbe molto complicato!

Nel link che hai mostrato c'è la soluzione, forse non è cosi immediato capirla per un principiante come NOI! :)

Nel display a 7 segmenti gestisci la stampa su un solo riquadro! Se il display è a 2 cifre, prima stampo le unità e poi stampo le decine, non è come un lcd che automaticamente  stampa più cifre.


Per cui tu hai un numero intero che va da 0 a 90,
1) Ti ricavi le unità
2)Ti ricavi le decine
3) Stampi le unità sul display
4) Stampi le decine sul display


Adesso per ricavare le unità prendi il resto della divisione per dieci, e in C si fa con l'operatore %


Esempio :

Code: [Select]


int contatore=46;
int unità=0;
int decine=0;

void loop(){

   unita=contatore%10; // Il resto della divisione per 10 sono la cifra unità
   decine=contatore/10; // Divido il numero per 10 e ottengo le decine
  
   lc.setDigit(0,0,(byte)unita,false);// stampo le cifre delle unita
   lc.setDigit(0,1,(byte)decine,false);// stampo le cifre delle decine
  
}



torn24

Che poi è quello che cera scritto nel link da te postato ;)

Nel link non calcola solo decine e unità ma anche le migliaia!


Dal tuo link

Code: [Select]


ones=v%10;
    v=v/10;
    tens=v%10;
    v=v/10;
    hundreds=v;
    if(negative) {
       //print character '-' in the leftmost column
       lc.setChar(0,3,'-',false);
    }
    else {
       //print a blank in the sign column
       lc.setChar(0,3,' ',false);
    }
    //Now print the number digit by digit
    lc.setDigit(0,2,(byte)hundreds,false);
    lc.setDigit(0,1,(byte)tens,false);
    lc.setDigit(0,0,(byte)ones,false);
}





Flavi71

Ok grazie Torn, con la tua spiegazione mi è più chiaro, ora provo ad applicarlo.

Flavi71

Ok sono riuscito nel mio intento, contare fino a 90, ma per curiosità ho provato a inserire anche la variabile per le centinaia in modo da poter contare anche oltre il 99, ma al nr. 100 appare la scritta 1a0  e a 110 appare 1b0 e così via senza però visualizzare 100...110...120... Cosa c'è di sbagliato?

Code: [Select]


 //State change detection (edge detection)
//We always have to include the library
#include "LedControl.h"

/*
 Now we need a LedControl to work with.
 pin 12 is connected to the DataIn
 pin 11 is connected to the CLK
 pin 10 is connected to LOAD
 We have only a single MAX72XX.
 */
LedControl lc=LedControl(12,11,10,1);

/*  The circuit:
 - buttonpin attached to pin 2 from +5V
 - buttonreset attached to pin 4 from +5V
 - 10 kilohm resistor attached to pin 2&4 from ground
*/
// this constant won't change:
const int  buttonPin = 2;// the pin that the pushbutton is attached to
const int  buttonReset = 4;// the pin that the buttonreset is attached to

// Variables will change:
int contatore = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button
int unita = 0;
int decine = 0;
int centinaia = 0;

void setup(){
  /*
   The MAX72XX is in power-saving mode on startup,
   we have to do a wakeup call
   */
  lc.shutdown(0,false);
  /* Set the brightness to a medium values */
  lc.setIntensity(0,8);
  /* and clear the display */
  lc.clearDisplay(0);

  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  pinMode(buttonReset, INPUT);
}

void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      contatore++;
 unita=contatore%10;
 decine=contatore/10;
 centinaia=contatore/100;
 
      lc.setDigit(0,2,(byte)centinaia,false);
      lc.setDigit(0,1,(byte)decine,false);
      lc.setDigit(0,0,(byte)unita,false);
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;

  // if the buttonreset is pressed reset the buttonpushcounter
  if  (digitalRead(buttonReset) == HIGH){
      (contatore = 0);
       lc.clearDisplay(0);
    }
  }

Silente

La sequenza corretta di operazioni é
Variabile n=numero%10;
Numero=numero/10;
Varuabile n1=numero%10;
Numero=numero/10
... E così via.
Se metti le variabilinin un array con una for ti fai fino a quando vuoi (salvo poi finire i pin)
Dove va un numero va una variabile o una funzione. E dove va una boolean va un insieme di test.

Se vuoi ottenere devi saper spiegare

In pochi capiscono l'importanza di formattare, sii tra di essi

torn24

Ciao! Di sbagliato c'è il modo in cui calcoli le migliaia!



Code: [Select]

// Tu fai cosi e non stai calcolando le migliaia...
unita=contatore%10;
 decine=contatore/10;
 centinaia=contatore/100;

/******************************************/

//Dovrebbe essere [b]per passare all'ordine di grandezza superiore dividi sempre per 10 e poi prendi il resto[/b]

unita=contatore%10; //Resto della divisione per dieci sono le unità
contatore=contatore/10; // Divido per dieci adesso contatore contiene le DECINE esempio 23 decine
decine=contatore%10;// Prendo il resto della divisione per dieci e sono le decine

// Esempio se contatore è uguale a 23 DECINE prendo il resto e sono 3 decine


 centinaia=contatore/10;// Adesso decine diviso 10 sono le centinaia ESEMPIO 23 decine/10=2,3
//visto che usiamo variabili intere int, in centinaia sarà inserito solo 2



Flavi71

La sequenza corretta di operazioni é
Variabile n=numero%10;
Numero=numero/10;
Varuabile n1=numero%10;
Numero=numero/10
... E così via.
Se metti le variabilinin un array con una for ti fai fino a quando vuoi (salvo poi finire i pin)
Allora seguendo la sequenza di Silente ho compilato il codice che segue, ma il risultato che ottengo è che appare solo il nr. 1 poi basta, resta fermo lì!!

Code: [Select]

[code]

 //State change detection (edge detection)
//We always have to include the library
#include "LedControl.h"

/*
 Now we need a LedControl to work with.
 pin 12 is connected to the DataIn
 pin 11 is connected to the CLK
 pin 10 is connected to LOAD
 We have only a single MAX72XX.
 */
LedControl lc=LedControl(12,11,10,1);

/*  The circuit:
 - buttonpin attached to pin 2 from +5V
 - buttonreset attached to pin 4 from +5V
 - 10 kilohm resistor attached to pin 2&4 from ground
*/
// this constant won't change:
const int  buttonPin = 2;// the pin that the pushbutton is attached to
const int  buttonReset = 4;// the pin that the buttonreset is attached to

// Variables will change:
int contatore = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button
int unita = 0;
int decine = 0;
int centinaia = 0;


void setup(){
  /*
   The MAX72XX is in power-saving mode on startup,
   we have to do a wakeup call
   */
  lc.shutdown(0,false);
  /* Set the brightness to a medium values */
  lc.setIntensity(0,8);
  /* and clear the display */
  lc.clearDisplay(0);

  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  pinMode(buttonReset, INPUT);
}

void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      contatore++;
     
 unita=contatore%10;
 contatore=contatore/10;
 decine=contatore%10;
 contatore=contatore/10;
 centinaia=contatore%10;
 contatore=contatore/10;
 
      lc.setDigit(0,2,(byte)centinaia,false);
      lc.setDigit(0,1,(byte)decine,false);
      lc.setDigit(0,0,(byte)unita,false);
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;

  // if the buttonreset is pressed reset the buttonpushcounter
  if  (digitalRead(buttonReset) == HIGH){
      (contatore = 0);
       lc.clearDisplay(0);
    }
  }



Flavi71

Ciao! Di sbagliato c'è il modo in cui calcoli le migliaia!



Code: [Select]

// Tu fai cosi e non stai calcolando le migliaia...
unita=contatore%10;
 decine=contatore/10;
 centinaia=contatore/100;

/******************************************/

//Dovrebbe essere [b]per passare all'ordine di grandezza superiore dividi sempre per 10 e poi prendi il resto[/b]

unita=contatore%10; //Resto della divisione per dieci sono le unità
contatore=contatore/10; // Divido per dieci adesso contatore contiene le DECINE esempio 23 decine
decine=contatore%10;// Prendo il resto della divisione per dieci e sono le decine

// Esempio se contatore è uguale a 23 DECINE prendo il resto e sono 3 decine


 centinaia=contatore/10;// Adesso decine diviso 10 sono le centinaia ESEMPIO 23 decine/10=2,3
//visto che usiamo variabili intere int, in centinaia sarà inserito solo 2




Scusa ma a cosa serve calcolare le migliaia se fino a 999 bastano le centinaia?

torn24

Se guardavi il codice trovavi scritto centinaia! Quindi mi sono sbagliato ma il codice è corretto!

Nel codice ho messo commenti che spiegavano il ragionamento, ma visto che non le hai letti non hai capito.
PER L'ULTIMA CIFRA devi dividere solo per 10 e non prendere il resto


Ti faccio un esempio NUMERO=498

unita=NUMERO%10  unita vale 8 resto
NUMERO=NUMERO/10  numero vale 49 decine
decine=NUMERO%10 decine vale 9 resto di 10
Centinaia=NUMERO/10   49 DECINE/10  4 CENTINAIA


Questo perché usiamo variabili in  49/10 fa 4,9  ma noi prendiamo solo la parte intera 4

Code: [Select]


unita=contatore%10; // Resto di dieci sono le unità
 contatore=contatore/10; // Divido per dieci e ottengo le decine che potrebbero essere superiori a 46
 decine=contatore%10; // Prendo il resto e ottengo le decine
centinaia=contatore/10; // Sono già le centinaia non c'è bisogno di prendere il resto

 





torn24

Ho visto che hai aperto un altra discussione su display, mi sembra che ti hanno suggerito una libreria diversa da quella che usi con cui puoi stampare direttamente un numero a più cifre!
A seconda della libreria che usi fai le cose in modo diverso, più semplice o più complesso.

Flavi71

Ho visto che hai aperto un altra discussione su display, mi sembra che ti hanno suggerito una libreria diversa da quella che usi con cui puoi stampare direttamente un numero a più cifre!
A seconda della libreria che usi fai le cose in modo diverso, più semplice o più complesso.
Si Torn, perchè per il mio progetto contapezzi volevo sostituire il Display 8 cifre MAX 7219 con quello a 4 cifre TM1637, visto che 4 cifre sono più che sufficienti per quello che devo contare, ma il TM 1637 sto imparando a usarlo perchè ho visto che i comandi da dargli sono diversi.

Flavi71

#12
Nov 15, 2018, 01:38 pm Last Edit: Nov 15, 2018, 01:46 pm by gpb01
Se guardavi il codice trovavi scritto centinaia! Quindi mi sono sbagliato ma il codice è corretto!

Nel codice ho messo commenti che spiegavano il ragionamento, ma visto che non le hai letti non hai capito.
PER L'ULTIMA CIFRA devi dividere solo per 10 e non prendere il resto
Scusa Torn o sono "de coccio" io o ... ho sostituito la porzione di codice esattamente uguale alla tua, ma non cambia nulla, appare solo il numero 001 e poi non va più avanti.


Code: [Select]


 //State change detection (edge detection)
//We always have to include the library
#include "LedControl.h"

/*
 Now we need a LedControl to work with.
 pin 12 is connected to the DataIn
 pin 11 is connected to the CLK
 pin 10 is connected to LOAD
 We have only a single MAX72XX.
 */
LedControl lc=LedControl(12,11,10,1);

/*  The circuit:
 - buttonpin attached to pin 2 from +5V
 - buttonreset attached to pin 4 from +5V
 - 10 kilohm resistor attached to pin 2&4 from ground
*/
// this constant won't change:
const int  buttonPin = 2;// the pin that the pushbutton is attached to
const int  buttonReset = 4;// the pin that the buttonreset is attached to

// Variables will change:
int contatore = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button
int unita = 0;
int decine = 0;
int centinaia = 0;


void setup(){
  /*
   The MAX72XX is in power-saving mode on startup,
   we have to do a wakeup call
   */
  lc.shutdown(0,false);
  /* Set the brightness to a medium values */
  lc.setIntensity(0,8);
  /* and clear the display */
  lc.clearDisplay(0);

  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  pinMode(buttonReset, INPUT);
}

void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      contatore++;
     
 unita=contatore%10;
 contatore=contatore/10;
 decine=contatore%10;
 centinaia=contatore/10;
 
      lc.setDigit(0,2,(byte)centinaia,false);
      lc.setDigit(0,1,(byte)decine,false);
      lc.setDigit(0,0,(byte)unita,false);
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;

  // if the buttonreset is pressed reset the buttonpushcounter
  if  (digitalRead(buttonReset) == HIGH){
      (contatore = 0);
       lc.clearDisplay(0);
    }
  }



torn24

#13
Nov 15, 2018, 04:11 pm Last Edit: Nov 15, 2018, 04:24 pm by torn24
Avevi detto che fino a 90 contava, quindi dovrebbe funzionare.
Se contava fino a 90 adesso dovrebbe contare fino a 999, non vedo motivi perché non lo faccia!
Controlla anche i collegamenti elettronica.
Prova a vedere se cosi il programma funziona! Ho semplificato la lettura del pulsante togliendo l'antirimbalzo, io i pulsanti li uso cosi con un piccolo delay() e non ho problemi.

Code: [Select]




 //State change detection (edge detection)
//We always have to include the library
#include "LedControl.h"

/*
 Now we need a LedControl to work with.
 pin 12 is connected to the DataIn
 pin 11 is connected to the CLK
 pin 10 is connected to LOAD
 We have only a single MAX72XX.
 */
LedControl lc=LedControl(12,11,10,1);

/*  The circuit:
 - buttonpin attached to pin 2 from +5V
 - buttonreset attached to pin 4 from +5V
 - 10 kilohm resistor attached to pin 2&4 from ground
*/
// this constant won't change:
const int  buttonPin = 2;// the pin that the pushbutton is attached to
const int  buttonReset = 4;// the pin that the buttonreset is attached to

// Variables will change:
int contatore = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button
int unita = 0;
int decine = 0;
int centinaia = 0;


void setup(){
  /*
   The MAX72XX is in power-saving mode on startup,
   we have to do a wakeup call
   */
  lc.shutdown(0,false);
  /* Set the brightness to a medium values */
  lc.setIntensity(0,8);
  /* and clear the display */
  lc.clearDisplay(0);

  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  pinMode(buttonReset, INPUT);
}

void loop() {
  
    if (digitalRead(buttonPin)==HIGH){
      
        contatore++;
      
        unita=contatore%10;
        contatore=contatore/10;
        decine=contatore%10;
        centinaia=contatore/10;
 
        lc.setDigit(0,2,(byte)centinaia,false);
        lc.setDigit(0,1,(byte)decine,false);
        lc.setDigit(0,0,(byte)unita,false);
    }
    if(contatore>999) contatore=0; // Ritorna a zero quando deve contare 1000
    delay(200);
  
  

  
    if  (digitalRead(buttonReset) == HIGH){
        (contatore = 0);
         lc.clearDisplay(0);
    }
  }









Silente

Fa un gioco: aggiungi la seriale, anche se non sarà parte del programma definitivo. Scrivi su seriale il contatore e le sue varie parti per poter verificare se la procedura di calcolo è giusta, e se Quindi il problema si trova nella parte di rappresentazione.
Dove va un numero va una variabile o una funzione. E dove va una boolean va un insieme di test.

Se vuoi ottenere devi saper spiegare

In pochi capiscono l'importanza di formattare, sii tra di essi

Go Up