WiFi (ESP8266) und MLX90614 an ThingSpeak

Hallo liebe Profis

Ich bin am verzweifeln... In meinem Studium habe ich ein Projekt erhalten, bei welchem ich Temperaturen messen soll und diese Daten übers Internet abrufen soll. Nun habe ich als völliger Anfänger mir den Starterkit von Arduino Uno R3 geholt, dazu den Infrarotsensor MLX90614 und das WiFi-Modul ESP8266. Ich konnte beides einzeln in Betrieb nehmen. Das heisst, ich habe ein Projekt gefunden, mit dem ich simulierte Daten ins Internet senden konnte und diese bei ThingSpeak abrufen konnte. Den Temperatursensor habe ich auch zum laufen gekriegt und per seriellen Monitor die Temperaturen ablesen können.

Nun zu meinem Problem. Irgendwie muss ich das jetzt verbinden, und da es kein Kochrezept dazu gibt, bin ich völlig aufgeschmissen!

Kann mir hier irgendjemand helfen? Was braucht ihr von mir, damit ihr mir helfen könnt?

Ich bin für jede Antwort sehr dankbar, muss das Projekt bald abgeben :(

Schöne Grüsse Romano

Romano16: Kann mir hier irgendjemand helfen? Was braucht ihr von mir, damit ihr mir helfen könnt?

Hallo Romano,

wie wäre es wenn du uns deine zwei Sketche zeigst, die funktionieren? Ohne die können wir gar nichts sagen...

@TO: Was studierst Du denn? Ich hoffe nicht Elektronik oder Informatik.

Gruß Tommy

Natürlich, sorry hätte ich auch selbst drauf kommen können…

Sketch für den Infrarot-Sensor:

#include <Adafruit_MLX90614.h>

#include <Wire.h>



Adafruit_MLX90614 mlx = Adafruit_MLX90614();

void setup() {
Serial.begin(9600);

Serial.println("Adafruit_MLX90614");

mlx.begin();
}

void loop() {
Serial.print("Ambient = "); Serial.print(mlx.readAmbientTempC());
Serial.print("*C\tObject = "); Serial.print(mlx.readObjectTempC()); Serial.println("*C");
Serial.print("Ambient = "); Serial.print(mlx.readAmbientTempF());
Serial.print("*F\tObject = "); Serial.print(mlx.readObjectTempF()); Serial.println("*F");

Serial.println();
delay(2000);
}

Sketch für WiFi Verbindung mit simulierten Daten:

#include <SoftwareSerial.h>
#define RX 10
#define TX 11
String AP = "FRITZ!Box 7412";       // CHANGE ME
String PASS = "53651686828646504587"; // CHANGE ME
String API = "P6WO274NF1Z4Y4Z2";   // CHANGE ME
String HOST = "api.thingspeak.com";
String PORT = "80";
String field = "field1";
int countTrueCommand;
int countTimeCommand; 
boolean found = false; 
int valSensor = 1;
SoftwareSerial esp8266(RX,TX); 


void setup() {
Serial.begin(9600);
esp8266.begin(115200);
sendCommand("AT",5,"OK");
sendCommand("AT+CWMODE=1",5,"OK");
sendCommand("AT+CWJAP=\""+ AP +"\",\""+ PASS +"\"",20,"OK");
}
void loop() {
valSensor = getSensorData();
String getData = "GET /update?api_key="+ API +"&"+ field +"="+String(valSensor);
sendCommand("AT+CIPMUX=1",5,"OK");
sendCommand("AT+CIPSTART=0,\"TCP\",\""+ HOST +"\","+ PORT,15,"OK");
sendCommand("AT+CIPSEND=0," +String(getData.length()+4),4,">");
esp8266.println(getData);delay(1500);countTrueCommand++;
sendCommand("AT+CIPCLOSE=0",5,"OK");
}
int getSensorData(){
return random(1000); // Replace with 
}
void sendCommand(String command, int maxTime, char readReplay[]) {
Serial.print(countTrueCommand);
Serial.print(". at command => ");
Serial.print(command);
Serial.print(" ");
while(countTimeCommand < (maxTime*1))
{
  esp8266.println(command);//at+cipsend
  if(esp8266.find(readReplay))//ok
  {
    found = true;
    break;
  }

  countTimeCommand++;
}

if(found == true)
{
  Serial.println("OYI");
  countTrueCommand++;
  countTimeCommand = 0;
}

if(found == false)
{
  Serial.println("Fail");
  countTrueCommand = 0;
  countTimeCommand = 0;
}

found = false;
}

Ich würde ein dreifachen Rückwärstssalto schlagen, wenn ihr mir helfen könnt und wir das zum laufen kriegen :smiley:

Schöne Grüsse
Romano

Sieht doch schonmal gut aus, aber benutzte doch bitte die Code Tags oben links im Editorfenster. Da ist der Code auch auf dem Handy besser lesbar...

So wie ich es sehe, schließt du den ESP und den Sensor an den Arduino. Hat das einen bestimmten Grund? Warum nicht ohne Arduino und direkt an den ESP?

Mein Vorschlag: lasse den Arduino weg und nehme nur den ESP. Letztendlich ist es ja nur ein URL Aufruf der IP "api.thingspeak.com/update?api_key=...". Ein entsprechender Sketch ist bei den Beispielsketchs zu finden.

PS: nächstes mal lässt du deinen API Key im Code draußen, wenn du ihn postest. Gilt für alle Passwörter.

Ohje, ich oute mich mit jedem Satz mehr als Anfänger ::slight_smile:

Ich versuchs nochmal:

Sketch für den Infrarot-Sensor:

#include <Adafruit_MLX90614.h>

#include <Wire.h>



Adafruit_MLX90614 mlx = Adafruit_MLX90614();

void setup() {
  Serial.begin(9600);

  Serial.println("Adafruit_MLX90614");

  mlx.begin();
}

void loop() {
  Serial.print("Ambient = "); Serial.print(mlx.readAmbientTempC());
  Serial.print("*C\tObject = "); Serial.print(mlx.readObjectTempC()); Serial.println("*C");
  Serial.print("Ambient = "); Serial.print(mlx.readAmbientTempF());
  Serial.print("*F\tObject = "); Serial.print(mlx.readObjectTempF()); Serial.println("*F");

  Serial.println();
  delay(2000);
}

Sketch für WiFi Verbindung mit simulierten Daten:

#include <SoftwareSerial.h>
#define RX 10
#define TX 11
String AP = "xxxx";       // CHANGE ME
String PASS = "xxxx"; // CHANGE ME
String API = "xxxx";   // CHANGE ME
String HOST = "api.thingspeak.com";
String PORT = "80";
String field = "field1";
int countTrueCommand;
int countTimeCommand; 
boolean found = false; 
int valSensor = 1;
SoftwareSerial esp8266(RX,TX); 
 
  
void setup() {
  Serial.begin(9600);
  esp8266.begin(115200);
  sendCommand("AT",5,"OK");
  sendCommand("AT+CWMODE=1",5,"OK");
  sendCommand("AT+CWJAP=\""+ AP +"\",\""+ PASS +"\"",20,"OK");
}
void loop() {
 valSensor = getSensorData();
 String getData = "GET /update?api_key="+ API +"&"+ field +"="+String(valSensor);
sendCommand("AT+CIPMUX=1",5,"OK");
 sendCommand("AT+CIPSTART=0,\"TCP\",\""+ HOST +"\","+ PORT,15,"OK");
 sendCommand("AT+CIPSEND=0," +String(getData.length()+4),4,">");
 esp8266.println(getData);delay(1500);countTrueCommand++;
 sendCommand("AT+CIPCLOSE=0",5,"OK");
}
int getSensorData(){
  return random(1000); // Replace with 
}
void sendCommand(String command, int maxTime, char readReplay[]) {
  Serial.print(countTrueCommand);
  Serial.print(". at command => ");
  Serial.print(command);
  Serial.print(" ");
  while(countTimeCommand < (maxTime*1))
  {
    esp8266.println(command);//at+cipsend
    if(esp8266.find(readReplay))//ok
    {
      found = true;
      break;
    }
  
    countTimeCommand++;
  }
  
  if(found == true)
  {
    Serial.println("OYI");
    countTrueCommand++;
    countTimeCommand = 0;
  }
  
  if(found == false)
  {
    Serial.println("Fail");
    countTrueCommand = 0;
    countTimeCommand = 0;
  }
  
  found = false;
 }

Ich hoffe dieses Mal ist es leserlicher?

Gruss
Romano

Hi

Nichts für ungut - aber wenn Das Deine Einstellungen für Dein heimisches Netzwerk sind, solltest Du Diese bei Gelegenheit ändern :o .

Immer, wenn Passworte irgendwo eingetragen werden müssen, sollten Diese vor Veröffentlichung ge-x-t werden.

Jedem ist klar, daß Da ein Passwort hin muß und Dir steigen nicht gleich die Nachbarn ins WLan ein.

Zum eigentlichen Problem kann ich Dir leider nicht helfen. Für die Zukunft: Du kannst ALLE Deine Posts jederzeit ändern - als Neuling leider nur alle 15 Minuten (bis 100 Posts).

MfG

PS: Wenn Das Dein aktuelles Passwort war, solltest Du Das trotzdem zeitnah ändern - man weiß nicht, ob Google schon geschaut hat. (sollte man ja eh öfter machen ... jo)

Der einzige Grund warum ich das so mache ist, dass ich keine Ahnung habe, wie ich das dann zusammen verbinden soll?

Ich durchstöbere aber dann nochmal die Beispiel-Sketches.

Gruss Romano

Schau dir mal den HTTPSRequest Sketch an. Mit dem solltest du es hinbekommen. Bei mir läuft der ohne Probleme... Wenn du noch Frage hast, nur her mit.

Zudem solltest du dir dann anschauen, wie man einen ESP8266 mit einem Arduino oder USB zu TTL Modul programmiert.

Klingt zwar jetzt nach viel, aber glaub mir, im Endeffekt ist es deutlich leichter und die Lösung ist die sauberste.

Vielen Dank für die Hinweise bezüglich Datensicherheit. Das Netzwerk wurde speziell und nur für diesen Zweck eingerichtet, also ist nix zu holen und wird bei Erfolg wieder deaktiviert :) Trotzdem Danke für eure Aufmerksamkeit!!

Schöne Grüsse Romano

Doctor236, ich kriegs nicht hin... Habe jetzt mal bisschen nach dem HTTPSRequest gesucht und stosse immer wieder auf Sketches, die aber ein zusätzliches Modul benötigen (Node, Ethernet shield..?). Da ich so schon mein Studentenbudget gesprengt habe mit diesem Projekt, wollte ich keine weiteren Teile kaufen. Mal abgesehen davon, dass bis ich die habe mir die Zeit ausgeht :D

Ich weiss, ich stelle mir das wahrscheinlich zu einfach vor, aber gibt es nicht eine Möglichkeit den Sketch mit den simulierten Daten irgendwie mit dem Sketch für den Temperatursensor zu vereinen?

Tausend Dank für deine Unterstützung und schöne Grüsse Romano

Lese dir mal das hier durch. Das ist genau das was du brauchst. Statt dem USB zu TTL verwendest du einfach deinen Arduino (Achtung! Auf dem Arduino MUSS ein leerer Sketch drauf sein!!!). Du brauchst hier keine weiteren Teile kaufen. Ein Node oder auch bekannt als NodeMCU ist im Prinzip ein ESP8266, es ist zwar meist ein 12E drauf, das ist aber fast egal. Das NodeMCU Board hat eben den Vorteil, dass Spannungswandler und TTL Adapter drauf sind und man nur ein USB Kabel benötigt. Wichtig ist, dass das was auf dem ESP8266 läuft auch auf dem NodeMCU läuft und auch andersrum. Wobei für dich ein NodeMCU Board wahrscheinlich die bessere Alternative ist, allein aus dem Grund, dass alles einfacher ist. Vorausgesetzt du willst es nicht batteriebetrieben haben, da ist das NodeMCU eine sehr schlechte Wahl.

Falls du das nicht willst (glaub mir, ist die bessere Variante) mache folgendes:

Neuen Sketch: Aus beiden den Setup-Teil übernehmen. Den Teil für den Request auch übernehmen. die getSensorData() Schleife rausschmeißen. Die Library von dem Sensor liefert dir 4 Werte (siehe dein erster Sketch). Den Wert den du brauchst schreibst du in eine Variable und hängst diese Variable an dein Request. Und fertig ist das Ding.

Erwarte jetzt bitte nicht, dass ich dir einen fertigen Code schreibe, das solltest schon du machen. Du solltest schließlich nachher wissen was du gemacht hast. Eigentlich ist es nur Zusammenkopieren. Fragen sind aber immer willkommen.

Viel Erfolg

PS: Glaub mir, der die erste Variante ist deutlich einfacher. Da musst du nicht mit AT-Commands arbeiten.

warum nimmst keinen NodeMCU, da kannst du dir das UNO-ESP-Geraffel sparen. oder wozu einen UNO, wenn das ganze auch ein ESP direkt verarbeiten kann?

Tausend Dank!!! Ich werde das morgen direkt versuchen und klar, ich will und muss es ja auch verstehen, werde ja auch geprüft x)

Danke danke danke:)

So, habe den Code nun nach bestem Wissen geändert und versucht zu überprüfen. Leider scheitere ich nun an einer fehlenden Bibliothek, genannt FS.h. Nach bisschen googeln scheint das eine Bibliothek zu sein, die abhängig von dem gewählten Board in Arduino vorhanden ist, oder eben auch nicht. Scheint als wäre sie vorhanden, wenn ich das ESP als Board auswähle und wenn ich den UNO als Board wähle nicht. Was ich aber nicht verstehe ist, dass ich die Meldung vorher nicht hatte, bei den einzelnen Sketchen und da aber auch immer das UNO als Board eingestellt hatte.

Hier mal den Code, den ich angepasst habe:

#include <SoftwareSerial.h>
#define RX 10
#define TX 11

String AP = "FRITZ!Box 7412";       // CHANGE ME
String PASS = "x"; // CHANGE ME
String API = "P6WO274NF1Z4Y4Z2";   // CHANGE ME
String HOST = "api.thingspeak.com";
String PORT = "80";
String field = "field1";
int countTrueCommand;
int countTimeCommand; 
boolean found = false;
String valSensor;
SoftwareSerial esp8266(RX,TX); 

#include <Adafruit_MLX90614.h>

#include <Wire.h>



Adafruit_MLX90614 mlx = Adafruit_MLX90614();


void setup() {
{
 Serial.begin(9600);
 esp8266.begin(115200);
 sendCommand("AT",5,"OK");
 sendCommand("AT+CWMODE=1",5,"OK");
 sendCommand("AT+CWJAP=\""+ AP +"\",\""+ PASS +"\"",20,"OK");
}  

{
 Serial.begin(9600);

 Serial.println("Adafruit_MLX90614");

 mlx.begin();
} // put your setup code here, to run once:

}
void loop() {
 valSensor = Serial.print(mlx.readObjectTempC());
 String getData = valSensor;
sendCommand("AT+CIPMUX=1",5,"OK");
sendCommand("AT+CIPSTART=0,\"TCP\",\""+ HOST +"\","+ PORT,15,"OK");
sendCommand("AT+CIPSEND=0," +String(getData.length()+4),4,">");
esp8266.println(getData);delay(1500);countTrueCommand++;
sendCommand("AT+CIPCLOSE=0",5,"OK");
}

 
void sendCommand(String command, int maxTime, char readReplay[]) {
 Serial.print(countTrueCommand);
 Serial.print(". at command => ");
 Serial.print(command);
 Serial.print(" ");
 while(countTimeCommand < (maxTime*1))
 {
   esp8266.println(command);//at+cipsend
   if(esp8266.find(readReplay))//ok
   {
     found = true;
     break;
   }
 
   countTimeCommand++;
 }
 
 if(found == true)
 {
   Serial.println("OYI");
   countTrueCommand++;
   countTimeCommand = 0;
 }
 
 if(found == false)
 {
   Serial.println("Fail");
   countTrueCommand = 0;
   countTimeCommand = 0;
 }
 
 found = false;
}

Wie kommt das zustande? Fehlt mir eine Bibliothek?

Das ist etwas merkwürdig...

Poste bitte mal die komplette Fehlermeldung. Aktiviere bitte davor in den Einstellungen: Ausführliche Ausgabe während Kompilierung (und Upload).

Damit dein Code übersichtlicher wird und auch funktionieren kann: Als erstes alle Library einfügen, danach kommen Konstanten, dann der Setup Teil und dann der loop Teil. Die vielen Klammern im Setup Teil kannst du dir sparen, da reichen zwei: Ganz an Anfang und ganz am Ende. Die ersten zwei Zeilen in deiner loop() sind auch komplett falsch. So kann das nicht klappen.

Nehme es mir nicht übel, aber du solltest dich erstmal mit den Grundlagen beschäftigen, an denen scheiterst du jetzt schon. Da ist glaube ich die Library das kleinste Problem.

Und wie gesagt: Für dich wäre ein NodeMCU tatsächlich die bessere Wahl (sage ja nicht nur ich, sondern auch spunky1a. Zumindest aber mal, wenn du keine 6 Euro ausgeben willst, solltest du den UNO aus dem Spiel lassen und nur mit dem ESP und dem Sensor arbeiten.

Kaum den Code aufgeräumt und die mehrfachen gleichen Bibliotheken gelöscht funktioniert es mit dem Upload!

Also ich benutze das UNO Board als Schnittstelle zum PC, ansonsten bräuchte ich ja ein USB zu TTL Teil (glaube ich zumindest), welches mir die Schnittstelle ermöglicht?

Das Programm scheint jetzt mit dem folgenden Code zu laufen, ohne Fehlermeldung. Hier nochmals der Code:

#include <SoftwareSerial.h>
#define RX 10
#define TX 11
#include <Adafruit_MLX90614.h>
#include <Wire.h>
SoftwareSerial esp8266(RX,TX); 
String AP = "FRITZ!Box 7412";       // CHANGE ME
String PASS = "X"; // CHANGE ME
String API = "P6WO274NF1Z4Y4Z2";   // CHANGE ME
String HOST = "api.thingspeak.com";
String PORT = "80";
String field = "field1";
int countTrueCommand;
int countTimeCommand; 
boolean found = false;
String valSensor;

Adafruit_MLX90614 mlx = Adafruit_MLX90614();

void setup() 
{
  Serial.begin(9600);
  esp8266.begin(115200);
  sendCommand("AT",5,"OK");
  sendCommand("AT+CWMODE=1",5,"OK");
  sendCommand("AT+CWJAP=\""+ AP +"\",\""+ PASS +"\"",20,"OK");

  Serial.begin(9600);

  Serial.println("Adafruit_MLX90614");

  mlx.begin();
}

void loop() {
  valSensor = Serial.print(mlx.readObjectTempC());
  String getData = valSensor;
sendCommand("AT+CIPMUX=1",5,"OK");
 sendCommand("AT+CIPSTART=0,\"TCP\",\""+ HOST +"\","+ PORT,15,"OK");
 sendCommand("AT+CIPSEND=0," +String(getData.length()+4),4,">");
 esp8266.println(getData);delay(1500);countTrueCommand++;
 sendCommand("AT+CIPCLOSE=0",5,"OK");
}
 
void sendCommand(String command, int maxTime, char readReplay[]) {
  Serial.print(countTrueCommand);
  Serial.print(". at command => ");
  Serial.print(command);
  Serial.print(" ");
  while(countTimeCommand < (maxTime*1))
  {
    esp8266.println(command);//at+cipsend
    if(esp8266.find(readReplay))//ok
    {
      found = true;
      break;
    }
  
    countTimeCommand++;
  }
  
  if(found == true)
  {
    Serial.println("OYI");
    countTrueCommand++;
    countTimeCommand = 0;
  }
  
  if(found == false)
  {
    Serial.println("Fail");
    countTrueCommand = 0;
    countTimeCommand = 0;
  }
  
  found = false;
 }

Und hier die Ausgabe am seriellen Monitor:

  1. at command => AT+CIPSTART=0,“TCP”,“api.thingspeak.com”,80 OYI
  2. at command => AT+CIPSEND=0,5 OYI
  3. at command => AT+CIPCLOSE=0 OYI
    1037.555. at command => AT+CIPMUX=1 OYI
  4. at command => AT+CIPSTART=0,“TCP”,“api.thingspeak.com”,80 OYI
  5. at command => AT+CIPSEND=0,5 OYI
  6. at command => AT+CIPCLOSE=0 OYI
    33.1710. at command => AT+CIPMUX=1 OYI
  7. at command => AT+CIPSTART=0,“TCP”,“api.thingspeak.com”,80 Fail

Scheint als würde die Temperatur korrekt entnommen werden (1037 Grad, liegt an einem kleinen Wackelkontakt, wird noch fix verlötet).

Auf ThingSpeak ist allerdings nichts angekommen. Liegt das an den ersten zwei Zeilen? Ich habe mich bisschen schlau gelesen und wollte den gemessenen Wert als Int angeben. Also habe ich bei den Konstanten erst angegeben Int valSensor. Da dann aber die Fehlermeldung kam, dass bei einem Int die länge nicht angegeben werden kann (nicht wie bei String), war ich mir unsicher, ob der gelesene Wert von MLX nicht schon als String ausgegeben wird… Des Weiteren weiss ich auch nicht, wie die Ausgabe sein muss, damit ThingSpeak diese richtig verarbeiten kann.

Also um vielleicht konkret zu fragen, folgendes ist meiner Meinung nach der Befehl, bei welchem der gelesene Wert an ThingSpeak gesendet wird:

sendCommand(“AT+CIPSEND=0,” +String(getData.length()+4),4,">");

Kann ich diesen String auch als Int umwandeln und ThingSpeak liest das noch korrekt?

Ich zweifle keine Sekunde an dem was du mir empfiehlst und die Antworten von Anderen auch bestätigen. Jedoch fehlen mir wahrscheinlich für beide Arten das UNO zu umgehen die entsprechenden Bauteile :-\

Ich hoffe ich habe jetzt nicht noch mehr Verwirrung gestiftet.

Vielen Dank für die Hilfe, ich weiss das echt zu schätzen!

Gruss

Ich kenne den Sensor nicht und die Library sowieso nicht. Das musst du ausprobieren. Nehme den Standartsketch und probier das mit Strings und Integer. ich kann mir nicht vorstellen, dass die Library die Werte als String ausgibt.

Und nochmal: Dir fehlen keine Bauteile. Du kannst den ESP auch ohne Arduino betreiben. Du brauchst den nur um den Sketch hochzuladen. Die beste Alternative für dich wäre das NodeMCU. Ich würde an deiner Stelle das ganze zumindest mal ohne Arduino machen.