Forum: Mikrocontroller und Digitale Elektronik Arduino: Probleme mit dem Zählen von Impulsen


von Stefan S. (kami)


Lesenswert?

Hi,

ich habe hier einen Abtastkopf an meinem Gaszähler hängen und versuche 
die Impulse zu zählen. Der Zähler arbeitet mit einem Magneten an der 
Walze und bei jeder Umdrehung wird im Abtastkopf ein Reed-Relais 
geschlossen und anschliessen wieder geöffnet. Ich habe dafür einen 
Jeenode Arduino Controller verwendet, der daran angeschlossen.
Das eigentliche Zählen sieht wie folgt aus:

Port connector(1);

static unsigned long last;

int gescount,bettersend = 0;

MilliTimer countsend1;

void setup () {



    connector.mode2(INPUT); // Set AIO mode as input
    connector.digiWrite2(0); // Activate pull-up resistor for

last = millis();
}

void loop () {


   static boolean ledOn = false;

 if (countsend1.poll(1000)) {
  bettersend=0;

}

int pushed = connector.digiRead2();



    if (!ledOn && pushed == 0) {
        ledOn = true;

    } else if (ledOn && pushed == 1 && bettersend == 0) {
        ledOn = false;

    gescount +=1;



     bettersend=1;
    }


}

Es handelt sich hierbei um eine verkürzt Version des Quellcodes der nur 
den wichtigen Teil des Zählens enthält.

Mein eigentlicher Gedanke ist nun das er nur nach eine steigenden Flanke 
und einer fallenden Flanke das ganze als Umlaufen zählt.
Außerdem soll durch "bettersend" eine 1 Sekunden Sperre eingestellt 
werden, damit er nur jede Sekunde maximal einen Impuls zählt. Das ganze 
klappt aber nicht und ich habe immer zuviele Impulse gezählt. Wenn ich 
das ganze händisch mit einem Magneten teste, finde ich keinen Fehler 
aber bei richtigen Test am Gaszähler habe müsste ich zum Beispiel 323 
Impulse drauf haben, habe aber 510 gezählt. Eine direkte ungenauigkeit 
ist für mich nicht zu erkennen? Ich zähle also aus irgendeinem Grund 
nicht immer richtig.

Kann mir bitte jemand helfen, wie ich das richtig mache, mit dem Zählen.

Vielen Dank.

Gruß kami

von Alexander S. (esko) Benutzerseite


Lesenswert?

Ein Wort:
Entprellung

von Spess53 (Gast)


Lesenswert?

Hi

>Der Zähler arbeitet mit einem Magneten an der
>Walze und bei jeder Umdrehung wird im Abtastkopf ein Reed-Relais
>geschlossen und anschliessen wieder geöffnet.

>Mein eigentlicher Gedanke ist nun das er nur nach eine steigenden Flanke
>und einer fallenden Flanke das ganze als Umlaufen zählt.

Auch ein Reedkontakt prellt.

MfG Spess

von Stefan S. (kami)


Lesenswert?

Hi,

okay ich habe jetzt mal mit der Software des Controllers versucht eine 
Entprellung zu schaffen. Zurzeit habe ich den  Schalter wie hier bei dem 
Phototransitor zu sehen angeschlossen.

http://www.mikrocontroller.net/articles/Lichtsensor_/_Helligkeitssensor#Phototransistor

Wie sollte ich das entprellen mit HArdware richtig lösen? Kondensator 
parallel dazu schalten? Wenn ja wie groß?


Gruß kami

von Peter D. (pdiener) Benutzerseite


Lesenswert?

So ganz verstehe ich den Quellcode nicht, weil ich nicht weiß, was die 
ganzen Klassen machen.
Bei einem bin ich mir aber sicher:

    connector.mode2(INPUT); // Set AIO mode as input
    connector.digiWrite2(0); // Activate pull-up resistor for

Das DEAKTIVIERT den Pullup-Widerstand beim AVR. Aktiviert wird er duch 
Schreiben von einer logischen 1 in das PORT-Register (digiWrite2(1)).

Das mit dem Timer mit 1 Sekunde ist ja schon eine Entprellung, nur wie 
das in der gezeigten Software funktioniert, ist für mich etwas 
undurchsichtig.

Das liegt wohl auch daran, dass man den Quelltext in der gezeigten 
Formatierung kaum lesen kann.

Deswegen bitte richtig einrücken und farbig darstellen:
1
Port                 connector(1);
2
static unsigned long last;
3
int                  gescount,bettersend = 0;
4
5
MilliTimer           countsend1;
6
7
8
9
void setup ()
10
{
11
  connector.mode2(INPUT);  // Set AIO mode as input
12
  connector.digiWrite2(0); // Activate pull-up resistor for
13
  last = millis();
14
}
15
16
17
18
void loop ()
19
{
20
  static boolean ledOn = false;
21
22
  if (countsend1.poll(1000)) 
23
  {
24
    bettersend=0;
25
  }
26
  
27
  int pushed = connector.digiRead2();
28
29
  if (!ledOn && pushed == 0) 
30
  {
31
    ledOn = true;
32
  } 
33
  else if (ledOn && pushed == 1 && bettersend == 0) 
34
  {
35
    ledOn = false;
36
    gescount +=1;
37
    bettersend=1;
38
  }
39
}

So geht das schon besser, und kaum kann man das lesen, ergeben sich 
weitere Fragen.

Warum ist pushed vom Typ int? Das ist doch ein Binäreingang, also würde 
ich da boolean verwenden.
Und bettersend ist ja auch nur ein Flag, also auch boolean.

Für eine richtige Entprellung sollte der Timer auf den Taster 
aufsynchronisiert werden, also auf Null gesetzt werden, wenn eine Flanke 
erkannt worden ist.
Sonst kann es passieren, dass bei geeignetem Zeitpunkt, an dem der 
Taster prellt, die Entprellung wirkungslos ist. Statistisch zeigt sich 
das dadurch, dass man zu viele Impulse misst.

Zur Sicherheit sollte man immer zusätzliche Klammern verwenden, die auch 
die Lesbarkeit verbessern:
1
(ledOn && (pushed == 1) && (bettersend == 0))

Grüße,

Peter

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.