GET HTTP requests (Arduino) - c++

I'm trying to send some http requests from Arduino to my server.
My code can upload once, but is disconnecting after uploading first time.
Any idea how I can modify my code so the Arduino will send a http request every 2-3 second?
Here is my code:
#include <SPI.h>
#include <Ethernet.h>
int counter = 0;
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress server(xxx, xx, xx, xx);
IPAddress ip(192, 168, 1, 1);
EthernetClient client;
void setup() { //connect to server
Serial.begin(9600);
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
Ethernet.begin(mac, ip);
}
// give the Ethernet shield a second to initialize:
delay(1000);
Serial.println("connecting...");
connect();
}
void loop()
{
send(counter);
delay(1000);
// if there are incoming bytes available
// from the server, read them and print them:
if (client.available()) {
char c = client.read();
Serial.print(c);
}
// if the server's disconnected, stop the client:
if (!client.connected()) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
// do nothing forevermore:
while(true);
}
counter++;
}
void connect(){
// if you get a connection, report back via serial:
client.connect(server, 80);
Serial.println("CONNECTED");
delay(1000);
}
void send(int value){
// Make a HTTP request:
client.print("GET /arduino.php?rom=D201");
client.print("&count=");
client.print(value);
client.println(" HTTP/1.0");
client.println("Host: 158.36.70.36");
client.println("Connection: close");
client.println();
Serial.print("Sending value");
Serial.println(value);
}

This Web client sketch has been tested and works flawlessly.
#include <SPI.h>
#include <Ethernet.h>
// this must be unique
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// change to your network settings
IPAddress ip(192,168,2,2);
IPAddress gateway(192, 168, 2, 1);
IPAddress subnet(255, 255, 255, 0);
// change to your server
IPAddress server(74,125,227,16); // Google
//Change to your domain name for virtual servers
char serverName[] = "www.google.com";
// If no domain name, use the ip address above
// char serverName[] = "74.125.227.16";
// change to your server's port
int serverPort = 80;
EthernetClient client;
int totalCount = 0;
char pageAdd[64];
// set this to the number of milliseconds delay
// this is 30 seconds
#define delayMillis 30000UL
unsigned long thisMillis = 0;
unsigned long lastMillis = 0;
void setup() {
Serial.begin(9600);
// disable SD SPI
pinMode(4,OUTPUT);
digitalWrite(4,HIGH);
// Start ethernet
Serial.println(F("Starting ethernet..."));
Ethernet.begin(mac, ip, gateway, gateway, subnet);
// If using dhcp, comment out the line above
// and uncomment the next 2 lines
// if(!Ethernet.begin(mac)) Serial.println(F("failed"));
// else Serial.println(F("ok"));
Serial.println(Ethernet.localIP());
delay(2000);
Serial.println(F("Ready"));
}
void loop()
{
thisMillis = millis();
if(thisMillis - lastMillis > delayMillis)
{
lastMillis = thisMillis;
// Modify next line to load different page
// or pass values to server
sprintf(pageAdd,"/",totalCount);
// sprintf(pageAdd,"/arduino.php?test=%u",totalCount);
if(!getPage(server,serverPort,pageAdd)) Serial.print(F("Fail "));
else Serial.print(F("Pass "));
totalCount++;
Serial.println(totalCount,DEC);
}
}
byte getPage(IPAddress ipBuf,int thisPort, char *page)
{
int inChar;
char outBuf[128];
Serial.print(F("connecting..."));
if(client.connect(ipBuf,thisPort) == 1)
{
Serial.println(F("connected"));
sprintf(outBuf,"GET %s HTTP/1.1",page);
client.println(outBuf);
sprintf(outBuf,"Host: %s",serverName);
client.println(outBuf);
client.println(F("Connection: close\r\n"));
}
else
{
Serial.println(F("failed"));
return 0;
}
// connectLoop controls the hardware fail timeout
int connectLoop = 0;
while(client.connected())
{
while(client.available())
{
inChar = client.read();
Serial.write(inChar);
// set connectLoop to zero if a packet arrives
connectLoop = 0;
}
connectLoop++;
// if more than 10000 milliseconds since the last packet
if(connectLoop > 10000)
{
// then close the connection from this end.
Serial.println();
Serial.println(F("Timeout"));
client.stop();
}
// this is a delay for the connectLoop timing
delay(1);
}
Serial.println();
Serial.println(F("disconnecting."));
// close client end
client.stop();
return 1;
}
If for some reason it keeps hanging, you can implement a watchdog timer mechanism. For more info about WDT on ATmega328P Datasheet.
I have an example from one of my projects:
void watchdogSetup(void) {
cli(); // disable all interrupts
wdt_reset(); // reset the WDT timer
/*
WDTCSR configuration:
WDIE = 1: Interrupt Enable
WDE = 1 :Reset Enable
WDP3 = 0 :For 2000ms Time-out
WDP2 = 1 :For 2000ms Time-out
WDP1 = 1 :For 2000ms Time-out
WDP0 = 1 :For 2000ms Time-out
*/
// Enter Watchdog Configuration mode:
WDTCSR |= (1<<WDCE) | (1<<WDE); //x |= y is the same as x = x | y
// Set Watchdog settings:
WDTCSR = (1<<WDIE) | (1<<WDE) | (0<<WDP3) | (1<<WDP2) | (1<<WDP1) | (1<<WDP0);
sei();
}
ISR(WDT_vect){// Watchdog timer interrupt.
digitalWrite(ETHERNET_SHIELD_RESET_PIN, LOW);
}

Related

How do I fix a HTTP Error 400 in my code?

I am trying to make an rfid attendance system with NodeMCU8266.
I have gotten some code online and modified it with the help of a friend since I have zero experience with coding.
The code below scans an rfid card for data, and will then connect to a google sheet with google apps script. The code will show the web app url in the serial monitor that will send the data to google sheets automatically. However, I keep getting HTTPS GET: code 400 error and the data is not being sent to google sheets. But the web app url that shows up in serial monitor works when manually pasted into the address bar.
I have tried using the url fingerprint and the client.SetInsecure but it has not worked regardless of what i used. Any ideas what might be wrong? Your help is highly appreciated!
#include <SPI.h>
#include <MFRC522.h>
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <WiFiClientSecureBearSSL.h>
//-----------------------------------------------------------
const String web_app_url = "ENTER WEB APP URL HERE";
//-----------------------------------------------------------
#define WIFI_SSID "SSID"
#define WIFI_PASSWORD "PASSWORD"
//-----------------------------------------------------------
int blocks[] = {4,5,6,8,9,10,12,13,14,18};
#define blocks_len (sizeof(blocks) / sizeof(blocks[0]))
//-----------------------------------------------------------
//GPIO 0 --> D3
//GPIO 2 --> D4
//GPIO 4 --> D2
#define RST_PIN D3
#define SS_PIN D4
#define BUZZER D0
#define GreenLed D1 //When WIFI is connected, LED ON.
#define YellowLed D8 // When CARD is scanned, LED ON.
#define RedLed D2 //When NODEMCU is not connected to WIFI, LED ON
//-----------------------------------------
MFRC522 mfrc522(SS_PIN, RST_PIN);
MFRC522::MIFARE_Key key;
MFRC522::StatusCode status;
//-----------------------------------------
/* Be aware of Sector Trailer Blocks */
int blockNum = 2;
/* Create another array to read data from Block */
/* Legthn of buffer should be 2 Bytes more than the size of Block (16 Bytes) */
byte bufferLen = 18;
byte readBlockData[18];
//-----------------------------------------
// Fingerprint for demo URL, expires on ‎Monday, ‎May ‎2, ‎2022 7:20:58 AM, needs to be updated well before this date
//const uint8_t fingerprint[20] = {0xb3 0x3f 0xf3 0xe4 0x5f 0x76 0x59 0x2e 0xf9 0xa2 0x0b 0xf7 0x99 0x5e 0x44 0x89 0x21 0x4d 0x2e 0x22};
//const uint8_t fingerprint[20] = {0xb3, 0x3f, 0xf3, 0xe4, 0x5f, 0x76, 0x59, 0x2e, 0xf9, 0xa2, 0x0b, 0xf7, 0x99, 0x5e, 0x44, 0x89, 0x21, 0x4d, 0x2e, 0x22};
//0x9a 0x71 0xde 0xe7 0x1a 0xb2 0x2c 0xab 0x4f 0x23 0x64 0x9a 0xbc 0xef 0x62 0x56 0x20 0x4e 0x43 c
//0x9a, 0x71, 0xde,0xe7, 0x1a, 0xb2, 0x25, 0xca, 0xb4, 0xf2, 0x36, 0x49, 0xab, 0xce, 0xf6, 0x25, 0x62, 0x04, 0xe4, 0x3c
//0xb3 0x3f 0xf3 0xe4 0x5f 0x76 0x59 0x2e 0xf9 0xa2 0x0b 0xf7 0x99 0x5e 0x44 0x89 0x21 0x4d 0x2e 0x22 -LATEST
//b33ff3e45f76592ef9a20bf7995e4489214d2e22
//-----------------------------------------
/****************************************************************************************************
* setup() function
****************************************************************************************************/
void setup()
{
Serial.begin(9600);
WiFi.mode(WIFI_OFF); //Prevents reconnection issue (taking too long to connect)
delay(1000);
WiFi.mode(WIFI_STA); //This line hides the viewing of ESP as wifi hotspot
WiFi.begin(WIFI_SSID, WIFI_PASSWORD); //Connect to your WiFi router
Serial.println("");
Serial.print("Connecting to ");
Serial.print(WIFI_SSID);
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
//If connection successful show IP address in serial monitor
Serial.println("");
Serial.println("Connected");
digitalWrite(GreenLed, HIGH);
Serial.print("IP address: ");
Serial.println(WiFi.localIP()); //IP address assigned to your ESP
//--------------------------------------------------
/* pin outputs */
pinMode(BUZZER, OUTPUT);
pinMode(GreenLed, OUTPUT);
pinMode(YellowLed, OUTPUT);
pinMode(RedLed, OUTPUT);
//--------------------------------------------------
/* Initialize SPI bus */
SPI.begin();
//--------------------------------------------------
}
/****************************************************************************************************
* loop() function
****************************************************************************************************/
void loop()
{
if(WiFi.status() != WL_CONNECTED){
WiFi.disconnect();
WiFi.mode(WIFI_STA);
Serial.print("Reconnecting to ");
digitalWrite(RedLed, HIGH);
digitalWrite(GreenLed,LOW);
Serial.println(WIFI_SSID);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("Connected");
digitalWrite(RedLed, LOW);
digitalWrite(GreenLed, HIGH);
Serial.print("IP address: ");
Serial.println(WiFi.localIP()); //IP address assigned to your ESP
}
//------------------------------------------------------------------------
/* Initialize MFRC522 Module */
mfrc522.PCD_Init();
/* Look for new cards */
/* Reset the loop if no new card is present on RC522 Reader */
if ( ! mfrc522.PICC_IsNewCardPresent()) {return;}
/* Select one of the cards */
if ( ! mfrc522.PICC_ReadCardSerial()) {return;}
/* Read data from the same block */
Serial.println();
Serial.println(F("Reading last data from RFID..."));
//------------------------------------------------------------------------
String fullURL = "", temp;
for (byte i = 0; i < blocks_len; i++) {
ReadDataFromBlock(blocks[i], readBlockData);
if(i == 0){
temp = String((char*)readBlockData);
temp.trim();
fullURL = "data" + String(i) + "=" + temp;
}
else{
temp = String((char*)readBlockData);
temp.trim();
fullURL += "&data" + String(i) + "=" + temp;
}
}
//Serial.println(fullURL);
fullURL.trim();
fullURL = web_app_url + "?" + fullURL;
fullURL.trim();
Serial.println(fullURL);
//------------------------------------------------------------------------
digitalWrite(BUZZER, HIGH);
digitalWrite(YellowLed,HIGH);
delay(100);
digitalWrite(BUZZER, LOW);
delay(100);
digitalWrite(BUZZER, HIGH);
delay(100);
digitalWrite(BUZZER, LOW);
delay(100);
digitalWrite(BUZZER, HIGH);
delay(100);
digitalWrite(YellowLed, LOW);
digitalWrite(BUZZER, LOW);
delay(100);
//------------------------------------------------------------------------
//MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
if (WiFi.status() == WL_CONNECTED) {
//-------------------------------------------------------------------------------
std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
//-------------------------------------------------------------------------------
//uncomment following line, if you want to use the SSL certificate
//client->setFingerprint(fingerprint);
//or uncomment following line, if you want to ignore the SSL certificate
client->setInsecure();
//-------------------------------------------------------------------------------
HTTPClient https;
Serial.print(F("[HTTPS] begin...\n"));
//-------------------------------------------------------------------------------
//NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
if (https.begin(*client, (String)fullURL)){
//-----------------------------------------------------------------
// HTTP
Serial.print(F("[HTTPS] GET...\n"));
// start connection and send HTTP header
int httpCode = https.GET();
//-----------------------------------------------------------------
// httpCode will be negative on error
if (httpCode > 0) {
// HTTP header has been send and Server response header has been handled
Serial.printf("[HTTPS] GET... code: %d\n", httpCode);
// file found at server
}
//-----------------------------------------------------------------
else
{Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());}
//-----------------------------------------------------------------
https.end();
delay(1000);
}
//NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
else {
Serial.printf("[HTTPS} Unable to connect\n");
}
//NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
}
//MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
}
/****************************************************************************************************
* ReadDataFromBlock() function
****************************************************************************************************/
void ReadDataFromBlock(int blockNum, byte readBlockData[])
{
//----------------------------------------------------------------------------
/* Prepare the ksy for authentication */
/* All keys are set to FFFFFFFFFFFFh at chip delivery from the factory */
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
//----------------------------------------------------------------------------
/* Authenticating the desired data block for Read access using Key A */
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, blockNum, &key, &(mfrc522.uid));
//----------------------------------------------------------------------------s
if (status != MFRC522::STATUS_OK){
Serial.print("Authentication failed for Read: ");
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
//----------------------------------------------------------------------------
else {
Serial.println("Authentication success");
}
//----------------------------------------------------------------------------
/* Reading data from the Block */
status = mfrc522.MIFARE_Read(blockNum, readBlockData, &bufferLen);
if (status != MFRC522::STATUS_OK) {
Serial.print("Reading failed: ");
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
//----------------------------------------------------------------------------
else {
readBlockData[16] = ' ';
readBlockData[17] = ' ';
Serial.println("Block was read successfully");
}
//----------------------------------------------------------------------------
}

Arduino+Ethernet shield. It does not connect to a server by local name, but do connect by the IP

I am quite new to Arduino, so probably it is a newby question.
I have a local server having local name "raspberrypi.local". It is visible ("ping raspberrypi.local" and "ssh raspberrypi.local" work) by other machines in the same local network. However, I cannot connect to it from Arduino by that name. If I change the name to IP everything works. How, if possible, to make it work also by local name?
The sketch is bellow.
#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h> // MQTT
byte mac [ ] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED } ;
//byte server[] = { 192, 168, 199, 17 }; // THIS IS WORKING
char server[] = "raspberrypi.local"; // THIS IS NOT
char clientName[] = "tmp_client";
EthernetClient ethClient;
// Time to store the last MQTT access
unsigned long lastMqtt = 0;
void callback(char* topic, byte* payload, unsigned int length) {
payload[length] = '\0';
Serial.println(topic);
}
PubSubClient client(server, 1883, callback, ethClient);
void connect_mqtt_client() {
if (client.connect(clientName)) {
client.subscribe("/tmp/in/#"); // WITH IP IT IS HERE
Serial.println("connected");
} else {
Serial.println("NOT(!) connected"); // WITH LOCAL NAME IT IS ALWAYS HERE
}
}
void setup ( ) {
Serial.begin( 9600 );
Ethernet.begin( mac );
Serial.print ( "IP:" ) ;
Serial.println ( Ethernet.localIP ( ) ) ;
connect_mqtt_client();
}
void loop ( ) {
if (lastMqtt > millis()) {
lastMqtt = 0;
}
client.loop();
if (millis() > (lastMqtt + 10000)) {
if( !client.connected() ) {
connect_mqtt_client();
}
if( client.connected() ) {
client.publish("/tmp/out", "CRYA CRYA");
}
lastMqtt = millis();
}
delay(1000);
}

After assigning static IP to my ESP32 server doesn't respond anymore

So I've got ESP32 acting as a server, and when calling http://IP_OF_ESP32:7777/SOMETEXT my code enables me to view the text written after the slash, the problem is that after assigning static IP to my ESP32 it doesn't work anymore here's my code
#include <WiFi.h>
const char* ssid = "Inovec1";
const char* password = "ccb255fd8f52";
WiFiServer server(7777);
IPAddress local_IP(192, 168, 121, 100);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 0, 0);
IPAddress primaryDNS(8, 8, 8, 8);
IPAddress secondaryDNS(8, 8, 4, 4);
void setup() {
Serial.begin(115200);
WiFi.config(local_IP,gateway,subnet,primaryDNS, secondaryDNS);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print(".");
}
Serial.println(WiFi.localIP());
server.begin();
}
void loop() {
WiFiClient client = server.available();
String message;
while(client.available()){
char c = client.read();
message += c;
}
String command = getCommand(message);
if(command.length()>0)
Serial.println(command);
}
String getCommand(String s){
String toFind1 = "GET /";
String toFind2 = " HTTP";
int start = s.indexOf(toFind1)+toFind1.length();
int end = s.indexOf(toFind2);
return s.substring(start,end);
}
So as a first try give your ESP a IP address within the address range of your PC.
IPAddress local_IP(192, 168, 0, 10);
If that works ( I assume there is no other device with that address)
your problem is not the firmware/program but your routing.
(Routing, Subnets and so on is a topic on its own)
Try this sketch, Ip Adress have to be in the same subnet.
#include <WiFi.h>
const char* ssid = "yourSSID";
const char* password = "yourPWD";
IPAddress local_IP(192, 168, 1, 139);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress primaryDNS(8, 8, 8, 8);
void setup()
{
Serial.begin(115200);
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
if (!WiFi.config(local_IP, gateway, subnet, primaryDNS)) { //just one DNS and Configuration after connect
Serial.println("STA Failed to configure");
}
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected!");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
Serial.print("ESP Mac Address: ");
Serial.println(WiFi.macAddress());
Serial.print("Subnet Mask: ");
Serial.println(WiFi.subnetMask());
Serial.print("Gateway IP: ");
Serial.println(WiFi.gatewayIP());
Serial.print("DNS: ");
Serial.println(WiFi.dnsIP());
}
void loop()
{
}

Can connect through ethernet shield but not when using MQTT on my arduino

I have been trying to send messages via MQTT from my Arduino to my amazon web server. The following code connects the ethernet client but not the MQTT client. Why would my MQTT client not be connecting?
#include <SPI.h>
#include <Ethernet.h>
#include <PubSubClient.h>
byte mac[] = { 0x12, 0x42, 0x98, 0x85, 0x49, 0x3A }; //MAC address of server
char server[] = "http://52.1.29.117/"; //web address of server
IPAddress ip(172, 31, 51, 13); //IP address of server
void callback(char* topic, byte* payload, unsigned int length) {
// handle message arrived
}
EthernetClient ethClient;
PubSubClient client(server, 80, callback, ethClient);
void setup()
{
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
// start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
Ethernet.begin(mac, ip);
}
delay(1000);
Serial.println("connecting...");
if (ethClient.connect(server, 80)) {
Serial.println("connected");
// Make a HTTP request:
ethClient.println("GET /search?q=arduino HTTP/1.1");
ethClient.println("Host: www.google.com");
ethClient.println("Connection: close");
ethClient.println();
}
else {
Serial.println("connection failed");
}
// if (client.connect(server)) {
if (client.connect(server, "ubuntu", "")) {
Serial.print("Data sent/n");
client.publish("hello/world","hello world");
client.subscribe("hiWorld");
}
else {
Serial.print("nope");
}
}
void loop()
{
client.loop();
}
IIRC AWS only opens a couple of specific ports, this may help you open up some more:
http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/authorizing-access-to-an-instance.html

Use of select in c++ to do a timeout in a protocol to transfer files over serial port

I have a function to write data to the serial port with a certain protocol. When the function writes one frame, it waits for one answer of receiver. If no answer is received it has to resend data during 3 timeouts and in the end of 3 timeouts with no success, close the communication...
I have this function:
int serial_write(int fd, unsigned char* send, size_t send_size) {
......
int received_counter = 0;
while (!RECEIVED) {
Timeout.tv_usec = 0; // milliseconds
Timeout.tv_sec = timeout; // seconds
FD_SET(fd, &readfs);
//set testing for source 1
res = select(fd + 1, &readfs, NULL, NULL, &Timeout);
//timeout occurred.
if (received_counter == 3) {
printf(
"Connection maybe turned off! Number of resends exceeded!\n");
exit(-1);
}
if (res == 0) {
printf("Timeout occured\n");
write(fd, (&I[0]), I.size());
numTimeOuts++;
received_counter++;
} else {
RECEIVED = true;
break;
}
}
......
}
I have verified that this function, when it goes into timeout, does not resend the data. Why?