Hallo,
ich benutze ein ESP8266 aber mit der Arduino IDE und habe folgendes Problem. Egal ob ich mit Interrupts arbeite oder mit millis(), haben die Ausgabe in der Konsole die falschen Zeitstempel.
Wodurch kann diese Verzögerung kommen oder ist die Konsole ungenau? Zur Anwendung. Ich will alle 10ms Daten von einer I2C Schnittstelle lesen.
Bei einem Test mit 100ms Intervallen werden die Daten laut Konsole alle in 93 oder 92ms gelesen. Der ESP8266 hat 80MHZ. Daran sollte es nicht liegen oder ?
EDIT: Bei 10ms Intervallen gibt er mir beim gleichen Zeitstempel 3-4 vier veschiedene ausgelesene Daten. Da der Sensor höchstens 100Hz kann muss es doch am Serial.monitor liegen ? Baudrate sind 115200.
Vielen Dank
uwefed
August 11, 2021, 1:04am
2
Sollen wir Hellsehen?
Bitte gib uns den Sketch und den Link zum Sensor.
Grüße Uwe
Hallo,
ich denke mal das liegt am delay().
Dann lies dir doch mal das Datenblatt des Sensors genau durch, ob dieser überhaupt die Daten so schnell liefern kann.
meine Glaskugel ist zur Zeit in der Spülmaschine
Sorry Leute. Werde meine Beiträge in Zukunft besser verfassen:D
BNO055 Adafruit
Also der Sensor ist ein BNO055 und hat ne Samplerate von 100Hz also 10ms.
Code 1 mit millis():
uint8_t sendtest[]= {1,2,3,4};
WiFiServer server(1045);
Adafruit_BNO055 IMU = Adafruit_BNO055(-1, 0x28);
unsigned long interval = 10;
unsigned long currentmillis;
unsigned long previousmillis = 0;
void setup() {
WiFi.mode(WIFI_AP);
WiFi.softAPConfig(local_ip,gateway,subnet);
WiFi.softAP(ssid,password);
Serial.begin(115200);
Serial.println();
Serial.print("IP Adresse: "); Serial.println(WiFi.softAPIP());
Serial.println("Wifi connected");
delay(100);
server.begin();
Serial.println("Server started");
IMU.begin();
//Timer interrupt
noInterrupts();
}
void loop() {
currentmillis = millis();
if(currentmillis - previousmillis >= interval){
previousmillis = currentmillis;
WiFiClient client = server.available();
if(client){
if(client.connected() && client.available() > 0){
//Serial.println("Client avaialable");
client.write(sendtest, sizeof(sendtest));
}
}
imu::Vector<3> acc = IMU.getVector(Adafruit_BNO055::VECTOR_ACCELEROMETER);
Serial.println(acc.x());
/*Serial.print(",");
Serial.print(acc.y());
Serial.print(",");
Serial.println(acc.z());
*/
}
Die dazugehörige Konsolenausgabe konnte ich nciht hochladen, da ich ein neuer Benutzer bin im Forum.
Mit interval = 10, gleicher Zeitstempel verschiedene Sensorwerte.
Mit interval = 100, keine gleichen Zeitstempel verschiedene Sensorwerte, keine periodische Wiederholung der Zeitstempel.
Habe es auch mit nem timer interrupt versucht. Gleiches Verhalten. Es ist zum Zeitpunkt von diesem Testlauf kein Client verbunden, das heißt die if(client) wird nicht durchlaufen.
Danke für jede Hilfe.
Moko
August 11, 2021, 7:47am
8
Das sollte doch nur Text sein, denn kannst Du doch kopieren und hier einfügen.
Evtl als Zitat oder formatierter Text.
Hier der vollständige Code mit includes und Interrupt Versuch:
#include <ESP8266WiFi.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>
/*SSID and Password for Connection*/
const char* ssid="xxxxxx";
const char* password ="xxxx";
IPAddress local_ip(192,168,11,1);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);
uint8_t data = 0;
uint8_t sendtest[]= {1,2,3,4};
WiFiServer server(1045);
Adafruit_BNO055 IMU = Adafruit_BNO055(-1, 0x28);
//Timer variables
volatile unsigned long uc1mscount = 0;
//bool uc10msFlag;
volatile bool uc10msFlag = 1;
void setup() {
WiFi.mode(WIFI_AP);
WiFi.softAPConfig(local_ip,gateway,subnet);
WiFi.softAP(ssid,password);
Serial.begin(115200);
Serial.println();
Serial.print("IP Adresse: "); Serial.println(WiFi.softAPIP());
Serial.println("Wifi connected");
/*WiFi.softAPConfig(local_ip,gateway, subnet);*/
delay(100);
server.begin();
Serial.println("Server started");
IMU.begin();
//Timer interrupt
//noInterrupts();
timer0_isr_init();
timer0_attachInterrupt(ISR);
timer0_write(ESP.getCycleCount() + 80000L);
interrupts();
}
void loop() {
// myTimer();
if(uc10msFlag == 1){
WiFiClient client = server.available();
if(client){
if(client.connected() && client.available() > 0){
//Serial.println("Client avaialable");
client.write(sendtest, sizeof(sendtest));
}
}
imu::Vector<3> acc = IMU.getVector(Adafruit_BNO055::VECTOR_ACCELEROMETER);
Serial.println(acc.x());
/*Serial.print(",");
Serial.print(acc.y());
Serial.print(",");
Serial.println(acc.z());
*/
uc10msFlag = 0;
}
}
void ISR(void){
timer0_write(ESP.getCycleCount() + 80000L);
uc1mscount++;
if(uc1mscount >= 10){
uc1mscount=0;
uc10msFlag=1;
}
}
Nachtrag zur Ausgabe.
Ausgabe 10ms:
Blockzitat
09:50:02.090 -> -0.36
09:50:02.090 -> -0.36
09:50:02.144 -> -0.34
09:50:02.144 -> -0.35
09:50:02.144 -> -0.33
09:50:02.144 -> -0.34
09:50:02.144 -> -0.35
09:50:02.190 -> -0.34
09:50:02.190 -> -0.35
09:50:02.190 -> -0.34
09:50:02.190 -> -0.34
09:50:02.190 -> -0.37
09:50:02.244 -> -0.33
09:50:02.244 -> -0.34
09:50:02.244 -> -0.35
09:50:02.244 -> -0.33
09:50:02.244 -> -0.34
09:50:02.244 -> -0.34
09:50:02.291 -> -0.35
09:50:02.291 -> -0.35
09:50:02.291 -> -0.36
09:50:02.291 -> -0.36
09:50:02.346 -> -0.34
Blockzitat
Ausgabe mit 100ms interval:
Blockzitat
09:51:42.116 -> -0.34
09:51:42.201 -> -0.33
09:51:42.301 -> -0.35
09:51:42.402 -> -0.34
09:51:42.502 -> -0.32
09:51:42.605 -> -0.34
09:51:42.705 -> -0.34
09:51:42.805 -> -0.35
09:51:42.905 -> -0.35
09:51:43.000 -> -0.34
09:51:43.123 -> -0.34
09:51:43.212 -> -0.36
09:51:43.349 -> -0.36
09:51:43.444 -> -0.35
09:51:43.528 -> -0.33
09:51:43.629 -> -0.33
Blockzitat
[EDIT] PW gelöscht. Grüße Uwe [/EDIT]
Sorry habe nun alles gepostet:D
Nächstes Mal mach ich es direkt so:)
Okay hast Recht habs so gemacht.
Danke:)
uwefed
August 11, 2021, 2:39pm
12
Meiner Ansicht hängt es von Millis ab weil die Auflösung zu gering ist.. Im Beispiel das mit der Bibliothek kommt verwenden sie Micros(): Adafruit_BNO055/position.ino at master · adafruit/Adafruit_BNO055 · GitHub
Grüße Uwe
1 Like
Das wird nichts genaues.
Zwei Dinge:
Du brauchst die Var currentmillis nicht.
Dann solltest aus intervall ein const machen.
const unsigned long interval = 10;
unsigned long previousmillis = 0;
Und dann musst Du anders auf den Zeitablauf reagieren. Sieht dann so aus:
if (millis() - previousmillis >= interval)
{
previousmillis += interval;
WiFiClient client = server.available();
Ändert sich was?
Hallo,
Wozu ist eigentlich der ganze WIFI Kram da ??, kann ja sein das ich Blind bin
ich vermute ehr das: Der angezeigte Zeitstempel stammt doch vom PC (IDE Monitor mit Zeitstempel)
Du lässt jetzt alle 10ms einen Messwert entstehen und gibst Ihn über die Serielle raus. Die rappeln in die Serielle im PC rein ( Buffer) und werden da etwa alle 50ms abgeholt. Damit erhalten immer mehrere von Windows den gleichen Zeitstempel.
Heinz
1 Like
Leider nicht.
Blockzitat
21:04:28.268 -> -0.38
21:04:28.268 -> -0.36
21:04:28.268 -> -0.36
21:04:28.268 -> -0.34
21:04:28.268 -> -0.33
21:04:28.268 -> -0.35
21:04:28.308 -> -0.34
21:04:28.308 -> -0.34
21:04:28.308 -> -0.35
21:04:28.308 -> -0.35
21:04:28.354 -> -0.36
21:04:28.354 -> -0.35
21:04:28.354 -> -0.36
21:04:28.354 -> -0.35
21:04:28.401 -> -0.37
21:04:28.401 -> -0.34
Mit interval= 100
21:06:34.330 -> -0.33
21:06:34.424 -> -0.34
21:06:34.517 -> -0.34
21:06:34.611 -> -0.33
21:06:34.704 -> -0.34
21:06:34.798 -> -0.34
21:06:34.940 -> -0.35
21:06:35.037 -> -0.34
21:06:35.129 -> -0.35
21:06:35.220 -> -0.36
21:06:35.314 -> -0.34
21:06:35.407 -> -0.34
21:06:35.500 -> -0.33
21:06:35.596 -> -0.35
21:06:35.739 -> -0.36
21:06:35.830 -> -0.35
Aber vielen Dank !
Da ich die Daten über Wifi bzw TCP an den PC sende im weiteren Verlauf. Das funktioniert auch, jedoch muss das ganze in einem bestimmten Zeitraum geschehen.
Das ist die Frage mit dem Buffer kenne mich mit der Konsole nicht so aus, aber kann die Konsole nicht mehr als 50ms ? Das wäre interessant zu wissen.
Das würde ja bedeuten, das die Konsole ungeeignet ist um zu prüfen, ob die Zeiten eingehalten werden.
Danke:)
Hi vielen Dank erstmal .
Änderungen im Code.
const unsigned long interval = 10000;
// long currentmillis;
unsigned long previousmillis = 0;
if(micros() - previousmillis >= interval){
previousmillis += interval;
Ausgabe:
Blockzitat
21:16:38.220 -> -0.34
21:16:38.266 -> -0.34
21:16:38.266 -> -0.35
21:16:38.266 -> -0.35
21:16:38.266 -> -0.33
21:16:38.266 -> -0.33
21:16:38.316 -> -0.34
21:16:38.316 -> -0.35
21:16:38.316 -> -0.35
21:16:38.316 -> -0.34
21:16:38.361 -> -0.33
21:16:38.361 -> -0.33
21:16:38.361 -> -0.32
21:16:38.361 -> -0.33
21:16:38.361 -> -0.34
21:16:38.407 -> -0.34
Ändert sich leider auch nichts...
Gib doch mal den aktuellen Wert von millis() mit aus. Die Zeitstempel sind von der IDE also nicht relevant.
Gruß Tommy
1 Like
Hallo,
aber sehe ich das richtig deine "Ausgabe" stammt aus dem IDE Monitor und Du hast den haken "Zeitstempel anzeigen" gesetzt.
21:16:38.266 -> -0.34
21:16:38.266 -> -0.35
21:16:38.266 -> -0.35
21:16:38.266 -> -0.33
21:16:38.266 -> -0.33
21:16:38.316 -> -0.34
21:16:38.316 -> -0.35
21:16:38.316 -> -0.35
21:16:38.316 -> -0.34
Dann ist das nun mal so , liegt an Windows, das hat ja letztlich noch was anderes zu tun.
Du suchst an der falschen Stelle , was willst Du wirklich ?
Heinz
Genau.
Das ist genau die Frage. Also ist die IDE Konsole nicht zuverlässig was das angeht ?
Im Grunde genommen bin ich davon ausgegangen, dass das System Windows, Arduino IDE es packt 10ms Intervalle mit Zeitstempel abzubilden.
Denn was ich will ist, die Daten in einer Tabelle speichern mit 100Hz. Bzw das ist das Endziel des Projekts.