I'm trying to use an ESP8266 and Arduino Uno to connect to wunderground and get the JSON file to get the current weather. With my code I am connecting to the server fine. What seems to be the issue is that it's not giving me the whole return file.
#include <SoftwareSerial.h>
#include <ArduinoJson.h>
SoftwareSerial esp8266(8, 9);
bool flag = true;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
esp8266.begin(9600);
}
void loop() {
if (flag) {
String cmd;
int length;
cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += "api.wunderground.com";
cmd += "\",80";
esp8266.println(cmd);
Serial.println(cmd);
delay(2000);
Serial.write(esp8266.read());
if (esp8266.find("CONNECT")) {
Serial.println("CONNECT found so your connected");
}
String action;
action = "GET http://api.wunderground.com/api/APIKEY/conditions/q/Canada/Regina.json HTTP/1.0\r\n\r\n";
length = action.length();
cmd = "AT+CIPSEND=";
cmd += length;
esp8266.println(cmd);
Serial.println(cmd);
delay(5000);
if (esp8266.find(">")) {
Serial.print(">");
} else {
esp8266.println("AT+CIPCLOSE");
Serial.println(F("connect timeout"));
}
esp8266.println(action);
Serial.println(action);
delay(700);
String test = "";
while (esp8266.available()) {
char c = esp8266.read();
test += c;
}
Serial.println(test);
flag = false;
Serial.println("Flag is false");
}
}
Running this code give me the following result:
AT+CIPSTART="TCP","api.wunderground.com",80
ACONNECT found so your connected
AT+CIPSEND=97
GET http://api.wunderground.com/api/7287eb3ace065563/conditions/q/Canada/Regina.json HTTP/1.0
busy s...
Recv 97 bytes
SEND OK
+IPD,1460:HTTP/1.0:"0.1",
"termsofService":"http://www.wunderground.com/weather/api/d/terms.html",
"
Flag is false
As you can see I only get a snippet of the JSON file. I'm not sure what the problem is.
It's not sending JSON at all. It detected that your Arduino/ESP combo was not a human, and is scolding you, letting you know that you are in breach of the Terms of Service, as described in http://www.wunderground.com/weather/api/d/terms.html. You need to set some headers, to masquerade as a browser and thus pass as a human user.
Related
Im trying to connect a ldr sensor to telegram bot, so that i know if the lights are tripping or not, but it seems like the tripped messages aren't going through. I tried to restart the chip, but it keeps showing "testconnection NOK"Can someone help me to see if there are anyways to troubleshoot this issue? Below is the code used for my arduino.
#include <WiFiClient.h> //CLIENT LIBRARY
#include <ESP8266WebServer.h> //WEBSERVICER LIBRARY
#include <ESP8266HTTPClient.h> //HTTP CLIENT LIBRARY
#include "CTBot.h" //TELEGRAM BOT LIBRARY
CTBot myBot; //INITIALIZE TELEGRAM BOT VARIABLE
String ssid = "CGA-Farm" ; // ASSIGN SSID VARIABLE WITH WIFI SSID
String pass = "0003606367"; // ASSIGN PASS VARIABLE WITH WIFI PASSWORD
String token = "1715253121:AAHqI4O2mt11ono-wFQ-_p5UfVpu0OeekeY"; // TELEGRAM BOT TOKEN RETRIEVED FROM BOTFATHER
int CNT = 0;
void setup() {
Serial.begin(9600);
Serial.println("Starting TelegramBot...");
myBot.wifiConnect(ssid, pass); // CONNECT ESP TO ACCESS POINT
myBot.setTelegramToken(token); // SET TELEGRAM BOT TOKEN
if (myBot.testConnection())// DEBUG CONNECTION
Serial.println("\ntestConnection OK");
else
Serial.println("\ntestConnection NOK");
}
void loop() {
float reading = analogRead(A0);
Serial.println(reading);
delay(1000);
if (reading < 800)
{
if (CNT < 1)
{
Serial.println("No light!");
myBot.sendMessage(-1001412490907,"GR1 Zone1 tripped!");
CNT = CNT + 1;
}
} else
{
CNT = 0;
}
}
Maybe your error is in the Serial.begin(9600) because the baud rate of the Arduino is not compatible with the Telegram bot. Try to change the value 9600 with this number :
115200
I'm trying to connect to a remote MySQL database directly from my arduino to do some telemetry on some hardware. However the code gets stuck while connecting to the db, and gives always the answer "no db found". Where am I wrong?
I'm sure that I'm correct with the user/pass thing, however I really can't figure out why it won't connect to the db to execute the query.
#include <ESP8266WiFi.h>
#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>
char ssid[] = "mywifissid";
char pass[] = "mywifipass";
char mysqlUser[] = "mysqluser";
char mysqlPass[] = "mysqlpassword";
char id[] = "someidforthearduino";
WiFiClient wifiClient;
MySQL_Connection mysqlConnection ((Client *)&wifiClient);
IPAddress mysqlServer (/*some kind of address for the mySQL server*/);
bool is_Sending = false;
char queryToExecute[128];
char queryUpdate[] = "somequery";
int nPresses = 0;
void setup() {
Serial.begin(115200);
Serial.println("Inizializzazione pin in corso...");
pinMode(D4, INPUT_PULLUP);
Serial.println("Connessione alla rete in corso...");
WiFi.disconnect();
WiFi.begin(ssid,pass);
while(WiFi.status() != WL_CONNECTED) {
delay(200);
Serial.print(".");
}
Serial.println("");
Serial.print("Connesso con ip ");
Serial.println(WiFi.localIP());
Serial.println("Inizializzazione completata");
}
void loop() {
if (!digitalRead(D4) && !is_Sending) {
is_Sending = true;
nPresses++;
Serial.println("Rilevata pressione tasto. Connessione in corso...");
if (mysqlConnection.connect(mysqlServer,3306,mysqlUser,mysqlPass)) {
Serial.println("");
Serial.println("Connesso. Inserimento dato...");
sprintf(queryToExecute, queryUpdate, nPresses, id);
MySQL_Cursor *c = new MySQL_Cursor(&mysqlConnection);
c->execute(queryToExecute);
delete c;
Serial.println("Aggiornamento effettuato!");
} else {
Serial.println("No db found.");
}
mysqlConnection.close();
is_Sending = false;
}
}
I figured it out. The code is correct, I just typed the wrong IP for the MySQL server! I discovered it by opening the command prompt and pinging the host name;
I have connect Processing and SQL by using database library "de.Bezier.data.sql".
I don't know How can I get the name of columns in a specific Table.
I get the correct name of database, but i got the following as result of name of columns "Tables_in_sql7363100"
import de.bezier.data.sql.*;
MySQL sql;
String[] tableNames;
String[] columnNames;
void setup() {
size(300, 300);
database_connection();
if (connect) {
tableNames = sql.getTableNames();
for (int i=0; i<tableNames.length; i++) {
println(tableNames[i]);
}
columnNames = sql.getColumnNames();
for (int i=0; i<ColumnNames.length; i++) {
println(columnNames[i]);
}
}
}
void draw() {
background(255);
}
void database_connection() {
sql = new MySQL(this, "ServerName", "DataBase", "DUN", "PW");
if (sql.connect()) {
connect = true;
connect_status = "Conected";
} else {
connect = false;
connect_status = "Connection Failed";
}
}
There are 2 problems with what I'm seeing. The first one, which interests you, is that you didn't select any table. That's why you don't get a list of columns. You can fix this by using a simple query:
sql.query("SELECT * FROM myTable");
But that's not the only thing: you're not accounting for lag. It may work for now on a local database because lag is really low, but this won't fly with something which is over the internet. Here's an example where I show columns from a public test database and how long it takes to get the result from my query back:
import de.bezier.data.sql.*;
MySQL sql;
String user = "rfamro";
String pass = "";
String server = "mysql-rfam-public.ebi.ac.uk:4497";
String database = "Rfam";
String[] columnNames;
void setup() {
size(300, 300);
sql = new MySQL(this, server, database, user, pass);
}
void draw() {
if (columnNames != null) {
println("It took " + millis() + "ms to get this data back.");
for (String s : columnNames) {
println(s);
}
noLoop();
} else if (sql.connect()) {
sql.query("SELECT * FROM family");
sql.next(); // only use .next when you know you have data
columnNames = sql.getColumnNames();
}
}
From here, it takes between 2-7 seconds to get the data back. You'll understand that, the setup() method running taking about a couple milliseconds, you won't have any results back by then.
Hope this helps. Have fun!
I am trying to get the response sent by the web server through Java NIO socketChannel. The read call of SocketChannel is not returning anything when it is in non-blocking
clientSocket.configureBlocking(false);
When specified true, means blocking mode, then it is returning response. Someone saying that we should use Selector when non-blocking mode enabled. But I didn't find a way to implement this.
FYI, Following is the code snippet I am trying.
public static void main(String[] args) throws IOException, InterruptedException
{
URL u = new URL("http://www.google.com");
InetSocketAddress addr = new InetSocketAddress("www.google.com", 80);
SocketChannel clientSocket = SocketChannel.open(addr);
clientSocket.configureBlocking(false);
byte[] message = new String("GET " + u.getFile() + " HTTP/1.0\r\n").getBytes();
ByteBuffer writeBuff = ByteBuffer.wrap(message);
clientSocket.write(writeBuff);
ByteBuffer readBuff = MappedByteBuffer.allocate(1500);
clientSocket.read(readBuff);
while(clientSocket.read(readBuff) > 0)
{
System.out.println(new String(readBuff.array()).trim());
}
clientSocket.close();
}
Thanks in advance.
You should use loops to read() and write() till the buffer has no remaining bytes when non-blocking mode.
There two problems in your code:
the http request body is wrong. it needs additional "\r\n".
the readBuff need to cleared each time after reading.
below code is a working version:
static void working() throws Exception {
URL u = new URL("http://www.baidu.com");
InetSocketAddress addr = new InetSocketAddress("www.baidu.com", 80);
SocketChannel clientSocket = SocketChannel.open(addr);
clientSocket.configureBlocking(false);
byte[] message = new String("GET / HTTP/1.0\r\n\r\n").getBytes();
ByteBuffer writeBuff = ByteBuffer.wrap(message);
clientSocket.write(writeBuff);
ByteBuffer readBuff = MappedByteBuffer.allocate(1500);
while (clientSocket.read(readBuff) != -1) {
System.out.println("Entring...");
System.out.println(new String(readBuff.array()).trim());
readBuff.clear();
}
clientSocket.close();
}
}
Notice, if it's http version 1.1, it will not break too. because it has a keeplive.
I am new to GWT. I have written a piece of code which makes asynchronous calls to the server. The server side code is running fine as seen through the logs. But on the client side I am getting a failure message.
I am trying to load large amount of data from the server. It seems like the async call times out before the entire data is returned from the server. Is there a way I can increase the timeout of the call? or is there any other issue with my code?
public MapDataServiceFacadeAsync getMapDataServiceInstance()
{
if (mapDataService == null)
{
mapDataService = MapDataServiceFacade.Util.getInstance();
}
return mapDataService;
public void setTreeInstance(final String productName, final Object invObject, final boolean isToLoadTickets, final SearchItem search)
{
refreshSearch = search;
this.inventoryMapPanel = (InventoryMapPanel) invObject;
long startTime = System.currentTimeMillis();
getMapDataServiceInstance().getProductTree(userProfile, isToLoadTickets, search, new AsyncCallback()
{
public void onFailure(Throwable caught)
{
CommonMapUI.loadLabel(false);
Window.alert("Failed to Load Tree. Please try again");
}
public void onSuccess(Object result)
{
tmpData = (MapItem[]) ((HashMap) result).get("tree");
if (tmpData == null && Count < 3)
{
Count++;
setTreeInstance(productName, invObject, isToLoadTickets, search);
}
else
{
buildProductTree(result, invObject, isToLoadTickets);
}
}
});
}
It is always throwing the error "Failed to load Tree" if I try and retrieve large amount of data. It works fine if small amount of data is to be loaded.
Interface:
public interface MapDataServiceFacadeAsync {
public void getProductTree(CommonUserProfile user, boolean isToLoadTickets,SearchItem search, AsyncCallback asynCall);
Any help would be appreciated.