Voice outout on a Google Nest mini using ESP32 - arduino

I am trying to output as a voice message inputted text. I am using Google Nest Mini and ESP32.
The code displayed below works as intended. It uses ghn.notify() to pass a message to the voice assistant and it says it out loud.
#include <WiFi.h>
#include <esp8266-google-home-notifier.h>
const char* ssid = "your_ssid";
const char* password = "your_password";
GoogleHomeNotifier ghn;
void setup()
{
Serial.begin(9600);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
const char displayName[] = "Living Room speaker";
if (ghn.device(displayName, "en") != true)
{
Serial.println(ghn.getLastError());
return;
}
ghn.notify("Hi, how are you");
}
However, when I try to pass a String as an argument to ghn.notify() I have the following error:
no matching function for call to 'GoogleHomeNotifier::notify(String&)'
This is the added code:
void loop() {
if (Serial.available()) {
String command = Serial.readStringUntil('\n');
ghn.notify(command);
}
}
Is there a way to make the voice assistant say the text that was inputted in the serial monitor?

I found a solution to the problem.
When using
ghn.notify(command);
a built-in function was used to fix the error.
So in the end the code looks like this:
void loop() {
if (Serial.available()) {
String command = Serial.readStringUntil('\n');
ghn.notify(command.c_str());
}
}

Related

ESP32: How to change WiFi SSID using access point with Arduino IOT cloud running

I have been trying to use WiFi.h, WebServer.h and EEPROM.h together with ArduinoIoTCloud.h and
Arduino_ConnectionHandler.h to be able to change the WiFi credentials if required without changing the sketch and reuploading it.
The problem is when moving;
WiFiConnectionHandler ArduinoIoTPreferredConnection(SSID, PASS)
inside void setup() wouldn't work whether with constant char of the credentials or after modifying it to read from the EEPROM, like
WiFiConnectionHandler ArduinoIoTPreferredConnection(esid.c_str(), epass.c_str());
Please, is there any way to change the WiFi credentials from a web browser?
The Code
#include <ArduinoIoTCloud.h>
#include <Arduino_ConnectionHandler.h>
const char DEVICE_LOGIN_NAME[] = "********************";
const char SSID[] = "SECRET_SSID"; // Network SSID (name)
const char PASS[] = "SECRET_OPTIONAL_PASS"; // Network password (use for WPA, or use as key for WEP)
const char DEVICE_KEY[] = "SECRET_DEVICE_KEY"; // Secret device password
void onTemperatureChange();
float temperature;
void initProperties()
{
ArduinoCloud.setBoardId(DEVICE_LOGIN_NAME);
ArduinoCloud.setSecretDeviceKey(DEVICE_KEY);
ArduinoCloud.addProperty(temperature, READWRITE, ON_CHANGE, onTemperatureChange);
}
WiFiConnectionHandler ArduinoIoTPreferredConnection(SSID, PASS);
void setup() {
Serial.begin(9600);
delay(1500);
initProperties();
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
setDebugMessageLevel(2);
ArduinoCloud.printDebugInfo();
}
void loop() {
ArduinoCloud.update();
}
void onTemperatureChange() {
}
So, when I add the code for the access point to write and read from the EEPROM, I then, o my knowledge, need to move this line inside the void setup.
WiFiConnectionHandler ArduinoIoTPreferredConnection(SSID, PASS);
For example
void setup() {
Serial.begin(9600);
delay(1500);
// Code for reading from EEPROM and the eeprom_SSID and eeprom_SSID_PASS will then pass to SSID and PASS Chars
//
initProperties();
WiFiConnectionHandler ArduinoIoTPreferredConnection(SSID, PASS);
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
setDebugMessageLevel(2);
ArduinoCloud.printDebugInfo();
}
After that, the ESP will be pushed to restart as the IoT library doesn't find the SSID and PASS.
I have tried to do so with Blynk and many other libraries, and it worked; I could enter the credentail by activating a server and creating an access point to do so, and then blynk read from that and connected perfectly. The problem is that I have to use the Arduino IoT cloud, not Blynk.
Thanks for your support.

esp8266 soft AP displays the wrong name

device: esp8266 (nodeMCU, esp-12E)
I have a esp8266 that previously run micropython on it. and now i wanted to return back to arduino programing.
using the example code on the docs:https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/soft-access-point-examples.html
#include <ESP8266WiFi.h>
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.println("setting up soft-AP");
boolean result = WiFi.softAP("ESPsoftAP", "11234");
if (result = true)
{
Serial.println("ready!");
}
else
{
Serial.println("failed!");
}
}
void loop(){
Serial.printf("station connected = %d\n", WiFi.softAPgetStationNum());
delay(3000);
}
but the access point that shows up is named "MicroPython-7b15141" and the password does not work.
which to me seems like the line
boolean result = WiFi.softAP("ESPsoftAP", "11234");
was not able to do its function for some reason.
however on the serial monitor, the text "station connected = 0" does show.
so what went wrong here?
in your sketch the Wifi parameters are not updated because the Wifi password is too short, therefore it keeps the previous ssid and password.
Try this, now it works: All the best:
boolean result = WiFi.softAP("ESPsoftAP", "1234567890")

How to make a response in Bluetooth module (Arduino)

I connected my Bluetooth module to the mobile phone and made up a code to communicate between Arduino and mobile through Bluetooth (send messages from Bluetooth module to device and vice versa).
Now I want to make a response, which means that if I send from the mobile "hi" the arduino replies and says "Hello" or whatever.
I have tried tons of codes but none worked, so would anyone please help me?
#include <SoftwareSerial.h>
SoftwareSerial myserial (6,5);
void setup() {
myserial.begin(9600);
Serial.begin (9600);
}
void loop() {
if (myserial.available()) {
Serial.write(+ myserial.read());
}
if (Serial.available()) {
myserial.write(Serial.read());
}
}
Another code but making a loop without sending anything
#include <SoftwareSerial.h>
SoftwareSerial myserial(6,5); //Arduino: R:5,T:6; bluetooth: T:5, R:6;
void setup() {
myserial.begin(9600);
Serial.begin (9600);
}
void loop() {
if (myserial.available()) {
Serial.write(myserial.read());
}
if (Serial.available()) {
myserial.write(Serial.read());
}
for (int i = 0; i=2; i++) {
myserial.write("hello");
}
if (myserial.read() =="n") {
myserial.write("hello");
}
}
You need to build your serial string char by char using the SerialEvent() interrupt, then do a String comparison using the .equals method. Despite many people will tell you that String types are 'evil' (see this and this) it might be a good solution for making things clearer (and perhaps a bit easier if you don't want to mess with C char strcmp() functions and pointers. In the end, the String type is there for you and I see no reason for not using it in general projects.
Based on the SerialEvent() documentation [1], and the String reference [2], you could do something like:
String inputString = ""; // a String to hold incoming data
bool stringComplete = false; // whether the string is complete
void setup() {
// initialize serial:
Serial.begin(9600);
// reserve 200 bytes for the inputString:
inputString.reserve(200);
}
void loop() {
// print the string when a newline arrives:
if (stringComplete) {
//Then you compare the inputString with the word you want to detect using the .equals method from the String class
if(inputString.equals("Hi"){
Serial.println("Hello");
}
// clear the string for a new comparison:
inputString = "";
stringComplete = false;
}
}
/*
SerialEvent occurs whenever a new data comes in the hardware serial RX. This
routine is run between each time loop() runs, so using delay inside loop can
delay response. Multiple bytes of data may be available.
*/
void serialEvent() {
while (Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag so the main loop can
// do something about it:
if (inChar == '\n') {
stringComplete = true;
}
}
}
EDIT 1: Of course, you can replace the Serial object from this example code with your own myserial object from the BlueTooth communication.

Arduino SIM900 GSM how to Join Char on String

I am currently making an Arduino project with GSM900 GSM GPRS. In this project, I have to receive data sent from a phone. I could easily receive data with a single character, but I can`t join does character to obtain a full word (String). I have to use this full word inside an If statement if this word equals to that other word (string), make something...
#include <SoftwareSerial.h>
// Configure software serial port
SoftwareSerial SIM900(7, 8);
//Variable to save incoming SMS characters
char incoming_char=0;
String newchar = "";
void setup() {
// Arduino communicates with SIM900 GSM shield at a baud rate of 19200
SIM900.begin(19200);
Serial.begin(19200);
// Give time to your GSM shield log on to network
delay(20000);
// AT command to set SIM900 to SMS mode
SIM900.print("AT+CMGF=1\r");
delay(100);
// Set module to send SMS data to serial out upon receipt
SIM900.print("AT+CNMI=2,2,0,0,0\r");
delay(100);
}
void loop() {
if(SIM900.available() >0) {
incoming_char=SIM900.read();
Serial.print(incoming_char);
}
}
I tried putting this command on the the if statement inside the loop, but after i tried comparing the words, it wouldnt work.
void loop() {
if(SIM900.available() >0) {
incoming_char=SIM900.read();
newString = incoming_char + "";
Serial.print(incoming_char);
}
if (newString == "Test"){
Serial.println("It worked");
}
}
The output that i get from the Monitor Serial is this:
+CMT: "+myNumber","","19/09/20,16:31:05-12"
Test
void loop() {
if (SIM900.available() >0) {
incoming_char=SIM900.read();
newString += incoming_char;
Serial.print(incoming_char);
}
if (newString.endsWith("Test")) {
Serial.println("It worked");
}
}
For does who are wondering how it finished:
Thanks to phoenixstudio...
void loop() {
if(SIM900.available() >0) {
incoming_char=SIM900.read();
newString += incoming_char;
Serial.print(incoming_char);
}
if (newString.endsWith("Test1")){
Serial.println("Worked1");
}
if (newString.endsWith("Test2")){
Serial.println("Worked2");
}
if (newString.endsWith("Test3"){
Serial.println("Worked3");
}
}

Get time with API in Arduino

I'm trying to get the current local time with an API. I am using a WEMOS D1 Mini and the get method with blynk to return JSON from the API and store it.
I use this code
#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include <BlynkSimpleEsp8266.h>
String json;
char auth[] = "";
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
BLYNK_WRITE(V0) {
json = param.asStr();
}
void setup() {
Serial.begin(9600);
Blynk.begin(auth, ssid, pass);
}
void loop() {
Blynk.run();
Blynk.virtualWrite(V0, "https://api.bot-dev.org/time/");
JsonObject& root = jsonBuffer.parseObject(json);
long time = root[String("ENtime")];
}
But i cant receive time in long time variable.
You can do that in simpler way.
You need to add WebHook widget to your app. In the webhoook widget you need to put https://api.bot-dev.org/time/ url. And assign this widget to the virtual pin, let's say V0. Webhook widget will return response to your hardware after it was triggered. So your code should look like that:
BLYNK_WRITE(V0) {
//here you'll get response from the webhook
json = param.asStr();
}
void setup() {
Serial.begin(9600);
Blynk.begin(auth, ssid, pass);
}
void loop() {
Blynk.run();
//trigger the webhook
Blynk.virtualWrite(V0, 1); //you can send any value to trigger webhook
}
Have in mind that you need also to move out Blynk.virtualWrite from main loop in order to avoid flooding.
Here is more details regarding the webhook widget.

Resources