Benutzer-Werkzeuge

Webseiten-Werkzeuge


hardware:controllers:bk-g4m_lesekopf

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
hardware:controllers:bk-g4m_lesekopf [2022/10/12 00:29] istlerhardware:controllers:bk-g4m_lesekopf [2022/11/12 11:54] (aktuell) – [Binary] tilman
Zeile 4: Zeile 4:
 [[https://www.youtube.com/watch?v=KReNpe72iHs | Aufbau eines Gaszähler / youtube video]] [[https://www.youtube.com/watch?v=KReNpe72iHs | Aufbau eines Gaszähler / youtube video]]
  
-Typischer Weise wird dieses mit einem Reed-Kontakt realisiert. Dieser schließt, wenn der Magnet auf der Walze in die Nähe des Kontaktes kommt. Bei manchen Gaszählern ist das Magnetfeld zu schwach, um einen Reedkontakt zu schließen oder einen Hallsensor auszulösen. Der vorliegender Ansatz verwenden einen elektronischen Kompass, der die fallende Flanke eines Magnetfelds zählt und dadurch auf das Gasvolumen zurückschließt+Typischer Weise wird dieses mit einem Reed-Kontakt realisiert. Dieser schließt, wenn der Magnet auf der Walze in die Nähe des Kontaktes kommt. Bei manchen Gaszählern ist das Magnetfeld zu schwach, um einen Reedkontakt zu schließen oder einen Hallsensor auszulösen. Der vorliegender Ansatz verwenden einen elektronischen Kompass, der die fallende Flanke eines Magnetfelds zählt und dadurch auf das Gasvolumen schließen lässt
  
 Als Magnetfeldsensor wird mit dem HSCDTD008A ein Low-Cost-Sensor verwendet, der für die Anwendung völlig ausreicht. Der HSCDTD008A vermisst die Stärke des Magnetfelds in den 3 Raumrichtungen. Für die Anwendung interessiert lediglich die Stärke des Gesamtfeldes. Die Richtung ist nicht wesentlich.  Als Magnetfeldsensor wird mit dem HSCDTD008A ein Low-Cost-Sensor verwendet, der für die Anwendung völlig ausreicht. Der HSCDTD008A vermisst die Stärke des Magnetfelds in den 3 Raumrichtungen. Für die Anwendung interessiert lediglich die Stärke des Gesamtfeldes. Die Richtung ist nicht wesentlich. 
  
-Gegenwärtig die Software hat den Reifestand eines PoC, d.h. er stellt einen funktionalen Durchstich da und der Funktionsumfang ist nicht komplett. +Gegenwärtig hat die Software den Reifestand eines PoC, d.h. er stellt einen funktionalen Versuch dar und der Funktionsumfang ist nicht komplett. 
  
-Das Programm misst alle 500 ms die 3 Komponenten des Magnetfeldes und errechnet den Betrag des gemessenen Magnetfeldes. Zusammen mit dem vorherigen Messwert kann man dann ermitteln, ob eine fallende Flanke vorliegt: Wenn der alte Messwerte einen Triggerlevel überschreitet, und der nächsten einen zweiten tiefer liegenden Triggerlevel unterschreitet, dann liegt eine fallende Flanke vor, die gezählt wird. Ein weitere Programm, ein Python-Script, wird regelmäßig von vzlogger aufgerufen und transportiert die gezählten Impulse in die Datenbank des Volkszählers.+Das Programm misst alle 500ms die 3 Komponenten des Magnetfeldes und errechnet den Betrag des gemessenen Magnetfeldes. Zusammen mit dem vorherigen Messwert kann man dann ermitteln, ob eine fallende Flanke vorliegt: Wenn der alte Messwerte einen Triggerlevel überschreitet, und der nächsten einen zweiten tiefer liegenden Triggerlevel unterschreitet, dann liegt eine fallende Flanke vor, die gezählt wird. Ein weitere Programm, ein Python-Script, wird regelmäßig von vzlogger aufgerufen und transportiert die gezählten Impulse in die Datenbank des Volkszählers.
  
-__ +=====Benötigte Komponenten===== 
-Benötigte Komponenten__ +  * HSCDTD008A mit BreakoutBox  
-===================== +  * Halterung ([[https://www.thingiverse.com/thing:2142740| Thingiverse]]) 
-* HSCDTD008A mit BreakoutBox +  * HSCDTD008A Library ([[https://github.com/bobveringa/HSCDTD008A-Library| HSCDTD008A library ]]) 
 +  * Binary (PoC) zum Zählen der Impulse 
 +  * Python Script zum Vorbreiten der gezählten Impulse für [[software/controller/vzlogger]] 
 +  * Linux Kleinrechner (z.B. Raspberry PI)
  
-* Halterung als 3D-Druckdatei ([[https://www.stlfinder.com/model/elster-bk-g4-gas-meter-sensor-clip-Holm4hjw/1668194/| STL Finder]])+=====Aufbau===== 
 +  - 3D-Druck der Halterung 
 +  Nach dem Drucken der Halterung habe ich, in Ermangelung der Fähigkeit, STL-Files zu editieren, eine Öffnung in die Halterung für die Platine des Sensors hineingeschnitten 
 +  Entfernen der I2C-Widerstände auf der Platine des Sensors, da diese bereits im Raspberry Pi einbaut sind 
 +  Anlöten eines Kabels an den Sensors 
 +  Die Platine des Sensors ist lediglich in die Halterung gesteckt. Das Kabel ist mit Kabelbindern an der Halterung befestigt. Das ist stabil genug. Man könnte den Sensor sicherlich zusätzlich in die Öffnung der Halterung einkleben, um ihn vor Umwelteinflüssen zu schützen
  
-* HSCDTD008A Library ([[https://github.com/bobveringa/HSCDTD008A-LibraryHSCDTD008A library ]])+{{:hardware:controllers:bk-g4m_lesekopf:img_6017.jpg?400| Halterung}} {{:hardware:controllers:bk-g4m_lesekopf:img_6020_1.png?400Halterung}}
  
-* Programm / PoC zum Zählen der Impulse+{{:hardware:controllers:bk-g4m_lesekopf:img_6019.jpg?400| Halterung}} {{:hardware:controllers:bk-g4m_lesekopf:img_6018.jpg?400| Halterung}}
  
-* Python Script zum Transport der gezählten Impulse in die vzlogger-Datenbank+=====Software===== 
 +Ein Proof of Concept (PoC).
  
-* Raspberry PI +====Binary==== 
- +<code cpp>
-__Aufbau__ +
-====== +
-* 3D-Druck der Halterung +
- +
-* Nach dem Drucken der Halterung habe ich, in Ermangelung der Fähigkeit, STL-Files zu editieren, eine Öffnung in die Halterung für die Platine des Sensors hineingeschnitten +
- +
-* Entfernen der I2C-Widerstände auf der Platine des Sensors, da diese bereits im Raspberry Pi einbaut sind +
- +
-* Anlöten eines Kabels an den Sensors +
- +
-* Die Platine des Sensors ist lediglich in die Halterung gesteckt. Das Kabel ist mit Kabelbindern an der Halterung befestigt. Das ist stabil genug. Man könnte den Sensor sicherlich zusätzlich in die Öffnung der Halterung einkleben, um ihn vor Umwelteinflüssen zu schützen +
- +
-{{:hardware:controllers:bk-g4m_lesekopf:img_6017.jpg?400| Halterung}} +
- +
-{{:hardware:controllers:https:wiki.volkszaehler.org:hardware:controllers:img_6018.jpg?400| Halterung}} +
- +
-{{:hardware:controllers:https:wiki.volkszaehler.org:hardware:controllers:img_6019.jpg?400| Halterung}} +
- +
-{{:hardware:controllers:https:wiki.volkszaehler.org:hardware:controllers:img_6020_1.png?400| Halterung}} +
- +
-__Das Programm / Der Proof of Concept (PoC)__ +
- +
-<code>+
 /**************************************************************** /****************************************************************
  * Example5_Basics.cpp  * Example5_Basics.cpp
  * HSCDTD008A Library Demo  * HSCDTD008A Library Demo
- Copyright Tilman Glötzner+ * Tilman Glötzner
  * Original Creation Date: 2022-09-03  * Original Creation Date: 2022-09-03
  *  *
Zeile 73: Zeile 59:
 #include <pthread.h> #include <pthread.h>
 #include <semaphore.h> #include <semaphore.h>
 +
 +#define NUMBABSENTRIES 3
  
 // Create an instance of the sensor. // Create an instance of the sensor.
Zeile 81: Zeile 69:
   hscdtd_status_t status;   hscdtd_status_t status;
      
 +  //geomag.begin();
   // If you know the I2C address is different than in the provided   // If you know the I2C address is different than in the provided
   // data sheet. Uncomment the line below, and configure the address.   // data sheet. Uncomment the line below, and configure the address.
Zeile 103: Zeile 91:
 hscdtd_status_t status; hscdtd_status_t status;
 sem_t mutex; sem_t mutex;
-float bAbs = 0+float bAbs[NUMBABSENTRIES];
-float bAbsOld = 0;+int bAbsLastEntryIndex = 0;
 float lowLimit = 50; float lowLimit = 50;
 float highLimit = 200; float highLimit = 200;
Zeile 110: Zeile 98:
 unsigned long totalCounter = 0; unsigned long totalCounter = 0;
 int stopFlag = 0; int stopFlag = 0;
 +int daemonized = 0; 
 +int verbose = 2;
  
 void* loop(void *ptr) void* loop(void *ptr)
 { {
-    // Explicitly start a reading. + int k;
-  while (stopFlag == 0) +
-  { +
-   int i = 0;+
  
-   for (i = 0; i < 2;i++) + memset(bAbs, 0, sizeof(float)); 
-   { + // Explicitly start a reading
-   status = geomag.startMeasurement(); + while (stopFlag == 0) 
-   // If the status is OK then we can print the result+ {
-   if (status == HSCDTD_STAT_OK) +
-   { +
-   bAbs = sqrt(pow(geomag.mag.mag_x, 2) + +
-   pow(geomag.mag.mag_y, 2) + +
-   pow(geomag.mag.mag_z, 2)); +
-  +
-   if (( bAbs < highLimit) && (abs(bAbsOld - bAbs)>0.001)+
-   { +
-   printf("X: %f uT, Y: %f uT, Z: %f uT; |B|: %f uT; |Bold|: %f uT", +
-   geomag.mag.mag_x, geomag.mag.mag_y, geomag.mag.mag_z, bAbs, bAbsOld); +
-   printf(";Counter: %lu; TotalCounter: %lu\n", counter,totalCounter);  +
-   } +
-   // trigger on falling flank +
-   if (((bAbs < lowLimit) && (bAbsOld > highLimit)) ) +
-   { +
- sem_wait(&mutex); +
- counter++; +
- sem_post(&mutex);+
  
- totalCounter++;+ status = geomag.startMeasurement(); 
 + // If the status is OK then we can print the result. 
 + if (status == HSCDTD_STAT_OK) 
 +
 + bAbs[bAbsLastEntryIndex] = sqrt(pow(geomag.mag.mag_x, 2) + 
 + pow(geomag.mag.mag_y, 2) + 
 + pow(geomag.mag.mag_z, 2));
  
- printf("INC: Counter: %lu", counter); + // weed out erroneous readings bAbs = 0 
- printf(";TotalCounter: %lu\n", totalCounter);+ if (bAbs[bAbsLastEntryIndex] == 0) 
 +
 + //erronous measurement
  
-   + if (verbose >=2) 
-   bAbsOld = bAbs; +
-   + char c; 
-   else + printf("bABS==0;"); 
-   + printf("X: %f uT, Y: %f uT, Z: %f uT; |B|: %f uT;\n", 
-  + geomag.mag.mag_x, geomag.mag.mag_y, geomag.mag.mag_z,bAbs[bAbsLastEntryIndex]); 
-   printf("Error occurred, unable to read sensor data. Exiting ...\n"); + for (k = 0 ; k < NUMBABSENTRIES; k++) 
-   stopFlag = 1; +
-   }+ 
 + if (k == bAbsLastEntryIndex) 
 + c = '*'; 
 + else 
 + c = ' '; 
 + printf("%c|B[%d]|: %f uT;",c,k,bAbs[k]); 
 +
 + printf(";Counter: %lu; TotalCounter: %lu\n", counter,totalCounter); 
 +
 + continue; 
 + 
 +
 + // trigger on falling flank. 
 + // To prevent occassional missreadings (i.e. bAbs 0)  several measurements are used 
 + // all new entries but the oldest need to be under the lower limit 
 + // while the oldest entriey needs to be above the high limit 
 + int trigger = 0; 
 + int index = 0; 
 + int mod = 0; 
 + for (k=0; k < NUMBABSENTRIES; k++) 
 +
 + mod = ((bAbsLastEntryIndex-k) % NUMBABSENTRIES); 
 + index = mod >= 0 ? mod : NUMBABSENTRIES + mod ; 
 + if (k<NUMBABSENTRIES-1) 
 +
 + if (bAbs[index] < lowLimit) 
 + trigger++
 +
 + else 
 + { 
 + if (bAbs[index] > highLimit) 
 + trigger++; 
 +
 + if (verbose >=3 ) 
 +
 + printf("trigger: %d; bAbs[%d]: %f\n", trigger, index, bAbs[index] ); 
 + } 
 +
 + 
 + 
 + if (trigger ==  NUMBABSENTRIES) 
 +
 + sem_wait(&mutex); 
 + counter++; 
 + sem_post(&mutex); 
 + 
 + totalCounter++; 
 + 
 + if (verbose >= 2) 
 + { 
 + printf("INC: Counter: %lu", counter); 
 + printf(";TotalCounter: %lu;", totalCounter); 
 + 
 + char c; 
 + for (k = 0 ; k < NUMBABSENTRIES; k++) 
 +
 + if (k == bAbsLastEntryIndex) 
 + c = '*'; 
 + else 
 + c = ' '; 
 + printf("%c|B[%d]|: %f uT;",c,k,bAbs[k]); 
 +
 + printf("\n"); 
 +
 +
 + bAbsLastEntryIndex = (bAbsLastEntryIndex + 1) % NUMBABSENTRIES; 
 +
 + else 
 +
 + if (verbose >= 1) 
 +
 + printf("Error occurred, unable to read sensor data. Exiting ...\n"); 
 +
 + stopFlag = 1; 
 + //exit(1); 
 + } 
 + 
 + // Wait 500ms  before reading the next sample. 
 + usleep(500000);
  
-   // Wait 500ms  before reading the next sample. 
-   usleep(500000); 
-   } 
   }   }
   return NULL;   return NULL;
 } }
- 
  
  
 int main(int argc, char** argv) int main(int argc, char** argv)
 { {
 +
    setup();    setup();
  
Zeile 222: Zeile 273:
  
  
-</code> 
  
-__Das Python Skript__ 
-<code> 
  
 +
 +
 +</code>
 +
 +====Pythonscript====
 +<code Python>
 #!/usr/bin/python3 #!/usr/bin/python3
 import datetime import datetime
Zeile 252: Zeile 306:
  
 </code> </code>
-__ 
-Die vzlogger-Config__ 
  
-<code>+====vzlogger.conf==== 
 + 
 +<code base>
 .... ....
   {   {
hardware/controllers/bk-g4m_lesekopf.1665527368.txt.gz · Zuletzt geändert: 2022/10/12 00:29 von istler