Failing to send data to ThingSpeak Using Arduino Ethernet Shield

Sofia Fourkioti il 7 Giu 2022
Ultime attività Replicato da Christopher Stapels il 8 Giu 2022

Hi, there ! Need some serious help.... I have trouble trying to upload my data to my Channel. Any ideas to fix it?
Below you can see my code:
#include <ThingSpeak.h>// Η βιβλιοθήκη του ThingSpeak.
#include <SPI.h>
#include <Ethernet.h>
#include <SoftwareSerial.h>
#include <Servo.h> // Η βιβλιοθήκη του σερβοκινητήρα.
#include "DHT.h"
#include "MQ7.h"
//Για τον αισθητήρα DHT11.
#define DHTPIN 7
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
//Για τον φωτισμό.
#define DELAY 5000 // Καθυστέρηση μεταξύ μετρήσεων σε ms για τον φωτισμό.
#define VIN 5 // Τάση 5V.
#define R 10000 //Αντίσταση 10.000 Ω.
//Για τον αισθητήρα MQ7.
int MQ7pin = A0;
int MQ7Reading;
int MQ7led = 3;
//Για τον αισθητήρα Soil.
int val;
int soil_dig= 8;
int soil_analog = A1;
//Μεταβλητές για τον φωτισμό και για τον υπολογισμό lux.
const int sensorPin = A3; // Το pin στο οποίο συνδέεται ο αισθητήρας.
const int led = 12;
const int greenled = 10;
const int redled = 4;
const long onduration = 10000;
const long offduration = 30000;
int ledstate = HIGH;
long remembertime = 0;
int sensorVal; // Αναλογική τιμή από τον αισθητήρα.
int lux; //Τιμές για τα lux
int valvePin = 13; // Το pin στο οποίο συνδέεται το ρελέ, ώστε να ενεργοποιεί την ηλεκτροβάνα.
//Για τον αισθητήρα Ultrasonic.
#define echoPin 5 // Το echoPin.
#define trigPin 6 // To trigPin.
long duration; // Η διάρκεια που κάνει το ηχητικό κύμα να ταξιδέψει.
int distance; // Ο υπολογισμός της ταχύτητας του ηχητικού κύματος.
//Για τον αισθητήρα Rain.
const int rain_D = 2;//Ψηφιακή τιμή αισθητήρα βροχής.
const int rain_A = A2;//Αναλογική τιμή αισθητήρα βροχής.
int rain_val;// Μεταβλητή για την αποθήκευση της τιμής του αισθητήρα βροχής.
int r;// Μεταβλητή για την αποθήκευση της τιμής του αισθητήρα βροχής.
Servo servo; // Το όνομα του σερβοκινητήρα.
int servoPin = 11; // Το pin στο οποίο συνδέεται ο σερβοκινητήρας.
#define pwm 9 // Το pin στο οποίο συνδέεται ο ανεμιστήρας.
//Σύνδεση
String readString;
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //H mac address.
byte ip[] = {192,168,2,123};
EthernetClient client;
unsigned long myChannelNumber = 1*******; //Ο αριθμός του καναλιού.
const char * myWriteAPIKey = "****************"; //Το ΑΡΙ Κey του καναλιού.
const int updateInterval = 10000;
void setup() {
Serial.begin(9600);
ThingSpeak.begin(client);// Σύνδεση στο cloud του ThingSpeak.
dht.begin();
pinMode(MQ7led, OUTPUT);// Θέτει το led του MQ7 ως OUTPUT.
pinMode(trigPin, OUTPUT); // Θέτει το trigPin ως OUTPUT.
pinMode(echoPin, INPUT); // Θέτει το echoPin ως INPUT.
pinMode(rain_D, INPUT); // Θέτει το rain_D ως INPUT.
pinMode(rain_A, INPUT); // Θέτει το rain_A ως INPUT.
pinMode(servoPin, OUTPUT);// Θέτει το servoPin ως OUTPUT.
servo.attach(servoPin);// Σύνδεση σε pin της μεταβλητής του σερβοκινητήρα.
analogWrite(pwm, 255);// Γράφει μία αναλογική τιμή (PWM pin) σε ένα pin.
pinMode(soil_analog, INPUT); // Θέτει το soil_analog ως INPUT.
pinMode(soil_dig, INPUT);// Θέτει το soil_dig ως INPUT.
pinMode(valvePin, OUTPUT); //Θέτει το 13 ως OUTPUT pin, ώστε να στέλνει σήμα στο relay.
pinMode(led, OUTPUT); // Θέτει το ledPin ως output.
digitalWrite(led,ledstate);
pinMode(sensorPin, INPUT);// Θέτει το sensorPin ως INPUT.
pinMode(greenled, OUTPUT);// Θέτει το greenled ως OUTPUT.
pinMode(redled, OUTPUT);// Θέτει το redled ως OUTPUT.
}
void loop() {
Serial.println(F("======================================"));
Serial.println(F("Συνθήκες στο Θερμοκήπιο :"));
//DHT11
float t = dht.readTemperature();// Η θερμοκρασία σε °C.
float h = dht.readHumidity(); // Η υγρασία του χώρου.
float f = dht.readTemperature(true); //Η θερμοκρασία σε °F.
// Υπολογισμός του heat index, ο οποίος πρέπει να μετατραπεί σε Fahrenheit.
float hi = dht.computeHeatIndex(f, h);
Serial.print(F("Temperature: "));
Serial.print(t);
Serial.print(F("°C "));
Serial.print(F(" and "));
Serial.print(f);
Serial.print(F("°F\t"));
Serial.print(F("Humidity: "));
Serial.print(h);
Serial.print(F(" %\t"));
Serial.print(F("Heat index: "));
Serial.print(hi);
Serial.println(F(" °F"));
// Έλεγχος της θερμοκρασίας , ώστε να ενεργοποιείται ο ανεμιστήρας όποτε χρειάζεται.
if (t == 26)
{
analogWrite(pwm, 51);
Serial.print(F("Ταχύτητα ανεμιστήρα: 20% "));
delay(1000);
}
else if (t == 30)
{
analogWrite(pwm, 204);
Serial.print(F("Ταχύτητα ανεμιστήρα: 80% "));
delay(1000);
}
else if (t > 40 )
{
analogWrite(pwm, 255);
Serial.print(F("Ταχύτητα ανεμιστήρα: 100% "));
delay(1000);
Serial.print(F("\t"));
}
//MQ7
float g = analogRead(MQ7pin);
Serial.print(F("MQ7: "));
Serial.println(g);
// Έλεγχος της τιμής του MQ7, ώστε να ανάβει το led που αναπαριστά ανεμιστήρα.
if ( g < 200)
{
Serial.println(F("O ανεμιστήρας κλειστός - Φυσιολογική ποσότητα CO στον χώρο εργασίας."));
digitalWrite(MQ7led, LOW);
}
else if (201 < g && g < 220)
{
Serial.println(F("Η μέγιστη φυσιολογική ποσότητα CO για χώρους εργασίας ξεπεράστηκε!!!- Λειτουργία εξαερισμού στο 50%."));
digitalWrite(MQ7led,HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(MQ7led, LOW); // turn the LED off by making the voltage LOW
delay(1000);
}
if (g > 220)
{
Serial.println(F("Eπικίνδυνα αέρια CO !!!- Λειτουργία εξαερισμού στο 100%."));
digitalWrite(MQ7led, HIGH); // turn the LED on (HIGH is the voltage level)
delay(5000);
}
//Soil Humidity
int soil_analog_value = analogRead(soil_analog);
soil_analog_value = map(soil_analog_value, 0, 1023, 230, 0);//Συνάρτηση map για μετρατροπή τιμής σε %.
val = digitalRead(soil_dig);
Serial.print(F("Soil moisture (Αναλογική τιμή) : "));
Serial.print(soil_analog_value);
Serial.print(F("\t"));
//Έλεγχος υγρασίας εδάφους για αυτόματο πότισμα.
if (soil_analog_value < 50)
{
digitalWrite(valvePin, LOW); //Όταν η τιμή γίνει LOW,τότε και το relay πρέπει να λάβει τιμή LOW.
Serial.println(F("relay on"));
}
else
{
digitalWrite(valvePin, HIGH); //Όταν η τιμή γίνει HIGH, τότε και το relay πρέπει να λάβει τιμή HIGH.
Serial.println(F("relay off"));
}
//Ultrasonic Sensor
// Αρχικοποίηση του trigPin.
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Το trigPin σε HIGH (ACTIVE) για 10 μs.
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
//Διαβάζει το echoPin, επιστρέφει το χρόνο του ηχητικού κύματος σε μs.
duration = pulseIn(echoPin, HIGH);
// Υπολογισμός απόστασης.
distance = (duration - 10) * 0.034 / 2;
Serial.println("");
Serial.print(F("Distance: "));
Serial.print(distance);
Serial.print(F(" cm"));
//Rain Sensor
rain_val = digitalRead(rain_D);
r = analogRead (rain_A);
r = abs ((100*r-40000)/623);
Serial.println(F(""));
Serial.print(F("Rain (Αναλογική τιμή) :"));
Serial.print(r);
Serial.print(F("\t"));
Serial.print(F("Rain (Ψηφιακή τιμή) :"));
Serial.print(rain_val);
//Έλεγχος για λειτουργία του σερβοκινητήρα.
if ((rain_val != HIGH) && (distance < 9)) {
servo.write(0);
}
if ((rain_val != HIGH) && (distance > 9)) {
servo.write(90);
}
else {
servo.write(0);
}
//Μέτρηση τιμής της φωτοαντίστασης και μετατροπή σε lux.
sensorVal = analogRead(sensorPin);
lux=sensorRawToPhys(sensorVal);
Serial.print("Raw value from sensor= ");
Serial.println(sensorVal); //Τύπωση αναλογικής τιμής.
Serial.print("Physical value from sensor = ");
Serial.print(lux); //Τύπωση αναλογικής τιμής.
Serial.println(" lumen");
//Συνθήκες για το άνοιγμα των led και των κουρτινών σκίασης σε διάφορες γωνίες.
if (ledstate == HIGH){
if((millis() - remembertime) >= onduration){
ledstate = LOW;
remembertime = millis();
}
}
if (ledstate == LOW){
if((millis() - remembertime) >= offduration){
ledstate = HIGH;
remembertime = millis();
}
}
//Lux.
if (lux < 100){
digitalWrite(led, HIGH);
if (lux < 200){
digitalWrite(greenled, ledstate);
if (lux < 300){
digitalWrite(redled, ledstate);
}}}
if(lux > 350){
digitalWrite(redled, LOW);
if(lux > 450){
digitalWrite(greenled, LOW);
if (lux>600){
digitalWrite(led, LOW);
}}}
else
digitalWrite(led,ledstate);
//Τα δεδομένα για το ThingSpeak, τα οποία στέλνονται στα αριθμημένα fields.
ThingSpeak.writeField(myChannelNumber,1,t, myWriteAPIKey);
ThingSpeak.writeField(myChannelNumber,2,h ,myWriteAPIKey);
ThingSpeak.writeField(myChannelNumber,3,g ,myWriteAPIKey);
ThingSpeak.writeField(myChannelNumber,4,soil_analog_value, myWriteAPIKey);
ThingSpeak.writeField(myChannelNumber,5,distance, myWriteAPIKey);
ThingSpeak.writeField(myChannelNumber,6,r, myWriteAPIKey);
delay(15000);
}
int sensorRawToPhys(int raw){
// Conversion rule
float Vout = float(raw) * (VIN / float(1023));// Conversion analog to voltage
float RLDR = (R * (VIN - Vout))/Vout; // Conversion voltage to resistance
int phys=500/(RLDR/1000); // Conversion resitance to lumen
return phys;
}
Christopher Stapels
Christopher Stapels il 7 Giu 2022
Please consider starting with the code from the ThingSpeak library for arduino.
Are you seeing any data in ThingSpeak? What have you tried?
To write multiple fields, use setfield and then write fields. See the examples in the library for the correct syntax. The way you have it is for seperate writes to each field. The first one might work, but the next five would be rejected for being too fast.
Sofia Fourkioti
Sofia Fourkioti il 7 Giu 2022
I also tried the following :
ThingSpeak.setField(1,t);
ThingSpeak.setField(2,h);
int x = ThingSpeak.writeField(myChannelNumber, 1, t, myWriteAPIKey);
if(x == 200){
Serial.println("Channel update successful.");
}
else{
Serial.println("Problem updating channel. HTTP error code " + String(x));
}
This returns back the error -302. I can't find how to fix this error.
Christopher Stapels
Christopher Stapels il 7 Giu 2022
Did you look at the examples in the library?
You are using the wrong functions.
Sofia Fourkioti
Sofia Fourkioti il 7 Giu 2022
Yes, you are right. I managed to create the following, but without any luck. (I followed the examples.)
ThingSpeak.setField(1,t);
ThingSpeak.setField(2,h);
int x = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
if(x == 200){
Serial.println("Channel update successful.");
}
else{
Serial.println("Problem updating channel. HTTP error code " + String(x));
}
delay(16000);
I think I use the functions the right way now, but still I can't send anything to ThingSpeak. It still returns -302 error, but I can't find anything about that.
Vinod
Vinod il 8 Giu 2022

A 302 means there is a network redirection happening. Perhaps your network has a proxy that is doing redirects.

Perhaps try moving your device to a different network?

Sofia Fourkioti
Sofia Fourkioti il 8 Giu 2022
Well, I think the solution may be to use a different network. How can I do that?
Christopher Stapels
Christopher Stapels il 7 Giu 2022
Thanks! Im glad you checked out the library. Sorry it is still not working. Can you confirm that you can update your channel via http in a browser window? You can get the right fromat from the API keys tab of your channel.
You can see the -302 error on the Thingspeak library main github page, but its not very helpful description.
Can you share the part of your code where you instantiate the HTTP client? Usually there is a wifi client but that wont be needed in your case. You may need an ethernet client using another library.
If the browser writing works, I would try writing a single field, using the command you had before (but just one of them). If that still fails, I would try switching to a different network.
Sofia Fourkioti
Sofia Fourkioti il 8 Giu 2022
Well I use the following;
//Σύνδεση
String readString;
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; //H mac address.
byte ip[] = {192,168,2,123};
EthernetClient client;
unsigned long myChannelNumber = 1*******; //Ο αριθμός του καναλιού.
const char * myWriteAPIKey = "****************"; //Το ΑΡΙ Κey του καναλιού.
const int updateInterval = 10000;
void setup() {
Serial.begin(9600);
ThingSpeak.begin(client);// Σύνδεση στο cloud του ThingSpeak.
}
If I use the Ethernet.begin(mac,ip) function, it sends data, but it also laggs the rest code.
To answer your question, when I update the channel via browser window it returns a number, which is the number of the total values in my channel, (plus one, which I think is the new value from the update it does).
For example, before I opened the link, the total values where 18075 and when the window opened, it showed 18076.
I also tried to write just one field, but it fails.
So I think I have to find a way to use a different network. Any suggestions?
Vinod
Vinod il 8 Giu 2022
Please refer to the documentation for Ethernet.begin. If you do not do that, your network connectivity is not established and it is no wonder you are getting a 302 - because your code can't reach the ThingSpeak server.
Sofia Fourkioti
Sofia Fourkioti il 8 Giu 2022
Yes I get it, but I can't understand why the code does not work well when I use the function Ethernet.begin. All the devices I have in the system start to malfunction. So, if I use it I send data, but my system is problematic. If I don't, I have a fully functional system but it can't send any data.
Is there a way to have them both?
Christopher Stapels
Christopher Stapels il 8 Giu 2022
I suggest you strip everything out, and start with just the ethernet code and thingspeak writing a constant number. Then add the sensors in one by one to see which is causing the problem.
Sofia Fourkioti
Sofia Fourkioti il 8 Giu 2022
I have done it before and I did it again.
I think it has to do with the interrupts of Ethernet library which causes jitter in the Servo library interrupt timings. The same thing is happening with the solenoid valve. Someone had posted to the forum the same problem but he couldn't find a solution.
Is there a library which doesn't need interrupts (for Servo)?
Christopher Stapels
Christopher Stapels il 8 Giu 2022
I suggest upgrading your hardware. My code for the esp32 works fine with servo and wifi connection to ThingSpeak (with various other GPIO in use). You can also get an MKR1000, or MKR1010, or nano 33 IoT. Perhaps the limited Uno memory is making hardware resources unavailable.
Christopher Stapels
Christopher Stapels il 8 Giu 2022
Its definitely not a long term solution, but take the device to your friends house, or work, (or your friends work),or home or school and try it there. That way we will know if it is the network. It does seem unlikely that that is the issue since your browser based post worked fine.
Another option you can try would be to use the MQTT interface, but that will be a little more work.