Windrad Daten an ThingSpeak

So zum ersten bin ich Blutiger Arduino Anfänger bitte habt Nachsicht!!!

Ich steh total an, darum hab ich mich jetzt hier angemeldet bestimmt kann mir hier wer
weiterhelfen.

Hab letztes Jahr damit begonnen mir ein Windrad zu bauen stehe nun kurz vor Fertigstellung.
Da ich es etwas entfernt von meinem Haus installieren muss und ich es jedoch immer etwas unter
Kontrolle haben möchte setze ich einen NodeMCU Esp8266 oben drauf der mir ständig die Drehzahl (halsensor)
und Temperatur (DS18B20) misst und natürlich über wlan an ThingSpeak schickt.
so kann ich jederzeit sehen was es grad treibt.

so in meinem selbst zusammengeschnippselten skech den ich selbst nur zur hälfte verstehe funktioniert
die Datenausgabe zumindest schon mal am seriellen Monitor jedoch bekomme ich sie nicht auf ThingSpeak
angezeigt.

Hab schon unzählige Stunden mit dem Sketch verbracht und rumprobiert ich bekomme es einfach nicht hin.

ich kopier jetzt mal meinen Sketch hier rein, bin gespannt was ihr dazu sagt.
ich möchte nochmal betonen ich bin blutiger Anfänger…

#include <OneWire.h>
#include <DallasTemperature.h>
#include “ThingSpeak.h”
#include “RunningMedian.h”
#include <ESP8266WiFi.h>

#define Upm D3
#define Temp D4

OneWire oneWire(Temp);
DallasTemperature DS18B20(&oneWire);

char temperaturStr[6];
uint8_t UPM_Pin = D3;
const int m_time = 5; //Messzeit für Upm

float UPM;
int UPM_ct;

unsigned long ThingspeakLastLogTime = 0;
unsigned long SensorenLetzteAktualisierung; // Hilfsvariable für Zeitmessung
int ThingspeakSampleTime = 30000; // Die schnellste Sample Time ist 15s ich empfehle
// 60s zu verwenden oder 300 Sekunden

int SensorenSampleTime = 1; // Zeit in s für Aktualisierung der

WiFiClient client;
int status = WL_IDLE_STATUS;

/(Thingspeak Eistellungen)/
unsigned long myChannelNumber = ; // Deine ThingSpeak Kanal Nummer
const char * myWriteAPIKey = "
"; // Dein ThingSpeak API Key

/(Wifi Einstellungen)/
char ssid[] = "
"; // Deine Wlan SSID (name)
char pass[] = "
**"; // Dein Wlan Passwort

void setup() {
WiFi.begin(ssid,pass); // Wlan Aktivieren und mit definiertem Netzwerk verbinden
ThingSpeak.begin(client); // ThingSpeak Client starten
Serial.begin(115200);
DS18B20.begin();
}

float getTemperatur() {
float temp;
do {
DS18B20.requestTemperatures();
temp = DS18B20.getTempCByIndex(0);
delay(100);
} while (temp == 85.0 || temp == (-127.0));
return temp;
}

void loop() {
meassure_UPM();

float temperatur = getTemperatur();
dtostrf(temperatur, 2, 2, temperaturStr);

Serial.print(" Upm: “);
Serial.print(Upm);
Serial.print(” Temp: ");
Serial.println(temperaturStr);
}

void meassure_UPM() {
UPM_ct = 0;
attachInterrupt(digitalPinToInterrupt(UPM_Pin), IntCallback, RISING);
delay(1000 * m_time);
UPM = (float)UPM_ct * (float)m_time * 2.4 ;
}

void IntCallback() {
UPM_ct ++;
}

/(Funktion um Daten an Thingspeak zu senden)*****/
void MesswerteSenden() {

if (millis() - ThingspeakLastLogTime > ThingspeakSampleTime) {
ThingSpeak.setField(3, Upm);
ThingSpeak.setField(4, temperaturStr);
ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
ThingspeakLastLogTime = millis();
}
}

Hi

Ok - wäre doch fast nicht aufgefallen, daß Du blutiger Anfänger bist ... dann noch mit einem Count von 1 - stünde dort eine 600, hätte ich Dir Das wahrscheinlich gar nicht abgekauft!!

Hättest Du Deinen Sketch in Code-Tags gesetzt, wäre Das wohl auch nicht aufgefallen -> Nachbessern: Code will in Code-Tags

Vorher bitte in der IDE die unnötigen Leerzeilen raus werfen, STRG+T drücken und den Kram mittels Code-Tags in lesbarer Form darbieten.

Was ich in Deinem Sketch sehe: Du setzt diverse Werte im 'ThingSpeak-Objekt'. Darf ich annehmen, daß diese Werte noch 'verschickt' werden wollen? Kann mir nur schlecht vorstellen, daß ein IOT-Gerät jeden Mückenfurz, Der irgendwo eingestellt wird, separat ins INet versenden will - Das kostet doch unnötig und unmengen an Strom, oder?

MfG

Ich verstehe gerade nicht, was du mit ThingSpeak machen möchtest. Mal abgesehen davon, dass es nicht funktioniert.

ok Code Tags !!! Musste ich mich auch mal reinlesen keine Ahnung was damit gemeint war.

Ich verstehe gerade nicht, was du mit ThingSpeak machen möchtest.
Mal abgesehen davon, dass es nicht funktioniert.

möchte zu jederzeit und überall sehen was mein windrad grad macht. funktioniert ja mit Thingspeak ganz gut finde ich. bin jedoch für jeden Verbesserungsvorschlag offen.

So ich versuch das jetzt mit den Tags nochmal. Bin leider auch kompletter Forum´sNoob.

#include <OneWire.h>
#include <DallasTemperature.h>
#include "ThingSpeak.h"
#include "RunningMedian.h"
#include <ESP8266WiFi.h>

#define Upm  D3
#define Temp D4

OneWire oneWire(Temp);
DallasTemperature DS18B20(&oneWire);

char temperaturStr[6];
uint8_t UPM_Pin = D3;
const int m_time = 5;     //Messzeit für Upm

float UPM;
int UPM_ct;

unsigned long ThingspeakLastLogTime = 0;
unsigned long SensorenLetzteAktualisierung;   // Hilfsvariable für Zeitmessung
int ThingspeakSampleTime = 30000;             // Die schnellste Sample Time ist 15s ich empfehle
// 60s zu verwenden oder 300 Sekunden
int SensorenSampleTime = 1;                   // Zeit in s für Aktualisierung der

WiFiClient  client;
int status = WL_IDLE_STATUS;

/**********************************(Thingspeak Eistellungen)*******************************/
unsigned long myChannelNumber = +++++;         // Deine ThingSpeak Kanal Nummer
const char * myWriteAPIKey = "+++++"; // Dein ThingSpeak API Key

/************************************(Wifi Einstellungen)**********************************/
char ssid[] = "+++++";               // Deine Wlan SSID (name)
char pass[] = "+++++";             // Dein Wlan Passwort

void setup() {
  WiFi.begin(ssid, pass);            // Wlan Aktivieren und mit definiertem Netzwerk verbinden
  ThingSpeak.begin(client);           // ThingSpeak Client starten
  Serial.begin(115200);
  DS18B20.begin();
}

float getTemperatur() {
  float temp;
  do {
    DS18B20.requestTemperatures();
    temp = DS18B20.getTempCByIndex(0);
    delay(100);
  } while (temp == 85.0 || temp == (-127.0));
  return temp;
}

void loop() {
  meassure_UPM();

  float temperatur = getTemperatur();
  dtostrf(temperatur, 2, 2, temperaturStr);

  Serial.print(" Upm: ");
  Serial.print(Upm);
  Serial.print(" Temp: ");
  Serial.println(temperaturStr);
}

void meassure_UPM() {
  UPM_ct = 0;
  attachInterrupt(digitalPinToInterrupt(UPM_Pin), IntCallback, RISING);
  delay(1000 * m_time);
  UPM = (float)UPM_ct * (float)m_time * 2.4 ;
}


void IntCallback() {
  UPM_ct ++;
}

/*********************(Funktion um Daten an Thingspeak zu senden)**************************/
void MesswerteSenden() {

  if (millis() - ThingspeakLastLogTime > ThingspeakSampleTime) {
    ThingSpeak.setField(3, Upm);
    ThingSpeak.setField(4, temperaturStr);
    ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
    ThingspeakLastLogTime = millis();
  }
}

Hi

Ok - wäre doch fast nicht aufgefallen, daß Du blutiger Anfänger bist … dann noch mit einem Count von 1 - stünde dort eine 600, hätte ich Dir Das wahrscheinlich gar nicht abgekauft!!

Hättest Du Deinen Sketch in Code-Tags gesetzt, wäre Das wohl auch nicht aufgefallen → Nachbessern: Code will in Code-Tags

Vorher bitte in der IDE die unnötigen Leerzeilen raus werfen, STRG+T drücken und den Kram mittels Code-Tags in lesbarer Form darbieten.

Was ich in Deinem Sketch sehe: Du setzt diverse Werte im ‘ThingSpeak-Objekt’.
Darf ich annehmen, daß diese Werte noch ‘verschickt’ werden wollen?
Kann mir nur schlecht vorstellen, daß ein IOT-Gerät jeden Mückenfurz, Der irgendwo eingestellt wird, separat ins INet versenden will - Das kostet doch unnötig und unmengen an Strom, oder?

MfG

und jop ich möchte natürlich die Daten verschicken. mit dem Mückenpfurtz hast natürlich recht,
würde vollkommen reichen die Drehzahl und die Temp einmal pro Minute zu verschicken.

ich finde auch die Berechnung der Upm irgendwie kompliziert

ich steh Jedenfalls grad komplett am Schlauch. Wenn du da keinen Mentor oder sowas hast der dir
sowas verständlich erklären kann und du dir alles müsählig aus dem i net saugen musst erschwert die Sache nochmal ungemein.

ps: Danke für eure Antworten!!!

Deine Routine, um die Temperatur auszulesen, blockiert, wenn dein DS18b20 abgekackt ist. Da solltest du unbedingt eine Fehlerbehandlung einbauen.

oh Mann das auch noch!!!

ja und noch was.....

Darf ich annehmen, daß diese Werte noch 'verschickt' werden wollen?

Werden denn die Daten noch nicht verschickt???

Hi

DAS ist die Frage, Die Du eher beantworten können solltest, als ich :) Hatte Das oben in dem QUOTE-Tag nicht gesehen, denke, die .writeFields(myChannelNumber, myWriteAPIKey); Methode erledigt das Versenden?!? Dann gibt Diese doch bestimmt einen Error-Code zurück, oder? Was sagen die Beispiele zur ThingSpeak-Lib? Einen ESP8266 hätte ich wohl auch (zumindest eine der Varianten ...), Der könnte ja Mal die Raum-Temperatur loggen ... wieder Mehr auf der 'ToDo'-Liste (oder eher: AuchHabenWill)

MfG

Hallo,

ich hab mal gerade in die lib gesehen . Eigendlich fehlt bei dir die Abfrage ob eine Verbindung zu ThingSpek besteht , das ist die Abfrage auf den den Return Wert 200.

Heinz

Auschschnitt aus dem Beispiel

// Write to ThingSpeak. There are up to 8 fields in a channel, allowing you to store up to 8 different
  // pieces of information in a channel.  Here, we write to field 1.
  int x = ThingSpeak.writeField(myChannelNumber, 1, number, myWriteAPIKey);
  if(x == 200){
    Serial.println("Channel update successful.");
  }
  else{
    Serial.println("Problem updating channel. HTTP error code " + String(x));
  }

So jetzt funktioniert´s!

Danke für Eure Mithilfe! Werde das ganze jetzt noch optimieren hab mal was von so ner “RunningMedian” Geschichte gehört die die Durchschnittswerte berechnet und ja wie EIEspanol meint wenn mein DS18B20 abkackt alles zum stehen kommt hab ich auch noch nicht durchschaut.
Ich hab eigentlich so einiges noch nicht durchschaut,… egal.

Ich danke euch erst mal und zum Schluss, wen es interessiert mein funktionierender Sketch.

#include <OneWire.h>
#include <DallasTemperature.h>
#include "ThingSpeak.h"
#include <ESP8266WiFi.h>

#define UPM D3
#define Temp D4

OneWire oneWire(Temp);
DallasTemperature DS18B20(&oneWire);

char temperaturStr[6];
uint8_t Upm_Pin = D3;
const int m_time = 5;     //Messzeit für Upm
float Upm;
int UPM_ct;

unsigned long ThingspeakLastLogTime = 0;
unsigned long SensorenLetzteAktualisierung;   // Hilfsvariable für Zeitmessung
int ThingspeakSampleTime = 30000;             // Die schnellste Sample Time ist 15s ich empfehle
                                              // 60s zu verwenden oder 300 Sekunden
int SensorenSampleTime = 1;                   // Zeit in s für Aktualisierung der

WiFiClient  client;
int status = WL_IDLE_STATUS;

unsigned long myChannelNumber = *****;          //  ThingSpeak Kanal Nummer
const char * myWriteAPIKey = "*****";               //  ThingSpeak API Key

char ssid[] = "*****";      //  Wlan SSID (name)
char pass[] = "*****";     // Wlan Passwort

void setup() {
  WiFi.begin(ssid, pass);       // Wlan Aktivieren und mit definiertem Netzwerk verbinden
  ThingSpeak.begin(client);   // ThingSpeak Client starten
  Serial.begin(115200);
  DS18B20.begin();
}

float getTemperatur() {
  float temp;
   do {
    DS18B20.requestTemperatures();
    temp = DS18B20.getTempCByIndex(0);
    delay(100);
   }
   while (temp == 85.0 || temp == (-127.0));
  return temp;
}

void loop() {
  meassure_UPM();

  float temperatur = getTemperatur();
  dtostrf(temperatur, 2, 2, temperaturStr);

  Serial.print(" Upm: ");
  Serial.print(Upm);
  Serial.print(" Temp: ");
  Serial.println(temperaturStr);

  ThingSpeak.setField(3, Upm);
  ThingSpeak.setField(4, temperaturStr);
  ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);
  
}

void meassure_UPM() {
  UPM_ct = 0;
  attachInterrupt(digitalPinToInterrupt(Upm_Pin), IntCallback, RISING);
  delay(1000 * m_time);
  Upm = (float)UPM_ct * (float)m_time * 2.4 ;
}

void IntCallback() {
  UPM_ct ++;
}

Hi

Warum ein delay() und ein WHILE in der getTemperatur()? Wenn der Sensor tot ist, hilft weder Warten, noch erneutes anklopfen. Bis auf den Umstand, daß Du AUF JEDEN FALL mindestens 100ms wartest, bringt Dir Das Nichts.

So - Dein Sensor schwätzt nicht mehr/wird nicht mehr gefunden -> die Lib gibt -127 zurück - und Du fragst die nächsten zwei Jahre im 100ms-Takt, ob's den Sensor noch gibt - hier gibt's keine Fehlermeldung aka 'Hüülfäää ... Sensor defekt', sondern Dein Sketch hängt Sich, von Außen gesehen, einfach auf.

Die 85,0°C sind, sofern nicht wirklich gemessen (Was ja durchaus geht: -55...125°C), der Startwert.

WAS Du machen kannst: - den letzten Messwert per static in der Funktion behalten - den Zeitpunkt des Start der letzten Messwert-Generierung merken (ebenfalls static) - wenn der letzte Start länger als die Wandlerzeit her ist, neue Temperatur auslesen, neue Generierung (nicht blockierend) starten, neuen Startwert merken - die aktuell vorhandene Temperatur zurück geben - ist eh die aktuellste, Die Du hast.

Somit liefert Dir der Funktionsaufruf eine Temperatur und sorgt dafür, daß Du sogar eine Aktuelle bekommst, wenn die Zeit dafür gekommen ist.

Wenn man global noch ein Error-Flag einbaut, kann man auch einen ausgefallen Sensor 'melden', wobei auf Deiner Anzeige wohl fehlerhafte (und vor Allem statische) Werte wohl recht schnell auffallen.

Danke Dir für Dein Feedback, für Deinen aktuellen Sketch!

MfG

PS: Ich würde die Temperatur als Roh-Wert verarbeiten/versenden (sofern ThingSpeak damit 'um kann') - Das wären 1/16tel Grad und maximal 12 Bit, müsste man nicht mit float spielen. 2 statt 4 Byte zu transportierende Daten.