Introduction: Arduino PHP Text and Data to Speech - an Automatic Weatherman

In my continuing efforts to stay one step ahead of the forthcoming ai apocalypse, I have started teaching machines to speak in a human-ish voice so that we can all be future friends together. Here, I'm going to show how text and data can be woven together to produce audio 'sound bytes' for broadcast on a loudspeaker.

Think about it like this - imagine an automated weather man who might replace the one on the radio. He has all the data right at his finger tips - all we got to do is make him sound human. Our data is coming from a real weather station that updates every ten minutes onto the internet.

This is a deceptively easy and fun project and the Arduino hardware is very simple to set up - essentially just an Adafruit Fona Feather and an Emic text to speech module. I'm using a GPRS Fona module, but this could be replaced with a wifi version, but with different code (not so easy).

But what on earth is PHP? ..... I've no idea what is stands for, but basically it's a special language and protocol that can manipulate data and spit out very simple and useful information in easy to read formats. In this case, the PHP webpage displays an extremely simple long line of text (see video) that is picked up by the Feather module and fed into the Emic down a serial bus. If we tried to use an HTML webpage the readout would include all the HTML background code and not just what you'd see on a website - PHP conveniently hides all it's internal 'working' code from being published.

If you want to see the actual PHP readout with the text and data intermingled, click here:

http://www.goatindustries.co.uk/weather2/speech10.php

and if you cant be bothered to create your own PHP file (which can be rather tricky) - just use mine at the above address.

Special thanks to a kindly fellow called shamyl who hacked the Emic2 Arduino library and created a hardware serial compatible version:

https://github.com/shamyl/EMIC2_UART

Thank you shamyl !!!!!!!!!!!!!

Step 1: Arduino Code

Install shamyl's Arduino library and upload this code into the Fona Feather, without leaving anything out.

#include <SD.h>
#include <EMIC2_UART.h>
EMIC2_UART emic;  // Creates an instance of the EMIC2_UART library

#include "Adafruit_FONA.h"
#define FONA_RX 9
#define FONA_TX 8
#define FONA_RST 4
#define FONA_RI  7
#include <SoftwareSerial.h>

// this is a large buffer for replies
char replybuffer[255];

// We default to using software serial. If you want to use hardware serial
// (because softserial isnt supported) comment out the following three lines 
// and uncomment the HardwareSerial line
#include <SoftwareSerial.h>
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;
// Hardware serial is also possible!

//HardwareSerial *fonaSerial = &Serial1;

// Use this for FONA 800 and 808s
Adafruit_FONA fona = Adafruit_FONA(FONA_RST);
// Use this one for FONA 3G
//Adafruit_FONA_3G fona = Adafruit_FONA_3G(FONA_RST);

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);

uint8_t type;
int switchStatus=0;
int smsnumB=1000;
String textMessage;
String textMessageShort;
int previousNum =0;
int smsNumberStatus=0;
int i=0;
int z=0;
int selectSMS=0;
int speakStatus=0;
String d;
String nothing;
char webpage[600];

void setup() 
{ 
    emic.begin();
    emic.setVoice(4);  // Sets the voice (9 choices: 0 - 8)
    emic.setVolume(10);
    emic.speak("Hello There");

   pinMode(4, INPUT_PULLUP); // Use this to reset Fona.
   digitalWrite(4, HIGH);
   delay(100);
   digitalWrite(4, LOW);
   
  // tone(A0,500,500);
   //pinMode(20, INPUT_PULLUP);
   //attachInterrupt(digitalPinToInterrupt(20), textMessageRead, HIGH);

  
  //while (!Serial);

  Serial.begin(9600);
  Serial.println(F("FONA basic test"));
  Serial.println(F("Initializing....(May take 3 seconds)"));
  
    emic.speak(" .. How are you doing?");
    
  fonaSerial->begin(4800);
  if (! fona.begin(*fonaSerial)) {
    Serial.println(F("Couldn't find FONA"));
    emic.speak("Bad news .. We could not find the Fona .. Please reset all devices");
    while (1);
  }
    emic.speak("Good news .. we successfully connected with the Fona module");  
  type = fona.type();
  Serial.println(F("FONA is OK"));
  Serial.print(F("Found "));
  switch (type) {
    case FONA800L:
      Serial.println(F("FONA 800L")); break;
    case FONA800H:
      Serial.println(F("FONA 800H")); break;
    case FONA808_V1:
      Serial.println(F("FONA 808 (v1)")); break;
    case FONA808_V2:
      Serial.println(F("FONA 808 (v2)")); break;
    case FONA3G_A:
      Serial.println(F("FONA 3G (American)")); break;
    case FONA3G_E:
      Serial.println(F("FONA 3G (European)")); break;
    default: 
      Serial.println(F("???")); break;
  }
  
  // Print module IMEI number.
  char imei[15] = {0}; // MUST use a 16 character buffer for IMEI!
  uint8_t imeiLen = fona.getIMEI(imei);
  if (imeiLen > 0) {
    //Serial.print("Module IMEI: "); Serial.println(imei);
  }
  fona.setGPRSNetworkSettings(F("pp.vodafone.co.uk"), F("wap"), F("wap"));   // Change these settings! (Network APN, username ,password)
  delay(10000);
}


void loop() 
{   flushSerial();
    networkStatus();
    emic.speak("now attempting to connect to g p r s once more");
    delay (10000);
    if (fona.enableGPRS(true))
      while(1)
      {   
      readWebpage(); 
      delay(300000);       
      }  
    ;
}
void readWebpage()
{
          // read website URL
        uint16_t statuscode;
        int16_t length;
       char url[80] = "http://www.goatindustries.co.uk/weather2/speech8.php";
        if (!fona.HTTP_GET_start(url, &statuscode, (uint16_t *)&length)) {
          Serial.println("Failed!");
        }
        int aa=0;
        while (length > 0) 
        {
          while (fona.available()) 
          {
            char c = fona.read();
            webpage[aa] = c;
            aa++;      
           // d = "Z" + c;    
            // Serial.write is too slow, we'll write directly to Serial register!
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
            loop_until_bit_is_set(UCSR0A, UDRE0); /* Wait until data register empty. */
            UDR0 = c;
#else
            Serial.write(c);
#endif
            length--;
            if (! length);
          }
        }
        Serial.println(F("\n****"));
        fona.HTTP_GET_end();

  Serial.print("This should be character webpage: ....... "); Serial.println(webpage);
  emic.speak(webpage); 
}
void turnOffGPRS()
{
          // Turn off GPRS:
        if (!fona.enableGPRS(false))
        Serial.println(F("No - Failed to turn off"));
        Serial.println("If the line above says OK, then GPRS has just been turned off");
        delay (1000);
}
void turnOnGPRS()
{
        delay (10000);
        Serial.println("Now attempting to turn on GPRS .........");
     //   if (!fona.enableGPRS(true))
     //   Serial.println(F("No - Failed to turn on"));
     //   Serial.println("GPRS is on if the line above shows 'OK'");
     //   Serial.println("Wait for 10 seconds to make sure GPRS is on ...........");        
     //   delay (10000);
        if (fona.enableGPRS(true));
        //ledFastFlashB();                          // Indicates a connect to GPRS.

        //Serial.println(("No - Failed to turn on"));
}

void networkStatus()
{
          // read the network/cellular status
        uint8_t n = fona.getNetworkStatus();
        Serial.print(F("Network status "));
        Serial.print(n);
        Serial.print(F(": "));
        if (n == 0) Serial.println(F("Not registered"));
        if (n == 1) Serial.println(F("Registered (home)"));
        if (n == 2) Serial.println(F("Not registered (searching)"));
        if (n == 3) Serial.println(F("Denied"));
        if (n == 4) Serial.println(F("Unknown"));
        if (n == 5) Serial.println(F("Registered roaming"));
}

void flushSerial()
{
  while (Serial.available())
    Serial.read();
}

char readBlocking() 
{
  while (!Serial.available());
  return Serial.read();
}
uint16_t readnumber() 
{
  uint16_t x = 0;
  char c;
  while (! isdigit(c = readBlocking())) {
    //Serial.print(c);
  }
  Serial.print(c);
  x = c - '0';
  while (isdigit(c = readBlocking())) {
    Serial.print(c);
    x *= 10;
    x += c - '0';
  }
  return x;
}

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout) 
{
  uint16_t buffidx = 0;
  boolean timeoutvalid = true;
  if (timeout == 0) timeoutvalid = false;

  while (true) {
    if (buffidx > maxbuff) {
      //Serial.println(F("SPACE"));
      break;
    }

    while (Serial.available()) {
      char c =  Serial.read();

      //Serial.print(c, HEX); Serial.print("#"); Serial.println(c);

      if (c == '\r') continue;
      if (c == 0xA) {
        if (buffidx == 0)   // the first 0x0A is ignored
          continue;

        timeout = 0;         // the second 0x0A is the end of the line
        timeoutvalid = true;
        break;
      }
      buff[buffidx] = c;
      buffidx++;
    }

    if (timeoutvalid && timeout == 0) {
      //Serial.println(F("TIMEOUT"));
      break;
    }
    delay(1);
  }
  buff[buffidx] = 0;  // null term
  return buffidx;
}

Step 2: PHP Code

Here is an example of what the PHP code might look like. Looking at the block of text that starts with "hello my friend", it's essential that there are no large gaps between the words. The '..' is used to create pauses. Tabs must never be used!

The actual data is retrieved from a database with commands such as:

<? echo $hourminutes; ?>

and woven into text as shown below, with passwords etc. as XXXXXXXXXXXXXXX:

<?php
// this refreshes current page after 2 seconds.
header( "refresh:2;" );
include ("getid.php");
$host="localhost"; // Host name 
$username="XXXXXXXXXXXXXX"; // Mysql username 
$password="XXXXXXXXXXXXXX"; // Mysql password 
$db_name="XXXXXXXXXXXXXXX"; // Database name 
$tbl_name="XXXXXXXXXXXXXXX"; // Table name

// Connect to server and select database.
mysql_connect("$host", "$username", "$password")or die("cannot connect"); 
mysql_select_db("$db_name")or die("cannot select DB");

// Retrieve data from database 
 
$sql2="SELECT * FROM XXXXXXXXXXXXXXX  ORDER BY id DESC LIMIT 1";
$result2=mysql_query($sql2);
 
?><?php
// Start looping rows in mysql database.
 while($rows=mysql_fetch_array($result2)){
 ?>Hello my friend .. how are you doing? .. Here is a quick run down of the weather outside .. the current reading eye dee is <? echo $rows['id']; ?> .. and the last reading was on <? echo $day; ?>
 .. at <? echo $hourminutes; ?> hours .. the windpseed was <? echo $rows['windspeed']; ?> knots .. with a maximum gust of <? echo $rows['windgust']; ?> knots .. and the wind direction was <? echo $rows['windway']; ?> .. degrees .. The outside temperature was <? echo $rows['tempout']; ?> .. degrees celcius. .. The battery volts was <? echo $rows['volts']; ?> .. volts. .. and the humidity was at <? echo $rows['humidity']; ?> .. per cent .. Thankyou for listening .. and have a nice day .. oh .. one last thing ..please dont forget to vote for this instructable in the make noise competition.
<?php
// close while loop 
}

?><?php
// close MySQL connection 
mysql_close();
 ?>

Step 3: Parts and Circuit

I told you it was easy!

  • ANT1 Antenna
  • D1 Rectifier Diode type Rectifier; package 300 mil [THT]; part # 1A schottky
  • Part1 Adafruit Feather 32u4 FONA variant variant 1; part # Adafruit #3027
  • Power plug1 Power plug S1 Pushbutton package [THT] SPKR1
  • Loudspeaker U1
  • LIPO-1000mAh package lipo-1000; variant 1000mAh U2
  • EMIC2 true; pin spacing 100mil; pins 6; hole size 1.0mm,0.508mm; package THT; layout Single Row; label EMIC2; part # EMIC2

Step 4: Singing Weather Man

The emic2 can also be programmed to sing songs. I revamped the layout using a MEGA2560, Adafruit SIM800L Fona shield and a DS3231 real time clock (RTC) using the code below to get it singing. The first 12 lines of code shows how to connect the gadgets:

WARNING: The singing weather man is rather silly and may offend persons of a more serious nature. He's also very patriotic!

Singing is achieved using something called the 'DecTalk parser' and 'Phonemes' and using this example code and the datasheet attached, you can produce your own little ditties! The crucial example piece of code is here, which sings "God bless America":

https://youtu.be/qwthbYbccJ0

      emicSerial.println("P0");
      emicSerial.println("S [:phone arpa speak on][:rate 190][:n0][ GAA<400,12>DD<200,15>B<200,10>LLEH<200,19>EH<500,22>S<200,18>AH<100,18>MEH<200,16>K<100,13>AH<200,12>][:n0]");
      emicSerial.print('\n');   

And here's the code in it's entirety:

#define rxPin   11  // Serial input (connects to Emic 2's SOUT pin)
#define txPin   12  // Serial output (connects to Emic 2's SIN pin)
#define ledPin  13  // Most Arduino boards have an on-board LED on this pin
#include "Adafruit_FONA.h"
#define FONA_RX 9
#define FONA_TX 10
#define FONA_RST 4
#include <SoftwareSerial.h>
// CONNECTIONS:
// DS3231 SDA --> SDA
// DS3231 SCL --> SCL
// DS3231 VCC --> 3.3v or 5v
// DS3231 GND --> GND

#if defined(ESP8266)
#include <pgmspace.h>
#else
#include <avr/pgmspace.h>
#endif
    int i;
    int hobbits;
    int orks;
#include <Wire.h> // must be included here so that Arduino library object file references work
#include <RtcDS3231.h>
RtcDS3231<TwoWire> Rtc(Wire);
char datestringB[20];

// this is a large buffer for replies
char replybuffer[255];
char url[80];

#include <SoftwareSerial.h>
SoftwareSerial fonaSS = SoftwareSerial(FONA_TX, FONA_RX);
SoftwareSerial *fonaSerial = &fonaSS;
SoftwareSerial emicSerial =  SoftwareSerial(rxPin, txPin);

Adafruit_FONA fona = Adafruit_FONA(FONA_RST);

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout = 0);

uint8_t type;
int switchStatus=0;
int smsnumB=1000;
String textMessage;
String textMessageShort;
int previousNum =0;
int smsNumberStatus=0;
int z=0;
int p=0;
int selectSMS=0;
int speakStatus=0;
String d;
String nothing;
char webpage[1000];
int g=0;

  
void setup() 
{   Serial.begin(9600);
    Serial.print("compiled: ");
    Serial.print(__DATE__);
    Serial.println(__TIME__);
    //--------RTC SETUP ------------
    Rtc.Begin();
    RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
    printDateTime(compiled);
    Serial.println();
    RtcDateTime now = Rtc.GetDateTime();
    
   // while (!Serial);
    Serial.println("Hello There!");
    pinMode(LED_BUILTIN, OUTPUT);
    pinMode(ledPin, OUTPUT);
    pinMode(rxPin, INPUT);
    pinMode(txPin, OUTPUT);
    emicSerial.begin(9600);
    emicSerial.print('\n');             // Send a CR in case the system is already up
    while (emicSerial.read() != ':');   // When the Emic 2 has initialized and is ready, it will send a single ':' character, so wait here until we receive it
    delay(10);                          // Short delay
    emicSerial.flush();                 // Flush the receive buffer

   pinMode(4, INPUT_PULLUP); // Use this to reset Fona.
   digitalWrite(4, HIGH);
   delay(100);
   digitalWrite(4, LOW);

  Serial.println(F("FONA basic test"));
  Serial.println(F("Initializing....(May take 3 seconds)"));
    
  fonaSerial->begin(4800);
  if (! fona.begin(*fonaSerial)) {
    Serial.println(F("Couldn't find FONA"));
    //emic.speak("Bad news .. We could not find the Fona .. Please reset all devices");
    while (1);
  }
     emicSerial.println("P1");
     emicSerial.println("V12"); // 18 is max.
     emicSerial.print('S');
     emicSerial.print(("Good news .. All systems are fully operational."));
     emicSerial.print('\n');
  //emic.speak("Good news .. we successfully connected with the Fona module");  
  type = fona.type();
  Serial.println(F("FONA is OK"));
  Serial.print(F("Found "));
  switch (type) {
    case FONA800L:
      Serial.println(F("FONA 800L")); break;
    case FONA800H:
      Serial.println(F("FONA 800H")); break;
    case FONA808_V1:
      Serial.println(F("FONA 808 (v1)")); break;
    case FONA808_V2:
      Serial.println(F("FONA 808 (v2)")); break;
    case FONA3G_A:
      Serial.println(F("FONA 3G (American)")); break;
    case FONA3G_E:
      Serial.println(F("FONA 3G (European)")); break;
    default: 
      Serial.println(F("???")); break;
  }
  
  // Print module IMEI number.
  char imei[15] = {0}; // MUST use a 16 character buffer for IMEI!
  uint8_t imeiLen = fona.getIMEI(imei);
  if (imeiLen > 0) {
    //Serial.print("Module IMEI: "); Serial.println(imei);
  }
  fona.setGPRSNetworkSettings(F("pp.vodafone.co.uk"), F("wap"), F("wap"));   // Change these settings! (Network APN, username ,password)
  delay(10000);
  void turnOffGPRS();
}


void loop() 
{   
    RtcDateTime now = Rtc.GetDateTime();
    //printDateTime(now);
    printMinute(now);
    printHour(now);
    //Serial.println();

    delay(1000);
        if (((hobbits==0)||(g==0))&&(orks>7)&&(orks!=12))
    {
     Serial.println("Hobbits are GO!");
     //if (hobbits==0){g=1;} //Makes it do it once only.
     // else {g=0;}
     g=1;
/////////////////////////////////////////////////////////////////////////////////////////////////////
    emicSerial.println("P0");
    //emicSerial.println("S [:phone arpa speak on][:rate 190][:n0][ GOW<400,12>DD<200,15>B<200,10>LLEH<200,19>EH<500,22>S<200,18>AH<100,18>MEH<200,16>K<100,13>AH<200,12>][:n0]");
     //emicSerial.print('S');
   //emicSerial.println("S [:phone arpa speak on][:rate 190][:n3][:dv as 100 f4 3300 sm 5 nf 50 bf 20 ri 100][AH<100,16> TAY<100> N<100> SH<100> N<100>_<100> ow<200> ll<300>_hx<100>yu<200>muw<100>n<300> s<200>____DHAX<300,16> weh<200>DHAX<200>_ah<200> p<200> dey<200> t<200> ih<200>z<100> nuh<200> ih<100>m<100>ih<100>n<100>ah<100>n<100>t<100>][:n0]");
     //emicSerial.print('\n');

    emicSerial.println("S [:phone arpa speak on][:rate 190][:n0][D<200,25>ix<200>nx<300>_ D<200,12>ax<200>nx<300>_d<200,24>ao<600>nx<400>_ix<200,15>t<100>z<200> t<100,16>ay<100,12>ay<100,18>ay<100,20>ay<100,22>m<200> t<100>uw<200> ch<100,20>eh<100>k<100> dhax<200,14> weh<200,16>dhax<200>r<100,15>][:n0]");
    emicSerial.print('\n'); 
    delay(8000);
    emicSerial.println("P1");
    emicSerial.print('S');
    emicSerial.print(("It's naaoww time to check the weather once more."));
    emicSerial.print('\n');
    flushSerial();
    networkStatus();
    turnOffGPRS();
    delay(10000);
    //emic.speak("now attempting to connect to g p r s once more");
    if (fona.enableGPRS(true))

      readWebpageA(); 
      delay(1000); 

      turnOffGPRS();
      for (int i =0 ; i < 60 ; i++) 
      {
      delay(1000); 
      //ledFlash(); 
      //delay(3600000);
      }     
     ;
////////////////////////////////////////////////////////////////////////////////////////////////////   
      emicSerial.println("P0");
      emicSerial.println("S [:phone arpa speak on][:rate 190][:n0][ GAA<400,12>DD<200,15>B<200,10>LLEH<200,19>EH<500,22>S<200,18>AH<100,18>MEH<200,16>K<100,13>AH<200,12>][:n0]");
      emicSerial.print('\n');   
    }
  

}
#define countof(a) (sizeof(a) / sizeof(a[0]))
void ledFlash()
{
      for (int h =0 ; h < 5 ; h++) 
      {
      digitalWrite(LED_BUILTIN, HIGH);   
      delay(20);                       
      digitalWrite(LED_BUILTIN, LOW);    
      delay(20); 
      }
}
void readWebpageA()
{
          // read website URL
        uint16_t statuscode;
        int16_t length;

    char url[80] = "http://www.goatindustries.co.uk/weather2/speech10.php";
   
        if (!fona.HTTP_GET_start(url, &statuscode, (uint16_t *)&length)) {
          Serial.println("Failed!");
        }
        int aa=0;
        while (length > 0) 
        {
          while (fona.available()) 
          {
            char c = fona.read();
            webpage[aa] = c;
            aa++;      
           // d = "Z" + c;    
            // Serial.write is too slow, we'll write directly to Serial register!
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
            loop_until_bit_is_set(UCSR0A, UDRE0); /* Wait until data register empty. */
            UDR0 = c;
#else
            Serial.write(c);
#endif
            length--;
            if (! length);
          }
        }
        Serial.println(F("\n****"));
        fona.HTTP_GET_end();

 // Serial.print("This should be character webpage: ....... "); Serial.println(webpage);
//  Serial.print("The value of P is: ....... "); Serial.println(p);
 // emic.speak(webpage); 
     emicSerial.println("P1");
     emicSerial.print('S');
     emicSerial.print(webpage);
     emicSerial.print('\n');


}
void turnOffGPRS()
{
          // Turn off GPRS:
        if (!fona.enableGPRS(false))
        Serial.println(F("No - Failed to turn off"));
        Serial.println("If the line above says OK, then GPRS has just been turned off");
        delay (1000);
}
void turnOnGPRS()
{
        delay (10000);
        Serial.println("Now attempting to turn on GPRS .........");
     //   if (!fona.enableGPRS(true))
     //   Serial.println(F("No - Failed to turn on"));
     //   Serial.println("GPRS is on if the line above shows 'OK'");
     //   Serial.println("Wait for 10 seconds to make sure GPRS is on ...........");        
     //   delay (10000);
        if (fona.enableGPRS(true));
        //ledFastFlashB();                          // Indicates a connect to GPRS.

        //Serial.println(("No - Failed to turn on"));
}

void networkStatus()
{
          // read the network/cellular status
        uint8_t n = fona.getNetworkStatus();
        Serial.print(F("Network status "));
        Serial.print(n);
        Serial.print(F(": "));
        if (n == 0) Serial.println(F("Not registered"));
        if (n == 1) Serial.println(F("Registered (home)"));
        if (n == 2) Serial.println(F("Not registered (searching)"));
        if (n == 3) Serial.println(F("Denied"));
        if (n == 4) Serial.println(F("Unknown"));
        if (n == 5) Serial.println(F("Registered roaming"));
}

void flushSerial()
{
  while (Serial.available())
    Serial.read();
}

char readBlocking() 
{
  while (!Serial.available());
  return Serial.read();
}
uint16_t readnumber() 
{
  uint16_t x = 0;
  char c;
  while (! isdigit(c = readBlocking())) {
    //Serial.print(c);
  }
  Serial.print(c);
  x = c - '0';
  while (isdigit(c = readBlocking())) {
    Serial.print(c);
    x *= 10;
    x += c - '0';
  }
  return x;
}

uint8_t readline(char *buff, uint8_t maxbuff, uint16_t timeout) 
{
  uint16_t buffidx = 0;
  boolean timeoutvalid = true;
  if (timeout == 0) timeoutvalid = false;

  while (true) {
    if (buffidx > maxbuff) {
      //Serial.println(F("SPACE"));
      break;
    }

    while (Serial.available()) {
      char c =  Serial.read();

      //Serial.print(c, HEX); Serial.print("#"); Serial.println(c);

      if (c == '\r') continue;
      if (c == 0xA) {
        if (buffidx == 0)   // the first 0x0A is ignored
          continue;

        timeout = 0;         // the second 0x0A is the end of the line
        timeoutvalid = true;
        break;
      }
      buff[buffidx] = c;
      buffidx++;
    }

    if (timeoutvalid && timeout == 0) {
      //Serial.println(F("TIMEOUT"));
      break;
    }
    delay(1);
  }
  buff[buffidx] = 0;  // null term
  return buffidx;
}
void printDateTime(const RtcDateTime& dt)
{
    char datestringA[20];

    snprintf_P(datestringA, 
            countof(datestringA),
            PSTR("%02u/%02u/%04u %02u:%02u"),
            dt.Month(),
            dt.Day(),
            dt.Year(),
            dt.Hour(),
            dt.Minute()
        //    dt.Second()
            );
    Serial.println(datestringA);
}
void printHour(const RtcDateTime& dt)
{
    char datestringB[20];

    snprintf_P(datestringB, 
            countof(datestringB),
            PSTR("%02u"),
            dt.Hour()
            );
   // Serial.println(datestringB);
        String rabbits;
    rabbits += datestringB;
    //Serial.print("datestringB ..... ");         Serial.println(datestringB);
    orks = rabbits.toInt();
    Serial.print("orks ..... "); Serial.println(orks);
}
void printMinute(const RtcDateTime& dt)
{
    char datestringB[20];

    snprintf_P(datestringB, 
            countof(datestringB),
            PSTR("%02u"),
            dt.Minute()
            );
   // Serial.println(datestringB);
        String rabbits;
    rabbits += datestringB;
    //Serial.print("datestringB ..... ");         Serial.println(datestringB);
    hobbits = rabbits.toInt();
    Serial.print("hobbits ..... "); Serial.println(hobbits);
}
Please in the competitions - top right - Thanks!
Arduino Contest 2016

Participated in the
Arduino Contest 2016

Make Noise Challenge

Participated in the
Make Noise Challenge

Epilog Contest 8

Participated in the
Epilog Contest 8