hardware:channels:meters:water:wasserzaehler_ohne_s0
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende ÜberarbeitungNächste ÜberarbeitungBeide Seiten der Revision | ||
hardware:channels:meters:water:wasserzaehler_ohne_s0 [2019/05/03 20:19] – Ansatz 2 hinzugeschrieben. zugschlus | hardware:channels:meters:water:wasserzaehler_ohne_s0 [2019/06/20 08:11] – gabinvigoss_gmail.com | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
- | ====== | + | ====== |
- | ===== Ansatz 1: Laser ===== | + | ===== Le pointeur laser pour la pratique |
- | Idee: Das kleine Sternrad des Wasserzählers mit einem Laser anvisieren und die Reflexionen mit Photodiode und Arduino-Mikrocontroller auswerten. | + | Avez-vous besoin du pointeur laser puissant et pas cher? S'il me reste un problème avec la cartouche, ce n'est pas si facile à retirer du pistolet. Je dois enfoncer un goujon en bois dans le canon pour faire sortir la balle. Ce n'est pas grave, je suppose. Un autre problème est peut-être le fait que je dois armer les armes à feu pour chaque coup (ou DA). Ce pointeur laser fait clignoter un point rouge lorsque vous appuyez sur la gâchette. C'est idéal pour essayer votre point rapide et tirer sans viser. Bien que le fait de filmer sur une TV LED semble complètement engloutir le point. Il est livré avec un jeu de piles de rechange et après trois semaines de tournage occasionnel dans mon salon, elles sont toujours bonnes! Pour moi, je l’utilise à courte portée (7 à 10 mètres) avec une arme de poing. Dans cet environnement, |
- | ==== Hardware ==== | + | Si vous ne pouvez pas faire preuve de souplesse en raison de vos besoins, de votre patience ou du prix des unités, vous devez considérer que les plafonds peuvent échouer et échouent comme vous le lirez de temps en temps ici. J'ai continué à pratiquer, après quelques minutes, le laser s'est évanoui. Je pensais que les piles devaient être vieilles, alors comme j'ai commandé des piles supplémentaires, |
- | <note important> | + | Il n'y a aucun moyen d' |
- | \\ | + | |
- | {{:hardware: | + | Une autre recommandation: assurez-vous de nettoyer votre canon, surtout si vous tirez des recharges, car elles ne brûlent souvent pas aussi proprement. Je me suis rendu compte que le pointeur laser bleu 30000mW était éteint avec un baril sale. Je suis du genre à croire que la pratique rend parfait et je pense que c'est particulièrement vrai lorsqu' |
- | Den Laser gibt es im Zehnerpack bei Ebay ab 2,50: | + | Le laser est décentré d'environ |
- | [[http:// | + | |
- | + | ||
- | Das ganze habe ich mit einer BPW34 [[http:// | + | |
- | Als Schaltung habe ich das hier gewählt: | + | |
- | + | ||
- | [[https:// | + | |
- | + | ||
- | Halterung ist ein abgesägtes Stück graues PVC-Rohr. Abgesägt ist das Stück, wo normalerweise die Dichtung drin ist. | + | |
- | Darauf ist ein Aluminium Flachprofil geschraubt. | + | |
- | + | ||
- | So sieht es aus, wenn es fertig ist: | + | |
- | + | ||
- | {{: | + | |
- | + | ||
- | Neben dem Wasserzähler greife ich auch den Gaszähler ab. Auf dem letzten Rädchen ist hier ein silber beschichtetets Stück, das hervoragend reflektiert. Hier musste ich nicht den Aufwand mit dem Laser machen, sondern nutze hier dieses Bauteil [[http:// | + | |
- | + | ||
- | {{: | + | |
- | + | ||
- | Beide Zähler gehen an einen Analog in eines Arduino V3 (Ebay, deutlich unter 10 Euro) [[http:// | + | |
- | + | ||
- | Es empfiehlt sich, das Analogsignal, | + | |
- | + | ||
- | <note important> | + | |
- | + | ||
- | ==== Über Script in die Datenbank ==== | + | |
- | + | ||
- | Für Gas- und Wasserzähler, | + | |
- | + | ||
- | === Arduino === | + | |
- | + | ||
- | Das ist der Code auf dem Arduino. Die Idee ist die Differenz zwischen dem Tal und dem Berg bei dem analogen Sensor als Trigger zu verwenden | + | |
- | + | ||
- | <code c> | + | |
- | + | ||
- | //sets ground pin to LOW and input pin to HIGH | + | |
- | void setup() | + | |
- | { | + | |
- | Serial.begin(38400); | + | |
- | // | + | |
- | digitalWrite(A1, | + | |
- | } | + | |
- | long wasser_counter = 0; | + | |
- | long gas_counter = 0; | + | |
- | long loops = 0; | + | |
- | int wasser_max = 0; | + | |
- | int gas_max = 0; | + | |
- | long wasser = 0; | + | |
- | long gas = 0; | + | |
- | int wasser_z = 0; | + | |
- | int gas_z = 0; | + | |
- | unsigned long lastlog = 0; | + | |
- | unsigned long last_gas = 0; | + | |
- | unsigned long last_wasser = 0; | + | |
- | unsigned long time; | + | |
- | + | ||
- | void loop() | + | |
- | { | + | |
- | // Gleitender Durchschnitt anwenden. | + | |
- | gas = ((gas *9) + analogRead(1)) /10; | + | |
- | wasser = ((wasser *3) + analogRead(0))/ | + | |
- | time = millis(); | + | |
- | if (time < lastlog ){ //time ist übergelaufen | + | |
- | lastlog = 0; | + | |
- | last_gas= 0; | + | |
- | last_wasser = 0; | + | |
- | } | + | |
- | wasser_max = max(wasser_max, | + | |
- | gas_max = max(gas_max, | + | |
- | loops++; | + | |
- | if ((wasser_max - 400) > wasser | + | |
- | { | + | |
- | wasser_z++; | + | |
- | } else { | + | |
- | wasser_z = 0; | + | |
- | } | + | |
- | + | ||
- | if ((gas_max - 100) > gas ) | + | |
- | { | + | |
- | gas_z++; | + | |
- | } else { | + | |
- | gas_z = 0; | + | |
- | } | + | |
- | + | ||
- | if (gas_z > 100 && time - last_gas > 500){ | + | |
- | gas_counter++; | + | |
- | gas_max= 0; | + | |
- | last_gas = time; | + | |
- | } | + | |
- | //Qn 2.5 =2500 Liter die Stunde = 60000 Markierungen am Raedchen 0,06 Sekunden (=60 ms für einen Durchgang) | + | |
- | if (wasser_z > 40 && time - last_wasser > 30){ | + | |
- | wasser_counter++; | + | |
- | wasser_max= 0; | + | |
- | last_wasser = time; | + | |
- | } | + | |
- | + | ||
- | + | ||
- | if (time - lastlog > 50){ | + | |
- | // Serial.print(" | + | |
- | lastlog = time; | + | |
- | long checksum = time + gas + gas_counter + wasser + wasser_counter; | + | |
- | + | ||
- | Serial.print(time); | + | |
- | Serial.print(" | + | |
- | Serial.print(gas); | + | |
- | Serial.print(" | + | |
- | Serial.print(gas_counter); | + | |
- | Serial.print(" | + | |
- | Serial.print(wasser); | + | |
- | Serial.print(" | + | |
- | Serial.print(wasser_counter); | + | |
- | Serial.print(" | + | |
- | Serial.print(checksum); | + | |
- | Serial.print(" | + | |
- | Serial.print(gas_max); | + | |
- | Serial.print(" | + | |
- | Serial.print(wasser_max); | + | |
- | Serial.print(" | + | |
- | Serial.println(loops); | + | |
- | loops=0; | + | |
- | + | ||
- | } | + | |
- | + | ||
- | } | + | |
- | </ | + | |
- | + | ||
- | === Script zur Datenübernahme === | + | |
- | + | ||
- | Der Code auf der PC/ | + | |
- | (Aufruf mit Cron regelmäßig, | + | |
- | + | ||
- | <code perl> | + | |
- | # | + | |
- | # Set up the serial port | + | |
- | use Proc:: | + | |
- | die " | + | |
- | + | ||
- | use DBI; | + | |
- | #use LWP:: | + | |
- | use Time::HiRes qw(usleep nanosleep time); | + | |
- | + | ||
- | my $dbh2 = DBI-> | + | |
- | my $sth3 = $dbh2-> | + | |
- | #my $Gas_offset | + | |
- | #my $wasser_offset = | + | |
- | + | ||
- | system(" | + | |
- | my $dbh = DBI-> | + | |
- | my $sth = $dbh-> | + | |
- | my $sth2 = $dbh-> | + | |
- | $sth2-> | + | |
- | + | ||
- | #1014 | + | |
- | + | ||
- | open(LOGGING, ">>", | + | |
- | open(SERIAL, | + | |
- | $time_offset = 0; | + | |
- | while (1) { | + | |
- | # Poll to see if any data is coming in | + | |
- | # | + | |
- | eval { | + | |
- | local $SIG{ALRM} = sub { die " | + | |
- | + | ||
- | # alarm(x) muss in den eval()-Block | + | |
- | alarm(10); | + | |
- | $test = < | + | |
- | alarm(0); | + | |
- | + | ||
- | }; ## end of eval | + | |
- | + | ||
- | # Irgendetwas schiefgelaufen? | + | |
- | if ($@) { | + | |
- | print " | + | |
- | die(); | + | |
- | } | + | |
- | + | ||
- | elsif (length($test)==0){ | + | |
- | print " | + | |
- | sleep 20; | + | |
- | die(); | + | |
- | } | + | |
- | + | ||
- | + | ||
- | + | ||
- | if ( $test =~ /([0-9]*) - ([0-9]*) - ([0-9]*) - ([0-9]*) - ([0-9]*) - ([0-9]*) - ([0-9]*) - ([0-9]*)/ && $1 + $2 + $3 + $4 + $5 == $6){ | + | |
- | $time = $1; | + | |
- | $time_offset2 = int(time * 1000) - $time; | + | |
- | if (abs($time_offset-$time_offset2) > | + | |
- | $time_offset = $time_offset2; | + | |
- | } | + | |
- | $gas = $2; | + | |
- | $gas_counter = $3; | + | |
- | $wasser = $4; | + | |
- | $wasser_counter = $5; | + | |
- | # | + | |
- | + | ||
- | if ($wasser_counter > $wasser_counter_old){ | + | |
- | $sth3-> | + | |
- | + | ||
- | } | + | |
- | $wasser_counter_old = $wasser_counter; | + | |
- | if ($gas_counter > $gas_counter_old){ | + | |
- | $sth3-> | + | |
- | + | ||
- | } | + | |
- | $gas_counter_old = $gas_counter; | + | |
- | chop($test); | + | |
- | chop($test); | + | |
- | print LOGGING $test.gmtime()." | + | |
- | print $test.gmtime()." | + | |
- | } | + | |
- | + | ||
- | + | ||
- | + | ||
- | } | + | |
- | + | ||
- | </ | + | |
- | + | ||
- | < | + | |
- | Die Kanäle (channel_id) sind hart codiert: 12 und 9.</ | + | |
- | + | ||
- | Was noch justiert werden muss, ist die Differenz, die zwischen Tal und Berg nötig ist: | + | |
- | + | ||
- | <code php> | + | |
- | <?php | + | |
- | //include ("/ | + | |
- | //include ("/ | + | |
- | include ("/ | + | |
- | include ("/ | + | |
- | include ("/ | + | |
- | + | ||
- | $graph = new Graph(3000, | + | |
- | $graph-> | + | |
- | + | ||
- | // | + | |
- | // | + | |
- | $graph-> | + | |
- | $graph-> | + | |
- | # | + | |
- | // | + | |
- | $graph-> | + | |
- | $graph-> | + | |
- | $graph-> | + | |
- | $graph-> | + | |
- | $graph-> | + | |
- | + | ||
- | + | ||
- | $connection = mysql_connect(" | + | |
- | $db_selected = mysql_select_db(" | + | |
- | if (!$connection) | + | |
- | { | + | |
- | die(' | + | |
- | } | + | |
- | if (!$db_selected) | + | |
- | { | + | |
- | die('Can\'t use db : ' . mysql_error()); | + | |
- | } | + | |
- | $query = " | + | |
- | $result = mysql_query($query); | + | |
- | $i=0; | + | |
- | while ($row = @mysql_fetch_assoc($result)) | + | |
- | { | + | |
- | $ywert[$i] = $row['wert2' | + | |
- | + | ||
- | $stunden[$i] = $row[' | + | |
- | $i +=1; | + | |
- | } | + | |
- | + | ||
- | $lineplot=new LinePlot($ywert, | + | |
- | $lineplot-> | + | |
- | + | ||
- | $graph-> | + | |
- | $graph-> | + | |
- | + | ||
- | ?> | + | |
- | + | ||
- | </ | + | |
- | + | ||
- | So sieht so eine Grafik aus: | + | |
- | + | ||
- | {{: | + | |
- | {{: | + | |
- | + | ||
- | <note tip>Oder den " | + | |
- | + | ||
- | ==== Über vzlogger an die Middleware ==== | + | |
- | + | ||
- | Für **nur einen** Wasserzähler, | + | |
- | + | ||
- | === Arduino === | + | |
- | + | ||
- | Hier der Code für den Arduino. Verkürzte Version von oben, weil nur eine Diode ausgewertet wird und die Impulse im Arduino nicht gezählt werden. | + | |
- | + | ||
- | <code c> | + | |
- | + | ||
- | // Original von mikemiller 2015-2016 | + | |
- | // Reduziert auf nur 1 Wasserzähler mit Ausgabe | + | |
- | // des Impulses auf die USB-Schnittstelle | + | |
- | + | ||
- | void setup() | + | |
- | { | + | |
- | Serial.begin(300); | + | |
- | // Open serial communications and wait for port to open: | + | |
- | // A baud rate of 115200 is used instead of 9600 for a faster data rate | + | |
- | // on non-native USB ports | + | |
- | //Serial.begin(115200); | + | |
- | while (!Serial) { | + | |
- | ; // wait for serial port to connect. Needed for native USB port only | + | |
- | } | + | |
- | + | ||
- | // | + | |
- | pinMode(A0, INPUT); | + | |
- | digitalWrite(A1, HIGH); | + | |
- | } | + | |
- | int wasser_max = 0; | + | |
- | long wasser = 0; | + | |
- | int wasser_z = 0; | + | |
- | unsigned long lastlog = 0; | + | |
- | unsigned long last_wasser = 0; | + | |
- | unsigned long time; | + | |
- | + | ||
- | void loop() | + | |
- | { | + | |
- | // Gleitender Durchschnitt anwenden. | + | |
- | wasser = ((wasser *3) + analogRead(0))/ | + | |
- | time = millis(); | + | |
- | if (time < lastlog ){ //time ist übergelaufen | + | |
- | lastlog = 0; | + | |
- | last_wasser = 0; | + | |
- | } | + | |
- | wasser_max = max(wasser_max, | + | |
- | + | ||
- | if ((wasser_max - 200) > wasser) | + | |
- | { | + | |
- | wasser_z++; | + | |
- | } else { | + | |
- | wasser_z = 0; | + | |
- | } | + | |
- | + | ||
- | // Qn 2,5 m³/h = 2.500 Liter pro Stunde | + | |
- | // Das Raedchen hat 6 Fluegel und dreht sich 1x je 0,1 Liter --> 60 Impulse je Liter | + | |
- | // Bei Maximaldurchfluss 2.500 l/h * 60 Imp/l = 2.500*60 Imp/h = 2.500/60 Imp/s = 41,7 Imp/s | + | |
- | // --> Mindestens 24 ms zwischen zwei Impulsen (" | + | |
- | + | ||
- | if (wasser_z > 40 && time - last_wasser > 30) { | + | |
- | wasser_max= 0; | + | |
- | lastlog = time; | + | |
- | last_wasser = time; | + | |
- | Serial.print(0x00); | + | |
- | } | + | |
- | + | ||
- | } | + | |
- | </ | + | |
- | + | ||
- | Die Differenz zwischen Hell und Dunkel muss für dieses Code-Beispiel mindestens 200 betragen, sonst wird kein Impuls erzeugt. | + | |
- | + | ||
- | === Frontend === | + | |
- | + | ||
- | Kanal erstellen als Wassermengenzähler mit einer Auflösung von 60 (Impulse/l, siehe Berechnung im Code) und Stil=steps. UUID notieren. | + | |
- | + | ||
- | === Beispielkonfiguration === | + | |
- | Exemplarische / | + | |
- | <code base vzlogger.conf> | + | |
- | { | + | |
- | // Water as S0 meter | + | |
- | + | ||
- | " | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | + | ||
- | " | + | |
- | " | + | |
- | + | ||
- | " | + | |
- | " | + | |
- | " | + | |
- | " | + | |
- | // " | + | |
- | // " | + | |
- | // " | + | |
- | " | + | |
- | } | + | |
- | } // meter | + | |
- | </ | + | |
- | + | ||
- | ===== Ansatz 2: grüne LED und Fototransistor ===== | + | |
- | + | ||
- | Im [[https:// | + | |
- | + | ||
- | Beim Nachbau hat es sich gezeigt, dass es u.a. auf die Helligkeit der verwendeten LED ankommt. Die zuerst beschafft LED war nicht hell genug, um den Fototransistor selbst bei direkter Belichtung durchzusteuern. Mit der nachbeschafften Nichia NSPG300D gelang der Betrieb dann auf Anhieb. | + | |
- | + | ||
- | Wie in der Original-Anleitung beschrieben, | + | |
+ | //Les modules laser habituels sont disponibles avec une longueur d'onde différente: |
hardware/channels/meters/water/wasserzaehler_ohne_s0.txt · Zuletzt geändert: 2024/04/23 18:03 von jau