Hallo, ich bin absoluter Anfänger und habe fast gar keine Ahnung von Arduino. Ich habe eine Geigerzähler Platine von Amazon gekauft und den VIN Anschluss des Zählers mit dem 3. Digitalport des Arduino verbunden. Ein SH1106 OLED-Display zeigt die Messwerte an. Es hat 4 Anschlüsse, 2 für Strom (VDD und GND) sowie einen SCK, der am A5 des Arduino hängt und einen SDA der am A4 hängt. Den Code hab ich aus dem Internet und hab ihn etwas modifiziert. Der Code misst für 10 Sekunden die Interrupt Impulse, und rechnet das Ergebnis mal 6. So erhalte ich die Counts per Minute (cpm) diese werden mal 0,0081 gerechnet um auf die Einheit uSv/h zu kommen. Angezeigt wird cpm und uSv/h. Der Code funktioniert, ich möchte aber noch eine Funktion hinzufügen. In der letzten Zeile sollen noch cpm und uSv/h von den tatsächlichen letzten 60 Sekunden gezeigt werden. Reicht aus wenn dieser Wert alle 60 Sekunden neu berechnet wird, schnelleres aktualisieren der Anzeige für die letzte Minute wär aber schöner. Ich hoffe ihr könnt mir helfen. Hier der Code:
#include <Wire.h>
#include <U8glib.h>
const int Interruptpin = 3; // GPIO Anschluss des Zählrohrs
const int durchlaufzeit = 10000; // 10 Sekunden
unsigned long treffer; // Gezählte Treffer des Zählrohrs
unsigned long tpm; // Treffer pro Minute
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE);
void setup() {
treffer = 0;
tpm = 0;
pinMode(Interruptpin, INPUT);
u8g.begin();
delay(2000);
u8g.firstPage();
do {
u8g.setFont(u8g_font_6x10);
u8g.drawStr(3, 10, "Geigerzähler");
u8g.drawStr(5, 35, "Willkommen");
} while (u8g.nextPage());
// immer wenn fallendes Signal am Geigerzähler soll Funktion counter_hit Zähler um 1 erhöhen
attachInterrupt(digitalPinToInterrupt(Interruptpin), counter_hit, FALLING);
}
void loop() {
static unsigned long startzeit;
unsigned long zeit = millis(); // Millisekunden seit Auslöser
double uSv; // Microsievert Wert pro Stunde
// Wert errechnen beim Ende der Durchlaufzeit
if (zeit - startzeit > durchlaufzeit) {
startzeit = zeit;
if (treffer) {
tpm = treffer * 6; // Treffer pro Durchlauf mal Wert um auf eine Minute zu kommen
uSv = tpm * 0.0081; // Zählrohr Konversationsrate J305: 153,8 CPM = 1 uSv/h
} else {
uSv = 0;
}
u8g.firstPage();
do {
u8g.setFont(u8g_font_6x10);
u8g.drawStr(7, 10, "Messung aktiv");
u8g.drawStr(7, 18, "Treffer:");
u8g.setPrintPos(57, 18);
u8g.print(treffer);
u8g.drawStr(7, 30, "pro Minute cpm:");
u8g.setPrintPos(100, 30);
u8g.print(tpm);
u8g.drawStr(7, 43, "uSv/h:"); // Mikrosievert/h
u8g.setPrintPos(50, 43);
u8g.print(uSv, 4);
} while (u8g.nextPage());
treffer = 0;
tpm = 0;
}
delay(50);
}
void counter_hit() {
treffer++; // bei Treffer plus 1 pro Durchlaufzeit
}
herzlich willkommen im Forum.
Sehr gut gemacht den Code als Code-Section zu posten und eine präzise Beschreibung zu posten.
Man braucht ja ein bisschen Zeit zum lesen. Also alle 10 Sekunden ablesen.
Du nimmst einen Array mit 13 Elementen (Index-Zählweise 0,1,2,3,4,5,6,7,8,9,10,11,12)
Wegen dem Start bei Index 0 sind es dann 13 Elemente
Das nullte Element wird dann gar nicht benutzt. Muss aber trotzdem da sein.
Der Indexzähler startet bei 1
nach 10 Sekunden Zählwert im Element 1 speichern
nach 20 Sekunden Zählwert im Element 2 speichern
...
nach 60 Sekunden Zählwert im Element 6 speichern
Damit ist der gleitende Summenspeicher zum ersten mal gefüllt
Jetzt kann man Elemente 1 bis 6 Zusammenzählen und hat den 60 Sekundenwert
nach 70 Sekunden Zählwert im Element 7 speichern
jetzt kann man die Elemente 2 bis 7 zusammenzählen und hat den nächsten Summenwert
nach 80 Sekunden Zählwert im Element 8 speichern
jetzt kann man die Elemente 3 bis 8 zusammenzählen und hat den nächsten Summenwert
....
nach 120 Sekunden Zählwert im Element 12 speichern
jetzt kann man die Elemente 7 bis 12 zusammenzählen und hat den nächsten Summenwert
Wenn man bei Index 12 angekommen ist wird der Index auf 1 zurückgesetzt
Und der nächste 10 Sekundenwert wird wieder in Element 1 gespeichert
dann kann man Elemente 1 bis 6 Zusammenzählen und hat den 60 Sekundenwert
usw. usw. so läuft das dann im Kreis
Wenn du noch kürzere Intervalle willst dann muss eben die Zeitkontstante kleiner werden
und der Array entsprechend mehr Elemente haben.
Kann sein. Das wirst du jetzt ändern indem du mal einen Programmierversuch machst
oder
in dem du spezifische Fragen stellst.
Was immer auch die Frage sein mag.
Dieser Forum funktioniert NICHT so, dass man hier seinen Funktionalitätswunsch postet und dann alles fertig programmiert bekommt.
Danke für die Hilfe. Ich habe deinen Code aufgespielt. Beide neuen Werte werden zwar angezeigt, allerdings bewegt sich der minuteTpm immer zwischen 100 und 200, während der vorher schon existierende tpm auf Basis der 10 Sekunden bei 15 bis 40 liegt. Dementsprechend auch ein Unterschied zwischen uSv und minuteTpm+0,0081. Weißt du woran das liegen könnte. (Zählt man das Klicken des Geigerzählers pro Minute sind die 15-40 realistisch)
Und dann interessiert mich noch wo die Schwachstelle in der Verarbeitung der Treffer liegt.
Dann ist es doch richtig.
Du bekommst 6 mal den Wert, der im 10 Sekundentakt aufaddiert war.
Der muss also irgendwo zwischen 6*15 und 6*40 liegen.
Das war doch die Ausgangssituation:
Wenn Du jetzt den Mittelwert der letzten 60 sekunden haben willst, dann
Alt:
Neu:
// Ab hier neu: XX ersetzen!
uint32_t minuteTpm = 0;
for (byte b = 0; b < maxTmp; b++)
{ minuteTpm += allTpm[b]; }
minuteTpm/=maxTmp;
u8g.setPrintPos(XX, XX);
u8g.print(minuteTpm);
u8g.setPrintPos(XX, XX);
u8g.print(minuteTpm * 0.0081);
// Ende neu
Ja, Mist. Du hast Deinen Post gelöscht, während ich schreibe...
Danke dir, der Code funktioniert. Ich musste aber in folgendem Codeteil
allTpm[idx] = tpm;
idx++;
Das tpm durch Treffer ersetzen, um auf den Durchschnitt zu kommen. Könnte es sein dass es da ein Missverständnis über die Bedeutung von treffer und tpm gab oder meinst du was anders mit dem Problem in der Verarbeitung von treffer zu tpm?
Ja.
Eine Variable zu füttern, deren Inhalt zur Laufzeit errechnet werden kann, macht manchmal solche...
Aber hast ja gefunden, auf was es rausläuft.
Solltest Du noch Fragen zur Verarbeitung eines 32bit Wertes auf einem 8bit Controller haben, musst Du den Post wiederherstellen...
Erklär ich dann morgen.