http://sites.schaltungen.at/arduino-uno-r4/frequenzzaehler
Wels, am 2019-05-10BITTE nützen Sie doch rechts OBEN das Suchfeld [ ] [ Diese Site durchsuchen]DIN A3 oder DIN A4 quer ausdrucken
*******************************************************************************I** DIN A4 ausdrucken (Heftrand 15mm / 5mm) siehe http://sites.schaltungen.at/drucker/sites-prenninger
********************************************************I* ~015_b_PrennIng-a_arduino-uno-r4/frequenzzaehler (xx Seiten)_1a.pdf
Frequenzzähler mit Arduino
An manchen Schulen werden Zählraten und andere Ereignisse im Praktikum gemessen. Ein GM-Zählrohr liefert Impulse, die der Intensität von z.B. Gamma-Stahlen entsprechen. In der Mechanik können Geschwindigkeiten mittels Speichenrad in eine Frequenz gewandelt werden. Interferenzübergänge erlauben Aussagen zu optischen Weglängenänderungen.
FrequencyCounter 50Hz Arduino zeigt die Netzfrequenz bei offenem Eingang auf einem LCD-Display. Ein Blick in die Referenz auf arduino.cc zeigt bei den Eingaben unter 'Advanced I/O' die Funktion pulseIn(). Die Beschreibung sagt, dass mit dem Aufruf pulseiIn(pin, HIGH) gewartet wird, bis das Signal an dem Eingangs-Pin (pin) auf Logikpegel HIGH geht. Dann wird ein Timer gestartet und gewartet bis der Pegel LOW erreicht wird. Die verstrichene Zeit wird in Mikrosekunden zurück geliefert. Etwas anders ausgedrückt: puseIn(pin,HIGH) liefert die Impulsdauer ti. Die Impulspause tp kann mit pulsIN(pin,LOW) ermittelt werden. Die Periodendauer T ergibt sich aus T = ti+ tp. Bei einem symmetrischen Rechtecksignal ist ti = tp, also die Zeit für HIGH-Pegel gleich der Zeit für LOW-Pegel. Die Funktion kehrt bei einem Timeout mit dem Wert 0 zurück, womit auch bei fehlendem Signal das Programm fortgesetzt werden kann. Der Kehrwert der Periodendauer T entspricht der Frequenz f. Aus Mikrosekunden (1e-6) werden Megahertz (1e6). Um eine Anzeige in Hertz zu erreichen wird mit 1e6 multipliziert. Hier der Sketch. /* Frequenzzähler Gibt die Frequenz des Spannungsignals an Pin 7 aus */int pin = 7;unsigned long T; //Periodendauer in usdouble f; //Frequenz in MHz void setup() {Serial.begin(9600); pinMode(pin, INPUT);}void loop() {T = pulseIn(pin, HIGH) + pulseIn(pin, LOW); if (T==0) Serial.println("Timeout."); else {f=1/(double)T; // f=1/T Serial.println(f*1e6); //Ausgabe in Hertz } }
Quelle:
http://www.hjberndt.de/soft/ardfreq.html
Arduino Frequency Counter 27,78Hz
Program Code (if You Use LCD Without 3Pin Interface Board)# Program code (if you use LCD without 3Pin interface Board) #include <LiquidCrystal.h> LiquidCrystal lcd(11, 7, 5, 4, 3, 2); const int pulsePin = 12; // Input signal connected to Pin 12 of Arduino int pulseHigh; // Integer variable to capture High time of the incoming pulse int pulseLow; // Integer variable to capture Low time of the incoming pulse float pulseTotal; // Float variable to capture Total time of the incoming pulse float frequency; // Calculated Frequency void setup() { pinMode(pulsePin, INPUT); lcd.begin(16, 2); lcd.setCursor(0, 0); lcd.print("Instructables"); lcd.setCursor(0, 1); lcd.print(" Freq Counter "); delay(5000); } void loop() { lcd.setCursor(0, 0); lcd.print("Frequency is "); lcd.setCursor(0, 1); lcd.print(" "); pulseHigh = pulseIn(pulsePin, HIGH); pulseLow = pulseIn(pulsePin, LOW); pulseTotal = pulseHigh + pulseLow; // Time period of the pulse in microseconds frequency = 1000000/ pulseTotal; // Frequency in Hertz (Hz) lcd.setCursor(0, 1); lcd.print(frequency); lcd.print(" Hz"); delay(500); } Quelle: ARDUINO FreqCountQuelle: Frequency counter using Arduino (upto 40kHz)
Viele Leute hier fragten nach einem Frequenzzähler und endlich hatte ich genug Zeit, um einen zu machen.
Dieser Frequenzzähler, der Arduino verwendet, basiert auf der UNO-Version und kann bis zu 40 KHz zählen.
Ein 16 × 2 LCD-Display dient zur Anzeige der Frequenzzählung.
Die Schaltung hat ein Minimum an externen Komponenten und zählt direkt die Frequenz.
In jedem Fall darf die Amplitude der Eingangsfrequenz nicht größer als 5 V sein.
Wenn Sie Signale über 5 V messen möchten, müssen zusätzliche Begrenzungskreise hinzugefügt werden, die ich zu einem anderen Zeitpunkt anzeigen werde.
Jetzt machen Sie es einfach mit 5V-Signalen. Die zu zählende Frequenz ist mit dem digitalen Pin 12 des Arduino verbunden.
Die Funktion pulseIn () wird hier zum Zählen der an Pin 12 angeschlossenen Frequenz verwendet.
Die Funktion pulseIn () zählt die Anzahl der Impulse (HIGH oder LOW), die an einem bestimmten Pin des Arduino ankommen.
Die allgemeine Syntax dieser Funktion lautet pulseIn (Pin, Wert, Zeit), wobei Pin der Name des Pins ist, Wert entweder HIGH oder LOW ist und Zeit die Zeit ist, für die die Funktion auf einen Impuls warten soll.
Die Funktion gibt Null zurück, wenn innerhalb der angegebenen Zeit kein gültiger Impuls vorhanden ist.
Die pulseIn () - Funktion kann Impulse mit einer Zeitspanne von 10 bis 3 Minuten zählen.
Mit dem Potentimeter R1 = 10k wird der Kontrast des LCD-Bildschirms eingestellt.
Der Widerstand R2 begrenzt den Strom durch die LED-Hintergrundbeleuchtung.
Im Programm werden die hohe Zeit und die niedrige Zeit des Eingangssignals mit separaten pulseIn () - Funktionen gemessen.
Dann werden die hohen und niedrigen Zeiten addiert, um die Gesamtzeitdauer des Signals zu erhalten.
Die Frequenz ist nur eine Zeitspanne in Sekunden.
Die pulseIn () - Funktion gibt den Zeitraum in Mikrosekunden zurück.
Gesamtzeitspanne in Mikrosekunden, zuerst geteilt durch 1000.
Dann wird 1000 durch das Ergebnis geteilt, um die Frequenz in Hertz zu erhalten.
Das Programm des Frequenzzählers mit Arduino ist unten dargestellt.
Programm / Sketch
#include <LiquidCrystal.h>int input=12;int high_time;int low_time;float time_period;float frequency;LiquidCrystal lcd(7, 6, 5, 4, 3, 2);void setup(){pinMode(input,INPUT);lcd.begin(16, 2);}void loop(){lcd.clear();lcd.setCursor(0,0);lcd.print("Frequency Meter");high_time=pulseIn(input,HIGH);low_time=pulseIn(input,LOW); time_period=high_time+low_time;time_period=time_period/1000;frequency=1000/time_period;lcd.setCursor(0,1);lcd.print(frequency);lcd.print(" Hz");delay(500);}
Quelle:
http://www.circuitstoday.com/frequency-counter-using-arduino
Vor kurzem hatte ein Freund von mir ein Problem mit der ECU seines Autos und brauchte ein Frequenzzählgerät.
Die Lösung war eine Vorrichtung zur Bestimmung der vom Steuergerät abgegebenen Impulsfrequenz gegen den Drehzahlmesser.
Das Gerät musste also in der Lage sein, digitale Impulse zwischen 1,0V und 5,0V zu lesen, die dann von einem digitalen pin am Arduino als HIGH- und LOW-Impulse interpretiert werden.
Dann wird die Frequenz in Hz / kHz auf dem LCD-Display ausgegeben.
Hardware
1x Arduino Uno 1x 16×2 LCD SPI (nicht der I2C) 3x Schaltdrähte 0,64mm Die Einrichtung Ich hatte einen 16×2-LCD-Monitor gekauft und nie etwas damit gemacht, also war es an der Zeit. Das LCD hatte die Form eines mit Arduino Uno kompatiblen Schildes.
Ich schnappte das LCD auf den Arduino und befestigte einen Überbrückungsdraht an Analog-Pin A5.
Ich verwende immer noch den digitalen Eingang in meinem Code, aber da fast alle digitalen Pins vom LCD-Display belegt wurden, habe ich mich für eine analoge Pin entschieden.
Jetzt kann das Gerät über den USB-Anschluss, den Klinkenstecker oder die Vin mit Strom versorgt werden.
Ich verwende die Vin hier, da mir kein Wagenheber zur Verfügung stand und ich die Vorräte des Autos benutzte (ungefähr 12V..14V).
Schaltung
Wenn Sie die LCD-Abschirmung verwenden, können Sie diesen Teil überspringen.
Wenn Sie jedoch keine Abschirmung haben, finden Sie hier die erforderlichen Anschlüsse.
LCD ———— Arduino RS ———– 12
Enable ——11
D4 ———– 5
D5 ———– 4 D6 ———– 3 D7 ———– 2 R / W - GND Vss ———- GND Vcc ------ + 5V Fügen Sie einen 10k Ohm Widerstand zwischen + 5V und GND hinzu.
Stecken Sie die + 12V der Batterie in den Arduino Vin-Pin und die Masse der Batterie in die Arduino GND.
Zum Schluss wird der A1-Pin-Jumper mit der Quelle der zu messenden Frequenz verbunden.
HINWEIS:
In meinem Fall waren sowohl die ECU als auch der Arduino mit dem GND verbunden (am GND-Anschluss der Batterie).
Der Sketch
Die Sketch ist ziemlich einfach.
Wir werden 3 Werte auf dem Bildschirm anzeigen.
Die aktuelle Frequenz, die maximale Frequenz und die minimale Frequenz werden jede Sekunde aktualisiert.
Min und Max werden alle 5 Minuten zurückgesetzt.
Wir verwenden den LiquidCrystal.h, der in der Arduino IDE-Installation enthalten ist.
Sie müssen also nichts hinzufügen.
Einschränkungen
Wir haben das Gerät mit einem anderen Arduino getestet (was wahrscheinlich nicht das Beste ist)
und fanden heraus, dass das Gerät bei 50kHz einen Fehler von etwa +/- 3% hatte, also ist es ziemlich gut.
Über 50 kHz hinaus begann der Fehler zu steigen und wurde sehr ungenau.
Wir empfehlen daher, es nur für Frequenzen unter 50 kHz zu verwenden.
ARDUINO UNO Sketch
/* * The MIT License (MIT) * * Copyright (c) 2016 RuntimeProjects * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */#include <LiquidCrystal.h>LiquidCrystal lcd(8, 9, 4, 5, 6, 7);long microSecs;long freq;int lastBit;int nowVal;long secs;long maxHz;long minHz;long minmax;void setup() { // set up the LCD's number of columns and rows: lcd.begin(16, 2); // Print a message to the LCD. lcd.print("Loading..."); pinMode(A1,INPUT); pinMode(A5,OUTPUT); microSecs = micros(); freq = 0; lastBit = 0; nowVal =0; maxHz=0; minHz=0; minmax=0; secs = millis(); //Serial.begin(9600);}int x=0;void loop() { if ((microSecs+20)<micros()){ nowVal=digitalRead(A1); if (lastBit!=nowVal) { lastBit=nowVal; freq=freq+1; } if (freq>maxHz){ maxHz=freq; } if (freq<minHz){ minHz=freq; } //lcd.clear(); //lcd.print(); microSecs = micros(); } if (secs+1000<millis()){ if (minmax+300000<millis()) { minmax=millis(); minHz=freq; maxHz=freq; } lcd.clear(); lcd.print((freq/2)); lcd.print("hz"); lcd.setCursor(0,1); lcd.print("+: "); lcd.print(maxHz); lcd.print(" -: "); lcd.print(minHz); freq=0; secs=millis(); }}
Sie zählen beide Flanken innerhalb von 20µs -> es ist klar, dass dies nur für weniger als 50kHz funktioniert.
Sie können einen Interrupt bei Änderung für die Eingabe verwenden. Sie stellen die microSecs am Ende des Zählens neu ein - dies sollte durch Hinzufügen von 20 zu microSecs erfolgen Sie prüfen während des Zählens auf Min & Max. Dies ist nicht erforderlich. Jede Sekunde ist gut
Quelle:
https://www.hackster.io/jasirtp/arduino-frequency-counter-with-16x2-lcd-display-c99779
Pulse Counter on ArduinoFrequency Counting Using Arduino Quelle: Quelle:
https://www.tek.com/sites/default/files/courseware/Arduino_Frequency_Counter.pdf
Speed Measuring Sensor Counter Motor Test Groove Coupler Module For Arduino
Vcc Connect the positive 3.3 5 v power supply
GND Connect power negative Do TTL switch signal output Ao This module does not work
Geschwindigkeitsmesssensorzähler Motor Test Groove Coupler Module für Arduino
Merkmal: Verwendung eines optischen Sensors mit eingekerbter Nut, Breite 5 mm. Der Ausgangsstatus leuchtet, wenn der Ausgangspegel hoch ist, sind die Lichter ausgeschaltet. Wenn der Ausgangspegel niedrig ist, ist er eingeschaltet. Wenn es abgedeckt ist, gibt es einen hohen Pegel aus, andernfalls einen niedrigen Pegel. Gutes Signal und Wellenform mit starker Ansteuerung für mehr als 15mA. Die Arbeitsspannung von 3,3V bis 5,0V. Ausgang: Digitaler Schaltausgang (0 und 1). Ausgestattet mit einem festen Bolzenloch, einfach zu installieren. Platinengröße für kleine Platinen: 32mm x 14mm. Use the LM393 wide voltage compare
Quelle:
https://forum.arduino.cc/index.php?topic=365449.0https://www.amazon.com/Measuring-Sensor-Counter-Coupler-Arduino/dp/B00Q6WKFE2 https://nl.aliexpress.com/item/Speed-Meetsensor-Counter-Motor-Test-Groove-Koppeling-Module-Optische-Koppeling-Module-Voor-Arduino-3-2-cm/32914762903.html Eingangsverstärker für den Arduino Frequenzzähler 10 Hz bis 10 MHzFür den Arduino Uno Frequenzzähler wird ein Eingangsverstärker entwickelt um auch kleinere Signale messen zu können und den Arduino zu schützen. Die Forderungen
Eine einfache 5V Spannungsversorgung. Die Schaltung Eingangsverstärker Die Bauteile Es werden BC547B Transistoren verwendet mit einer Transitfrequenz (Verstärkung = 1) von ca. 300 MHz.
Die sollten bis 8 MHz ausreichend Verstärkung haben.
Um die Schaltung zu schützen wird ein Eingangswiderstand und 2 Dioden gegeneinander zu Masse geschaltet.
Der 1kOhm Widerstand muss bei 30V knapp 30mA Strom vertragen, was eine Gleichspannungs Verlustleistung von 0,9W ergibt.
Bei einer Wechselspannung ist das ca. die halbe Leistung, also 0,5W. Es kann ein Metallschicht Widerstand verwendet werden.
Die Dioden 1N4148 sind mit 30mA auch weit unter ihrem Maximalstrom von 300mA.
Die erste Stufe wird mir einem Kondensator gekoppelt um einen stabilen Gleichspanungsarbeitspunkt zu bekommen.
Für kleine Frequenzen wird ein 4,7uF Keramik Kondensator vorgeschaltet.
Zur Sicherheit für den Resonanzfall wird ein 100nF Kondensator parallel geschaltet.
Im Emitter wird ein Widerstand verwendet um die Schaltung etwas hochohmiger zu machen, dafür sinkt die Verstärkung.
Der CB Widerstand R2 wird auf eine Kollektorspannung von ca. 2,5V ausgelegt.
Die zweite Stufe wird auch über einen Kondensator gekoppelt, hier 2 x 4,7uF parallel zu 100 nF, da die Ausgangsspannung der ersten Stufe höher ist
und diese 2. Transistorstufe ohne Emitterwiderstand im Eingang niederohmiger ist.
Dahinter ist ein Inverter eingesetzt. Das wird in der Schaltung später ein 7400 TTL Baustein werden.
Hier reicht ein Koppelkondensator von 100nF. Damit ist eine saubere 5V TTL Ausgangsspannung gegeben, die direkt an den Arduino Uno Pin gelegt werden kann.
Die Simulationsergebnisse Die Ergebnisse sind im Zeitbereich dargestellt für jeweils einige Schwingungen. Rot > Eingangssignal Blau > Signal nach der 1. Transistor Stufe Grün > Ausgangssignal des idealen Inverters (hier 1V, später mit dem TTL Baustein 5V) Eingangsspannung 10MHz 10mV Bei 10MHz macht sich die Verstärkungsabsenkung (ft=3MHZ) schon deutlich bemerkbar, sodass hier 10mV Eingangssignal anliegen sollten. Die Simulation wurde mit LT-Spice durchgeführt, das bei Linear Technology kostenlos zur Verfügung steht. Quelle: http://shelvin.de/eingangsverstaerker-fuer-den-frequenzzaehler-10-hz-10-mhz/ Ein Frequenzzähler für niedrige Frequenzen mit dem Arduino Uno und der Periodendauer Messung
Frequenzzähler für niedrige Frequenzen mit Pulslängenmessung
4 Antworten Über die Messung der Pulslängen HIGH und LOW kann aus einem Rechtecksignal, oder einem ähnlichen Signal, die Frequenz bestimmt werden. Der Arduino bietet hierzu die Funktion pulseIn(pin, signal) an.
Die funktioniert an jedem Digital Pin und misst, wenn man die HIGH und die LOW Zeit addiert die Periodendauer T in Mikrosekunden.
Die Grenzwertbetrachtung Bei einer Periodendauer von 100 Mikrosekunden entspricht +- 1 Mikrosekunde Fehler 1%, sodass bis ca. 10 kHz gemessen werden kann mit einem Fehler <1%. Die Periodendauer T wird als unsigned long angegeben und kann somit bis maximal 4.294.967.295 zählen.
Das entspricht 230 Mikroherz und somit ist der Millihertz Bereich voll erfasst und 3 Kommastllen sind bei niedrigen Frequenzen möglich.
Der Messbereich beträgt also 1 Millihertz bis 10 kHz. Das Programm void loop() { time=micros(); do { T = pulseIn(pin, HIGH) + pulseIn(pin, LOW); if (T==0) { Serial.println("Timeout."); } else { f=1/(double)T; // f=1/T k++; } fsum+=f*1e6; } while( micros() < (time+1e6)); // 1 Sekunde mitteln f = fsum/k*0.9925; // Korrekturwert einrechnen Serial.println(f); fsum=0.0; k=0;}
Für niedrigerer Frequenzen muss entsprechend länger gemittelt werden, zum Beispiel 10, 100 oder 1000 Sekunden um 3 Millihertz erfassen zu können. Fazit Mit dieser einfachen und flexiblen Routine sind Messung von 3Hz bis 10 kHz möglich incl. einiger Nachkommastellen. Links Für höher Frequenzen wird die hier beschriebene Technik verwendet.
Quelle:
http://shelvin.de/ein-frequenzzaehler-fuer-niedrige-frequenzen-mit-dem-arduino-uno-und-der-pulslaengenmessung/
Frequenzzähler mit LCD Display am Arduino UnoZum Frequenzzähler wird ein LCD Display 16 x 2 hinzugefügt basierend auf den beiden Projekten: – Frequenzzähler Teil 1 & Teil 2 – LCD Display Teil 1 & Teil 2 Das 1602 LCD Display soll die gemessene Frequenz ausgeben.
Die Anschlüsse bei beiden Projekten überschneiden sich nicht, sodass sie alle weiter verwendet werden.
Die Display Anschlüsse: LCD > Arduino ————- VSS > GND VDD > +5V V0 > 10k Poti + 1kOhm Widerstand > GND RS > Pin 12 R/W > Pin 13 E > Pin 11 D4 > Pin 7 D5 > Pin 8 D6 > Pin 9 D7 > Pin 10 A > +5V K > 10 Ohm Widerstand > GND Die Messfrequenz wird mit einem Pegel von ca. 5V auf Pin 5 und GND angeschlossen.
Achtung: nicht über 5V Pegel!
Der Aufbau // Arduino Uno Frequenzzähler bis ca. 5 MHz// Eingangsspannung muss an Pin 5 mit ca. 5V Pegel ankommen.// V 1.2: 1602 Display hinzugefügt// // Beschreibung und Library unter:// http://interface.khm.de/index.php/lab/experiments/arduino-frequency-counter-library///// Matthias Busse 24.05.2014 Version 1.2/* LCD Display Anschlüsse:LCD > Arduino-------------VSS > GNDVDD > +5VV0 > 10k Poti + 1kOhm Widerstand > GNDRS > Pin 12R/W > Pin 13E > Pin 11D4 > Pin 7D5 > Pin 8D6 > Pin 9D7 > Pin 10A > +5VK > 10 Ohm Widerstand > GND */#include < FreqCounter.h>#include < LiquidCrystal.h>LiquidCrystal lcd(12, 13, 11, 7, 8, 9, 10);long int rfreq, mfreq; // rfreq=Rechenfrequenz, mfreq=Messfrequenzint hz=0, khz=0, mhz=0; // Hz, kHz und MHz je 3 Ziffernchar sfreq[15]; // sfreq=Stringfrequenzvoid setup() { Serial.begin(38400); // Serielle Ausgabe Serial.println("Frequenz Zaehler V 1.2"); lcd.begin(20,4); lcd.clear(); lcd.setCursor(0,0); lcd.print("Frequenz Zaehler"); delay(1000);}void loop() { FreqCounter::f_comp= 8; // Kompensation einstellen FreqCounter::start(1000); // Zähler starten für 1000ms while (FreqCounter::f_ready == 0) // warten bis der Zähler fertig ist mfreq=FreqCounter::f_freq; // Ergebnis lesen rfreq=mfreq; hz=rfreq-(int((rfreq/1000))*1000); // Hz ermitteln rfreq=(rfreq-hz)/1000; // kHz ermitteln khz=rfreq-(int((rfreq/1000))*1000); rfreq=(rfreq-khz)/1000; // MHz ermitteln mhz=rfreq-(int((rfreq/1000))*1000); if(mfreq<1000) // Hz in String schreiben sprintf(sfreq," %3d Hz",hz); if((mfreq>=1000)&&(mfreq<1000000)) // kHz.Hz in String schreiben sprintf(sfreq," %3d.%03d Hz",khz,hz); if(mfreq>999999) // MHz.kHz.Hz in String schreiben sprintf(sfreq,"%3d.%03d.%03d Hz",mhz,khz,hz); Serial.println(sfreq); // Terminal ausgeben lcd.setCursor(1,1); // Display ausgeben lcd.print(" "); lcd.setCursor(1,1); lcd.print(sfreq);} Frequenzzähler mit dem Arduino Uno Teil 1Wenn eine 5V Wechselspannung vorliegt, z.B. aus dem Rechteckgenerator, kann der Arduino die Frequenz direkt zählen.
Das funktioniert bis ca. 8 MHz bei einem symmetrischen
Rechtecksignal, ansonsten weniger. Martin Nawrath hat hierzu eine gute Library geschrieben und bereit gestellt. Die Hardware Beim Uno wird die 5V Rechteckspannung direkt an Pin 5 gelegt. Bitte keine höhere Spitzenspannung verwenden, da das den Arduino beschädigen oder zerstören kann.
Am besten schaltet man einen TTL Baustein 74xx davor, der ist billiger zu ersetzen als der Mikrocontroller.
Die Software Hier der Arduino Programmcode mit Kommentaren: // Arduino Uno Frequenzzähler bis ca. 5 MHz// Eingangsspannung muss an Pin 5 mit 5V Pegel ankommen.// // Beschreibung und Library unter:// http://interface.khm.de/index.php/lab/experiments/arduino-frequency-counter-library///// Matthias Busse 11.04.2014 Version 1.0#include < FreqCounter.h>long int freq;void setup() { Serial.begin(38400); // Serielle Ausgabe Serial.println("Frequenz Zaehler V 1.0");}void loop() { FreqCounter::f_comp= 8; // Kompensation einstellen FreqCounter::start(1000); // Zähler starten für 1000ms while (FreqCounter::f_ready == 0) // warten bis der Zähler fertig ist freq=FreqCounter::f_freq; // Ergebnis lesen Serial.println(freq); // und ausgeben}
Quelle:
http://shelvin.de/frequenzzaehler-mit-dem-arduino-uno/
http://shelvin.de/frequenzzaehler-mit-display/
Frequenzzähler mit dem Arduino Uno Teil 2Die Frequenz wird zu besseren Lesbarkeit mit Dezimalpunkten ausgegeben.Anstelle von 123445566 Hz wird nun 123.445.566 Hz ausgegeben. Die Software Hier der Arduino Programmcode mit Kommentaren: // Arduino Uno Frequenzzähler bis ca. 5 MHz// Eingangsspannung muss an Pin 5 mit 5V Pegel ankommen.// // Beschreibung und Library unter:// http://interface.khm.de/index.php/lab/experiments/arduino-frequency-counter-library///// Matthias Busse 12.04.2014 Version 1.1#include < FreqCounter.h>long int rfreq, mfreq; // rfreq=Rechenfrequenz, mfreq=Messfrequenzint hz=0, khz=0, mhz=0; // Hz, kHz und MHz je 3 Ziffernchar sfreq[15]; // sfreq=Stringfrequenzvoid setup() { Serial.begin(38400); // Serielle Ausgabe Serial.println("Frequenz Zaehler V 1.1");}void loop() { FreqCounter::f_comp= 8; // Kompensation einstellen FreqCounter::start(1000); // Zähler starten für 1000ms while (FreqCounter::f_ready == 0) // warten bis der Zähler fertig ist mfreq=FreqCounter::f_freq; // Ergebnis lesen rfreq=mfreq; hz=rfreq-(int((rfreq/1000))*1000); // Hz ermitteln rfreq=(rfreq-hz)/1000; // kHz ermitteln khz=rfreq-(int((rfreq/1000))*1000); rfreq=(rfreq-khz)/1000; // MHz ermitteln mhz=rfreq-(int((rfreq/1000))*1000); if(mfreq<1000) // Hz in String schreiben sprintf(sfreq," %3d Hz",hz); if((mfreq>=1000)&&(mfreq<1000000)) // kHz.Hz in String schreiben sprintf(sfreq," %3d.%03d Hz",khz,hz); if(mfreq>999999) // MHz.kHz.Hz in String schreiben sprintf(sfreq,"%3d.%03d.%03d Hz",mhz,khz,hz); Serial.println(sfreq); // und ausgeben}
http://shelvin.de/frequenzzaehler-mit-dem-arduino-uno-teil-2/ LCD Display Teil 1 4×20 am Arduino betreiben.Ein LCD Display mit 4 Zeilen a 20 Zeichen mit dem Arduino betreiben.Das Display wird im 4-Bit Modus parallel an den Arduino angeschlossen. Die Hardware Die Verbindungen ———————— LCD > Arduino ———————— VSS > GND VDD > +5V V0 > 10k Poti + 1kOhm Widerstand > GND RS > Pin 12 R/W > Pin 13 E > Pin 11 D4 > Pin 7 D5 > Pin 8 D6 > Pin 9 D7 > Pin 10 A > +5V K > 10 Ohm Widerstand > GND Ich verwende hier zum Testen für die Anschlüsse ein Steckbrett.
LCD Steckbrett Arduino
Eine zusätzliche Helligkeitseinstellung der Hintergrundbeleuchtung ist hier realisiert. // 4x20 LCD Display Ausgabe//// Diese Bauteile verwendet werden: // Arduino Mega 2560 (auch für andere Arduinos geeignet)// LCD Display mit 4 Zeilen mit je 20 Zeichen// Widerstände: 1k und 10 Ohm// Poti: ca. 10 kOhm//// Matthias Busse 2.4.2013 Version 1.0/* LCD Display Anschlüsse:LCD > Arduino-------------VSS > GNDVDD > +5VV0 > 10k Poti + 1kOhm Widerstand > GNDRS > Pin 12R/W > Pin 13E > Pin 11D4 > Pin 7D5 > Pin 8D6 > Pin 9D7 > Pin 10 A > +5VK > 10 Ohm Widerstand > GND */#include < LiquidCrystal.h>LiquidCrystal lcd(12, 13, 11, 7, 8, 9, 10);void setup(){ lcd.begin(20,4); lcd.clear(); lcd.setCursor(0,0); // Cursor Zeile 0 setzen lcd.print("4x20 LCD TESTAUSGABE"); // Text ausgeben lcd.setCursor(0,3); // Cusor Zeile 3 lcd.print("Matthias Busse V 1.0");}void loop(){ lcd.setCursor(3,1); // Zeile 1 Sekunden ausgeben lcd.print("Sekunden: "); lcd.setCursor(13,1); lcd.print(millis()/1000); // die Sekunden seit Programmstart delay(994); // nur fast 1000 ms warten weil das Programm auch ca. 6 ms benötigt} http://shelvin.de/ein-lcd-display-4x20-am-arduino-betreiben/ https://www.arduino.cc/en/Reference/LiquidCrystal LCD Display Teil 2 mit PWM Dimmer FunktionDie Helligkeit der Hintergrundbeleuchtung beim LCD Display kann mit Hilfe der PWM – Puls Weiten Modulation – Funktion eingestellt werden.Die Stromaufnahme meines Displays beträgt ca. 19mA gemessen.
Der Arduino Mega ist für maximal 40mA Ausgangsstrom an den Pins ausgelegt.
Das heisst wir sind weit im grünen Bereich und können die PWM Funktion des Arduino direkt für das Dimmen der LCD Hintergrundbeleuchtung verwenden.
Basierend auf der LCD 4×20 Schaltung wird eine Helligkeitseinstellung hinzugefügt. Die Hardware Der K Anschluss (Kathode / Minus) der Displaybeleuchtung wird über einen 10 Ohm Widerstand an den Arduino PWM Pin 6 gelegt ansonsten ist die Verkabelung genau wir bei der LCD 4×20 Schaltung. Achtung: Die Logik ist jetzt umgekehrt, das heißt immer wenn der Pin 6 aus ist (0V) ist die LED Beleuchtung an.
PWM 0 bedeutet also volle Helligkeit und bei einem PWM Wert von 255 ist die Beleuchtung aus.
Die halbe Helligkeit wird bei einem Wert von ca. 200 erreicht.
Die Software Hier der Arduino Programmcode mit Kommentaren: // 4x20 LCD Display Ausgabe mit PWM Dimmer//// Diese Bauteile verwendet werden: // Arduino Mega 2560 (auch für andere Arduinos geeignet)// LCD Display mit 4 Zeilen mit je 20 Zeichen// Widerstände: 1k und 10 Ohm// Poti: ca. 10 kOhm//// Matthias Busse 22.4.2013 Version 1.1/* LCD Display Anschlüsse:LCD > Arduino-------------VSS > GNDVDD > +5VV0 > 10k Poti + 1kOhm Widerstand > GNDRS > Pin 12R/W > Pin 13E > Pin 11D4 > Pin 7D5 > Pin 8D6 > Pin 9D7 > Pin 10 A > +5VK > 10 Ohm Widerstand > PIN 6 */#include < LiquidCrystal.h>LiquidCrystal lcd(12, 13, 11, 7, 8, 9, 10);int belpin=6; // Pin für die Beleuchtungvoid setup(){ lcd.begin(20,4); lcd.clear(); lcd.setCursor(0,0); // Cursor Zeile 0 setzen lcd.print("4x20 LCD TESTAUSGABE"); // Text ausgeben lcd.setCursor(0,3); // Cusor Zeile 3 lcd.print("Matthias Busse V 1.0"); pinMode(belpin, OUTPUT); // PWM Pin ist ein Ausgang}void loop(){ analogWrite(belpin, 200); // Beleuchtung 0(hell) - 255(dunkel) lcd.setCursor(3,1); // Zeile 1 Sekunden ausgeben lcd.print("Sekunden: "); lcd.setCursor(13,1); lcd.print(millis()/1000); // die Sekunden seit Programmstart delay(994); // nur fast 1000 ms warten weil das Programm auch ca. 6 ms benötigt}
http://shelvin.de/lcd-display-mit-pwm-dimmer-funktion/
Den Frequenzzähler mit LCD Display auf der Platine aufgebaut.
Ist es möglich ein Schaltbild zu bekommen? Dann könnte man besser erkennen, wie die beiden 15nF Kondensatoren und der 100 Ohm Widerstand eingebaut wurden. Ich habe das Bild für die Standard Quarz Beschaltung eingefügt. Der 100 Ohm Widerstand ist für die LCD Beleuchtung und wird von LCD- (Kathode der LED Beleuchtung) zu Masse geschaltet. Da war ein Fehler in der Beschreibung. Die Quarz Kondensatoren sind nicht 15nF sondern 15pF. Das ist jetzt geändert. Schöner Artikel. Inzwischen gibt es ja arduinoartige Boards mit ESP8266 die mit 80 MHz getaktet werden. Das müßte doch wesentlich höhere Grenzfrequenzen ergeben. Schon probieert? Damit sollte es dann bis 30 MHz funktionieren. Theoretisch liegt die maximal meßbare Frequenz bei der halben Taktfrequenz wenn das Meßsignal symetrisch ist. In der Praxis ist das aber nicht sicher erreichbar, 1/3 ist da realistisch. Ich habe den Frequenzzähler auf einer 4 x 6 cm großen Platine aufgebaut.
Mit einer Sockelleiste wird das 1602 LCD Display drauf gesteckt.
Die Stromversorgung wird an den Klemmen mit 5V herausgeführt. Hier kommt auch das Frequenz-Signal rein.
Basierend auf diesen vorherigen Artikeln wird nun alles zusammengeführt. – Frequenzzähler Teil 1 & Teil 2 – LCD Display Teil 1 & Teil 2 – Arduino Uno als ISP – Ein Frequenzzähler für niedrige Frequenzen … Die Materialiste. 1 x Lochrasterplatine ca. 4 x 6 cm 1 x 26-poliger IC Sockel 1 x 16 polige Sockelleiste die Aufnahme des LCD Displays 1 x LCD Display 1602 mit 4-Bit Ansteuerung 1 x 16-polige Stiftleiste für das LCD Display 1 x 16MHz Quarz 2 x 15pF Kondensatoren SMD 1 x 100 Ohm Widerstand 1 x 1k Ohm Widerstand 1 x 5k Ohm Drehwiderstand 1 x 10uF Tantal Kondensator 1 x 4-polige Schraubklemme 1 Rolle Fädeldraht lötbar (ich verwende 0,28mm Material lackiert) Alles zusammen für ca. 10-15 Euro Materialwert. Nun zur Aufbaubeschreibung. 1. Als erstes werden in die Ecklöcher der Lochraster Platine 3mm Schrauben eingesetzt mit Muttern.
Sie schauen unter raus und sind die Standfüße.
Damit liegt die Platine nicht wackelig auf dem Tisch und es kann kein Kurzschluß durch herumliegende Metallteile (Drähte) entstehen.
2. Das LCD Display bekommt eine 16-polige Stiftleiste 3. Die 16-polige Sockelleiste wird an den Rand der Platine gesetzt, sodaß das LCD Display später direkt über der Platine liegt. 4. Der 28-polige Sockel für den ATMEGA328P-PU wird aufgelötet. 5. Der 16MHz Quarz wird an die IC-Pins 9 und 10 gelötet. Zwei Kondensatoren mit 15pF werden von den Pins an Masse gelegt. 6. Zur Stabilisierung der Spannungsversorgung wird ein 10nF Tantal ELKO an die Pins 7 (+) und 8 (-) gelötet. 7. Der Kontrast-Regelwiderstand wird aus einem 1kOhm Widerstand und einem 4,7kOhm Trimm-Widerstand aufgebaut.
Eine kleine senkrechte Bauform ist später leichter von der Seite einzustellen, ich hatte aber nur einen liegenden Widerstand in der Kiste.
8. Es kann noch ein 6-poliger Programmier-Stecker aufgelötet werden.
Ich habe mich später aber entschieden den ATMEGA328 auf dem Steckbrett zu programmieren.
Daher ist er vorhanden, wird hier aber nicht verwendet.
9. Die 4-polige Schraubklemme wird an den Rand gesetzt. Die Belegung von links nach recht: – 1 frei, hier kann eine 9 oder 12v Stromversorgung angeschlossen werden.
Dazu ist aber noch ein 5V Regler auf dem Board notwendig. Platz ist noch vorhanden.
– 2 Versorgungsspannung + 5V – 3 Masse Versorgungsspannung und Signal – 4 Signaleingang zum Vorverstärker 10. Daneben sitzt der Eingangsverstärker Transistor. Die Widerstände und der Eingangskondensator sind unter der Platine in SMD Bauform verlötet.
Aufbau wie hier, nur habe ich einen 2,2uF Kondensator im Eingang verwendet. Der Ausgang geht auf PIN 11.
11. Der Kathoden Anschluß der LCD Beleuchtung (LCD -) bekommt noch einen 100 Ohm Widerstand gegen Masse. 12. Nun werden alle Anschlüsse nacheinander mit Fädeldraht verbunden und verlötet. Hierfür habe ich gut 1m verbraucht.
Erst die Display Verbindungen und dann die Stromversorgung
Hier die Display Verbindungen. Von der LCD Sockelleiste geht es direkt zum entsprechenden 328 IC Pin.
Die Arduino Uno Bezeichnungen sind hier auch noch erwähnt weil das für die Entwicklung auf den Steckbrett wichtig war.
LCD > Arduino > 328 IC 28DIL Gehäuse ————- VSS > GND > P8 VDD > +5V > P7 V0 > 5k Poti + 1kOhm Widerstand > GND RS > Pin 12 > P18 R/W > Pin 13 > P19 E > Pin 11 > P17 D4 > Pin 7 > P13 D5 > Pin 8 > P14 D6 > Pin 9 > P15 D7 > Pin 10 > P16 A > +5V K > 100 Ohm Widerstand > GND Die Software // Arduino 328 Frequenzzähler auf Platine // von 1 Hz bis ca. 5 MHz// > 900 Hz Eingangsspannung muss an Pin 5 mit ca. 5V Pegel ankommen.// < 1000 Hz Eingangsspannung muss an Pin 5 mit ca. 5V Pegel ankommen.// V 1.2: 1602 Display hinzugefügt// V 2.0: niedrige Frequenzen hinzugefügt// V 2.41: hohe Frequenzen umgeschieben und lcdOut() hinzugefügt// V 2.42: FreqCounter Library wieder genommen// V 2.43: auf Nano 328 angepasst// V 2.44: auf Platine 328 + NPN Emitter Schutzschaltung//// Stromaufnahme incl. Display Beleuchtung 28mA// Messbereich bis ca. 5 MHz, je nach Symmetrie des Signals (max. 8 MHz) // Messsignal Amplitude min. 100mV SS// Eingangsschaltung: 2uF + BE-Strecke ( NPN 0,7V )//// Matthias Busse 16.11.2014 Version 2.44// http://interface.khm.de/index.php/lab/experiments/arduino-frequency-counter-library/#include < FreqCounter.h>#include LiquidCrystal lcd(12, 13, 11, 7, 8, 9, 10);/* LCD Display Anschlüsse:LCD > Arduino > 328 IC 28DIL Gehäuse-------------VSS > GND > P8VDD > +5V > P7V0 > 5k Poti + 1kOhm Widerstand > GNDRS > Pin 12 > P18R/W > Pin 13 > P19E > Pin 11 > P17D4 > Pin 7 > P13D5 > Pin 8 > P14D6 > Pin 9 > P15D7 > Pin 10 > P16A > +5VK > 100 Ohm Widerstand > GND Frequenz Messeingang > 2uF > BC547B NPN Emitterschaltung > P11, beim 328 28DIL Gehäuse Messbereich bis ca. 5 MHz Eingangsamplitude min. 100mV SS */unsigned long rfreq, mfreq;int mihz=0, hz=0, khz=0, mehz=0; // mHz, Hz, kHz und MHz je 3 Ziffernchar sfreq[15]; // sfreq=Stringfrequenzstatic int schnell=0; // > 1kHz = 1static int slgrenze=2000; // schnell / langsam Grenzedouble sum=0, mfrequency, rfrequency;int count=0;// langsamint k=0,pin=5;unsigned long T; // Periodendauer in usdouble fsum=0.0; // Summierendouble f=0; // Frequenz in MHz unsigned long time; // Startzeitvoid setup() { pinMode(pin, INPUT);// Serial.begin(38400); // Serielle Ausgabe lcd.begin(20,4); lcd.clear(); lcd.setCursor(0,0); lcd.print("Frequenz Zaehler"); lcd.setCursor(0,1); // Display ausgeben lcd.print(" MBS Ver. 2.44 "); // 2 Sekunden wegzählen, da die ersten beiden Messungen eh murks sind. FreqCounter::f_comp=120; // Cal Wert FreqCounter::start(1000); // 1 s Gate Time while (FreqCounter::f_ready == 0) mfreq=FreqCounter::f_freq; FreqCounter::f_comp=120; // Cal Wert FreqCounter::start(1000); // 1 s Gate Time while (FreqCounter::f_ready == 0) mfreq=FreqCounter::f_freq; schnell=0; if(mfreq > slgrenze) schnell=1;}void loop() { if(schnell==1) { FreqCounter::f_comp=120; // Cal Wert FreqCounter::start(1000); // 1 s Gate Time while (FreqCounter::f_ready == 0) mfreq=FreqCounter::f_freq; lcdOut((double)mfreq); if(mfreq < (slgrenze*0.97)) { // auf langsam umschalten schnell=0; } } // if (schnell==1) else { // langsam time=micros(); do { T = pulseIn(pin, HIGH) + pulseIn(pin, LOW); if (T==0) {// Serial.println("Timeout."); } else { f=1/(double)T; // f=1/T k++; } fsum+=f*1e6; } while( micros() < (time+1e6)); // 1 Sekunde mitteln mfrequency = fsum/k*0.9925; lcdOut(mfrequency); fsum=0.0; k=0; if(mfrequency > (slgrenze*1.03)) { schnell=1; } } // else langsam */} // loopvoid lcdOut(double f) {// Frequenz formatiert ausgeben// auf dem 16x2 LCD Display //// Matthias Busse Version 1.0int nachkomma=0;unsigned long rf; rf=(unsigned long)f*1000; if((f-(int)f) > 0.005) { // Nachkommastellen rf=(unsigned long)(f*1000); nachkomma=1; mihz = rf-(int(rf/1000)*1000); rf=(rf-mihz)/1000; } rf=(unsigned long)f; hz = rf-(int(rf/1000)*1000); rf=(rf-hz)/1000; khz = rf-(int(rf/1000)*1000); rf=(rf-khz)/1000; mehz = rf-(int(rf/1000)*1000); if(f >= 1000000.0) {sprintf(sfreq," %3d %03d %03d Hz",mehz,khz,hz);} if((f > slgrenze)&& (f<1000000.0)) {sprintf(sfreq," %3d %03d Hz",khz,hz);} else if((f >= 1000.0) && (f<1000000.0)) {sprintf(sfreq," %3d %03d,%03d Hz",khz,hz,mihz);} if((f>=1.0) && (f < 1000.0)) {sprintf(sfreq," %3d,%03d Hz",hz,mihz);} if(f < 1.0) {sprintf(sfreq," 0,%03d Hz",hz,mihz);} lcd.setCursor(1,1); // Display ausgeben lcd.print(" "); lcd.setCursor(1,1); lcd.print(sfreq); } Die IC Programmierung. Nach der Programmentwicklung auf dem Steckbrett wurde der ATMEA238P-PU Chip vom Uno aus programmiert wie in diesem Artikel beschrieben und dann auf die Platine gesteckt. Der erste Test Alle Verbindungen werden überprüft und durchgeklingelt. Nachbar Lötpads werden auf Isolation überprüft. Dann kann es los gehen. 5V werden angeschlossen. Die Schaltung läuft und die Stromaufnahme ist ca. 28mA, alles OK. Mit einem Frequenzgenerator werden die Grenzen ermittelt. Die Eingangsspannung sollte mindestens 100mV Spitze-Spitze betragen, dann werden Frequenzen bis zu ca. 5MHz gemessen, abhängig von der Symmetrie.
Theoretisch sind sogar 8MHz (halbe Taktfrequenz ) möglich.
Ein Nachtrag:
Der Frequenz Messfehler liegt bei ca. 60ppm also in der 4. oder 5. Stelle der angezeigten Frequenz bei den verwendeten Standard Bauteilen.
Für eine genauere Messung der Frequenz kann dieses Uhrzeit Modul mit eingebunden werden.
Dadurch kann der Fehler der Messung kleiner 3ppm werden und liegt damit an der 5. oder 6. Stelle der Frequenz.
Quelle.
http://shelvin.de/den-frequenzzaehler-mit-lcd-auf-platine-aufgebaut/
http://shelvin.de/frequenzzaehler-mit-display/
ATMEGA328P-PU Bootloader laden vom Arduino Uno als ISPDer Arduino Bootloader soll in einen neuen ATMEGA 328P-PU IC auf dem Steckbrett geladen werden.Dazu wird der Arduino Uno als ISP (In-System-Programmer) verwendet. Dazu sind 4 Schritte notwendig. 1. Den UNO zum ISP Programmer umfunktionieren Als erstes wird der UNO mit der Programmer Software geladen. Dazu darf das Steckbrett noch nicht angeschlossen sein. In der Arduino IDE unter Datei > Beispiele > ArduinoISP wird das ISP Programm geladen. Die Einstellungen sind Tools > Board > Arduino UNO und die richtige COMx Schnittstelle. Dann einfach hoch laden. 2. Das Steckbrett vorbereiten Als nächstes wird das Steckbrett mit dem ATMEGA328P-PU angeschlossen. ( Sollte direkt hinter der 328 das P fehlen, wird das so nicht funktionieren, dann hilft Google weiter.)
Dann wird der 16MHz Quarz auf das Steckbrett gesetzt zwischen Pin9 und Pin10.
Die beiden Kondensatoren mit 22nF fallen hier weg, sie wurden nicht benötigt.
Es werden 6 Leitungen vom Uno zum Steckbrett gezogen. Zusätzlich kann noch die LED13 mit Vorwiderstand auf das Steckbrett gesetzt werden mit dieser Verkabelung. IC Pin 19 > Widerstand 330-1000 Ohm > Diode (langes Bein) / Diode (kurzes Bein) > GND Damit kann später die Funktion prima überprüft werden. Arduino Uno als ISP 3. Den Bootloader auf das Steckbrett laden Dann wird das Board ausgewählt Tools > Board > Arduino Uno , der richtige Serielle Port eingestellt, unter Tools > Programmer > Arduino as ISP und mit Tools > Bootloader installieren der Bootloader auf das Steckbrett IC übertragen. 4. Das Programm auf das Steckbrett laden Unter Tools > Programmer > ist Arduino as ISP weiterhin eingetragen.
Dann öffne ich das Blink Beispiel unter Datei > Beispiele > Basics > Blink und lade es hoch mit Datei > Upload mit Programmer.
Das ist ein wichtiger Unterschied zu der normalen Programmierung.
Wenn Sie das einmal vergessen und wie gewohnt den Upload Button aufrufen, geht es nochmal bei Schritt 1 los, denn dann ist das Programm im UNO gelandet.
Jetzt wird die Verbindung UNO 13 getrennt, denn hier werden beide LEDs UNO und Steckbrett parallel geschaltet.
Nun blinkt nur noch die LED auf dem Steckbrett. Damit ist das Programm Blink auf dem Steckbrett angekommen und wird richtig ausgeführt.
Jetzt wird nur noch die 5V Spannungsversorgung und GND für das Steckbrett benötigt, die anderen Leitungen können entfernt werden.
Minimalschaltung Das bleibt als Minimal-Schaltung mit dem ATMEGA328P-PU übrig. Quelle: http://shelvin.de/atmega328p-pu-bootloader-laden-vom-arduino-uno-als-isp/ Frequenzen messen zu können ist immer mal hilfreich (Drehzahl von Motoren, PWM, Schwingkreise, usw.), wofür man jedoch einen dedizierten Frequenzzähler benötigt. Dennoch ist das Prinzip dahinter nicht kompliziert, somit ist eine Messung mit einem normalen Mikrocontroller auch ohne zusätzlichen Schaltungsaufwand möglich, in der einfachsten Version leider nur im Bereich von wenigen 100 kHz.
Allgemeine GrundlagenDoch wie misst man eigentlich eine Frequenz?
Definitionsgemäß ist eine Frequenz in der Elekrotechnik die Anzahl von Schwingungen eines Jetzt gibt es zwei Möglichkeiten diese Anzahl zu messen, entweder man macht es wie die Defintion besagt und zählt die Anzahl der Impulse pro Zeit, oder die Periodenlänge, also den zeitlichen Abstand zwischen zwei Impulsen.
Was ist nun besser? Nun, wenn man die Takte einfach nur zählt, hat man den Vorteil, dass das ziemlich einfach zu lösen ist, meist wird über einen Interrupt-Pin eine Countervariable hochgezählt und sekündlich deren Wert ausgegeben. Außerdem kann man mit dieser Methode relativ genau hohe Frequenzen messen, allgemein wird dieses Prinzip Frequenzzählung genannt. Um diesen Nachteil der Ungenauigkeit bei niedrigen Schwingungszahlen zu umgehen, wird häufig die Frequenzmessung angewendet. Hierbei wird die Zeit zwischen zwei Takten gemessen und über den Kehrbruch die Frequenz ausgerechnet. Da die meisten Mikroprozessoren einen Timer im µ-Sekundenbereich laufen haben, ist es möglich, 25 Hz mit bis zu 3 Nachkommastellen (also 25.012 Hz) anzugeben, allgemein lohnt sich die Messung aber erst ab Frequenzen mit weniger als ca. 300 Hz.
Als Endergebnis kann man festhalten, dass beide Methoden ihre Defizite haben, kombiniert man diese jedoch, hat man die Vorteile beider!
Kombination beider MethodenWenn man nun den Vorteil der Frequenzmessung bei niedrigen Frequenzen, sowie den Vorteil der Frequenzzählung bei hohen Frequenzen vereint, hat man ein sehr gutes Mittelmaß an Präzision und Bandbreite (also der Abstand zwischen minimal und maximal messbarer Frequenz) erreicht. Doch wie wird das praktisch umgesetzt? Da es zwei verschiedene Messmethoden sind, kann man diese nicht wirklich “kombinieren”, wohl aber selektiv ausführen. Das bedeutet für eine Messung, dass zunächst eine Frequenzzählung gestartet wird. Sollte die gemessene Frequenz unter einem bestimmten Schwellenwert liegen, bei dem eine Frequenzmessung genauer wäre als eine Zählung (beispielsweise so um die 300Hz), wird noch mal die Frequenz gemessen, jetzt allerdings über die Messung statt Zählung. Somit hat man eine automatische Fallunterscheidung, ein Ablaufschema könnte folgendermaßen aussehen:
Frequenzzählung –> wenn Zähler größer/gleich 300 –> return Ergebnis (Zähler) [Bsp: 491 Hz]
Beispiel an einem ArduinoDamit ein Pin des AVR-Chips als High-Pegel registriert wird, muss eine Spannung von mehr als 0,7*VCC anliegen, bei einem Arduino mit 5V-Logik also entsprechend 3,5 V, bei einem Arduino mit 3,3 V dann ~2,3 V. Unterhalb dieser Schwelle wird logischerweise kein Impuls feststellbar sein. Die Pins selbst sind mit Schutzdioden versehen, fügt man vor diesen noch einen 100k-Widerstand (und am Besten noch eine Diode gegen VCC), kann man auch höhere Spannung als 3,3/5V messen.
In dieser Zeile wird ein Interrupt auf den Pin 2 festgelegt, dessen Methode ausgeführt wird,
attachInterrupt(0, Messung, RISING);
Hier ist die Methode des Interrupts. Sobald eine Frequenz am Pin vorliegt, wird bei jedem Takt eine Zählervariable hochgezählt (Frequenzzählung), sowie der Zeitpunkt der Messung in µS gespeichert und vom alten Zeitpunkt abgezogen, was dann der Periodendauer entspricht.
Wie man sieht, werden beide Messvarianten gleichzeitig angewendet, wobei für das Endergebnis immer nur eine Methode benutzt wird.
void Messung()
{
zaehler++;
timer = micros() - timerOld;
timerOld = micros();
}
Im Hauptteil wird einmal pro Sekunde die ermittelte Frequenz über den seriellen Port ausgegeben. Der Grund warum ich kein “delay(1000)” eingefügt habe, sondern die Verzögerung über einen Timer realisiere, ist ganz einfach der, dass im loop-Teil zwischen den Messwert-Ausgaben weiterer Code ausgeführt werden kann, während delay den ganzen Programmfluss für eine bestimmte Zeit anhält.
In der Praxis funktioniert das folgendermaßen: Um Übertragungsfehler am seriellen Port zu vermeiden, wird während der Übertragung der Interrupt deaktiviert (Zeile 7) und nach Beendigung wieder aktiviert. (Zeile 24)
void loop()
{
if ((micros() - startzeit) >= messzeit)
{
float f = timer; //Datentyp 'float', wegen untenstehender Division
f = 1000000/f; //Aus Periodendauer Frequenz berechnen
detachInterrupt(0);
if(f >= 300){
Serial.print("Zaehler: ");
Serial.println(zaehler);
}
else if(f < 300 && f >= 30){
Serial.print("Messung: ");
Serial.println(f, 1);
}
else if(f < 30 && f >= 3){
Serial.print("Messung: ");
Serial.println(f, 3);
}
else if(f < 3){
Serial.print("Messung: ");
Serial.println(f, 5);
}
attachInterrupt(0, Messung, RISING);
zaehler = 0; //Frequenzzähler zurücksetzen
startzeit = micros(); //Zeitpunkt der letzten Ausgabe speichern
}
Quelle:
http://www.breadboarding.de/frequenzmessung-arduino/
Attiny13 Frequenzmesser und Drehzahlmesser
Opto Reflexkoppler CNY70
Quelle:
http://www.elektronik-labor.de/Elo/Drehzahl.html
Ein ganz einfacher Stückzähler mit Arduino mit DF-Robot LCD:
Die LiquidCrystal-Library bedient alle LCD-Displays, die auf dem HD44780 basieren.
Der LiquidCrystal-Konstruktor definiert die Pins, an denen das LCD angeschlossen ist. Und mit dem begin(Spalten, Zeilen) erklärt man der Library die Geometrie des LCD. Unterstützt wird alles von 8 bis 80 Zeichen, also 8x1 bis 20x4 bzw. 40x2
Quelle:
https://forum.zerspanungsbude.net/viewtopic.php?t=2769
Beispiel-Software für reziproke Frequenzzähler etc. Diverse Programmbeispiele mit reziprokem Meßverfahren 1. aktuelles Programmbeispiel für ATmega88 0,005Hz - 200 MHz 2. reziproker Frequenzzähler GPS-stabilisiert ATmega162 3. Drehzahlmessung 4. 4-Kanal Drehzahlmessung 5. altes Programmbeispiel für AT90S2313 6. Start-Stopp, Geschwindigkeit, Pulsweite 7. Frequenz-Periode-Drehzahl angepaßt für Arduino UNO R3 8. Frequenz-Spannungs-Wandler, ATmega48 9. Frequenz-Spannungs(PWM)-Wandler, ATtiny44 10. ATmega48 mit BASCOM-AVR 0,005Hz - 200 MHz 11. 5-stell. Zähler, 10mm 7-Segment multiplex, Einbaumodul, Batteriebetrieb xx. weitere Frequenzzähler mit LED-Anzeige ff. zurück zur Übersicht 3. Drehzahlmessung, ATmega328P erstellt mit AVR-Studio 4.18:Anbei eine Schaltung und ein Programm für einen einfachen Drehzahlmesser sowie die .hex-Datei.
Die Schaltung ist einfach: sie besteht aus einem ATmega328P, einer LCD-Anzeige 2x16 und wenigen passiven Bauteilen. Gemessen wird im Grunde die Eingangsfrequenz; angezeigt werden Drehzahl ("D") und Zeit_pro_Umdrehung ("T") als 6-stellige Werte (gerundet). Die Berechnungen werden mit den 'float'-Routinen des AVR-GCC durchgeführt; das Programm benötigt ca. 5,4KB Programmspeicher. Gemessen wird lückenlos - jede Sekunde ein neuer Wert bei 60 rpm - und angezeigt werden drei Ergebnisse/s; eine LED signalisiert eine fertige Messung.
Zur Schaltung:
2013-08-12: Möchte man den Abgleich mit einem anderen Referenzsignal durchführen, kann man dazu den Korrekturwert selbst errechnen und direkt im EEPROM an Adr. 2-3 (low-high) als 'int16_t' ablegen.
/*
Beispielprogramm 'einfacher Drehzahlmesser' fuer ATmega88 entwickelt mit AVR-Studio 4.18 Funktionsbereich etwa 0,3 rpm - 15 Mrpm bei 20MHz Prozessortakt entsprechend 0,005Hz - 250kHz Eingangsfrequenz Schaltung dazu siehe: FMETER48 in abgespeckter Form http://www.mino-elektronik.de Alle Angaben ohne Gewaehr ! 2011-09-07 2013-08-11: automatischer Abgleich mit 1Hz Referenzsignal oder manueller Abgleich durch ext. Programmierung des EEPROM an Adresse EE_ADR_OFFSET. */ #include <avr/io.h> #include <avr/interrupt.h> #include <avr/sleep.h> #include <avr/wdt.h> #include <avr/eeprom.h> #include <util/delay.h> #include <stdlib.h> #define BIT(x) (1<<x) #define F_CLOCK 20000000 // 20MHz ggf. an eff.Frequenz anpassen #define EE_ADR_OFFSET 2 // Platz f�r Korrekturwert #define KAL_TASTE 2 // PORTC-2 #define STELLEN 6 // angezeigte Stellen #define MESSZEIT 100 // max. 3 Messungen/Sek. (100 x 3,3ms) #define LED_EIN 30 // 0,1 Sek. (30 x 3,3ms) #define LED_BIT 5 // PORTD.5 #define LCD_CMD 1 // wenn ein Befehl ausgegeben wird #define LCD_STROBE 2 // Schreibimpuls E fuers LCD #define ZEILE1 0x7f // jeweils 1 addieren fuer 1. Spalte #define ZEILE2 0xbf // dto. enum status {MESSEN=0, AUSLESEN, AUSWERTEN}; // die Phasen der Messung char text1[]={"D:"}; // 1.Zeile der Anzeige char text2[]={"T:"}; // 2.Zeile der Anzeige char f_dim[][5]={"Mrpm","krpm","rpm ","mrpm","sek ","ms ","us "}; // Dimensionen zum Messwert float frequenz; // float-Ergebnis float f_clock; // korrigierter Referenzwert // 'volatile' zur Sicherheit volatile unsigned char messwert_vorhanden, // nur gueltige Messungen anzeigen mess_status, // Ablaufsteuerung led_cnt, // LED kurz aufleuchten lassen sync_flag; // wird mit T1OV gesetzt volatile unsigned int zeit_low, // Timer1-Anteil zeit_high, // T1 Ueberlauf-Anteil mess_dauer, // minimale Wartezeit ueberlauf; volatile unsigned long start_ereignis, // Impulse zu Beginn der Messung end_ereignis, // Impulse am Ende der Messung start_zeit, // rel. Zeit: Beginn der Messung end_zeit, // Zeitpunkt der Auswertung mess_zeit, // genaue Zeit der Messung mess_ereignisse; // Impulse der Messung // Routinen zur Ausgabe auf LCD 2x16 void warten(void) // Warteschleife fuer LCD-Init { volatile char n = 50; while(n--) _delay_ms(1); } void lcd_impuls(void) // Schreibimpuls mit Mindestlaenge { PORTC |= LCD_STROBE; _delay_us(2); PORTC &= ~LCD_STROBE; } void lcd_nibble(char c) // 4-bit-Wert ausgeben { char temp; temp = PORTB & 0xc3; // Datenleitungen an PortB.2 -> PortB.5 temp |= ((c>>2) & 0x3c); PORTB = temp; lcd_impuls(); } void lcd_out(char z,char mode) // Ausgabe von Daten (mode==1) oder CMDs (mode==0) { if(mode) PORTC |= LCD_CMD; else PORTC &= ~LCD_CMD; lcd_nibble(z); z <<= 4; lcd_nibble(z); _delay_ms(1); // wir haben Zeit } void lcd_cmd(char z) // einen LCD-Befehl ausgeben { lcd_out(z,0); } void lcd_zeichen(char z) // ein Zeichen ausgeben { lcd_out(z,1); } void lcd_f_string(char *s) // Zeichenkette auf LCD { signed char temp; while((temp=*s++) != 0) { lcd_zeichen(temp); } } void lcd_init_nibble(char c) // 4-bit-Wert ausgeben LCD_INIT { lcd_nibble(c); _delay_ms(10); // genug Zeit lassen } void init_lcd(void) // LCD initialisieren { warten(); lcd_init_nibble(0x30); lcd_init_nibble(0x30); lcd_init_nibble(0x30); lcd_init_nibble(0x20); lcd_cmd(0x28); // im 4-bit mode lcd_cmd(0xc); lcd_cmd(1); warten(); lcd_cmd(ZEILE1+1); // 1.Zeile, 1.Spalte lcd_f_string(text1); lcd_cmd(ZEILE2+1); // 2.Zeile, 1.Spalte lcd_f_string(text2); } // Routine zur Wandlung und Ausgabe eines Me�wertes void zeige_x(float x,char zeige_periode) // Anzeige von Frequenz oder Periode { signed char i,j,dez_punkt,dimension; dez_punkt = 0; if(x >= 0.001) { // 1mHz ist Untergrenze if(!zeige_periode) { // Frequenz x *= 60.0; // auf Drehzahl skalieren dimension=2; // und in Sekunden als Dimension } else { // Zeit fuer eine Umdrehung x = 1/x; // Kehrwert bilden dimension=4; // und in Sekunden als Dimension } while(x<1.0) {x*=1000.0;dimension++;} // in den Hz-Bereich bringen while(x>=1000.0) {x*=0.001;dimension--;} while(x >= 10.0) { x *= 0.1; dez_punkt++; } x += 5e-6; // runden if(x >= 10.0) { // Ueberlauf bei Rundung x *= 0.1; dez_punkt++; if(dez_punkt > 2) { // Ueberlauf der Dimension dimension--; dez_punkt = 0; } } } else { x = 0.0; dez_punkt=0; dimension=2; // 0.00000 rpm ausgeben } for(i=0;i<STELLEN;i++) { j = x; lcd_zeichen(j+'0'); if(i == dez_punkt) lcd_zeichen('.'); x -= j; x *= 10; } lcd_zeichen(' '); lcd_f_string(f_dim[dimension]); lcd_zeichen(' '); } // Routinen zur Erfassung der Eingangsimpulse ISR(TIMER1_OVF_vect) // wird mit ca. 305Hz aufgerufen (20MHz/65536) { ueberlauf++; // Ueberlaeufe von T1 ergeben obere 16bit der Messzeit sei(); // gleich wieder freigeben // ab hier unkritisches Timing mess_dauer++; // ungefaehre Dauer der Messung if(led_cnt) { led_cnt--; // LED Einschaltdauer abzaehlen PORTD |= 1<<LED_BIT; // LED einschalten } else { PORTD &= ~(1<<LED_BIT); // LED ausschalten } } ISR(TIMER1_CAPT_vect) // Eingangsimpulse mit genauem Zeitpunkt erfassen { static unsigned long count; // Impulse per Interrupt count++; if(mess_status == AUSLESEN) { // Ergebnisse synchron zum Eingangsimpuls auslesen+ablegen end_ereignis = count; // Anzahl der Impulse lesen zeit_low = ICR1; // capture-reg lesen: untere 16bit zeit_high = ueberlauf; // dazu die oberen 16bit if((TIFR1 & 1<<TOV1) && (zeit_low < 0x8000)) // evtl. Ueberlauf T1 noch offen? zeit_high++; // nur, wenn capture-int + overflow-int gleichzeitig ! mess_status = AUSWERTEN; // Daten fertig fuer Auswertung } } uint8_t ee_read_byte(uint16_t adr) { while(EECR & BIT(EEPE)); // abwarten EEAR = adr; EECR |= BIT(EERE); // lesebit setzen return(EEDR); } void ee_write_byte(uint8_t data, uint16_t adr) { if(data != ee_read_byte(adr)) { cli(); EEAR = adr; EEDR = data; EECR = BIT(EEMPE); // master schreibbit setzen, EEPMx l�schen EECR |= BIT(EEPE); // schreibbit setzen sei(); } } void ee_write_word(int16_t data, uint16_t adr) { ee_write_byte((uint16_t)(data)%256, adr); ee_write_byte((uint16_t)(data)/256, adr+1); } int16_t ee_read_word(uint16_t adr) { int16_t temp; temp = ee_read_byte(adr); temp += ee_read_byte(adr+1) * 256; return(temp); } /* Test auf gedr�ckte Taste an PortC.2 und externes Referenzsignal von 1Hz. Wenn beides vorliegt, wird die Referenzfrequenz 'f_clock' um den Korrekturwert 'f_offset' angepasst. 'f_offset' wird im EEPROM gespeichert und nach einem Reset erneut geladen und mit F_CLOCK verrechnet. */ void teste_kalibrierung(void) { static uint8_t temp_alt; // zur Ermittelung der aktiven Flanke uint8_t temp; int16_t f_offset; // Abweichung zu F_CLOCK temp = (PINC ^ BIT(KAL_TASTE)) & BIT(KAL_TASTE); // Zustand des Tasters lesen if((temp ^ temp_alt) & temp) { // Taste wurde gedr�ckt if(frequenz > 0.999 && frequenz < 1.001) { // Frequenzbereich eingrenzen +/- 1000ppm f_offset = mess_zeit - F_CLOCK; // Differenz ist-soll ermitteln f_clock = (float) (F_CLOCK + f_offset); // korrigierter Takt lcd_cmd(ZEILE1+5); // 1.Zeile, 5.Spalte lcd_f_string("Kal. FERTIG"); ee_write_word(f_offset, EE_ADR_OFFSET); // Korrekturwert speichern messwert_vorhanden = 0; // n�chte Messung verwerfen } } temp_alt = temp; // f�rs n�chste Mal merken } // Hauptprogramm int main(void) { CLKPR = 0x80; CLKPR = 0x0; // CKDIV auf 0; voller CPU-Takt PORTB = 0x3; // Pullup ungenutzte Pins PORTC = 0x3c; // dto. PORTD = 0x1f; // dto. DDRB = 0x3c; // fuer LC-Anzeige Datenleitungen DDRC = 0x03; // fuer LCD CMD+Strobe DDRD = 0x20; // fuer LED init_lcd(); messwert_vorhanden = 0; // 1.Ergebnis unterdruecken, weil es falsch ist ACSR |= 1<<ACIC; // analog Komparator verwenden mess_status = MESSEN; // zuerst messen TCCR1B = 0x01; // Timer1 ohne Vorteiler TIMSK1 = 1<<ICIE1 | 1<<TOIE1; // t1-overflow und cap. interrupts f_clock = (float) (F_CLOCK + ee_read_word(EE_ADR_OFFSET)); // eff. Referenzfrequenz sei(); for(;;) { TIMSK1 &= ~(1<<TOIE1); // t1-overflow interrupt sperren if(mess_status==MESSEN && mess_dauer >= MESSZEIT) { mess_status=AUSLESEN; // Auswertung starten mess_dauer = 0; // wieder Messzeit abwarten } TIMSK1 |= 1<<TOIE1; // t1-overflow interrupt freigeben if(mess_status==AUSWERTEN) { end_zeit = zeit_high*0x10000 + zeit_low; mess_zeit = end_zeit - start_zeit; // Zeit-Differenz bilden start_zeit = end_zeit; // neue startzeit merken mess_ereignisse = end_ereignis - start_ereignis; // Impuls-Differenz start_ereignis = end_ereignis;// fuers naechste Intervall mess_status = MESSEN; // wieder warten if(messwert_vorhanden) { led_cnt = LED_EIN; // LED-Zeit vorgeben frequenz = ((float)mess_ereignisse * f_clock) / mess_zeit; // Frequenz berechnen lcd_cmd(ZEILE1+5); // 1.Zeile, 5.Spalte zeige_x(frequenz,0); // Drehzahl anzeigen lcd_cmd(ZEILE2+5); // 2.Zeile, 5.Spalte zeige_x(frequenz,1); // Drehzahl anzeigen teste_kalibrierung(); // nach g�ltiger Messung ggf. neu abgleichen } else messwert_vorhanden = 1; // sperre wieder aufheben } } return(815); } Quelle: http://mino-elektronik.de/fmeter/fm_software.htm
********************************************************I*
Impressum: Fritz Prenninger, Haidestr. 11A, A-4600 Wels, Ober-Österreich, mailto:[email protected]ENDE |