Friday, January 27, 2023

Telegram messenger for IOT

 For an index to all my stories click this text

Short intro:
This story explains how I am going to send messages from Telegram to set a led on or off on an ESP8266 or ESP32.
I have been neglecting this for far to long, but now IFTTT is making things difficult for its users I was looking for another service that allowed me to send notifications to my phone.

Whatsapp would be nice cause all my friends, relatives, collegues at work and fellow board members of the Art Club (I am the treasurer) are using this. I am not particular fond of it but to stay in touch during this Corona crisis it was indispensable.

Whatsapp lacks only one very important thing: there is no direct API for us mortals. So I can not reach it through my computer. And more important I can not send or receive messages to/from it with my ESP's I could use Callmebot for sending messages to Whatsapp but alas that is no longer a free service if you use it regularly. It is cheap however (just 4 usd pro year) but hey: I am Dutch.............

In comes Telegram Messenger.

Telegram messenger is available for Android and IOS phones and tablets. Thats no different from whatsapp. But Telegram messenger is also available as a Desktop program for your windows machine or Apple. And there is a web-version. You can even run it on a Raspberry. You do need a smartphone to register, but then you can use it almost everywhere.

Telegram has been around for a while and basically offers for the average user the same as Whatsapp. You can send messages, photo's, video's and files. You can start groups and you can make voice and video calls.

Telegram has some nice extra features. You can join channels. Channels are open groups. You can find groups on Arduino, ESP32, ESP8266, Domoticz, Raspberry Pi etc. etc. etc. There is a lot of information to be found.

And the most important part is that there are ESP8266 and ESP32 libraries available.

I am going to use the AsyncTelegram library whose latest version is even capable of sending foto's to telegram. But that is for later. Let us start with sending messages from Telegram to an ESP8266 or ESP32 to set a led on or off.

Install the App.

To use Telegram Messenger on Android you need to install the app from Googles Play-store . You can find it here: https://play.google.com/store/apps/details?id=org.telegram.messenger&hl=nl&gl=US

To use Telegram messenger on an Apple iPhone install it from the App Store with this link: https://apps.apple.com/app/telegram-messenger/id686449807

Talk to the BotFather

To have Telegram Messenger communicate with your ESP we have to activate a so-called Bot. To build a bot we have to talk to the Botfather.


 

Start with pressing the looking glass on the right side of your screen and search for BotFather.



 

The BotFather greets you with the standard message.



 

To give the BotFather a command just type your text in the bottom of the screen just like wit any messenger program. To begin type /start. This will give you a list of commands.



 

Like said we need to build a Bot for communication with our ESP. The command /mybots shows that you have no bots. So let us build on. First you need to choose a name and next a username. It is the username that will show up in your contactlist so choose wise.


 

Now we have created a Bot the BotFather gives us a token. Store this somewhere safe and accessible cause you will need this to talk to your ESP.



 

If you ever need your token again just ask it from the BotFather with the command /mybots. You will get a list of your bots and click on the one you need the details from.



 

You can see that my Bot is called Myhome.



 

As you can see from the list the Bot Myhome is ready for use.
And the Telegram setup is now complete.Over to programming the ESP.

Arduino program.

We are going to start with something simple. The program that is listed here will put a simple menu on the Bot's screen. In Telegram in the Bot's screen you can then send a command to set the ESP's build-in led on or of.

This program will work on both ESP8266 and ESP32. For testing I used a Wemos D1 Esp8266 board and a DOIT ESP32 DEVKIT V1 board.



 

To use this program you will need two libraries. The first is the ArduinoJson library by Benoit Blanchon which you can install right from the Library Manager in the IDE. If you install a different version the next library probable won't work so make sure you install this one.



 

The other required library is the AsyncTelegram by Tolentino Cotesta which also can be found in the Library manager and otherwise can be downloaded from here: 

https://github.com/cotestatnt/asynctelegram

And here is the program.

/*
Name:                     Ledcommand
Library and demo Author:  Tolentino Cotesta <cotestatnt@yahoo.com>

Adapted by:               Luc Volders
                          http://lucstechblog.blogspot.com/
*/

#include <Arduino.h>
#include "AsyncTelegram.h"
AsyncTelegram myBot;

const char* ssid = "YOUR-ROUTERNAME-HERE";
const char* pass = "PASSWORD";
const char* token = "YOUR-TELEGRAM-TOKEN-HERE";    

int led = LED_BUILTIN; 

void setup() 
{
  // initialize the Serial
  Serial.begin(115200);
  Serial.println("Starting TelegramBot...");

  WiFi.setAutoConnect(true);   
  WiFi.mode(WIFI_STA);
  
  WiFi.begin(ssid, pass);
  delay(500);
  while (WiFi.status() != WL_CONNECTED) 
  {
  Serial.print('.');
  delay(500);
  }

  myBot.setUpdateTime(1000);
  myBot.setTelegramToken(token);
  
  Serial.print("\nTest Telegram connection... ");
  myBot.begin() ? Serial.println("OK") : Serial.println("NOK");

  pinMode(led, OUTPUT);
  digitalWrite(led, HIGH); 
}

void loop() 
{
  TBMessage msg;

  if (myBot.getNewMessage(msg)) 
  {
    if (msg.text.equalsIgnoreCase("Lon")) 
    {      
      digitalWrite(led, LOW);                          
      myBot.sendMessage(msg, "Light is now ON");        
    }
    else if (msg.text.equalsIgnoreCase("Loff")) 
    {       
      digitalWrite(led, HIGH);                         
      myBot.sendMessage(msg, "Light is now OFF");      
    }
    else 
    {                                                  
      // generate the message for the sender
      String reply;
      reply = "Welcome ESP8266 number 1\n" ;
      reply += "You can use these commands :\n" ;
      reply += "============================\n\n" ;
      //reply += msg.sender.username;
      reply += ". Mancave Light on = Lon\n";
      reply += ". Mancave Light off = Loff\n";
      myBot.sendMessage(msg, reply);
    }
  } 
}

 

I will highlight some parts here.

const char* ssid = "YOUR-ROUTERNAME-HERE";
const char* pass = "PASSWORD";
const char* token = "YOUR-TELEGRAM-TOKEN-HERE";    

Obvious but put your credentails in here. This is the part where you need to put in the Telegram token which you got earlier from the BotFather.

In the setup() you can find the following line:

myBot.begin() ? Serial.println("OK") : Serial.println("NOK");

This is a special language construction which is the same as an if-then statement.

if myBot.begin() is true then Serial.println("OK")
else Serial.println("NOK")


This kind of stetement is often used in Javascript. It is called a ternary operator. You do not see this often in Arduino programs.
 

TBMessage msg;

if (myBot.getNewMessage(msg))


In the loop() a new variable is created called msg, and then the program checks wether the Bot has send a message.

if (msg.text.equalsIgnoreCase("Lon"))

Here we check wether the text "Lon" is received. I check for "Lon"as I am a lazy typer. But alter this to your own liking.
The good part is that here also is a statement that you do not see often in Arduino programs: equalsIgnoreCase This is a nice feature that allows you to lype Lon, LON, lon, lOn or any other combination.

On my android phone the first word I type is always with a capital letter. On my PC a capital is only typed when you push shift at the same time. So this makes that I dont have to think when on my PC or Android Phone.

{      
  digitalWrite(led, LOW);                          
  myBot.sendMessage(msg, "Light is now ON");        
}


The led is set ON because LOW is the ON value for the build-in led. And a message is send back to the Telegram Bot that confirms that the action succeeded.

// generate the message for the sender
String reply;
reply = "Welcome ESP8266 number 1\n" ;
reply += "You can use these commands :\n" ;
reply += "============================\n\n" ;
//reply += msg.sender.username;
reply += ". Mancave Light on = Lon\n";
reply += ". Mancave Light off = Loff\n";
myBot.sendMessage(msg, reply);

This part generates the menu for Telegram Messenger. You can put any text in what you like. I use it to show the commands that my ESP listens to.

The \n code at the end of each line makes each line of the text being printed on a new line.

Back to Telegram Messenger

Make sure the ESP is up and running and connected to your router. Look in the Serial Monitor to see if the connection with Telegram has been made.

Now switch over to your phones screen and open the communication screen with your Bot.



Start with typing /start and you can see the start menu you created in the ESP's program. You can use this command at any time if you forgotten which commands to send to the ESP.

Then just type lon (or Lon or LON etc) and the led on the ESP will go on. Type loff and it will go off again. Each time you will get a message back from the ESP to verify that the command has been issued and accepted by the ESP.

Nice !!!

The answer is YES

Telegram is not only great as a messaging system and a very good replacement for Whatsapp but it also is a good companion for your home automation. Now if I just could get all my friends and relatives to switch over.......

The next steps

I have done a lot with Telegram Messenger lately. The next part in this series shows how you can send sensor readings to Telegram Messenger. Then we have a two way communication: sending commands to the ESP and getting readings from the ESP.

And off course I am going to show you how to send notifications from your ESP to Telegram Messenger. Then we can dump IFTTT.

I'll show you how to test things with the web-app so you do not have to type everything on your phone. Programming the ESP is done on your PC and it is nice to have a screen with Telegram Messenger open on that same PC.

My home automation system Domoticz can send notifications to Telegram Messenger. But I can not send messages from Telegram Messager to Domitcz. I have a fair idea on how to do that. An upcoming story will cover that.

My 3D printer is controlled by Octoprint. I am checking on how to send commands from Octoprint to Telegram. Keep tuned.

That's it for now. Something great to play with !!
Have fun, till next time

Luc Volders


Friday, January 20, 2023

Importing libraries in Wokwi

For an index to all my stories click this text.

Few months ago I was playing with Wokwi. And then I discovered something that even the developers did not know was possible. And things like that always flatters my ego.

For those that are not familiar with Wokwi here is a short description.

Wokwi is a simulator. It simulates Arduino, Raspberry Pi, ESP32 and Raspberry Pi Pico controllers. You can build simulations using the C++ and MicroPython languages. I did a more in depth story on Wokwi earlier on this weblog. You can find that story here: http://lucstechblog.blogspot.com/2022/04/simulate-your-controllers-with-wokwi.html  Wokwi self can be found here: https://wokwi.com/

What I wanted to do is to attach a TM1637 display to a Raspberry Pi Pico and simulate that in Wokwi. The TM1637 display is available in Wokwi but there is no support for MicroPython. Only the Arduino IDE is supported. Bummer !!

Then I had an idea.

I opened a new project in Wokwi. I chose for opening a project with MicroPython on Pi Pico.



With the + sign I added the TM1637 display and attached the wires.

As I wrote in my books Raspberry Pi Pico Simplified and Raspberry Pico W Simplified most MicroPython libraries are just programs.

 

I downloaded the library and in Wokwi I opened a new file and called it tm1637.py and pasted the code from the Library. In the main.py program I put import tm1637 and that's it.



And there you go. Worked like a charm.

Just make sure that you give the new opened file in Wokwi exact the same name as the library has. If you differ the program will not be able to find the library, and generally the library will not work.

You can find the example here:
https://wokwi.com/projects/339373435833549395

There is a program called main.py and that imports tm1637.py which is the library and a separate file. The library is copied from the github page and just pasted into the file.

If you need to work with the TM1637 in Wokwi just copy my project in Wokwi and add your own MicroPython code.

I can not guarantee that this trick will work with any library you find on the internet. Just try it. You can not break anything physically in a simulation................

On the Wokwi channel in Discord I mentioned this to Wokwi's developers. They did not know that this was possible and they said that they would put this into the documentation. And that indeed flatters my ego.

Have fun and be creative !
Till next time.

Luc Volders


Friday, January 13, 2023

Talking Thermometer - talkie part 3

For an index to all my stories click this text.

Having a talking ESP is fun. So in this third story about Talkie I am going to build a talking thermometer.

Talkie is a library for the ESP32 that makes this small wonder-chip talk. Actually the speech synthesises is a lot like the old days with the Apple ][ and Commodore 64 computers. Not as sophisticated as Google Home but a lot of fun to play with. To get it working you need to attach an amplifier with a speaker to one of the ESP32's DAC pins or use an active speaker (speaker with build-in amplifier). I discused this earlier in this story: http://lucstechblog.blogspot.com/2022/11/talkie-part-1-esp32-speech-synthesiser.html

To make a talking thermometer you will need a Dallas DS18B20 thermometer chip and a pull-up resistor.

Breadboard setup.

Here is the complete breadboard setup for making a talking Thermometer.

The basic setup is the same as the one I used in the first story about Talkie. I just added a Dallas DS18B20 thermometer chip and a 4.7K pull-up resistor.



As you can see a button is attached to pin 13 (D13) of the ESP32 Devkit board and the amplifier is attached to pin 25 (D25) which is the build-in DAC. You do not need to use a DAC but then you need to attach pin 25 to an active speaker. That is a speaker with a build-in amplifier just like the speakers you are using with your PC.

The Dallas DS18B20 is attached with a 4.7K pull-up resistor to pin 23 (D23). That's all.

Talking Thermometer program.

The program is thus written that the ESP32 speaks the actual temperature when you press the button.

The first story about Talkie discribes the framework for getting your ESP32 talking. So re-read that to know where to get the libraries etc. You can find that story here: http://lucstechblog.blogspot.com/2022/11/talkie-part-1-esp32-speech-synthesiser.html

I will here highlite some parts of the program. The complete program is at the bottom of this story.

#include <Arduino.h>

#include <OneWire.h>
#include <DallasTemperature.h>

#define dallasiopin 23
OneWire oneWire(dallasiopin);
DallasTemperature sensors(&oneWire);

First the necessary libraries are loaded and the Dallas DS18B20 is attached to pin D23.

int decnumbers;
int temp;
int button = 13;

Some helper variables are defined.

#include <Talkie.h>
Talkie voice;

The Talkie library is loaded and initiated.

const uint8_t spTHE[]       PROGMEM = {0x08,0xE8,0x3E,0x55,0x01,0xC3,0x86,0x27,0xAF,0x72,0x0D,0x4D,0x97,0xD5,0xBC,0x64,0x3C,0xF2,0x5C,0x51,0xF1,0x93,0x36,0x8F,0x4F,0x59,0x2A,0x42,0x7A,0x32,0xC3,0x64,0xFF,0x3F};
/*
a lot more lines
*/
const uint8_t spTEMPERATURE[] PROGMEM = {0x0A,0x38,0xDE,0x32,0x00,0x2F,0xBB,0x37,0xBF,0x59,0x57,0x76,0x6F,0xB8,0xB2,0x16,0xCA,0xC4,0x75,0xCB,0x4A,0xAB,0x4A,0xF3,0xF6,0xCD,0x2B,0x2D,0x66,0x94,0xD7,0xBA,0xB4,0x34,0x79,0x93,0x52,0x97,0x16,0xB2,0x28,0x5B,0x4D,0x43,0x36,0x10,0x20,0xAB,0xB2,0x52,0xC4,0x26,0x9A,0x26,0x49,0x47,0x9B,0x1B,0xA5,0xA6,0x74,0x5D,0x43,0xF1,0x65,0x14,0x91,0xAD,0xED,0xB5,0x99,0xB1,0x69,0x1A,0x20,0xC0,0x0A,0x84,0x0E,0xD8,0xD3,0x23,0x01,0xA3,0x4C,0x1A,0xA0,0xF5,0xC9,0xD6,0x95,0xE0,0x24,0x1D,0xD9,0x5A,0x9B,0x9C,0x8B,0xAE,0x79,0x2B,0x43,0xAC,0xA6,0xDE,0x9C,0x35,0x9D,0xB1,0xB3,0x47,0x52,0xD7,0x74,0xC6,0x2E,0x52,0xA1,0x5E,0xC2,0x1D,0x3B,0xEB,0xB8,0x65,0x0D,0x5F,0xAA,0x26,0xB6,0xE2,0x35,0x7C,0xA9,0x2A,0xFB,0x6A,0x16,0xF7,0xE7,0x9E,0x4C,0xEB,0xD9,0xFE,0x1F};

These are the lines where the speech is defined.

All the speech commands can be found in the, in the library included, examples. But to get the right words fro your own purposes you need to scroll through the examples and copy the lines of the words you need into your own program. That is what I did here.

void decimals()
{
switch (decnumbers)
  {
  case 0:
  break;
  case 1:
    voice.say(spONE);
    break;
  case 2:
    voice.say(spTWO);
    break;
\*
MANY MORE LINES
*/
  case 50:
    voice.say(spFIFTY);
    break;
 
  default:
    voice.say(spERROR);
    voice.say(spGETTING);
    voice.say(spTEMPERATURE);
    break;
  }
}

In this routine we check fot the number and with SWITCH-CASE statements we select what number Talkie has to speak out.

void setup()
{
  Serial.begin(115200);
  Serial.print("Starting the program");

  pinMode(25, OUTPUT);
  digitalWrite(25, HIGH);
  delay(10);
 
  sensors.begin();

  pinMode(button, INPUT);
}

In the setup() we activate the Serial-Monitor so we can see if everything works fine. Pin 25 is defined as output, and that is where the amplifier is attached. The Dallas library is activated and the button pin is defined as INPUT.

As usual the magic happens in the loop()

  if (digitalRead(button) == 0)

First we test wether the button is pressed. If so the routine is activated, This way the program is not continually speaking which is annoying in the long run.

    Serial.print("Requesting temperatures...");
    sensors.requestTemperatures();
    Serial.println("DONE");
 
    // When we got the temperatures, we can print it here.
    // Use the temperature from the first sensor only.
    Serial.print("Temperature for the device 1 (index 0) is: ");
    Serial.println(sensors.getTempCByIndex(0)); 

Next step gets the actual temperature and prints it in the Serial Monitor.

    temp = (sensors.getTempCByIndex(0));
    if (temp <= 0)
      {
      voice.say(spBELOW);
      voice.say(spZERO);
      }
    if (temp > 0)
      {
      decnumbers = temp;
      decimals();
      voice.say(spDEGREES);
      voice.say(spPAUSE1);
      }

First the temperature is fetched again.

If the temperature is below zero Talkie notifies us by saying: "Below Zero"
No further action is taken.

If the temperature is above zero it is put in the decnumbers variable and the decimals() routine is called which speaks out the actual temperature.

That is all !!!

This is really fun to play with and always a good show when you have visitors.

Expansion

I am thinking about making a permanent setup with two buttons. The first button makes the ESP32 say the time and the second button gives the temperature.
I bet you can come up with a lot of other fun projects that incorporate speech.

Till next time
Have fun

Luc Volders



// ==============================================
// ESP32 Talking Thermometer
// Using Talkie library
// Program by Luc Volders
// Amplifier for speaker on ESP32 pin D26
// ==============================================

#include <Arduino.h>

#include <OneWire.h>
#include <DallasTemperature.h>

#define dallasiopin 23
OneWire oneWire(dallasiopin);
DallasTemperature sensors(&oneWire);

int decnumbers;
int temp;
int button = 13;

#include <Talkie.h>
Talkie voice;

const uint8_t spTHE[]       PROGMEM = {0x08,0xE8,0x3E,0x55,0x01,0xC3,0x86,0x27,0xAF,0x72,0x0D,0x4D,0x97,0xD5,0xBC,0x64,0x3C,0xF2,0x5C,0x51,0xF1,0x93,0x36,0x8F,0x4F,0x59,0x2A,0x42,0x7A,0x32,0xC3,0x64,0xFF,0x3F};
const uint8_t spIS[]        PROGMEM = {0x21,0x18,0x96,0x38,0xB7,0x14,0x8D,0x60,0x3A,0xA6,0xE8,0x51,0xB4,0xDC,0x2E,0x48,0x7B,0x5A,0xF1,0x70,0x1B,0xA3,0xEC,0x09,0xC6,0xCB,0xEB,0x92,0x3D,0xA7,0x69,0x1F,0xAF,0x71,0x89,0x9C,0xA2,0xB3,0xFC,0xCA,0x35,0x72,0x9A,0xD1,0xF0,0xAB,0x12,0xB3,0x2B,0xC6,0xCD,0x4F,0xCC,0x32,0x26,0x19,0x07,0xDF,0x0B,0x8F,0xB8,0xA4,0xED,0x7C,0xCF,0x23,0x62,0x8B,0x8E,0xF1,0x23,0x0A,0x8B,0x6E,0xCB,0xCE,0xEF,0x54,0x44,0x3C,0xDC,0x08,0x60,0x0B,0x37,0x01,0x1C,0x53,0x26,0x80,0x15,0x4E,0x14,0xB0,0x54,0x2B,0x02,0xA4,0x69,0xFF,0x7F};
const uint8_t spONE[]       PROGMEM = {0xCC,0x67,0x75,0x42,0x59,0x5D,0x3A,0x4F,0x9D,0x36,0x63,0xB7,0x59,0xDC,0x30,0x5B,0x5C,0x23,0x61,0xF3,0xE2,0x1C,0xF1,0xF0,0x98,0xC3,0x4B,0x7D,0x39,0xCA,0x1D,0x2C,0x2F,0xB7,0x15,0xEF,0x70,0x79,0xBC,0xD2,0x46,0x7C,0x52,0xE5,0xF1,0x4A,0x6A,0xB3,0x71,0x47,0xC3,0x2D,0x39,0x34,0x4B,0x23,0x35,0xB7,0x7A,0x55,0x33,0x8F,0x59,0xDC,0xA2,0x44,0xB5,0xBC,0x66,0x72,0x8B,0x64,0xF5,0xF6,0x98,0xC1,0x4D,0x42,0xD4,0x27,0x62,0x38,0x2F,0x4A,0xB6,0x9C,0x88,0x68,0xBC,0xA6,0x95,0xF8,0x5C,0xA1,0x09,0x86,0x77,0x91,0x11,0x5B,0xFF,0x0F};
const uint8_t spTWO[]       PROGMEM = {0x0E,0x38,0x6E,0x25,0x00,0xA3,0x0D,0x3A,0xA0,0x37,0xC5,0xA0,0x05,0x9E,0x56,0x35,0x86,0xAA,0x5E,0x8C,0xA4,0x82,0xB2,0xD7,0x74,0x31,0x22,0x69,0xAD,0x1C,0xD3,0xC1,0xD0,0xFA,0x28,0x2B,0x2D,0x47,0xC3,0x1B,0xC2,0xC4,0xAE,0xC6,0xCD,0x9C,0x48,0x53,0x9A,0xFF,0x0F};
const uint8_t spTHREE[]     PROGMEM = {0x02,0xD8,0x2E,0x9C,0x01,0xDB,0xA6,0x33,0x60,0xFB,0x30,0x01,0xEC,0x20,0x12,0x8C,0xE4,0xD8,0xCA,0x32,0x96,0x73,0x63,0x41,0x39,0x89,0x98,0xC1,0x4D,0x0D,0xED,0xB0,0x2A,0x05,0x37,0x0F,0xB4,0xA5,0xAE,0x5C,0xDC,0x36,0xD0,0x83,0x2F,0x4A,0x71,0x7B,0x03,0xF7,0x38,0x59,0xCD,0xED,0x1E,0xB4,0x6B,0x14,0x35,0xB7,0x6B,0x94,0x99,0x91,0xD5,0xDC,0x26,0x48,0x77,0x4B,0x66,0x71,0x1B,0x21,0xDB,0x2D,0x8A,0xC9,0x6D,0x88,0xFC,0x26,0x28,0x3A,0xB7,0x21,0xF4,0x1F,0xA3,0x65,0xBC,0x02,0x38,0xBB,0x3D,0x8E,0xF0,0x2B,0xE2,0x08,0xB7,0x34,0xFF,0x0F};
const uint8_t spFOUR[]      PROGMEM = {0x0C,0x18,0xB6,0x9A,0x01,0xC3,0x75,0x09,0x60,0xD8,0x0E,0x09,0x30,0xA0,0x9B,0xB6,0xA0,0xBB,0xB0,0xAA,0x16,0x4E,0x82,0xEB,0xEA,0xA9,0xFA,0x59,0x49,0x9E,0x59,0x23,0x9A,0x27,0x3B,0x78,0x66,0xAE,0x4A,0x9C,0x9C,0xE0,0x99,0xD3,0x2A,0xBD,0x72,0x92,0xEF,0xE6,0x88,0xE4,0x45,0x4D,0x7E,0x98,0x2D,0x62,0x67,0x37,0xF9,0xA1,0x37,0xA7,0x6C,0x94,0xE4,0xC7,0x1E,0xDC,0x3C,0xA5,0x83,0x1F,0x8B,0xEB,0x52,0x0E,0x0E,0x7E,0x2E,0x4E,0xC7,0x31,0xD2,0x79,0xA5,0x3A,0x0D,0xD9,0xC4,0xFF,0x07};
const uint8_t spFIVE[]      PROGMEM = {0x02,0xE8,0x3E,0x8C,0x01,0xDD,0x65,0x08,0x60,0x98,0x4C,0x06,0x34,0x93,0xCE,0x80,0xE6,0xDA,0x9A,0x14,0x6B,0xAA,0x47,0xD1,0x5E,0x56,0xAA,0x6D,0x56,0xCD,0x78,0xD9,0xA9,0x1C,0x67,0x05,0x83,0xE1,0xA4,0xBA,0x38,0xEE,0x16,0x86,0x9B,0xFA,0x60,0x87,0x5B,0x18,0x6E,0xEE,0x8B,0x1D,0x6E,0x61,0xB9,0x69,0x36,0x65,0xBA,0x8D,0xE5,0xE5,0x3E,0x1C,0xE9,0x0E,0x96,0x9B,0x5B,0xAB,0x95,0x2B,0x58,0x6E,0xCE,0xE5,0x3A,0x6A,0xF3,0xB8,0x35,0x84,0x7B,0x05,0xA3,0xE3,0x36,0xEF,0x92,0x19,0xB4,0x86,0xDB,0xB4,0x69,0xB4,0xD1,0x2A,0x4E,0x65,0x9A,0x99,0xCE,0x28,0xD9,0x85,0x71,0x4C,0x18,0x6D,0x67,0x47,0xC6,0x5E,0x53,0x4A,0x9C,0xB5,0xE2,0x85,0x45,0x26,0xFE,0x7F};
const uint8_t spSIX[]       PROGMEM = {0x0E,0xD8,0xAE,0xDD,0x03,0x0E,0x38,0xA6,0xD2,0x01,0xD3,0xB4,0x2C,0xAD,0x6A,0x35,0x9D,0xB1,0x7D,0xDC,0xEE,0xC4,0x65,0xD7,0xF1,0x72,0x47,0x24,0xB3,0x19,0xD9,0xD9,0x05,0x70,0x40,0x49,0xEA,0x02,0x98,0xBE,0x42,0x01,0xDF,0xA4,0x69,0x40,0x00,0xDF,0x95,0xFC,0x3F};
const uint8_t spSEVEN[]     PROGMEM = {0x02,0xB8,0x3A,0x8C,0x01,0xDF,0xA4,0x73,0x40,0x01,0x47,0xB9,0x2F,0x33,0x3B,0x73,0x5F,0x53,0x7C,0xEC,0x9A,0xC5,0x63,0xD5,0xD1,0x75,0xAE,0x5B,0xFC,0x64,0x5C,0x35,0x87,0x91,0xF1,0x83,0x36,0xB5,0x68,0x55,0xC5,0x6F,0xDA,0x45,0x2D,0x1C,0x2D,0xB7,0x38,0x37,0x9F,0x60,0x3C,0xBC,0x9A,0x85,0xA3,0x25,0x66,0xF7,0x8A,0x57,0x1C,0xA9,0x67,0x56,0xCA,0x5E,0xF0,0xB2,0x16,0xB2,0xF1,0x89,0xCE,0x8B,0x92,0x25,0xC7,0x2B,0x33,0xCF,0x48,0xB1,0x99,0xB4,0xF3,0xFF};
const uint8_t spEIGHT[]     PROGMEM = {0xC3,0x6C,0x86,0xB3,0x27,0x6D,0x0F,0xA7,0x48,0x99,0x4E,0x55,0x3C,0xBC,0x22,0x65,0x36,0x4D,0xD1,0xF0,0x32,0xD3,0xBE,0x34,0xDA,0xC3,0xEB,0x82,0xE2,0xDA,0x65,0x35,0xAF,0x31,0xF2,0x6B,0x97,0x95,0xBC,0x86,0xD8,0x6F,0x82,0xA6,0x73,0x0B,0xC6,0x9E,0x72,0x99,0xCC,0xCB,0x02,0xAD,0x3C,0x9A,0x10,0x60,0xAB,0x62,0x05,0x2C,0x37,0x84,0x00,0xA9,0x73,0x00,0x00,0xFE,0x1F};
const uint8_t spNINE[]      PROGMEM = {0xCC,0xA1,0x26,0xBB,0x83,0x93,0x18,0xCF,0x4A,0xAD,0x2E,0x31,0xED,0x3C,0xA7,0x24,0x26,0xC3,0x54,0xF1,0x92,0x64,0x8B,0x8A,0x98,0xCB,0x2B,0x2E,0x34,0x53,0x2D,0x0E,0x2F,0x57,0xB3,0x0C,0x0D,0x3C,0xBC,0x3C,0x4C,0x4B,0xCA,0xF4,0xF0,0x72,0x0F,0x6E,0x49,0x53,0xCD,0xCB,0x53,0x2D,0x35,0x4D,0x0F,0x2F,0x0F,0xD7,0x0C,0x0D,0x3D,0xBC,0xDC,0x4D,0xD3,0xDD,0xC2,0xF0,0x72,0x52,0x4F,0x57,0x9B,0xC3,0xAB,0x89,0xBD,0x42,0x2D,0x0F,0xAF,0x5A,0xD1,0x71,0x91,0x55,0xBC,0x2C,0xC5,0x3B,0xD8,0x65,0xF2,0x82,0x94,0x18,0x4E,0x3B,0xC1,0x73,0x42,0x32,0x33,0x15,0x45,0x4F,0x79,0x52,0x6A,0x55,0xA6,0xA3,0xFF,0x07};
const uint8_t spTEN[]       PROGMEM = {0x0E,0xD8,0xB1,0xDD,0x01,0x3D,0xA8,0x24,0x7B,0x04,0x27,0x76,0x77,0xDC,0xEC,0xC2,0xC5,0x23,0x84,0xCD,0x72,0x9A,0x51,0xF7,0x62,0x45,0xC7,0xEB,0x4E,0x35,0x4A,0x14,0x2D,0xBF,0x45,0xB6,0x0A,0x75,0xB8,0xFC,0x16,0xD9,0x2A,0xD9,0xD6,0x0A,0x5A,0x10,0xCD,0xA2,0x48,0x23,0xA8,0x81,0x35,0x4B,0x2C,0xA7,0x20,0x69,0x0A,0xAF,0xB6,0x15,0x82,0xA4,0x29,0x3C,0xC7,0x52,0x08,0xA2,0x22,0xCF,0x68,0x4B,0x2E,0xF0,0x8A,0xBD,0xA3,0x2C,0xAB,0x40,0x1B,0xCE,0xAA,0xB2,0x6C,0x82,0x40,0x4D,0x7D,0xC2,0x89,0x88,0x8A,0x61,0xCC,0x74,0xD5,0xFF,0x0F};
const uint8_t spELEVEN[]    PROGMEM = {0xC3,0xCD,0x76,0x5C,0xAE,0x14,0x0F,0x37,0x9B,0x71,0xDE,0x92,0x55,0xBC,0x2C,0x27,0x70,0xD3,0x76,0xF0,0x83,0x5E,0xA3,0x5E,0x5A,0xC1,0xF7,0x61,0x58,0xA7,0x19,0x35,0x3F,0x99,0x31,0xDE,0x52,0x74,0xFC,0xA2,0x26,0x64,0x4B,0xD1,0xF1,0xAB,0xAE,0xD0,0x2D,0xC5,0xC7,0x2F,0x36,0xDD,0x27,0x15,0x0F,0x3F,0xD9,0x08,0x9F,0x62,0xE4,0xC2,0x2C,0xD4,0xD8,0xD3,0x89,0x0B,0x1B,0x57,0x11,0x0B,0x3B,0xC5,0xCF,0xD6,0xCC,0xC6,0x64,0x35,0xAF,0x18,0x73,0x1F,0xA1,0x5D,0xBC,0x62,0x45,0xB3,0x45,0x51,0xF0,0xA2,0x62,0xAB,0x4A,0x5B,0xC9,0x4B,0x8A,0x2D,0xB3,0x6C,0x06,0x2F,0x29,0xB2,0xAC,0x8A,0x18,0xBC,0x28,0xD9,0xAA,0xD2,0x92,0xF1,0xBC,0xE0,0x98,0x8C,0x48,0xCC,0x17,0x52,0xA3,0x27,0x6D,0x93,0xD0,0x4B,0x8E,0x0E,0x77,0x02,0x00,0xFF,0x0F};
const uint8_t spTWELVE[]    PROGMEM = {0x06,0x28,0x46,0xD3,0x01,0x25,0x06,0x13,0x20,0xBA,0x70,0x70,0xB6,0x79,0xCA,0x36,0xAE,0x28,0x38,0xE1,0x29,0xC5,0x35,0xA3,0xE6,0xC4,0x16,0x6A,0x53,0x8C,0x97,0x9B,0x72,0x86,0x4F,0x28,0x1A,0x6E,0x0A,0x59,0x36,0xAE,0x68,0xF8,0x29,0x67,0xFA,0x06,0xA3,0x16,0xC4,0x96,0xE6,0x53,0xAC,0x5A,0x9C,0x56,0x72,0x77,0x31,0x4E,0x49,0x5C,0x8D,0x5B,0x29,0x3B,0x24,0x61,0x1E,0x6C,0x9B,0x6C,0x97,0xF8,0xA7,0x34,0x19,0x92,0x4C,0x62,0x9E,0x72,0x65,0x58,0x12,0xB1,0x7E,0x09,0xD5,0x2E,0x53,0xC5,0xBA,0x36,0x6B,0xB9,0x2D,0x17,0x05,0xEE,0x9A,0x6E,0x8E,0x05,0x50,0x6C,0x19,0x07,0x18,0x50,0xBD,0x3B,0x01,0x92,0x08,0x41,0x40,0x10,0xA6,0xFF,0x0F};
const uint8_t spTHIRTEEN[]  PROGMEM = {0x08,0xE8,0x2C,0x15,0x01,0x43,0x07,0x13,0xE0,0x98,0xB4,0xA6,0x35,0xA9,0x1E,0xDE,0x56,0x8E,0x53,0x9C,0x7A,0xE7,0xCA,0x5E,0x76,0x8D,0x94,0xE5,0x2B,0xAB,0xD9,0xB5,0x62,0xA4,0x9C,0xE4,0xE6,0xB4,0x41,0x1E,0x7C,0xB6,0x93,0xD7,0x16,0x99,0x5A,0xCD,0x61,0x76,0x55,0xC2,0x91,0x61,0x1B,0xC0,0x01,0x5D,0x85,0x05,0xE0,0x68,0x51,0x07,0x1C,0xA9,0x64,0x80,0x1D,0x4C,0x9C,0x95,0x88,0xD4,0x04,0x3B,0x4D,0x4E,0x21,0x5C,0x93,0xA8,0x26,0xB9,0x05,0x4B,0x6E,0xA0,0xE2,0xE4,0x57,0xC2,0xB9,0xC1,0xB2,0x93,0x5F,0x09,0xD7,0x24,0xCB,0x4E,0x41,0x25,0x54,0x1D,0x62,0x3B,0x05,0x8D,0x52,0x57,0xAA,0xAD,0x10,0x24,0x26,0xE3,0xE1,0x36,0x5D,0x10,0x85,0xB4,0x97,0x85,0x72,0x41,0x14,0x52,0x5E,0x1A,0xCA,0xF9,0x91,0x6B,0x7A,0x5B,0xC4,0xE0,0x17,0x2D,0x54,0x1D,0x92,0x8C,0x1F,0x25,0x4B,0x8F,0xB2,0x16,0x41,0xA1,0x4A,0x3E,0xE6,0xFA,0xFF,0x01};
const uint8_t spFOURTEEN[]  PROGMEM = {0x0C,0x58,0xAE,0x5C,0x01,0xD9,0x87,0x07,0x51,0xB7,0x25,0xB3,0x8A,0x15,0x2C,0xF7,0x1C,0x35,0x87,0x4D,0xB2,0xDD,0x53,0xCE,0x28,0x2B,0xC9,0x0E,0x97,0x2D,0xBD,0x2A,0x17,0x27,0x76,0x8E,0xD2,0x9A,0x6C,0x80,0x94,0x71,0x00,0x00,0x02,0xB0,0x58,0x58,0x00,0x9E,0x0B,0x0A,0xC0,0xB2,0xCE,0xC1,0xC8,0x98,0x7A,0x52,0x95,0x24,0x2B,0x11,0xED,0x36,0xD4,0x92,0xDC,0x4C,0xB5,0xC7,0xC8,0x53,0xF1,0x2A,0xE5,0x1A,0x17,0x55,0xC5,0xAF,0x94,0xBB,0xCD,0x1C,0x26,0xBF,0x52,0x9A,0x72,0x53,0x98,0xFC,0xC2,0x68,0xD2,0x4D,0x61,0xF0,0xA3,0x90,0xB6,0xD6,0x50,0xC1,0x8F,0x42,0xDA,0x4A,0x43,0x39,0x3F,0x48,0x2D,0x6B,0x33,0xF9,0xFF};
const uint8_t spFIFTEEN[]   PROGMEM = {0x08,0xE8,0x2A,0x0D,0x01,0xDD,0xBA,0x31,0x60,0x6A,0xF7,0xA0,0xAE,0x54,0xAA,0x5A,0x76,0x97,0xD9,0x34,0x69,0xEF,0x32,0x1E,0x66,0xE1,0xE2,0xB3,0x43,0xA9,0x18,0x55,0x92,0x4E,0x37,0x2D,0x67,0x6F,0xDF,0xA2,0x5A,0xB6,0x04,0x30,0x55,0xA8,0x00,0x86,0x09,0xE7,0x00,0x01,0x16,0x17,0x05,0x70,0x40,0x57,0xE5,0x01,0xF8,0x21,0x34,0x00,0xD3,0x19,0x33,0x80,0x89,0x9A,0x62,0x34,0x4C,0xD5,0x49,0xAE,0x8B,0x53,0x09,0xF7,0x26,0xD9,0x6A,0x7E,0x23,0x5C,0x13,0x12,0xB3,0x04,0x9D,0x50,0x4F,0xB1,0xAD,0x14,0x15,0xC2,0xD3,0xA1,0xB6,0x42,0x94,0xA8,0x8C,0x87,0xDB,0x74,0xB1,0x70,0x59,0xE1,0x2E,0xC9,0xC5,0x81,0x5B,0x55,0xA4,0x4C,0x17,0x47,0xC1,0x6D,0xE3,0x81,0x53,0x9C,0x84,0x6A,0x46,0xD9,0x4C,0x51,0x31,0x42,0xD9,0x66,0xC9,0x44,0x85,0x29,0x6A,0x9B,0xAD,0xFF,0x07};
const uint8_t spSIXTEEN[]   PROGMEM = {0x0A,0x58,0x5A,0x5D,0x00,0x93,0x97,0x0B,0x60,0xA9,0x48,0x05,0x0C,0x15,0xAE,0x80,0xAD,0x3D,0x14,0x30,0x7D,0xD9,0x50,0x92,0x92,0xAC,0x0D,0xC5,0xCD,0x2A,0x82,0xAA,0x3B,0x98,0x04,0xB3,0x4A,0xC8,0x9A,0x90,0x05,0x09,0x68,0x51,0xD4,0x01,0x23,0x9F,0x1A,0x60,0xA9,0x12,0x03,0xDC,0x50,0x81,0x80,0x22,0xDC,0x20,0x00,0xCB,0x06,0x3A,0x60,0x16,0xE3,0x64,0x64,0x42,0xDD,0xCD,0x6A,0x8A,0x5D,0x28,0x75,0x07,0xA9,0x2A,0x5E,0x65,0x34,0xED,0x64,0xBB,0xF8,0x85,0xF2,0x94,0x8B,0xAD,0xE4,0x37,0x4A,0x5B,0x21,0xB6,0x52,0x50,0x19,0xAD,0xA7,0xD8,0x4A,0x41,0x14,0xDA,0x5E,0x12,0x3A,0x04,0x91,0x4B,0x7B,0x69,0xA8,0x10,0x24,0x2E,0xE5,0xA3,0x81,0x52,0x90,0x94,0x5A,0x55,0x98,0x32,0x41,0x50,0xCC,0x93,0x2E,0x47,0x85,0x89,0x1B,0x5B,0x5A,0x62,0x04,0x44,0xE3,0x02,0x80,0x80,0x64,0xDD,0xFF,0x1F};
const uint8_t spSEVENTEEN[] PROGMEM = {0x02,0x98,0x3A,0x42,0x00,0x5B,0xA6,0x09,0x60,0xDB,0x52,0x06,0x1C,0x93,0x29,0x80,0xA9,0x52,0x87,0x9A,0xB5,0x99,0x4F,0xC8,0x3E,0x46,0xD6,0x5E,0x7E,0x66,0xFB,0x98,0xC5,0x5A,0xC6,0x9A,0x9C,0x63,0x15,0x6B,0x11,0x13,0x8A,0x9C,0x97,0xB9,0x9A,0x5A,0x39,0x71,0xEE,0xD2,0x29,0xC2,0xA6,0xB8,0x58,0x59,0x99,0x56,0x14,0xA3,0xE1,0x26,0x19,0x19,0xE3,0x8C,0x93,0x17,0xB4,0x46,0xB5,0x88,0x71,0x9E,0x97,0x9E,0xB1,0x2C,0xC5,0xF8,0x56,0xC4,0x58,0xA3,0x1C,0xE1,0x33,0x9D,0x13,0x41,0x8A,0x43,0x58,0xAD,0x95,0xA9,0xDB,0x36,0xC0,0xD1,0xC9,0x0E,0x58,0x4E,0x45,0x01,0x23,0xA9,0x04,0x37,0x13,0xAE,0x4D,0x65,0x52,0x82,0xCA,0xA9,0x37,0x99,0x4D,0x89,0xBA,0xC0,0xBC,0x14,0x36,0x25,0xEA,0x1C,0x73,0x52,0x1D,0x97,0xB8,0x33,0xAC,0x0E,0x75,0x9C,0xE2,0xCE,0xB0,0xDA,0xC3,0x51,0x4A,0x1A,0xA5,0xCA,0x70,0x5B,0x21,0xCE,0x4C,0x26,0xD2,0x6C,0xBA,0x38,0x71,0x2E,0x1F,0x2D,0xED,0xE2,0x24,0xB8,0xBC,0x3D,0x52,0x88,0xAB,0x50,0x8E,0xA8,0x48,0x22,0x4E,0x42,0xA0,0x26,0x55,0xFD,0x3F};
const uint8_t spEIGHTEEN[]  PROGMEM = {0x2E,0x9C,0xD1,0x4D,0x54,0xEC,0x2C,0xBF,0x1B,0x8A,0x99,0x70,0x7C,0xFC,0x2E,0x29,0x6F,0x52,0xF6,0xF1,0xBA,0x20,0xBF,0x36,0xD9,0xCD,0xED,0x0C,0xF3,0x27,0x64,0x17,0x73,0x2B,0xA2,0x99,0x90,0x65,0xEC,0xED,0x40,0x73,0x32,0x12,0xB1,0xAF,0x30,0x35,0x0B,0xC7,0x00,0xE0,0x80,0xAE,0xDD,0x1C,0x70,0x43,0xAA,0x03,0x86,0x51,0x36,0xC0,0x30,0x64,0xCE,0x4C,0x98,0xFB,0x5C,0x65,0x07,0xAF,0x10,0xEA,0x0B,0x66,0x1B,0xFC,0x46,0xA8,0x3E,0x09,0x4D,0x08,0x2A,0xA6,0x3E,0x67,0x36,0x21,0x2A,0x98,0x67,0x9D,0x15,0xA7,0xA8,0x60,0xEE,0xB6,0x94,0x99,0xA2,0x4A,0x78,0x22,0xC2,0xA6,0x8B,0x8C,0x8E,0xCC,0x4C,0x8A,0x2E,0x8A,0x4C,0xD3,0x57,0x03,0x87,0x28,0x71,0x09,0x1F,0x2B,0xE4,0xA2,0xC4,0xC5,0x6D,0xAD,0x54,0x88,0xB2,0x63,0xC9,0xF2,0x50,0x2E,0x8A,0x4A,0x38,0x4A,0xEC,0x88,0x28,0x08,0xE3,0x28,0x49,0xF3,0xFF};
const uint8_t spNINETEEN[]  PROGMEM = {0xC2,0xEA,0x8A,0x95,0x2B,0x6A,0x05,0x3F,0x71,0x71,0x5F,0x0D,0x12,0xFC,0x28,0x25,0x62,0x35,0xF0,0xF0,0xB3,0x48,0x1E,0x0F,0xC9,0xCB,0x2F,0x45,0x7C,0x2C,0x25,0x1F,0xBF,0x14,0xB3,0x2C,0xB5,0x75,0xFC,0x5A,0x5C,0xA3,0x5D,0xE1,0xF1,0x7A,0x76,0xB3,0x4E,0x45,0xC7,0xED,0x96,0x23,0x3B,0x18,0x37,0x7B,0x18,0xCC,0x09,0x51,0x13,0x4C,0xAB,0x6C,0x4C,0x4B,0x96,0xD2,0x49,0xAA,0x36,0x0B,0xC5,0xC2,0x20,0x26,0x27,0x35,0x63,0x09,0x3D,0x30,0x8B,0xF0,0x48,0x5C,0xCA,0x61,0xDD,0xCB,0xCD,0x91,0x03,0x8E,0x4B,0x76,0xC0,0xCC,0x4D,0x06,0x98,0x31,0x31,0x98,0x99,0x70,0x6D,0x2A,0xA3,0xE4,0x16,0xCA,0xBD,0xCE,0x5C,0x92,0x57,0x28,0xCF,0x09,0x69,0x2E,0x7E,0xA5,0x3C,0x63,0xA2,0x30,0x05,0x95,0xD2,0x74,0x98,0xCD,0x14,0x54,0xCA,0x53,0xA9,0x96,0x52,0x50,0x28,0x6F,0xBA,0xCB,0x0C,0x41,0x50,0xDE,0x65,0x2E,0xD3,0x05,0x89,0x4B,0x7B,0x6B,0x20,0x17,0x44,0xAE,0xED,0x23,0x81,0x52,0x90,0x85,0x73,0x57,0xD0,0x72,0x41,0xB1,0x02,0xDE,0x2E,0xDB,0x04,0x89,0x05,0x79,0xBB,0x62,0xE5,0x76,0x11,0xCA,0x61,0x0E,0xFF,0x1F};
const uint8_t spTWENTY[]    PROGMEM = {0x01,0x98,0xD1,0xC2,0x00,0xCD,0xA4,0x32,0x20,0x79,0x13,0x04,0x28,0xE7,0x92,0xDC,0x70,0xCC,0x5D,0xDB,0x76,0xF3,0xD2,0x32,0x0B,0x0B,0x5B,0xC3,0x2B,0xCD,0xD4,0xDD,0x23,0x35,0xAF,0x44,0xE1,0xF0,0xB0,0x6D,0x3C,0xA9,0xAD,0x3D,0x35,0x0E,0xF1,0x0C,0x8B,0x28,0xF7,0x34,0x01,0x68,0x22,0xCD,0x00,0xC7,0xA4,0x04,0xBB,0x32,0xD6,0xAC,0x56,0x9C,0xDC,0xCA,0x28,0x66,0x53,0x51,0x70,0x2B,0xA5,0xBC,0x0D,0x9A,0xC1,0xEB,0x14,0x73,0x37,0x29,0x19,0xAF,0x33,0x8C,0x3B,0xA7,0x24,0xBC,0x42,0xB0,0xB7,0x59,0x09,0x09,0x3C,0x96,0xE9,0xF4,0x58,0xFF,0x0F};
const uint8_t spTHIRTY[]    PROGMEM = {0x08,0x98,0xD6,0x15,0x01,0x43,0xBB,0x0A,0x20,0x1B,0x8B,0xE5,0x16,0xA3,0x1E,0xB6,0xB6,0x96,0x97,0x3C,0x57,0xD4,0x2A,0x5E,0x7E,0x4E,0xD8,0xE1,0x6B,0x7B,0xF8,0x39,0x63,0x0D,0x9F,0x95,0xE1,0xE7,0x4C,0x76,0xBC,0x91,0x5B,0x90,0x13,0xC6,0x68,0x57,0x4E,0x41,0x8B,0x10,0x5E,0x1D,0xA9,0x44,0xD3,0xBA,0x47,0xB8,0xDD,0xE4,0x35,0x86,0x11,0x93,0x94,0x92,0x5F,0x29,0xC7,0x4C,0x30,0x0C,0x41,0xC5,0x1C,0x3B,0x2E,0xD3,0x05,0x15,0x53,0x6C,0x07,0x4D,0x15,0x14,0x8C,0xB5,0xC9,0x6A,0x44,0x90,0x10,0x4E,0x9A,0xB6,0x21,0x81,0x23,0x3A,0x91,0x91,0xE8,0xFF,0x01};
const uint8_t spFOURTY[]    PROGMEM = {0x04,0x18,0xB6,0x4C,0x00,0xC3,0x56,0x30,0xA0,0xE8,0xF4,0xA0,0x98,0x99,0x62,0x91,0xAE,0x83,0x6B,0x77,0x89,0x78,0x3B,0x09,0xAE,0xBD,0xA6,0x1E,0x63,0x3B,0x79,0x7E,0x71,0x5A,0x8F,0x95,0xE6,0xA5,0x4A,0x69,0xB9,0x4E,0x8A,0x5F,0x12,0x56,0xE4,0x58,0x69,0xE1,0x36,0xA1,0x69,0x2E,0x2B,0xF9,0x95,0x93,0x55,0x17,0xED,0xE4,0x37,0xC6,0xBA,0x93,0xB2,0x92,0xDF,0x19,0xD9,0x6E,0xC8,0x0A,0xFE,0x60,0xE8,0x37,0x21,0xC9,0xF9,0x8D,0x61,0x5F,0x32,0x13,0xE7,0x17,0x4C,0xD3,0xC6,0xB1,0x94,0x97,0x10,0x8F,0x8B,0xAD,0x11,0x7E,0xA1,0x9A,0x26,0x92,0xF6,0xFF,0x01};
const uint8_t spFIFTY[]     PROGMEM = {0x08,0xE8,0x2E,0x84,0x00,0x23,0x84,0x13,0x60,0x38,0x95,0xA5,0x0F,0xCF,0xE2,0x79,0x8A,0x8F,0x37,0x02,0xB3,0xD5,0x2A,0x6E,0x5E,0x93,0x94,0x79,0x45,0xD9,0x05,0x5D,0x0A,0xB9,0x97,0x63,0x02,0x74,0xA7,0x82,0x80,0xEE,0xC3,0x10,0xD0,0x7D,0x28,0x03,0x6E,0x14,0x06,0x70,0xE6,0x0A,0xC9,0x9A,0x4E,0x37,0xD9,0x95,0x51,0xCE,0xBA,0xA2,0x14,0x0C,0x81,0x36,0x1B,0xB2,0x5C,0x30,0x38,0xFA,0x9C,0xC9,0x32,0x41,0xA7,0x18,0x3B,0xA2,0x48,0x04,0x05,0x51,0x4F,0x91,0x6D,0x12,0x04,0x20,0x9B,0x61,0x89,0xFF,0x1F};
const uint8_t spPAUSE1[]    PROGMEM = {0x00,0x00,0x00,0x00,0xFF,0x0F};
const uint8_t spERROR[]             PROGMEM ={0x2B,0xAF,0xC9,0x9C,0xDC,0x97,0x9E,0xBC,0xE5,0x34,0x72,0x5F,0x77,0xF2,0x58,0x4D,0x35,0xA3,0xEB,0xCD,0x5A,0x6A,0x07,0x7B,0x27,0xAD,0xEA,0x59,0xCF,0x5B,0xE5,0xB6,0x89,0x37,0x6E,0xED,0x55,0xAF,0x7B,0xD7,0xFB,0x3A,0xF4,0xA1,0x8D,0xB6,0xB9,0xE8,0xD3,0x56,0x37,0xB9,0xA9,0x1A,0x43,0x5B,0xCC,0xEC,0x16,0x66,0xAB,0xA5,0x72,0x8B,0xAB,0x66,0xC6,0xA3,0xE4,0x01,0x00,0x00};
const uint8_t spGETTING[]           PROGMEM ={0xA3,0x9E,0xB9,0x52,0x99,0x1C,0xAF,0x64,0x05,0x67,0xD5,0x74,0x73,0x92,0xE6,0x42,0xB8,0x72,0xF1,0xC9,0x63,0x71,0xA5,0xAC,0x39,0x27,0x4F,0xD5,0x42,0x75,0x13,0xAF,0x3C,0x36,0x4B,0x8C,0xC9,0x06,0x01,0x28,0xD9,0x2C,0x85,0xCD,0x27,0xA3,0x7A,0xAB,0x53,0x95,0xE6,0xA2,0x11,0x4B,0x4E,0x53,0x93,0xB3,0x44,0x2E,0x3E,0x5D,0xCF,0xC6,0xE8,0xD1,0xA8,0x75,0xCD,0x2B,0x71,0x67,0xA4,0xD4,0x27,0x87,0xD2,0x19,0x92,0x4D,0x2F,0x9D,0x6C,0x44,0x4A,0x36,0x83,0xB5,0x38,0x21,0x25,0x43,0x0D,0xC6,0xE0,0x16,0x94,0x0C,0x33,0x38,0x03,0xDD,0x18,0x4E,0xC4,0xC0,0xAC,0x75,0x71,0xA4,0x32,0x53,0xAE,0xC6,0x22,0xE4,0x4C,0x4D,0x39,0x28,0x79,0x54,0x98,0x07,0x00,0x00};
const uint8_t spDEGREES[] PROGMEM = {0x0A,0x28,0x30,0x6C,0x74,0x53,0x25,0xB3,0x67,0xAC,0x95,0x0D,0x63,0x24,0x11,0x8B,0x57,0x31,0xBC,0xA1,0x54,0xAC,0x19,0xF5,0x70,0x06,0x3C,0xB6,0xC6,0x0D,0x91,0xA9,0xCE,0x52,0x28,0x36,0x32,0xDD,0x95,0x69,0xB2,0xF8,0xD8,0xBA,0x6C,0xDA,0x31,0x34,0x69,0xA9,0x53,0x30,0xE3,0x92,0x74,0xA9,0x2A,0x55,0x4D,0x92,0xD3,0x97,0xAA,0x46,0x13,0x2A,0x4D,0xBF,0xEA,0x1E,0x82,0xB1,0x74,0xEB,0xEA,0x86,0x09,0x82,0xF6,0x35,0x6B,0x18,0xCE,0x11,0x27,0x66,0x8D,0x69,0x38,0x47,0x9C,0x5C,0x3C,0x96,0xE9,0x1C,0xA1,0x73,0xF5,0xD8,0xA7,0x33,0xA4,0xCE,0xC5,0xE5,0x18,0x41,0x91,0x3B,0x1F,0xB7,0x73,0x04,0x25,0xAA,0x5C,0x53,0xDE,0x19,0x83,0x30,0x6C,0x6B,0x7A,0x87,0x77,0xE4,0x8C,0x3D,0xE5,0x1D,0xD1,0x50,0xCC,0xB7,0xA6,0x6F,0x38,0x27,0x76,0xDD,0x12,0xBE,0xA1,0x83,0x38,0x78,0xAF,0xF9,0x9A,0x0A,0x14,0xB7,0xCF,0xE9,0xBF,0x24,0x44,0x5C,0xF2,0xA6,0xFF,0x22,0x76,0xF3,0x70,0x93,0x7F,0x05,0x7C,0x8F,0xA4,0x01,0x01,0x6C,0xC8,0xC9,0x80,0x1F,0x3C,0xFE,0x1F};
const uint8_t spBELOW[] PROGMEM = {0x0C,0x50,0xD6,0x6C,0x24,0xD5,0x39,0x73,0x58,0xEB,0x55,0x75,0x9F,0x8C,0x65,0x6B,0x56,0xD3,0x9C,0x92,0x94,0x3F,0x19,0x6D,0xD3,0xC6,0x9C,0xB6,0x66,0x74,0x8B,0x89,0x6B,0x52,0xB7,0xD1,0x2D,0xC6,0x11,0xC1,0xE9,0x5B,0xB7,0x04,0x65,0x3A,0x66,0x1F,0xDD,0x16,0x54,0xA5,0xD8,0x6D,0xD5,0x8D,0x66,0xBB,0xF2,0xD6,0x55,0x15,0x9E,0xED,0x2A,0x5B,0x56,0x95,0x79,0x4F,0xA8,0x74,0x19,0x65,0x14,0xD3,0x21,0xD2,0xB9,0x15,0x51,0xCE,0x18,0x6B,0xE7,0x52,0x78,0xBD,0xAD,0xA4,0x9D,0x53,0xE9,0xE5,0xB6,0x91,0x74,0x49,0x55,0x90,0xD3,0xC2,0xBA,0x25,0xD4,0x91,0x74,0xAB,0x69,0x1B,0x57,0x47,0x31,0xEA,0xAA,0x75,0x44,0x23,0x45,0xBB,0x9B,0xCD,0xF9,0x7F};
const uint8_t spZERO[] PROGMEM = {0x69,0xFB,0x59,0xDD,0x51,0xD5,0xD7,0xB5,0x6F,0x0A,0x78,0xC0,0x52,0x01,0x0F,0x50,0xAC,0xF6,0xA8,0x16,0x15,0xF2,0x7B,0xEA,0x19,0x47,0xD0,0x64,0xEB,0xAD,0x76,0xB5,0xEB,0xD1,0x96,0x24,0x6E,0x62,0x6D,0x5B,0x1F,0x0A,0xA7,0xB9,0xC5,0xAB,0xFD,0x1A,0x62,0xF0,0xF0,0xE2,0x6C,0x73,0x1C,0x73,0x52,0x1D,0x19,0x94,0x6F,0xCE,0x7D,0xED,0x6B,0xD9,0x82,0xDC,0x48,0xC7,0x2E,0x71,0x8B,0xBB,0xDF,0xFF,0x1F};
const uint8_t spTEMPERATURE[] PROGMEM = {0x0A,0x38,0xDE,0x32,0x00,0x2F,0xBB,0x37,0xBF,0x59,0x57,0x76,0x6F,0xB8,0xB2,0x16,0xCA,0xC4,0x75,0xCB,0x4A,0xAB,0x4A,0xF3,0xF6,0xCD,0x2B,0x2D,0x66,0x94,0xD7,0xBA,0xB4,0x34,0x79,0x93,0x52,0x97,0x16,0xB2,0x28,0x5B,0x4D,0x43,0x36,0x10,0x20,0xAB,0xB2,0x52,0xC4,0x26,0x9A,0x26,0x49,0x47,0x9B,0x1B,0xA5,0xA6,0x74,0x5D,0x43,0xF1,0x65,0x14,0x91,0xAD,0xED,0xB5,0x99,0xB1,0x69,0x1A,0x20,0xC0,0x0A,0x84,0x0E,0xD8,0xD3,0x23,0x01,0xA3,0x4C,0x1A,0xA0,0xF5,0xC9,0xD6,0x95,0xE0,0x24,0x1D,0xD9,0x5A,0x9B,0x9C,0x8B,0xAE,0x79,0x2B,0x43,0xAC,0xA6,0xDE,0x9C,0x35,0x9D,0xB1,0xB3,0x47,0x52,0xD7,0x74,0xC6,0x2E,0x52,0xA1,0x5E,0xC2,0x1D,0x3B,0xEB,0xB8,0x65,0x0D,0x5F,0xAA,0x26,0xB6,0xE2,0x35,0x7C,0xA9,0x2A,0xFB,0x6A,0x16,0xF7,0xE7,0x9E,0x4C,0xEB,0xD9,0xFE,0x1F};

void decimals()
{
switch (decnumbers) 
  {
  case 0:
  break;
  case 1:
    voice.say(spONE);
    break;
  case 2:
    voice.say(spTWO);
    break;
  case 3:
    voice.say(spTHREE);
    break;
  case 4:
    voice.say(spFOUR);
    break;
  case 5:
    voice.say(spFIVE);
    break;
  case 6:  
    voice.say(spSIX);
    break;
  case 7:
    voice.say(spSEVEN);
    break;
  case 8:
    voice.say(spEIGHT);
    break;
  case 9:
    voice.say(spNINE);
    break;
  case 10:
    voice.say(spTEN);   
    break;
  case 11:
    voice.say(spELEVEN);
    break;
  case 12:
    voice.say(spTWELVE);
    break;
  case 13:
    voice.say(spTHIRTEEN);
    break;
  case 14:
    voice.say(spFOURTEEN);
    break;
  case 15:
    voice.say(spFIFTEEN);
    break;
  case 16:
    voice.say(spSIXTEEN);
    break;
  case 17:
    voice.say(spSEVENTEEN);
    break;   
  case 18:
    voice.say(spEIGHTEEN);
    break;
  case 19:
    voice.say(spNINETEEN);
    break;       
  case 20:
    voice.say(spTWENTY);
    break;
  case 21:
    voice.say(spTWENTY);
    voice.say(spONE);
    break;
  case 22:
    voice.say(spTWENTY);
    voice.say(spTWO);
    break;
  case 23:
    voice.say(spTWENTY);
    voice.say(spTHREE);
    break;
  case 24:
    voice.say(spTWENTY);
    voice.say(spFOUR);  
    break;
  case 25:
    voice.say(spTWENTY);
    voice.say(spFIVE);
    break;
  case 26:
    voice.say(spTWENTY);
    voice.say(spSIX);
    break;
  case 27:
    voice.say(spTWENTY);
    voice.say(spSEVEN);
    break;
  case 28:
    voice.say(spTWENTY);
    voice.say(spEIGHT);
    break;
  case 29:
    voice.say(spTWENTY);
    voice.say(spNINE);
    break;
  case 30:
    voice.say(spTHIRTY);
    break;
  case 31:
    voice.say(spTHIRTY);
    voice.say(spONE);
    break;
  case 32:
    voice.say(spTHIRTY);
    voice.say(spTWO);
    break;
  case 33:
    voice.say(spTHIRTY);
    voice.say(spTHREE);
    break;
  case 34:
    voice.say(spTHIRTY);
    voice.say(spFOUR);
    break;
  case 35:
    voice.say(spTHIRTY);
    voice.say(spFIVE);
    break;
  case 36:
    voice.say(spTHIRTY);
    voice.say(spSIX);
    break;
  case 37:
    voice.say(spTHIRTY);
    voice.say(spSEVEN);
    break;
  case 38:
    voice.say(spTHIRTY);
    voice.say(spEIGHT);
    break;
  case 39:
    voice.say(spTHIRTY);
    voice.say(spNINE);
    break;   
  case 40:
    voice.say(spFOURTY);
    break; 
  case 41:
    voice.say(spFOURTY);
    voice.say(spONE);
    break; 
  case 42:
    voice.say(spFOURTY);
    voice.say(spTWO);
    break; 
  case 43:
    voice.say(spFOURTY);
    voice.say(spTHREE);
    break; 
  case 44:
    voice.say(spFOURTY);
    voice.say(spFOUR);
    break;                 
  case 45:
    voice.say(spFOURTY);
    voice.say(spFIVE);
    break; 
  case 46:
    voice.say(spFOURTY);
    voice.say(spSIX);
    break; 
  case 47:
    voice.say(spFOURTY);
    voice.say(spSEVEN);
    break; 
  case 48:
    voice.say(spFOURTY);
    voice.say(spEIGHT);
    break; 
  case 49:
    voice.say(spFOURTY);
    voice.say(spNINE);
    break;   
  case 50:
    voice.say(spFIFTY);
    break; 
 
  default:
    voice.say(spERROR);
    voice.say(spGETTING);
    voice.say(spTEMPERATURE);
    break;
  }
}


void setup() 
{
  Serial.begin(115200);
  Serial.print("Starting the program");

  pinMode(25, OUTPUT);
  digitalWrite(25, HIGH);
  delay(10);
  
  sensors.begin();

  pinMode(button, INPUT); 
}


void loop() 
{
  if (digitalRead(button) == 0)
  {
    voice.say(spTHE);
    voice.say(spTEMPERATURE);
    voice.say(spIS);

    Serial.print("Requesting temperatures...");
    sensors.requestTemperatures();
    Serial.println("DONE");
  
    // When we got the temperatures, we can print it here.
    // Use the temperature from the first sensor only.
    Serial.print("Temperature for the device 1 (index 0) is: ");
    Serial.println(sensors.getTempCByIndex(0)); 

    temp = (sensors.getTempCByIndex(0));
    if (temp <= 0)
      {
      voice.say(spBELOW);
      voice.say(spZERO);
      }
    if (temp > 0)
      {
      decnumbers = temp;
      decimals();
      voice.say(spDEGREES);
      voice.say(spPAUSE1);
      }
  }
}