Get time with API in Arduino - 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.

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.

Voice outout on a Google Nest mini using ESP32

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());
}
}

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.

I2C onReceive-handler called only once

I'm having trouble communicating between Arduino's over I2C. For some reason, the onReceive handler is only called once.
Master Code (sender):
#include <Wire.h>
#include "i2csettings.h" // defines address
void setup()
{
Wire.begin(I2C_MASTER_ADDRESS);
}
void loop()
{
Wire.beginTransmission(I2C_SLAVE_ADDRESS);
Wire.write(0x11);
Wire.endTransmission();
delay(1000);
}
Slave Code (receiver):
#include <Wire.h>
#include "i2csettings.h"
void takeAction(int);
void setup()
{
Serial.begin(9600);
Wire.begin(I2C_SLAVE_ADDRESS);
Wire.onReceive(takeAction);
}
void loop()
{}
void takeAction(int nBytes)
{
Serial.println("Action!");
}
The idea in this test-setup is to have the sender send a byte every second, and let the receiver act on this by printing a message. However, the message is only printed once. When I reset the Slave, it's printed again, but just once.
Any ideas where this may come from?
You have to make sure you read all the bytes from the stream.
Other wise it seems to block.
Make your event handler look like this. So you can call it multiple times.
void takeAction(int nBytes)
{
Serial.println("Action!");
while(Wire.available())
{
Wire.read();
}
return;
}

Send get request with arduino to ASP.NET webservice

I created a webservices in ASP .NET, that i published on azure, with this function
public string GetObject(int id)
{
return ("it is a test !");
}
when i enter the right URL, it works.
But when i try to send the request with arduino (based on ethernetclient example), it does not work.
the arduino code :
#include "Arduino.h"
#include <SPI.h>
#include <WiFlyHQ.h>
#include <Ethernet.h>
#include <SoftwareSerial.h>
WiFly wifly;
char ssid[] = "myssid";
char password[] = "mypass";
void setup() {
Serial.begin(9600);
wifly.begin(&Serial, NULL);
if (!(wifly.setSSID(ssid))) {
Serial.println("Fail to set ssid");
}
/* if (!(wifly.setKey(password))) {
Serial.println("Fail to set passPhrase");
} */
if (!(wifly.setPassphrase(password))) {
Serial.println("Fail to set passPhrase");
}
wifly.enableDHCP();
if (wifly.join()) {
Serial.println("Joined wifi network");
} else {
Serial.println("Failed to join wifi network");
}
if (wifly.open(myurl.azurewebsites.net)) {
wifly.println("GET /api/object/123 HTTP/1.0");
wifly.println("");
}
else
Serial.println("Connection failed");
}
void loop() {
if (client.available()) {
char c = client.read();
Serial.print(c);
}
}
The connection to the ssid works. But it blocks on wifly.open(). But, if I put wifly.open("search.yahoo.com") and then wifly.write("GET /search?p=50+km+in+miles HTTP/1.0"), ALL WORKS !
Do you know why ?
Thanks for your help.
How does EthernetClient get connected with WiFly? I don't see any calls that connect them. I have done some playing with a WiFly module but I don't see how you use EthernetClient with it.
The WiFly module is the network connection and is accessed via serial. Wouldn't you need to make the request though it, handle the responses with serial processing?

Resources