Neopixel Clock RTC DS3231

salve a tutti sono uno studente al quinto anno e sto preparando un progetto per l'esame di maturità (faccio un istituto professionale), sto realizzando un orologio con dei neopixel ring uno da 60 dove scorrono minuti e secondi ed uno interno da 24 per le ore, la mia domanda riguarda proprio quest'ultimo perché il mio obiettivo sarebbe il led delle ore che si sposta ogni 30 minuti.
leds[((now.hour()/2)+60)] = hourColor; FastLED.show();
ho provato in questo modo ma non ottengo il risultato desiderato, chiedo il vostro aiuto ogni consiglio e ben accetto. in fodo al post ci sarà anche il codice completo utilizzato. grazie mille, Antonio.

#include "RTClib.h"
#include <FastLED.h>
 #include <Wire.h>
/********** RTC parameters ********************************/
 
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
char buffer[200] ="";
 
/********** FastLed parameters ****************************/
 
#define LED_PIN     2
#define NUM_LEDS   84
#define BRIGHTNESS  180
#define LED_TYPE    WS2811
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];
 
/********** Clock Parameter *******************************/
 
#define hourColor   CRGB::OrangeRed
#define minuteColor CRGB::DarkBlue 
#define secondColor CRGB::DarkGreen
 
/**********************************************************/
 
void setup() {
  Serial.begin(115200);
   
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    abort();
  }
  //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
 
  delay( 1000 ); // power-up safety delay
  FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  FastLED.setBrightness(  BRIGHTNESS );
 
  for( int i = 0; i < NUM_LEDS; ++i) { leds[i] = hourColor; FastLED.show(); delay(20); }
  for( int i = 0; i < NUM_LEDS; ++i) { leds[i] = minuteColor; FastLED.show(); delay(20); }
  for( int i = 0; i < NUM_LEDS; ++i) { leds[i] = secondColor; FastLED.show(); delay(20); }
  delay(500);
  for( int i = 0; i < NUM_LEDS; ++i) { leds[i] = CRGB::CRGB::Black; FastLED.show(); delay(20);}
  delay(1000);
  leds[0] = hourColor; FastLED.show();
  leds[15] = hourColor; FastLED.show();
  leds[30] = hourColor; FastLED.show();
  leds[45] = hourColor; FastLED.show();
  leds[60] = minuteColor; FastLED.show();
  leds[72] = minuteColor; FastLED.show();
  delay(5000);
}
 
void loop() {
   
  DateTime now = rtc.now();
 
  Serial.print("Current time: ");
  sprintf(buffer, "%02d/%02d/%04d (", now.day(), now.month(), now.year());
  Serial.print(buffer);
  sprintf(buffer, "%s", daysOfTheWeek[now.dayOfTheWeek()]);
  Serial.print(buffer);
  sprintf(buffer, ") %02d:%02d:%02d", now.hour(), now.minute(), now.second()); 
  Serial.print(buffer);
 
  for( int i = 0; i < NUM_LEDS; ++i) { leds[i] = CRGB::CRGB::Black; }
  leds[now.second()] = secondColor; FastLED.show();
  leds[now.minute()] = minuteColor; FastLED.show();
 // leds[(now.hour()+60)] = hourColor; FastLED.show();
  leds[((now.hour())+60)] = hourColor; FastLED.show();
  
  Serial.println();
  delay(500);
}

:warning:
Ti segnalo che, nella sezione in lingua Inglese, si può scrivere SOLO in Inglese ... quindi, per favore, la prossima volta presta più attenzione in quale sezione metti i tuoi post; questa volta esso è stato spostato, da un moderatore della sezione di lingua Inglese, nella sezione di lingua Italiana ... la prossima volta potrebbe venire direttamente eliminato.
Grazie.

A quanto detto da UKHeliBob aggiungo ...

... cortesemente, come prima cosa, leggi attentamente il REGOLAMENTO della sezione Italiana del forum, (... e, per evitare future possibili discussioni/incomprensioni, prestando sempre molta attenzione al punto 15), dopo di che, come da suddetto regolamento (punto 16.7), fai la tua presentazione NELL'APPOSITA DISCUSSIONE (... quello che vedi in blu è un link, fai click su di esso per raggiungere la discussione) spiegando bene quali esperienze hai in elettronica e programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.

Grazie,

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposita discussione, nel rispetto del succitato regolamento nessuno ti risponderà (eventuali risposte o tuoi ulteriori post, verrebbero temporaneamente nascosti), quindi ti consiglio di farla al più presto. :wink:

P.P.S.: Evitate di utilizzare la traduzione automatica fatta dal browser ... vi impedisce di capire la lingua della sezione dove andate a scrivere ...

chiedo umilmente scusa, é la prima volta che utilizzo il forum

... nessun problema :slight_smile: , ma NON aprire ulteriori discussioni sullo stesso argomento, si continua in questa. Grazie.

Guglielmo

Tutto dipende da 'cosa' ottieni

Prova a dircelo

L'istruzione now.hour() va da 0 a 23, ma le mezz'ore totali di cui tenere conto sono il doppio delle ore, come potresti mai ottenere il risultato che ti aspetti?

Inoltre ricorda sempre che gli idici degli array iniziano da 0 quindi il primo led che dovrai accendere sarà il numero 59 e non il numero 60 come hai scritto tu.

Edit:
Non ho ancora preso il caffè ed avevo scritto una stupidaggine :grimacing:

In realtà basta aggiungere 1 se minuto>31

Ovvero basta aggiungere il solo "+ min>31"

Grazie alle regole del C

Giusto, ma deve considerare il doppio dell'ora attuale

indice_led = now.hour() * 2 + (now.minute() > 30);

ho provato a fare in questo modo oggi ma da dopo le 12:00 non mi si accende nemmeno un led delle ore, pensavo se poi il tutto lo divido per 2 in questo modo indice_led = (now.hour() * 2 + (now.minute() > 30)/2);
grazie mille per i consigli dati e scusatemi per l'ora

Semplicemente non devi raddoppiare, credo che @cotestatnt abbia solo scambiato un per con un diviso

Ma scusa, fare due conti sulle dita?
Ti facilità molto la soluzione

Per arrivare a chiedere nuovamente consigli vuol dire che gia ho provato in diversi modi.
Ho provato senza alcuna moltiplicazione o divisione e il risultato era un led per ogni ora (ad esempio ore 17=17° led acceso)
dopodiché ho provato dividendo ma il risultato veniva fuori con un ora casuale,
ho provato a modificare qualcosa con le parentesi ma niente,
ho provato a rimuovere il now.hour e tenere solamente il now.minute >30 ma niente da fare…
se avete qualche consiglio e ben accetto grazie mille a tutti

Alle volte il problema appare semplice perché non gli si può dedicare del tempo per scoprire che poi tanto semplice non è, di certo non è banale. Un problema come questo (semplice o meno) richiede comunque tempo per analizzarlo e descriverlo in modo che non ci possa sfuggire nulla.

Il primo problema evidente è che in un ciclo infinito ripetiamo sempre lo stesso codice che esegue le stesse operazioni. Secondo problema, se sono le 00:00 o 12:00 il led che si deve accendere è il led all'indice zero, il quale dovrebbe essere posizionato ad ore 12. Se sono le 00:30, 00:31 si deve accendere il led 1 e spegnere il led 0. Se sono 13:00 si deve accendere il led 2 e spegnere il led 1 ecc.

La formuletta postata da @cotestatnt non è completa, manca qualcosa, però ti aveva dato un suggerimento che non hai saputo cogliere, ma che ho colto io. Da 0÷23 ci sono 24 ore, ma l'anello di led ha solo 12 led destinati alle ore gli altri sono per le mezze ore, quindi in totale hai si 24 led indicizzati a partire da 0, per finire a 23 (24 esimo led). Per coprire le 24 ore serve fare due volte il giro passando per il led 0.

ledIdx = (ora % 12) * 2 + (minuti > 30);

Questa sopra è la formuletta magica. la variabile ora è il valore restituito da now.hour() e minuti è il valore restituito da now.minute(). Questa risolve il secondo problema, mentre per il primo dobbiamo rimandare per adesso. Il primo problema riguarda il ciclo loop() dove spegni tutti i led anche quelli che non sono accesi e ne riaccendi alcuni senza memorizzare quelli che risultano accesi, poi un bel delay(500) e ripeti nuovamente all'infinito. Questo problema lo rimandiamo.

Il codice in sintesi lo vedi di seguito, però io trovo che la formuletta con le variabili ora e minuti sia
più comprensibile a chi si dovesse trovare a leggere il codice.

byte ledIdx = (now.hour() % 12) * 2 + (now.minute() > 30);
leds[ledIdx] = hourColor;
FastLED.show();

Ciao.

Hai perfettamente ragione ed ammetto che a volte mi capita di fare esattamente l'errore che hai descritto e leggere troppo di fretta o superficialmente il post.

Sono andato infatti a rileggermi di nuovo l'esposizione del problema ed io avevo capito che @ant02005 avesse una situazione del genere (dove ho inserito solo il ring da 24 led), ma evidentemente non è questo il funzionamento desiderato.

Forse un'immagine dell'orologio per capire come sono disposti i led aiuterebbe a fare chiarezza.

Ok :grinning:, non era rivolto a te il messaggio, semplicemente ho spiegato che accade e non solo a te, anche a me e forse a tutti, specie quando si è presi da altre cose di nostro interesse come sempre del resto. Io mi sono interessato e ci ho potuto dedicare tempo, anche troppo secondo me, perché anche io pensavo fosse semplice, quando poi mi sono arreso all'evidenza. Ho fatto dei cicli for con wokwi come codice sperimentale e ho staccato dal muro della cucina l'orologio a lancette e me lo sono messo accanto al PC.

Ciao.

1 Like

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