modificare data e ora RTC in seriale

Buonasera,
vorrei utilizzare un blocco di codice per modificare in seriale la data e ora. Per modificare la data scriverò in seriale:
‘data’ e poi 280517 per modificarla in 28 maggio 2017.
quindi i primi due byte ovvero il ciclo 0 e 1 del for, saranno destinati a modificare il giorno, il 2° e 3° ciclo destinati al mese infine il ciclo 4° e 5° per l’anno.

Scriverò ora e poi 1200 per modificare l’ora alle 12:00.

ecco lo sketch:

#include <Wire.h>
#include <HCRTC.h>
#include "RTClib.h"
#define I2CDS1307Add 0x68
char myCmd[128], minuto[128], ora[128], giorno[128], mese[128], anno[128];
unsigned long tempMillis;
int inputSize = 0, annoagg, meseagg, dayagg, oraagg, minagg;
HCRTC HCRTC;
RTC_DS1307 RTC;
void setup()
{
  Serial.begin(9600);
  RTC_DS1307 RTC;
  RTC.begin();
  Wire.begin();
  //RTC.adjust(DateTime(__DATE__, __TIME__));
  //HCRTC.RTCWrite(I2CDS1307Add, 17, 5, 7, 12, 29, 50, 1); //impostare una data predefinita
  HCRTC.RTCRead(I2CDS1307Add);
}

void loop()
{
  inputSize = 0;
  HCRTC.RTCRead(I2CDS1307Add);
  if (Serial.available())
  {
    delay(100);
    inputSize = Serial.available();
    for (int i = 0; i < inputSize; i++)
      myCmd[i] = Serial.read();
    if (myCmd[0] == 'd') if (myCmd[1] == 'a') if (myCmd[2] == 't') if (myCmd[3] == 'a')
          {
            myCmd[0] = 0; myCmd[1] = 0; myCmd[2] = 0; myCmd[3] = 0;
            delay(3000); //tempo per scrivere stringa

            if (Serial.available())
            {
              delay(100);
              inputSize = Serial.available(); //inputsize prende il valore di quante lettere si scrivono in seriale
              for (int i = 0; i < inputSize; i++)
              {
                if ((i == 0) || (i == 1))
                {
                  giorno[i] = Serial.read();
                  Serial.print("giorno: ");
                  Serial.println(giorno);
                }
                if ((i == 2) || (i == 3))
                {
                  mese[i] = Serial.read();
                  Serial.print("mese: ");
                  Serial.println(mese);
                }
                if ((i == 4) || (i == 5))
                {
                  anno[i] = Serial.read();
                  Serial.print("anno: ");
                  Serial.println(anno);
                }   
              }
              HCRTC.RTCWrite(I2CDS1307Add, anno, mese, giorno, ora, minuto, HCRTC.GetSecond(), 1);
            }
          }
    if (myCmd[0] == 'o') if (myCmd[1] == 'r') if (myCmd[2] == 'a')
        {
          myCmd[0] = 0; myCmd[1] = 0; myCmd[2] = 0;
          delay(3000); //tempo per scrivere stringa
          if (Serial.available())
          {
            delay(100);
            inputSize = Serial.available(); //inputsize prende il valore di quante lettere si scrivono in seriale
            for (int i = 0; i < inputSize; i++)
            {
              if ((i == 0) || (i == 1))
              {
                ora[i] = Serial.read();
                Serial.print("ora: ");
                Serial.println(ora);
              }
              if ((i == 2) || (i == 3))
              {
                minuto[i] = Serial.read();
                Serial.print("minuto: ");
                Serial.println(minuto);
              }
            }
            HCRTC.RTCWrite(I2CDS1307Add, anno, mese, giorno, ora, minuto, HCRTC.GetSecond(), 1);
          }
        }
  }
}

in seriale non capisco perchè mi stampa questo quando scrivo ‘data’ ed entro 3 secondi ‘120517’:

giorno: 1
giorno: 12
mese:
mese:
anno:
anno:

e quando scrivo ‘ora’ ed entro 3 secondi ‘1200’ mi stampa:

ora: 1
ora: 12
minuto:
minuto:

i primi due cicli del for vanno per il verso giusto poi non si assegnano negli altri parametri dell’RTC entrando comunque nell’if visto che stampa in seriale ‘minuto’ etc…

Dove sbaglio?

Ciao, senza essere volutamente scortese ma per tentare di darti qualche buon suggerimento, penso che dovresti rivedere i concetti base della programmazione C.

Questo ad esempio non si fa

if (myCmd[0] == 'o') if (myCmd[1] == 'r') if (myCmd[2] == 'a')

Il tuo codice è inutilmente complicato e pensato male, personalmente non mi viene neanche la voglia di tentare di farlo funzionare. :)

Potresti semplificare e rendere migliore il programma, usando una sola variabile String, il metodo Serial.readString(), e il metodo della classe string.substring()

1) Nel loop con un if() verifichi se ci sono dati da seriale if(serial.available())

2) All'interno dell' if() leggi una stringa di comando "data" o "ora" String dato=Serial.readString()

3) if(dato=="data") else if(dato=="ora"), fai qualcosa se il comando è == a ora o data

4) Acquisisci la stringa dato=Serial.readString(),

5) Usi i metodi string.substring() e gli altri metodi della classe string per ricavare ora, minuti, giorno, anno. A seconda che ti serva un numero intero o un array di char, puoi usare rispettivamente i metodi string.toInt() o string.toCharArray()

Questo metodo accetta numeri interi o stringhe o entrambi ????

HCRTC.RTCWrite(I2CDS1307Add, 17, 5, 7, 12, 29, 50, 1);

HCRTC.RTCWrite(I2CDS1307Add, anno, mese, giorno, ora, minuto, HCRTC.GetSecond(), 1);

torn24: ... Potresti semplificare e rendere migliore il programma, usando una sola variabile String, il metodo Serial.readString(), e il metodo della classe string.substring() ...

... questo suggerimento (... uso della classe String) te lo passo proprio perché stai parlando con uno che è veramente agli inizi e ha una scarsissima conoscenza del 'C', altrimenti ... :smiling_imp: :smiling_imp: :smiling_imp:

Guglielmo

Be non so se da sempre problemi la classe String, o se un uso moderato di un unica variabile globale è accettabile :) Di certo diviene più impegnativo spiegargli come leggere da seriale un array di char, e usare le funzioni strncpy() e atoi() :)

Diciamo che semplifica molto, è forse è stata introdotta per questo, ma eviterò di proporla in futuro :)

torn24: ... Di certo diviene più impegnativo spiegargli come leggere da seriale un array di char, e usare le funzioni strncpy() e atoi() :)

... difatti, in casi come questi, concordo al 100% ... poi, con il tempo e l'esperienza, impareranno a usare le vere stringhe del 'C' ;)

Guglielmo

Perfetto, grazie ai consigli di torn24 (+1 karma) seguendo il libro di leo72 (ottimo libro consiglio l'acquisto), sono riuscito a risolvere.

Inizialmente ho convertito la stringa in char e mi dava icone strane nel serial monitor, poi convertendoli in byte mi dava sempre valore 0, infine convertendole in long sono riuscito a cambiare la data e ora in seriale.

Ancora sono un vero e proprio newbie :sweat_smile: