Go Down

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

Flavi71

#15
Nov 15, 2018, 09:55 pm Last Edit: Nov 15, 2018, 09:56 pm by Flavi71
Con queste righe di codice (stessi collegamenti) conta fino a 99 senza problemi e lo visualizza correttamente sul display.

Code: [Select]

unita=contatore%10;
decine=contatore/10;

      lc.setDigit(0,1,(byte)decine,false);
      lc.setDigit(0,0,(byte)unita,false);
[code]
[/code]

Il tuo codice modificato l' ho provato Torn ma non funziona, mi da lo stesso risultato, solo 001 poi si ferma.

Flavi71

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.
In realtà è stata la prima cosa che ho fatto Silente, infatti per la scrittura del codice del Contapezzi ho preso spunto dall' esempio dell' IDE StateChangeDetection, in cui viene usato il monitor seriale e viene visualizzato il conteggio che avanza ad ogni pressione del tasto ButtonPushCounter. Poi il problema è sorto quando a visualizzare il conteggio deve essere il display 7 segment e non più il monitor seriale.

torn24

#17
Nov 16, 2018, 07:30 am Last Edit: Nov 16, 2018, 07:33 am by torn24
Prova a stampare su seriale i valori di unita,decine e centinaia, ma credo che sia tutto esatto.
Ma secondo me non c'è problema nel programma, sono abbastanza sicuro che il calcolo sia corretto e la stampa su display è copiata dall'esempio del link che hai postato.
Quindi non è un errore di programma!
A volte si hanno componenti elettronici difettosi è una possibilità da tenere presente.
Prova comunque a stampare su seriale, la stampa su display è quella del link quindi non è sbagliata...


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);

  Serial.begin(9600);
}

void loop() {
  
    if (digitalRead(buttonPin)==HIGH){
      
        contatore++;
      
        unita=contatore%10;
        contatore=contatore/10;
        decine=contatore%10;
        centinaia=contatore/10;

        Serial.print(centinaia);
        Serial.print("-");
        Serial.print(decine);
        Serial.print("-");
        Serial.print(unita);
        Serial.println(" ");
 
        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);
    }
  }













Flavi71

Ecco fatto! Allego schermata della seriale. Restituisce tutti 0-0-1.

Toglimi uno sfizio, prova a riprodurre i collegamenti (bastano due pulsanti, due resistenze e qualche cavetto) anche se non metti il display 7 segment, e prova anche tu lo sketch che mi hai proposto con la seriale, così tagliamo la testa al toro.  :D

Silente

Bene. Quindi abbiamo capito dove é il problema, ovvero sul valore delle variabili. Ora é necessario capire perché é li.
A tale scopo potresi aggiungere scritte su seriale. Una potrebbe essere il valore del contatore ogni volta che lo aumenti, e una seconda una scritta che indichi quando stai azzerando.
Dove va un numero va una variabile, una funzione e/o  un test.
Per ottenere devi spiegare

Strumenti/Formattazione automatica fino alla morte!
Cristianesimo:bibbia='C':K&R

elrospo

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);
    }
  }



ma non è che te non hai ancora afferrato qualcosa  :o  :smiley-confuse:

non puoi mettere la variabile contatore direttamente attraverso il ...contatore%10..  dopo pochi microsecondi l'avrai divisa per 10 migliaia di volte

Flavi71

ma non è che te non hai ancora afferrato qualcosa  :o  :smiley-confuse:

non puoi mettere la variabile contatore direttamente attraverso il ...contatore%10..  dopo pochi microsecondi l'avrai divisa per 10 migliaia di volte
E quindi? Spiegati meglio, cosa dovrei fare...?

Silente

Creare all'inizio del ciclo di scrittura su 7s una variabile ausiliaria (contatore2) resa uguale a contatore. Successivamente usi questultima invece di contatore per le varie divisioni. Così facendo non tocchi contatore, il quale resta dek suo valore, mentre la variabile nuova che usi viene resa ogni ciclo uguale a contatore.

Grazie elrospo, non ci sarei mai arrivato
Dove va un numero va una variabile, una funzione e/o  un test.
Per ottenere devi spiegare

Strumenti/Formattazione automatica fino alla morte!
Cristianesimo:bibbia='C':K&R

torn24

#23
Nov 17, 2018, 07:52 am Last Edit: Nov 17, 2018, 09:14 am by torn24
Be questo era un problema che non avevo pensato!BISOGNA USARE UNA VARIABILE DI APPOGGIO

int tmp=contatatore;

e poi fare i calcoli con la variabile temporanea cosi da non modificare contatore.
Fino a 99 funziona perchè non dividiamo contatore per 10, non facciamo contatore=contatore/10
Mentre per contare le centinaia dividiamo per 10
Dovrebbe essere quello il problema! ESEMPIO Conti uno poi lo dividiamo  per 10 e poi aggiungi uno, quindi hai sempre un unita, con la variabile di appoggio invece contatore arriva a 999

Per quanto riguarda fare calcoli li ho provati e sono corretti! Se devi valutare solo codice C e non usare librerie di arduino o elettronica, allora un qualunque compilatore C va bene.

Esempio qui dobbiamo fare dei calcoli, questo è C puro, per cui lo si può provare su qualunque compilatore,
io per provare piccoli pezzi di codice uso l'ide online IDEONE.


Con variabile di appoggio Modifica:



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;
int tmp=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);

  Serial.begin(9600);
}

void loop() {
  
    if (digitalRead(buttonPin)==HIGH){
      
        contatore++;
        tmp=contatore;
        unita=tmp%10;
        tmp=tmp/10;
        decine=tmp%10;
        centinaia=tmp/10;

        Serial.print(centinaia);
        Serial.print("-");
        Serial.print(decine);
        Serial.print("-");
        Serial.print(unita);
        Serial.println(" ");
 
        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);
    }
  }





Flavi71

Ok grazie, complimenti a tutti...problema risolto, testato e funziona ;D
Ora un ultima domanda: alimentando questo aggeggio con una pila da 9V, quanto tempo può durare?
Uso un arduino nano e un display 7 segment MAX7219. Vedi schema allegato.

Patrick_M

per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

Silente

#26
Nov 18, 2018, 11:45 am Last Edit: Nov 18, 2018, 11:56 am by Silente
NON é risposta alla domanda, ma si potrebbe ottimizzare un po il calcolo del contatore. Credo di poter eliminare i due if.
Code: [Select]
contatore=((contatore+letturapulsanteaggiungi)*(!letturapulsanteazzeramento))%100;

Inoltre credo che se metto prima di tutta la pappardella variabilediappoggio= ho ridotto di un'altra riga.
Potrei anche evitare il calcolo delle unità e delle decine ecc. come variabili singole, e passare direttamente alla funzione il calcolo. E inoltre se usassi un ciclo for potrei, con due righe di codice, stampare tutte le cifre che voglio:
Code: [Select]

for (byte numcifra=0;numcifra<massiko+1;numcifra++)
{
lcd.setdigit (0,numcifra,variabilediappoggio%10,0);
variabilediappoggio/=10;
}
Dove va un numero va una variabile, una funzione e/o  un test.
Per ottenere devi spiegare

Strumenti/Formattazione automatica fino alla morte!
Cristianesimo:bibbia='C':K&R

torn24

#27
Nov 19, 2018, 07:49 am Last Edit: Nov 19, 2018, 08:16 am by torn24
Quello del fare calcoli con un ciclo è un idea furba! Mi è già capitato di calcolare le cifre di un numero in altri linguaggi!

Forse serve un cast a byte, (byte)variabile%10, visto che variabile deve essere di tipo int.

E' una questione di necessità o meno che porta all'adozione di una soluzione o un altra! Esempio per calcolare unità,decine e centinaia abbiamo scritto 5 righe di codice, ottimizzarla è un bene ma non una necessità. Se invece avessimo dovuto calcolare le cifre di valori di miliardi avremmo dovuto scrivere decine di righe di codice ,probabilmente di fronte a questo problema sarebbe nato spontaneamente l'idea di usare un ciclo, perché la necessità portava a quella soluzione.

Fury_man

Salve, sono anche io interessato al contapezzi .. ma se invece di incrementare volessi decrementare facendo partire il contatore da 300? Il codice come varia? E volendo posso sostituire il pulsante fisico con un sensore IR singolo ? Proiettando su di esso un fascio luminoso cosi ad ogni passaggio di un oggetto si ha l interruzione di tale fascio e automaticamente mi decrementa a 299 poi 298 e cosi via?

Flavi71

Se vuoi andare a decrementare imposti il contatore iniziale a 300 poi con il pulsante (o col sensore come vuoi fare tu) al posto di contatore++ metti contatore--.
Per il sensore potresti usare anche uno a ultrasuoni, meno influenzabile dalla luce.

Go Up