Problema con orologio

Buongiorno a tutti, con un modulo RTC3231, 6 display a 7 segmenti ed un Arduino nano ho assemblato un orologio alimentato con 12V sul pin VIN.
Tutto ha funzionato bene (solo un paio di volte mi è toccato ripristinare il programma in quanto l'ora indicata era completamente errata) per ca 6 mesi, ora non funziona più nonostante abbia ricaricato il programma più volte.
I singoli componenti (RTC, display ed Nano) provati singolarmente funzionano e non riesco a capire l'origine del problema.
Il programma utilizzato è:

/*
   Programma ora/data/temp su 6 display a 7 elementi
   Sviluppato senza libreria Sevseg con RTC DS3231
   Catodo comune - utilizzo PORTD e B
   versione definitiva - 02.02.21
*/

#include "RTClib.h"

long num = 0; // valore di 6 cifre da scomporre
long num1 ;
long num2 ;
long num3 ;
long num4 ;
long num5 ;
long num6 ;

long v_sec;
long v_min;
long v_hr;
long v_day;
long v_mon;
long v_year;

int cambio = 17;
int stato = 0;

long t_debounce = 0;
long debounce_delay = 500;

float celsius;

byte numero[] = {
  //hgfedcba
  B10111111, // 0  -0
  B10000110, // 1  -1
  B11011011, // 2  -2
  B11001111, // 3  -3
  B11100110, // 4  -4
  B11101101, // 5  -5
  B11111101, // 6  -6
  B10000111, // 7  -7
  B11111111, // 8  -8
  B11101111, // 9  -9
  B00000000, // spento
  B00111001, // C
};

byte display[] = {
  B00011111, // PIN 13
  B00101111, // PIN 12
  B00110111, // PIN 11
  B00111011, // PIN 10
  B00111101, // PIN 9
  B00111110, // PIN 8
};

// Create a DS3231 object.
RTC_DS3231 myRTC;

void printTime() {
  DateTime now = myRTC.now();
  v_hr = now.hour();
  v_min = now.minute();
  v_sec = now.second();

  num = ((v_hr * 10000) + (v_min * 100) + v_sec);
}

void printDate() {
  DateTime now = myRTC.now();
  
  v_day = now.day();
  v_mon = now.month();
  int t_year =  (now.year() / 100);
  v_year = (now.year() - (t_year * 100));
//Serial.println(v_day);
  num = ((v_day * 10000) + (v_mon * 100) + v_year);
}

void setup() {
  myRTC.adjust(DateTime(F(__DATE__), F(__TIME__)));
//  Serial.begin(9600);
//  Serial.println("Pippo");
  DDRD = B11111111;
  DDRB = B11111111;

  pinMode(cambio, INPUT_PULLUP);
}

void loop() {
//Serial.println("Pippo");
  if (digitalRead(cambio) != HIGH)  {
    if ( (millis() - t_debounce) > debounce_delay) {
      stato ++;
      if (stato > 2)  {
        stato = 0;
      }
      t_debounce = millis();
    }
  }

  switch (stato) {
    case 0 :
      printTime();
      break;

    case 1 :
      printDate();
      break;

    case 2 :
      num = (myRTC.getTemperature() * 100);
      break;
  }

  valore();

  PORTB = display[0];  // unita sec
  PORTD = numero[num1];
  delay (3);

  PORTB = display[1];  // decine sec
  PORTD = numero[num2];
  delay (3);

  PORTB = display[2]; //unita min
  PORTD = numero[num3];
  delay (3);

  PORTB = display[3];  // decine min
  PORTD = numero[num4];
  delay (3);

  PORTB = display[4];  //unita ore
  PORTD = numero[num5];
  delay (3);

  PORTB = display[5];  // decine ore
  PORTD = numero[num6];
  delay (3);
}

void valore() {
  num1 = num % 10;  num /= 10;
  num2 = num % 10;  num /= 10;
  num3 = num % 10;  num /= 10;
  num4 = num % 10;  num /= 10;
  if (stato == 2) {
    num5 = 10;
  } else {
    num5 = num % 10;  num /= 10;
  }
  if (stato == 2) {
    num6 = 11;
  } else {
    num6 = num;
  }
}

Lo schema dei collegamenti è:

Grazie per eventuali suggerimenti, modifiche , ecc.

Saluti
Enrico

Ciao, Enrico. Non so darti una risposta, anche perché è impossibile dirlo sapendo così poco... Però vorrei farti notare un paio di cose:

  1. Con una sola resistenza per display e facendo la scansione classica, la corrente si divide fra i segmenti accesi perciò l'uno sarà molto più luminoso dell'otto (3,5 volte!).
  2. Questa potrebbe essere la causa del problema: forzando tutti gli 8 bit della porta B vai a scrivere anche dove non dovresti! Perciò dei devi usare una maschera, facendo or (PORTB|=) per mettere a livello alto dei bit e and (PORTB&=) per metterli a livello basso.

Grazie.

  1. lo avevo notato ed immaginato la causa, non ho comunque corretto il circuito sia per ragioni di spazio, sia perchè, nella pratica, la differenza non è così accentuata.

  2. sopravvaluti la mia capacità di comprensione causa gli studi fatti (chimica) e temporali (ai miei tempi il massimo dell'automazione era data dalle schede perforate, le scuole non avevano computers e i miei "pasticci" con l'elettronica e la programmazione risalgono a non più di 3 anni fa!). Questo è stato il mio primo tentativo di utilizzo delle "PORT", fino a 6 mesi fa non sapevo neppure esistessero! Potresti propormi un esempio o indicarmi dove guardare?

Ancora grazie + saluti
Enrico

Che valore hanno le resistenze sui catodi? Considera che la corrente massima assoluta (dal datasheet in Absolute Maximum Ratings, ammessa solo per brevi periodi) su ogni pin dell'ATmega328p è 40mA e 200mA complessivi!

Dal datasheet:

NOTICE: Stresses beyond those listed under “Absolute Maximum Ratings” may cause permanent damage to the device. This is a stress rating only and functional operation of the device at these or other conditions beyond those indicated in the operational sections of this specification is not implied. Exposure to absolute maximum rating conditions for extended periods may affect device reliability.

Accendendo un display per volta con una resistenza sul catodo, quindi, il suo valore minimo deve essere (con un po' di margine, considerando solo 150mA totali e 20mA/pin):
(5-1,6)/0,15 = 22 ohm considerando la corrente complessiva (stiamo entro i 150mA)
(5-1,6)/0,04 = 85 ohm considerando un minimo di due segmenti accesi (stiamo entro i 20mA/pin).
Le resistenze di catodo, quindi, devono avere un valore minimo di 82 ohm (valore commerciale).

470 mA

Scusa 470 Ohm

Ah, ecco!... Appena ho visto la notifica mi sono spaventato!!! :smiley:
470? Giallo - Viola - Marrone ?

oro, marrone (ma potrebbe viola scuro), amaranto, rosso; ancora scusa pensavo di aver montato quelli da 470 Ohm e non da 220 Ohm-

Uh?... Oro è l'ultima fascia: 5%;
Rosso: 2:
Amaranto???... Viola? 7;
Marrone: uno 0
270 ohm.
Puoi misurarla?

Fatto, mi da 217

Quindi sono 220 ohm nominali: rosso rosso marrone.

mah.. non vedo un bell'"affare" a pilotare i 7 seg senza un suo driver dedicato es max 7219