Das nenn ich mal "Timing", jetzt hätten wir fast gleichzeitig gepostet und der erste Gedanke ist auch noch gleich. Gedankenübertragung ?
Buffer habe ich schon, den Rest schaue ich mir an. Danke !
Ankündigung
Einklappen
Keine Ankündigung bisher.
ARDUINO am KNX
Einklappen
X
-
Ich habe mal den Serial_Buffer_Size auf 256 und siehe da, Zufall ?
2017-07-31 19_19_24-192.168.2.16_data_log_MONLOG_2017-07-31.htm_20170731191616.png
Einen Kommentar schreiben:
-
Hallo WagoKlemme,
den seriellen Speicher kann man vergrößern. Dazu sind lediglich ein paar Zeilen in der
innerhalb der IDE zu ändern. Mit allen Vorteilen und Nachteilen.Code:HardwareSerial.h
Aber vielleicht bedarf es nur einer kleineren Änderungen. Wertest und bearbeitest du die empfangenen Daten direkt in
aus? Würde dann vorschlagen, hier nur das Wesentliche zu tun. Die Leseanfrage pro Gruppenadresse in einer Variable speichern und dann den Rest inCode:void serialEvent()
zu erledigen -> z.B.: Antworten auf deine Leseanfrage. Dann könnte man noch den Schreibtimeout der KNX-Library von StandardCode:void loop()
auf den für dich notwendigen WertCode:#define SERIAL_WRITE_DELAY_MS 100
setzen.Code:#define SERIAL_WRITE_DELAY_MS (hier dein Wert)
Nur noch ein Hinweis am Rande. Je mehr Ram, je mehr Gruppenadressen sind möglich. Vielleicht belegst du schon einiges durch andere Libraries davon und es kommt dann zu diesem Phänomen.
Der Gedanke mit dem Queue in Array ist zwar ein guter Ansatz, jedoch sollte es auch ohne klappen. Die Leseanfrage an sich ist nicht groß, ich vermute nach wie vor ein Timing-Problem.
Mit freundlichen Grüßen
Mag Gyver
Einen Kommentar schreiben:
-
Hallo Mag Gyver,
danke für deine Einschätzung, hierzu hätte ich noch ein paar Fragen:
- wieviele Telegramme passen in den seriellen Speicher (ATMega328 64Bytes), bzw. wie groß ist ein Request* ? Und könnte man den nicht vergrössern, wie hier ?
- könnte man wenigstens die GA abfangen und später eine Antwort senden
- wie wäre es mit einer Queue in Array, und die Antworten dann sequenziell zu senden, nach Größe des Arrays ?
Ich kann Edomi oder generell einen Initscan einer Visu nicht dazu bringen, die Read Requests schön nacheinander abzuschicken. Schliesslich sind da in der Größenordnung 1500 GA's zu lesen, das würde zu lang dauern. Den Standard KNX Geräten macht es ja nichts aus. Das ist halt die Konzeption und ansonsten kein Problem in KNX, und wird unvermeidbar sein.
Edit: *Länge Request : Ein Datarequest ist 23 Byte und ein extended Datarequest hat 263 Bytes. Quelle
Zuletzt geändert von WagoKlemme; 31.07.2017, 08:34.
Einen Kommentar schreiben:
-
Hallo WagoKlemme,
ich entnehme dem Screenshot einfach anhand dem zeitlichen Verlauf, dass der ARDUINO noch in der Wartephase zwischen den Telegrammabarbeitung (delay) steckt und deswegen nicht auf deine sehr kurz hintereinander kommende Read Request antworten kann, weil der ARDUINO es einfach verschläft bzw. der Puffer der seriellen Schnittstelle überläuft.
Abhilfe könnte hier vielleicht sein, dass man hier am Sendetimeout in der Library dreht oder vielleicht doch besser erstmal eine Wartezeit zwischen den Abfragen des anderen Gerätes einbaut, wenn möglich.
Ich z.B. sende nur eine Anfrage (Write auf Anfrageadresse) zum ARDUINO und veranlasse den ARDUINO dann mir die aktuellen Daten zu senden, währe natürlich auch ein Weg um dein anderes Gerät mit den Daten zu füttern.

Mit freundlichen Grüßen
Mag GyverZuletzt geändert von Mag Gyver; 30.07.2017, 20:50.
Einen Kommentar schreiben:
-
Mag Gyver
Ich hätte eine Frage bzgl. Lib und Read Request von KNX-Seite. Von 4 gleichzeitigen Requests über Serialevent wird immer nur 1 beantwortet.
Was läuft schief ? Was kann ich tun ?
Ein einzelner Request funktioniert einwandfrei.
2017-07-30 19_47_36-192.168.2.16_data_log_MONLOG_2017-07-30.htm_20170730133735.png
Einen Kommentar schreiben:
-
Das mit der Lib muss ich mir nochmal anschauen. Zuerst dachte ich der Sensor ist defekt und wollte einfach nur Werte angezeigt bekommen. Das ging eben mit der Sparkfun-Lib erstmal nicht. Vielleicht lags auch am Wakeup.
Ich halte, so nach 2 Tagen Beobachtung, auch erstmal am iAQ fest.
Einen Kommentar schreiben:
-
Hmmm, den Sparkfun habe ich auch gesehen. Wenn bei einem die Lib funktioniert und beim anderen nicht, ist das kein gutes Zeichen...dann scheinen die Sensoren unterschiedlich zu sein (kenne ich von den Fake-NRF24L01 nur zu gut).
Aber mal ehrlich...bei 34€ kannst Du auch gleich den Core nehmen, der ist dann letztendlich kleiner und hat bereits eine Staubschutzkappe onboard. Ich bleibe jedenfalls erstmal beim Core P.
Einen Kommentar schreiben:
-
Hallo Stefan,
meiner ist von hier. War in einer Woche da.
Ich würde aber in Zukunft lieber den von EXPtech /Sparkfun nehmen. Kostet zwar 34 Euros, aber dafür funktioniert auch die LIB von Sparkfun. Mit meinem von Ebay funktioniert die LIB nicht. Deshalb auch die o.g. LIB, die auch prompt einen Bug bei der Modeumschaltung hatte.
Ausserdem glaube ich, wie auch beim BME280, dass die Verarbeitung schon entscheidend ist. Und damit das Messergebnis. Deshalb habe ich einen BME280 von Sparkfun geordert und werde das mal überprüfen.
Edit: Aufm Chip steht 811B und ein kreisförmiges Logo. Genau wie auf dem Bild in Ebay.Zuletzt geändert von WagoKlemme; 11.06.2017, 19:17.
Einen Kommentar schreiben:
-
Hallo Armin,
danke fürs Teilen!
Woher hast Du denn den CCS811? Ich traue den Dingern irgendwie (noch) nicht, die aktuell aus China kommen. Ist da irgendwas aufm Chip, was auf original AMS Chips hinweist?
Einen Kommentar schreiben:
-
Mein CCS811 ist eingetroffen !
Bevor jemand viel Zeit wegen einer fehlerhaften LIB vergeudet, so wie ich, hier der Code :
PIN WAK auf 4 Pro Mini. VCC, GND, SDA, SCL ist klar. Hiermit wird der MODE 3 aktiviert. D.h. alle 10s gepulst eine Messung. Für 60s bitte in der LIB das Byte ändern, ist mit Pfeilen markiert.
Zur Genauigkeit zum iAQ kann ich im Moment sagen, das der CCS811 (nach Burn-in) bei CO2 400ppm mehr misst als der iAQ und VOC ca. 200 weniger. Beide lagen direkt nebeneinander.
Welcher nun stimmt weiss ich noch nicht.
Edit: CO2 stimmt inzwischen ziemlich überein. Nur VOC 2ppb (CCS811) zu 131ppm(iAQ) scheint dann doch daneben. Da scheint was faul zu sein.
Der CCS811 braucht ein 48h Burn-in. Danach 20min. Nach Modeänderung auch 20min.
Programm:
LIB CCS811.cpp:Code:/*************************************************** This is an example for the CCS811 digital TVOC/eCO2 Sensor by CCMOSS/AMS http://www.ccmoss.com/gas-sensors#CCS811 Updated: March 28, 2017 The sensor uses I2C protocol to communicate, and requires 2 pins - SDA and SCL Another GPIO is also required to assert the WAKE pin for communication. this pin is passed by an argument in the begin function. A breakout board is available: https://github.com/AKstudios/CCS811-Breakout The ADDR pin on the sensor can be connected to VCC to set the address as 0x5A. The ADDR pin on the sensor can be connected to GND to set the address as 0x5B. Written by Akram Ali from AKstudios (www.akstudios.com) GitHub: https://github.com/AKstudios/ ****************************************************/ #include <CCS811.h> #define ADDR 0x5A #define WAKE_PIN 4 byte stat; byte measure; CCS811 sensor; void setup() { Serial.begin(9600); Serial.println("CCS811 test"); if(!sensor.begin(uint8_t(ADDR), uint8_t(WAKE_PIN))) Serial.println("Initialization failed."); pinMode(WAKE_PIN, OUTPUT); digitalWrite(WAKE_PIN, LOW); stat=sensor.readStatus(); measure=sensor.readMeasure(); Serial.print("Status Byte : "); Serial.print(stat); Serial.println(""); } void loop() { stat=sensor.readStatus(); if (bitRead(stat,3)) { sensor.compensate(21.9, 48.2); // replace with t and rh values from sensor sensor.getData(); Serial.print("CO2 : "); Serial.print(sensor.readCO2()); Serial.println(" ppm"); Serial.print("TVOC : "); Serial.print(sensor.readTVOC()); Serial.println(" ppb"); Serial.print("Measure Byte : "); Serial.print(measure); Serial.println(""); if (!bitRead(stat,0)) { Serial.print("Status : "); Serial.println("ok"); } if (bitRead(stat,0)) { Serial.print("Status : "); Serial.println("Error"); } if (!bitRead(stat,3)) { Serial.print("Data : "); Serial.println("No data"); } if (bitRead(stat,3)) { Serial.print("Data : "); Serial.println("ready"); } Serial.println(); bitWrite(stat,3,0); delay(1000); //} } delay(100); }
LIB CCS811.h:Code:/*************************************************** This is a library for the CCS811 digital TVOC/eCO2 Sensor by CCMOSS/AMS http://www.ccmoss.com/gas-sensors#CCS811 Updated: April 18, 2017 The sensor uses I2C protocol to communicate, and requires 2 pins - SDA and SCL Another GPIO is also required to assert the WAKE pin for communication. this pin is passed by an argument in the begin function. A breakout board is available: https://github.com/AKstudios/CCS811-Breakout The ADDR pin on the sensor can be connected to VCC to set the address as 0x5A. The ADDR pin on the sensor can be connected to GND to set the address as 0x5B. Written by Akram Ali from AKstudios (www.akstudios.com) GitHub: https://github.com/AKstudios/ BSD license, all text above must be included in any redistribution ****************************************************/ #include "CCS811.h" CCS811::CCS811() { // empty constructor, just because. } boolean CCS811::begin(uint8_t I2C_ADDR, uint8_t WAKE_PIN) { delay(70); // from datasheet - up to 70ms on the first Reset after new application download; up to 20ms delay after power on _I2C_ADDR = I2C_ADDR; _WAKE_PIN = WAKE_PIN; Wire.begin(); pinMode(_WAKE_PIN, OUTPUT); // set WAKE pin as OUTPUT PORTD &= ~(1<<PORTD4); // assert WAKE pin LOW to initiate communication with sensor digitalWrite(_WAKE_PIN, LOW); // WAKE_PIN on the sensor is active low, must always be asserted before any communication and held low throughout byte hw_id = CCS811::readHW_ID(); if(hw_id != 0x81) // this is the expected hardware ID { Serial.println("Error: Incorrect Hardware ID detected."); return false; } byte status = CCS811::readStatus(); uint8_t bit = (status & (1 << 5-1)) != 0; // black magic to read APP_VALID bit from STATUS register if(bit != 1) { Serial.println("Error: No application firmware loaded."); readErrorID(status); return false; } digitalWrite(_WAKE_PIN, LOW); Wire.beginTransmission(_I2C_ADDR); // least significant bit indicates write (0) or read (1) Wire.write(APP_START); Wire.endTransmission(); digitalWrite(_WAKE_PIN, HIGH); status = CCS811::readStatus(); bit = (status & (1<<8-1)) !=0; // black magic to read FW_MODE bit from STATUS register if(bit != 1) { Serial.println("Error: Firmware still in boot mode."); readErrorID(status); return false; } digitalWrite(_WAKE_PIN, LOW); Wire.beginTransmission(_I2C_ADDR); Wire.write(MEAS_MODE); Wire.write(B101000); // constant power mode, IAQ measurement every 10 second - B111000 = every 60s <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Wire.endTransmission(); //CCS811::sleep(); digitalWrite(_WAKE_PIN, HIGH); return true; } byte CCS811::readStatus(void) { digitalWrite(_WAKE_PIN, LOW); Wire.beginTransmission(_I2C_ADDR); Wire.write(STATUS); Wire.endTransmission(); Wire.requestFrom(_I2C_ADDR, (uint8_t)1); byte status; if(Wire.available() == 1) status = Wire.read(); digitalWrite(_WAKE_PIN, HIGH); return status; } byte CCS811::readMeasure(void) { digitalWrite(_WAKE_PIN, LOW); Wire.beginTransmission(_I2C_ADDR); Wire.write(MEAS_MODE); Wire.endTransmission(); Wire.requestFrom(_I2C_ADDR, (uint8_t)1); //byte MEAS_MODE = Wire.read(); byte _meas; if(Wire.available() == 1) _meas = Wire.read(); digitalWrite(_WAKE_PIN, HIGH); return _meas; } byte CCS811::readHW_ID(void) { digitalWrite(_WAKE_PIN, LOW); Wire.beginTransmission(_I2C_ADDR); Wire.write(HW_ID); Wire.endTransmission(); Wire.requestFrom(_I2C_ADDR, (uint8_t)1); byte hw_id = Wire.read(); digitalWrite(_WAKE_PIN, HIGH); return hw_id; } byte CCS811::readErrorID(byte _status) { digitalWrite(_WAKE_PIN, LOW); Wire.beginTransmission(_I2C_ADDR); Wire.write(ERROR_ID); Wire.endTransmission(); Wire.requestFrom(_I2C_ADDR, (uint8_t)1); byte error_id = Wire.read(); digitalWrite(_WAKE_PIN, HIGH); uint8_t bit = (_status & (1 << 1-1)) != 0; // black magic to read ERROR bit from STATUS register if(bit == 1) { Serial.print("Error ID: "); Serial.println(error_id); } return error_id; } void CCS811::sleep() { digitalWrite(_WAKE_PIN, LOW); Wire.beginTransmission(_I2C_ADDR); Wire.write(MEAS_MODE); Wire.write(0x00000000); // sets sensor to idle; measurements are disabled; lowest power mode Wire.endTransmission(); digitalWrite(_WAKE_PIN, HIGH); // set WAKE_PIN high - this puts sensor in sleep mode (~2uA) and all I2C communications are ignored } void CCS811::getData(void) { //CCS811::compensate(t, rh); digitalWrite(_WAKE_PIN, LOW); delay(1000); Wire.beginTransmission(_I2C_ADDR); Wire.write(ALG_RESULT_DATA); // reading ALG_RESULT_DATA clears DATA_READY bit in 0x00 Wire.endTransmission(); Wire.requestFrom(_I2C_ADDR, (uint8_t)4); delay(1); int buffer[4]; if(Wire.available() == 4) { for(int i=0; i<4; i++) { buffer[i] = Wire.read(); //Serial.print(buffer[i]); } } CO2 = ((uint8_t)buffer[0] << 8) + buffer[1]; TVOC = ((uint8_t)buffer[2] << 8) + buffer[3]; digitalWrite(_WAKE_PIN, HIGH); } int CCS811::readTVOC(void) { return TVOC; } int CCS811::readCO2(void) { return CO2; } void CCS811::compensate(float t, float rh) // compensate for temperature and relative humidity { digitalWrite(_WAKE_PIN, LOW); int _temp, _rh; if(t>0) _temp = (int)t + 0.5; // this will round off the floating point to the nearest integer value else if(t<0) // account for negative temperatures _temp = (int)t - 0.5; _temp = _temp + 25; // temperature high byte is stored as T+25°C in the sensor's memory so the value of byte is positive _rh = (int)rh + 0.5; // this will round off the floating point to the nearest integer value byte _ENV_DATA[4]; _ENV_DATA[0] = _rh << 1; // shift the binary number to left by 1. This is stored as a 7-bit value _ENV_DATA[1] = 0; // most significant fractional bit. Using 0 here - gives us accuracy of +/-1%. Current firmware (2016) only supports fractional increments of 0.5 _ENV_DATA[2] = _temp << 1; _ENV_DATA[3] = 0; Wire.beginTransmission(_I2C_ADDR); Wire.write(ENV_DATA); Wire.write(_ENV_DATA[0]); // 7 bit humidity value Wire.write(_ENV_DATA[1]); Wire.write(_ENV_DATA[2]); Wire.write(_ENV_DATA[3]); Wire.endTransmission(); digitalWrite(_WAKE_PIN, HIGH); }
Code:/*************************************************** This is a library for the CCS811 digital TVOC/eCO2 Sensor by CCMOSS/AMS http://www.ccmoss.com/gas-sensors#CCS811 October 28, 2016 The sensor uses I2C protocol to communicate, and requires 2 pins - SDA and SCL Another GPIO is also required to assert the WAKE pin for communication. this pin is passed by an argument in the begin function. A breakout board is available: https://github.com/AKstudios/CCS811-Breakout The ADDR pin on the sensor can be connected to VCC to set the address as 0x5A. The ADDR pin on the sensor can be connected to GND to set the address as 0x5B. Written by Akram Ali from AKstudios (www.akstudios.com) GitHub: https://github.com/AKstudios/ BSD license, all text above must be included in any redistribution ****************************************************/ #ifndef CCS811_h #define CCS811_h #if (ARDUINO >= 100) #include "Arduino.h" #else #include "WProgram.h" // to allow boolean and byte functions #endif #include "Wire.h" // Wire library for I2C protocol #define nWAKE 4 // pin 4 is tied to CCS811 nWAKE pin in sensor node #define nINT 7 // pin 7 is tied to CCS811 nINT pin in sensor node #define ADDR 0x5A // when I2C_ADDR pin is LOW //#define ADDR 0x5B // when I2C_ADDR pin is HIGH // Registers for CCS811 #define STATUS 0x00 #define MEAS_MODE 0x01 #define ALG_RESULT_DATA 0x02 #define ENV_DATA 0x05 #define APP_START 0xF4 #define HW_ID 0x20 #define ERROR_ID 0xE0 #define SW_RESET 0xFF class CCS811 { public: CCS811(); // constructor boolean begin(uint8_t I2C_ADDR, uint8_t WAKE_PIN); byte readStatus(void); byte readMeasure(void); byte readHW_ID(void); int readTVOC(void); int readCO2(void); void getData(void); void compensate(float t, float rh); byte readErrorID(byte _status); void reset(void); void sleep(); int TVOC, CO2; private: uint8_t _WAKE_PIN; uint8_t _I2C_ADDR; }; #endifZuletzt geändert von WagoKlemme; 11.06.2017, 19:28.
Einen Kommentar schreiben:
-
In der Zwischendecke liegen die rPi-Squeezeplayer, die dann praktischerweise gleich das komplette Messprogramm des BME280 per HTTP an Edomi schicken koennen. Drum dacht ich, ich "leg" den BME einfach daneben, aber die Testtemperaturmessung war dann doch eher ernuechternd...Zitat von WagoKlemme Beitrag anzeigenWas willst Du denn bitte in der Zwischendecke messen ?
Also waer jetzt son kleines Gehaeuse nett, dass ich von unten an die Decke schrauben koennte. Berker-Sensoreinsatz ist mir dafuer etwas zu gross.
Ich kenn das, darum hab ich das Thema fuer mich selbst schon vor langer Zeit intern abgehaktZitat von WagoKlemme Beitrag anzeigenDu weisst schon, was Du mit deinen Sensoren ausgelöst hast. Vormittag war für mich die Welt noch in Ordnung, jetzt muss ich zur Therapie.
Einen Kommentar schreiben:
-
Was willst Du denn bitte in der Zwischendecke messen ? Oder kommst Du an eine andere Stelle nicht mehr mitm Kabel hin ?Zitat von wintermute Beitrag anzeigenDie Dinger in der Zwischendecke zu verbauen funktioniert naemlich ueberhaupt garnicht - zumindest nicht wenn man Ansprechzeiten von unter 2 Tagen bevorzugt
Zur Feuchte:
Du weisst schon, was Du mit deinen Sensoren ausgelöst hast. Vormittag war für mich die Welt noch in Ordnung, jetzt muss ich zur Therapie.
Einen Kommentar schreiben:
-
Nein, der Luftdruck muss korrigiert auf deine Meereshöhe zum Zeitpunkt des Programmstarts im Code (in meinem Fall 1018hPa) eingegeben werden. Auch nach Berücksichtigung der Meereshöhe hat er dann 968hPa angezeigt. Und somit lag er exakt 50 daneben.
Ich denke Michael hat einen Sensor erwischt aus der Anfangsphase (sauber verarbeitet), bevor die Kopien kamen. Meine Chinakopie kann durchaus erhebliche Abweichungen haben, abhängig von der Kopierqualität. Denn eine Abweichung bei der Temperatur von 2,2K ist schon erheblich. Offensichtlich hat das der Sensor von Michael nicht.
Einen Kommentar schreiben:
-
Ich hoffe, das wird bei den Zukuenftigen ebenfalls so seinZitat von WagoKlemme Beitrag anzeigenDie Werks-Kalibrierung deiner BMEs scheint wirklich gut zu sein. Besser gehts nicht. Beeindruckend.
Was mir noch fehlt ist irgendein kleines weisses Gehaeuse so etwa in der Art vom AM2302, vllt optisch etwas ansprechender...
Die Dinger in der Zwischendecke zu verbauen funktioniert naemlich ueberhaupt garnicht - zumindest nicht wenn man Ansprechzeiten von unter 2 Tagen bevorzugt
Einen Kommentar schreiben:


Einen Kommentar schreiben: