Hi there.
First of all, I'd like to say thanks for your library.
I have a problem, that is, I'm only able to get the TTS link only once in a loop.
Once, the next loop comes in, the TTS library either takes a very long time to generate a link, or, just doesn't generate a link at all.
I've also edited the original library, so that it uses setInsecure instead of setFingerprint.
Only thing I've found is that the WiFi client is stuck at 0 on the next iteration. (while (client.available == 0)
)
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include <SPI.h>
#include <RFID.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "Tone.h"
#include <google-tts.h>
#include "AudioFileSourceICYStream.h"
#include "AudioFileSourceBuffer.h"
#include "AudioGeneratorMP3.h"
#include "AudioOutputI2SNoDAC.h"
TTS tts;
LiquidCrystal_I2C lcd(0x27, 16, 2);
#define SS_PIN D3
#define RST_PIN D4
#define Buzzer D8
const char* wifiName = "TD Samsung";
const char* wifiPass = "*******";
unsigned long currentMillis;
RFID rfid(SS_PIN, RST_PIN);
void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string)
{
const char *ptr = reinterpret_cast<const char *>(cbData);
(void) isUnicode;
char s1[32], s2[64];
strncpy_P(s1, type, sizeof(s1));
s1[sizeof(s1)-1]=0;
strncpy_P(s2, string, sizeof(s2));
s2[sizeof(s2)-1]=0;
Serial.printf("METADATA(%s) '%s' = '%s'\n", ptr, s1, s2);
Serial.flush();
}
void StatusCallback(void *cbData, int code, const char *string)
{
const char *ptr = reinterpret_cast<const char *>(cbData);
char s1[64];
strncpy_P(s1, string, sizeof(s1));
s1[sizeof(s1)-1]=0;
Serial.printf("STATUS(%s) '%d' = '%s'\n", ptr, code, s1);
Serial.flush();
}
void setup() {
Serial.begin(115200);
SPI.begin();
rfid.init();
delay(10);
pinMode(Buzzer, OUTPUT);
Wire.begin(D2, D1);
lcd.begin();
lcd.backlight();
Serial.println();
Serial.print("Connecting to ");
Serial.println(wifiName);
lcd.setCursor(1,0);
lcd.print("Initialization");
lcd.setCursor(2,1);
lcd.print("Connecting...");
WiFi.disconnect();
WiFi.mode(WIFI_STA);
WiFi.begin(wifiName, wifiPass);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP()); //You can get IP address assigned to ESP
ModeDevice();
}
void ModeDevice()
{
HTTPClient https;
Serial.print("Request Link:");
Serial.println(hostMode);
https.begin(hostMode);
int httpCode = https.GET(); //Send the request
String payload = https.getString(); //Get the response payload from server
Serial.print("Response Code:"); //200 is OK
Serial.println(httpCode); //Print HTTP return code
Serial.print("Returned data from Server:");
Serial.println(payload); //Print request response payload
if (httpCode == 200)
{
DynamicJsonDocument doc(1024);
// Parse JSON object
auto error = deserializeJson(doc, payload);
if (error) {
Serial.print(F("deserializeJson() failed with code "));
Serial.println(error.c_str());
return;
}
// Decode JSON/Extract values
String responStatus = doc["status"].as<String>();
String responMode = doc["mode"].as<String>();
String responKet = doc["ket"].as<String>();
Serial.println();
Serial.print("status : ");
Serial.println(responStatus);
Serial.print("mode : ");
Serial.println(responMode);
Serial.print("ket : ");
Serial.println(responKet);
Serial.println("-------------------");
Serial.println();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Dismissal System");
if (responMode == "SCAN"){
ModeAlat = "SCAN";
lcd.setCursor(0,1);
lcd.print("Scan your card>>");
}else{
ModeAlat = "";
lcd.setCursor(0,1);
lcd.print(responKet);
}
} else {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Connection error.");
Serial.println();
Serial.println("Koneksi Error");
lcd.print(" ");
}
Serial.println("Closing connection.");
Serial.println();
Serial.println("Scan a card.");
https.end();
delay(100);
}
void speak(const char *url) {
AudioGeneratorMP3 *mp3;
AudioFileSourceICYStream *file;
AudioFileSourceBuffer *buff;
AudioOutputI2SNoDAC *out;
bool audioPlaying = true;
bool hasSetUpAudio = false;
Serial.println("Start of TTS function.");
// While there are no audio playing,
while (audioPlaying) {
// and if audio hasn't been set up'ed,
if (!hasSetUpAudio) {
audioLogger = &Serial;
file = new AudioFileSourceICYStream(url);
file->RegisterMetadataCB(MDCallback, (void*)"ICY");
buff = new AudioFileSourceBuffer(file, 4096);
buff->RegisterStatusCB(StatusCallback, (void*)"buffer");
out = new AudioOutputI2SNoDAC();
mp3 = new AudioGeneratorMP3();
mp3->RegisterStatusCB(StatusCallback, (void*)"mp3");
Serial.println("MP3 begin.");
mp3->begin(buff, out);
// and set hasSetUpAudio to true, so that this code won't be executed twice.
hasSetUpAudio = true;
}
static int lastms = 0;
// While the audio is playing,
if (mp3->isRunning()) {
//Serial.println("MP3 is running.");
// Check if we've played for a second,
if (millis() - lastms >= 1000) {
lastms = millis();
// and show that we've played for a second.
Serial.printf("Running for %d ms...\n", lastms);
}
// If the mp3 is not looping,
if (!mp3->loop()) {
// stop the MP3.
mp3->stop();
}
} else {
// If the audio is not playing, print it and
// set audioplaying to true.
Serial.println("MP3 done");
audioPlaying = false;
}
}
delete mp3, file, buff, out;
mp3 = NULL;
file = NULL;
buff = NULL;
out = NULL;
Serial.println("End of TTS function.");
}
void loop() {
if (ModeAlat != "SCAN")
return;
rfid.halt();
if (!rfid.isCard() || !rfid.readCardSerial()) {
lcd.setCursor(0, 0);
lcd.print("Dismissal System");
lcd.setCursor(0,1);
lcd.print("Scan your card>>");
return;
}
currentMillis = millis();
Serial.println("Card found");
String RFID = String(rfid.serNum[0],HEX) +"-"+ String(rfid.serNum[1],HEX) +"-"+ String(rfid.serNum[2],HEX) +"-"+ String(rfid.serNum[3],HEX) +"-"+ String(rfid.serNum[4],HEX);
tone(Buzzer, NOTE_E7, 100);
Serial.print("RFID: ");
Serial.println(RFID);
Serial.println("");
String host = hostSCAN;
host += "&rfid=";
host += RFID;
HTTPClient https;
Serial.print("Request Link:");
Serial.println(host);
Serial.println("");
https.begin(host);
int httpCode = https.GET(); //Send the GET request
String payload = https.getString(); //Get the response payload from server
https.end();
Serial.print("Response Code:"); //200 is OK
Serial.println(httpCode); //Print HTTP return code
Serial.println("");
Serial.print("Returned data from Server: ");
Serial.println(payload); //Print request response payload
Serial.println("");
if (httpCode != 200) {
lcd.setCursor(0, 0);
lcd.print("Dismissal System");
lcd.setCursor(0,1);
lcd.print("HTTP: " + httpCode);
return;
}
DynamicJsonDocument doc(1024);
auto error = deserializeJson(doc, payload);
if (error) {
Serial.print(F("deserializeJson() failed with code "));
Serial.println(error.c_str());
return;
}
String responStatus = doc["status"].as<String>();
String responKeterangan = doc["ket"].as<String>();
String responNama = doc["nama"].as<String>();
String responLanguage = doc["language"].as<String>();
Serial.println();
Serial.print("Status: ");
Serial.println(responStatus);
Serial.print("Keterangan: ");
Serial.println(responKeterangan);
Serial.print("Language: ");
Serial.println(responLanguage);
Serial.println("-------------------");
Serial.println();
tone(Buzzer, NOTE_E7, 100);
if (millis() - currentMillis < 120) {
currentMillis = millis();
tone(Buzzer, NOTE_E7, 100);
}
if (responStatus != "success") {
lcd.clear();
lcd.print("Please register");
lcd.setCursor(2, 1);
lcd.print("an account.");
return;
}
lcd.clear();
lcd.print("Success!");
lcd.setCursor(0, 1);
lcd.print("Calling " + responNama + ".");
String ttsString;
if (responLanguage == "en") {
ttsString = "This is the pickup call for " + responNama + ". Please proceed to: Gate 1, immediately. Thank you.";
} else if (responLanguage == "zh" ) {
ttsString = "这是接听电话 " + responNama + ". 请立即前往:1号登机口。 谢谢。";
} else if (responLanguage == "ja") {
ttsString = responNama + "のピックアップコールです" + ". すぐにゲート1に進んでください。 ありがとうございました。";
} else if (responLanguage == "de") {
ttsString = "Dies ist der Abholanruf für " + responNama + ". Bitte fahren Sie sofort mit Gate 1 fort. Vielen Dank.";
} else if (responLanguage == "nl") {
ttsString = "Dit is het ophaalgesprek voor " + responNama + ". Ga onmiddellijk door naar: Gate 1. Dank je.";
} else if (responLanguage == "it") {
ttsString = "Questa è la chiamata di ripresa per " + responNama + ". Procedi immediatamente a: Gate 1. Grazie.";
} else if (responLanguage == "ru") {
ttsString = "Это звонок для " + responNama + ". Пожалуйста, немедленно направляйтесь к выходу №1. Спасибо.";
} else if (responLanguage == "id") {
ttsString = "Ini adalah panggilan penjemputan untuk " + responNama + ". Silakan keluar melalui: Gerbang 1, segera. Terima kasih.";
} else if (responLanguage == "jv") {
ttsString = responNama + "saiki mulih!" + ". Mangga metu liwat: Gerbang 1. Matur suwun.";
}
Serial.println(ttsString);
lcd.setCursor(0, 0);
lcd.print("Please wait.....");
String urlSpeech = tts.getSpeechUrl(ttsString, responLanguage);
urlSpeech.remove(4, 1);
Serial.println(urlSpeech.c_str());
speak(urlSpeech.c_str());
SPI.begin();
rfid.init();
Wire.begin(D2, D1);
lcd.clear();
Serial.println("Scan another card.");
}