http://sites.schaltungen.at/arduino-uno-r3/bandgapref-14
Der Geheimkanal Kanal 14 (ADC14 / C14) er erlaubt es die interne 1,1V Referenz zu messen.Wels, am 2014-11-08BITTE nützen Sie doch rechts OBEN das Suchfeld [ ] [ Diese Site durchsuchen]DIN A3 oder DIN A4 quer ausdrucken ********************************************************************************** DIN A4 ausdrucken
*********************************************************
Referenzspannung ArefWenn es darum geht, Spannungen zu messen, wird der Analog-/Digital-Wandler (kurz: A/D-Wandler) oder englisch Analog Digital Converter (ADC) benutzt. Er konvertiert eine elektrische Spannung in eine Digitalzahl. Prinzipiell wird dabei die Messspannung mit einer Referenzspannung verglichen. Die Zahl drückt daher das Verhältnis der Messspannung zu dieser Referenzspannung aus. Sie kann in gewohnter Weise von einem Mikrocontroller weiterverarbeitet werden.
Beschaltung Aref
Interne ReferenzspannungMittels Konfigurationsregister können beim ATmega8 verschiedene Referenzspannungen eingestellt werden. Dies umfasst die Versorgungsspannung AVcc sowie eine vom AVR bereitgestellte Spannung von 2,56V (bzw. bei den neueren AVRs 1,1V, wie z. B. beim ATtiny13, ATmega48, 88, 168, ...). In beiden Fällen wird an den AREF-Pin des Prozessors ein Kondensator von 100nF als Minimalbeschaltung nach Masse angeschlossen, um die Spannung zu puffern/glätten. Es ist jedoch zu beachten, dass die interne Referenzspannung ca. +/-10% vom Nominalwert abweichen kann, vgl. dazu das Datenblatt Abschnitt ADC Characteristics VINT (z. B. ATmega8: 2,3-2,9V, ATmega324P: 2,33-2,79V bzw. 1,0-1,2V "Values are guidelines only."). Die typische Abweichung der internen Referenzspannung vom Sollwert bei einigen AVR-Controllern wird in dieser Testschaltung exemplarisch untersucht. Externe ReferenzspannungWird eine externe Referenz verwendet, so wird diese an AREF angeschlossen. Aber aufgepasst! Wenn eine Referenz in Höhe der Versorgungsspannung benutzt werden soll, so ist es besser, dies über die interne Referenz zu tun. Außer bei anderen Spannungen als 5V bzw. 2,56V gibt es eigentlich keinen Grund, an AREF eine Spannungsquelle anzuschließen. In Standardanwendungen fährt man immer besser, wenn die interne Referenzspannung mit einem Kondensator an AREF benutzt wird. Die 10µH-Spule L1 kann man meist auch durch einen 47Ω-Widerstand ersetzen. Quelle: https://www.mikrocontroller.net/articles/AVR-Tutorial:_ADC ********************************************************* 704_d_ARDUINO-x_Arduino UNO - Tutorial Generelles - Marvin Baral (19 Seiten)_1a.pdf http://jeelabs.org/2012/05/04/measuring-vcc-via-the-bandgap/ Analog-/Digital-Wandler (kurz: A/D-Wandler) oder englisch Analog Digital Converter (ADC) Die ADC-Versorgungsspannung (AVcc) darf maximal um +/-0,3V von der Versorgung des Digitalteils (Vcc) abweichen, jedoch nicht 5,5V überschreiten. Die externe Referenzspannung Vref darf nicht kleiner als die im Datenblatt unter ADC Characteristics als VREFmin angegebene Spannung z. B. ATmega328: 1,023V und nicht größer als AVcc sein Ub = Vcc messen über die Bandlücke (bandgap) ARDUINO UNO Betriebspannung testet mit der internen 1,1V Referenz (Reference = Internal). Der ATmega328P hat einen 10-bit ADC. Diese ADCs sind ratiometrische, dh. sie beziehen sich auf die analoge Referenzspannung (in der Regel Vcc) Auf einem 5V ARDUINO, bedeutet dies dass Sie 0..5V als 0 ..1023 messen oder rund 5mV pro Schritt. Auf einem 3,3V Arduino, sind die Messwerte von 0 bis 3,3V (0 ..1023) oder ungefähr 3,3 mV pro Schritt. Es hat keinen Sinn Ub = Vcc mit einen analogen Eingang zu verbinden um diesen zu messen, das funktioniert nicht da der ausgelesene ADC-Wert immer 1023 sein wird egal ob Ub=4,5V oder 5,5V. http://www.mikrocontroller.net/articles/AVR-Tutorial:_ADC Wie können wir herausfinden, welche Spannung in Verwendung ist? Dies würde sehr nützlich sein, wenn man Batterien zum Betrieb des Boardes verwendet. Nun es gibt aber auch eine "bandgap referenz" in jedem ATmega / ATtiny, die im Wesentlichen eine 1,1V-Spannungsreferenz ist.
(min.1,0V, tatsächlich1,05, default 1,1, max.1,2V)
Wenn wir diesen Wert in Bezug auf unsere Ub = Vcc lesen, dann wird ein wenig Mathematik das Restliche tun:
Angenommen, wir lesen einen ADC-Wert von "x" aus, dieser representiert ca.1,1V, mit 5V als Vcc, würde dieser Wert (x) rund 1100 / 5000 * 1023 = 225 sein. während bei 3,3V als Vcc, würden wir einen Messwert von 1100 / 3300 * 1023 = 341 erhalten. x = 1100 / 1023 * Vcc Vcc = 1100 / x * 1023 Also alles, was wir tun müssen, ist die 1.1V Bandgap-Referenzspannung zu messen und daraus können wir ableiten, was Vcc war. Leider unterstützt dies ARDUINO analogRead () nicht, daher habe ich diesen Bandlücke (bandgap) Demo Sketch gemacht ! // Sketch: ARDUINO-IDE Geheimkanal_14_3a.ino /// @dir bandgap // Lesen der Bandgap-Referenzspannung um die aktuellen Vcc-Spannung indirekt zu messen. // Ub = Vcc = 5,001 mit Multimeter gemessen static int vccRead (byte us =250) { analogRead(6); // einrichten der beinah richtige ADC Auslese bitSet(ADMUX, 3); // fixieren dann wechseln auf Kanal 14 delayMicroseconds(us); // verzögerung wesentlich verbessert Genauigkeit bitSet(ADCSRA, ADSC); while (bit_is_set(ADCSRA, ADSC)); word x = ADC; return x ? (1071L * 1023) / x : -1; // 1000L..1100L..1200L der tatsächlichen mit Multimeter gemessenen Vcc-Spannung anpassen. } void setup(void) { Serial.begin(9600); Serial.println("\n [bandgap-referenz]"); } void loop() { analogRead(0); // nur um zu überprüfen, daß dieser AE0 keinen keinen Einfluß nimmt int pin_0_Reading = analogRead(0); Serial.print("Wert-AE0 = "); Serial.print(pin_0_Reading); delay(1000); Serial.print(" falsch = "); Serial.print(vccRead()); // erster Wert ist falsch Serial.print(" korrekt = "); Serial.print(vccRead()); Serial.println(" mV"); delay(2000); // 2 Sek. Wartezeit } https://github.com/netik/jeenode-roommon/blob/master/arduino/jeelib/examples/Ports/bandgap/bandgap.ino Beispielausgabe, für das von mir verwendete ADRUINO UNO Board mit Multimeter gemessen Ub = Vcc 5,001V und 1,071V Spannungsreferenz
[bandgap]
5002 5002 5002 5002 5002 5002 Es gibt eine Verzögerung bei der vccRead () Code, der zur Stabilisierung der Messung hilft. Hier steht, was bei vccRead(10) passiert - also 10us Verzögerung anstelle der Standard 250us: Laut Datenblatt 250 s ist übertrieben? TBG Bandgap-Referenzanlaufzeitstart - up time: VCC = 2,7 TA = 25 °C typisch = 40μs max = 70us IOW, ist die Bandlücke Genauigkeit nicht groß - wie in dem Datenblatt, das 1,0 .. 1,2V bei 25 °C, wenn Vcc 2,7V spezifiziert. Beachten Sie auch, dass die Bandgap-Referenz 70us braucht um zu starten, so kann es nicht sofort einsetzbar sein, wenn kommen aus einem Power-Down-Zustand. [bandgap] 3788 3606 3549 3538 3538 3538 3549 3561 3572 3572 3583 Bei nur 10us entstehen ganz unterschiedliche Werte wie man OBEN sehen kann Dennoch könnte dies eine hervorragende Möglichkeit sein, Unterspannungen anzuzeigen, bevor einem ATmega oder ATtiny beginnt die Puste auszugehen. http://jeelabs.org/?s=bandgap http://jeelabs.org/2012/05/12/improved-vcc-measurement/ http://jeelabs.org/2012/05/04/measuring-vcc-via-the-bandgap/ *************** Arduino Bandgap Reference "14" ist die korrekte ADMUX Wert, um die interne Bandgap-Spannung, aber die Arduino analogRead() Funktion ermöglicht keinen Zugriff mehr auf diesen Kanal-14 // Get the Vin see pin(14) on datasheet ACHTUNG funktioniert nicht // interner Bandgap-Referenz // ARDUINO_IDE_Geheimkanal_14_geht_nicht_1a.ino int reference; // Stores Refrence val float BGV, Vin; void setup() { Serial.begin(9600); } void loop(){ // ACHTUNG analogRead(14); ist gleich analogRead(0); // der Geheimkanal 14 kann mit analogRead(14); NICHT gelesen werden reference = analogRead(14); // 1.1Volts mit Multimeter 1,071 //reference = analogRead(0); // Analog-Eingang 0 = pin-A0 Vin = (1.071/reference)*1023; // Convert to Vin BGV = (Vin/1023)*reference; Serial.print(" reference = "); Serial.print(reference); Serial.print(" Vin = "); Serial.print(Vin); Serial.print(" BGV = "); Serial.println(BGV); delay(2500); // 2,5sec Wartezeit } *************** Einführung Beim Arduino ATmega168 und ATmega328 kann man die Betriebsspannung Ub in mV über die interne 1,1V Ref.-Spannung messen. Denken Sie daran, dass die ständige ... Ergebnis = 1091000L / Ergebnis; AVcc in mV wird daraus zuruckberechnet. Ref-intern von Prozessor zu Prozessor unterschiedlich mit Multimeter bestimmen (1,0V = 1126400L 1,092V = 1092000L 1,2V = 1200000L) Wenn mann eine genaue Vcc Wert benötigen, muss man die aktuellen Bandgap-Spannung vom Prozessor bestimmen. http://code.google.com/p/tinkerit/wiki/SecretVoltmeter Test-Sketch Geheimkanal C14 1,1V Bandgape // Die Spannung wird in Millivolt ausgegeben. Also 5V = 5000mV, 3300mV ist 3.3V.// ARDUINO_IDE_Geheimkanal_14_Bandgape_ref_1b.inolong readVcc() { long result; // 1,1V lesen Referenz gegen AVcc ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); delay(2); // 2ms warten bis Vref lesebereit ADCSRA |= _BV(ADSC); // konvertieren while (bit_is_set(ADCSRA,ADSC)); result = ADCL; result |= ADCH<<8; result = 1092000L / result; // int.-Ref 1,092V auf AVcc (in mV) hoch rechnen. return result;}void setup() { Serial.begin(9600); Serial.println("Wert-AE0 = WERT int-Ref hochgerechnet Ub");}void loop() { analogRead(0); // Analog Eingang pin-A0 einlesen int pin_0_Reading = analogRead(0); Serial.print("Wert-AE0 = "); Serial.print(pin_0_Reading); delay(1000); Serial.print(" readVcc = "); Serial.println( readVcc(), DEC ); delay(2500);} Die Spannung wird in Millivolt ausgegeben. Also 5000 ist 5V, 3300 ist 3.3V. Beachten Sie Folgendes: Dies funktioniert nur auf einem ARDUINO mit einem ATmega328 oder ATmega168. Wie es funktioniert Das ARDUINO ATmega328 und ATmega168 haben eine Präzisionsspannungsreferenz von 1,1V eingebaut. Dies wird manchmal für Präzisionsmessungen verwendet, in der Regel aber gegen Vcc = 5V gemessen wird. Der uC besitzt einen internen Schalter (Kanal-14), welcher Pins des Analog-Digital-Wandler auswählt. Das Software-Schalter hat ein paar frei gebliebenen Verbindungen. Einer dieser Signale ist, die interne Referenz von 1,1V. Wir messen, wie groß die bekannten 1,1V Referenz im Vergleich zu Vcc ist, nun können wir hochrechnen, was Vcc ist.
https://code.google.com/p/tinkerit/wiki/SecretVoltmeter siehe auch das interne Thermometer im ARDUINO UNO ATmega328P https://code.google.com/p/tinkerit/wiki/SecretThermometer Einführung Der uC des ARDUINO UNO ATmega328p hat einen eingebautem Temperatur-Sensor. Nicht aber die alten ATmega8 oder ATmega168 (aber mit ATmega168P und ATmega328P). Auch nicht der ARDUINO Mega. Test-Sketch Geheimkanal C8 interner Temperatur-sensor - funktioniert nur auf einem Arduino mit einem ATmega328 Chip. // Die Temperatur wird in hundertstel GradC ausgegeben. Also 22,0 gradC = 2200//ARDUINO_IDE_Geheimkanal_8_interner_Temp._Sensor_1a.inolong readTemp() { long result; // internen Temperatur-Sensor gegen 1,1V Referenz lesen ADMUX = _BV(REFS1) | _BV(REFS0) | _BV(MUX3); delay(2); // 2ms warten bis Vref abgesetzt ADCSRA |= _BV(ADSC); // konvertieren while (bit_is_set(ADCSRA,ADSC)); result = ADCL; result |= ADCH<<8; result = (result - 126) * 1075; // 126 = pi x Daumen - internen Temp-Sensor hoch rechnen return result;}void setup() { Serial.begin(9600); Serial.println("Wert-AE0 = WERT read int.-Temp"); Serial.println(" - - - - - - - - - - - - - - - -");}void loop() { analogRead(0); // Analog Eingang pin-A0 einlesen int pin_0_Reading = analogRead(0); Serial.print("Wert-AE0 = "); Serial.print(pin_0_Reading); delay(1000); Serial.print(" readTemp = "); Serial.println( readTemp(), DEC ); // Wert des int-Temp-Sensors in milli°C delay(2500);}Die Temperatur wird in hundertstel °C ausgegeben. 2500 = 25 °C. Wie es funktioniert Der Chip besitzt einen internen Schalter, welcher die pin's der Analog-Digital-Wandler auswählt. Das Schalter hat ein paar übrig gebliebenen Verbindungen. Einer dieser Signale ist, eine einfacher ungenauer eingebauter Temperatursensor. Wenn man die Sensorspannung gegen die interne 1,1V Referenz vergleicht kann man die ungefähre uC-Temperatur berechnen. Es erfordert ein Herumspielen mit den Registern, aber es geht auf +/- 10 °C Hinweise: Der Sensor ist nicht sehr genau - das Datenblatt sagt ± 10 °C. Aber wenn man einmal den herausgefundenen Offset mitberücksichtigt, verbessert sich die Genauigkeit erheblich. Beachten Sie Folgendes: Dies funktioniert nur auf Arduinos mit CPUs mit "8P" in der Teilenummer. Für Standard-Arduinos ATmega168 und ATmega328 funktioniert es nicht. Wenn Sie ein Arduino-Klon mit einem ATmega168P oder ATmega168PA haben, funktioniert dies auch.. Dieser Sensor ist ziemlich nutzlos, auch wenn Sie diesen mit einer bekannten Temperatur kalibrieren. Die Sensorausgänge in etwa 1 °C-Schritten. https://code.google.com/p/tinkerit/wiki/SecretThermometer *********************************************************
********************************************************* uC A/D-Wandler Referenz-Spannungen
http://arduino.cc/en/pmwiki.php?n=Reference/AnalogReference analogReference(DEFAULT); // die Referenzspannung ist die Betriebsspannung Ub (pin-Aref muß n.c. sein) #define BANDGAPREF 14Konfiguriert die Referenzspannung für den Analogeingang verwendet (also die, wie oben in den Eingangsbereich verwendet Wert). Die Optionen sind: DEFAULT: Die Standard-Analog-Referenz von 5 Volt (auf 5V Arduino-Boards) oder 3,3 Volt (auf 3,3 V Arduino-Boards) INTERNAL: eine integrierte Referenz, gleich 1,1 Volt auf den ATmega168 oder ATmega328 und 2,56 Volt auf dem ATmega8 (nicht auf dem Arduino Mega verfügbar) INTERNAL1V1 : eine integrierte 1,1 V-Referenz (nur Arduino Mega) INTERNAL2V56: eine eingebaute 2.56V Referenz (nur Arduino Mega) EXTERNAL: die an pin-Aref (0,5.. 5V) angelegte Spannung wird als Referenz verwendet. Parameter Typ: Folgende Arten von Referenzen gibt es (STANDARD, INTERNAL, oder EXTERNAL). Returns Keine. Hinweis Nach der Änderung des analogen Referenz können die ersten Lesungen aus analogRead () nicht genau. Warnung Etwas weniger als 0V oder mehr als 5V nicht für externe Referenzspannung am pin-Aref. Wenn Sie eine externe Referenz auf pin-Aref sind, müssen Sie die analogen Verweisen auf fremde vor dem Aufruf analogRead () ein. Andernfalls werden Sie kurz zusammen die aktive Referenzspannung (intern erzeugt) und das pin-Aref, möglicherweise eine Beschädigung der Mikrocontroller auf Ihrem Arduino-Board. Alternativ können Sie die externe Referenzspannung an den pin-Aref durch eine 5K Widerstand zu verbinden, so dass Sie zwischen externen und internen Referenzspannungen umschalten. Beachten Sie, dass der Widerstand die Spannung, die als die Referenz verwendet wird, weil es eine interne 32K Widerstand auf AREF Pin ändern. Die beiden wirken als Spannungsteiler, so beispielsweise 2,5 V angelegt wird durch den Widerstand 2.5 * 32 / (32 + 5) = ~ 2,2 V am pin-Aref ergeben. Siehe auch - Beschreibung der analogen Eingangspins - analogRead () Referenz Startseite Korrekturen, Anregungen und neue Dokumentation sollte in das Forum geschrieben werden. Der Text der Arduino Referenz ist unter einer Creative Commons Attribution-ShareAlike 3.0 License. Code-Beispiele in der Referenz werden in die Öffentlichkeit freigegeben. http://arduino.cc/en/Reference/AnalogReference********************************************************* BUCH: Die elektronische Welt mit ARDUINO entdecken Seite 950 Analog-Monitoring
pin-IOref
Es kann u. a. dazu genutzt werden, dass sich Shields dieser Spannung bedienen, um zu ermitteln, ob sie mit 3,3V oder 5,0V arbeiten müssen.
ACHTUNG: Mikrocontroller zerstören.
Sketch:
void setup() {
void loop() {
weitere Informationen zu den Themen
analogReference(INTERNAL); Laut ATmega328P Datenblatt Seite 323ist Vref int typisch 1,1V und zwischen 1,0V und 1,2V. Die Spannung ist nicht in jedem ATmega ganz gleich, aber konstant. Die Versorgungsspannung 5V ändern sich je nach Spannungsquelle und kann schon mal an USB auch nur 4,5V betragen. Die integrierten A/D-Wandler in Mikroprozessoren sind keine Präzions-Instrumente. Daß man bei niedrigeren Spannung mehr Einfluss der Störungen hat ist klar. Die normalen Messfehler von ADCs haben dann auch einen höheren Anteil am Ergebnis. Und auf dem Arduino Board fehlen Schaltungs-Maßnahmen um das zu kompensieren, wie der LC-Filter an der ADC-Versorgungsspannung. Es gibt in Software noch Möglichkeiten. Siehe Datenblatt "ADC Noise Canceler". Man kann den Rest des Prozessors in den Schlaf-Modus versetzten und während dessen messen. Dadurch strahlen andere Komponenten weniger in den ADC rein.Datenblat uC. 704_d_ATMEL-x_ATmega328P 8-bit Mikrocontroller mit 32K (448 Seiten) Datenblatt_1a.pdf http://www.atmel.com/Images/doc8161.pdf
********************************************************* Analog Monitoring Aref-pinAn diesen pin liegt die Referenz Spannung für die 6. analogen Inputs an. Er wird unter Verwendung der Funktion analogReference() genutzt. IOref-pin An diesem pin liegt die Referenzspannung an, mit welcher der Mikrocontroller arbeitet. Ein korrekt konfiguriertes Shield kann die Spannung des IOref nutzen um die richtige Stromquelle auszuwählen oder die Spannungsregler schalten um die Outputs mit 5V oder 3.3V zu versorgen. Vin-pin An diesem pin liegt die Input Spannung des Arduino an, wenn eine externe Stromquelle genutzt wird (anstatt der 5V einer USB Verbindung oder einer anderen regulierten Stromquelle). Sie können an diesen pin Spannung anlegen oder, wenn eine externe Stromquelle mit der Strombuchse verbunden ist, Spannung abgreifen. Der Aref-Pin wird für die Referenzspannung der analogen Eingänge verwendet. Wenn der Mikrocontroller mit einer Spannung von 5V arbeitet, liegt die Genauigkeit bei einer 10bit Auflösung bei ca. 4,88mV je Schritt. Möchten wir z.B. einen Sensor verwenden, der lediglich 3,3V als Maximalwert liefert, bedeutet das einen Genauigkeitsverlust, denn die mögliche Bandbreite von 10bit würde nicht ausgenutzt, um einen Spannungsbereich von 0V bis 3,3V abzubilden. Die analogRead() Funktion würde Werte von 0 bis 675 zurückliefern. Der Rest bis 1023 bliebe ungenutzt. Doch zurück zu unserem Aref-pin. Wenn wir diesen pin mit der real anliegenden Spannung von IOref versorgen würden, wäre diese Spannung die neue Referenzspannung für die analogen Eingänge und somit wäre das Problem der vermeintlich zu niedrigen Versorgungsspannung behoben. Schauen wir uns dazu einen entsprechenden Sketch an. Es muss vorausgeschickt werden, dass wir über die analogReference() Funktion mit dem EXTERNAL Argument dem Arduino mitteilen, nun eine externe Referenzspannung an Aref-pin anzulegen. Achtung Wenn eine externe Spannung am Aref-pin angelegt wird, darf sie sich nur im Bereich von 0V bis 5V bewegen! Des Weiteren muss vor dem Aufruf der analogRead() Funktion die analoge Referenz über die Funktion analogReference(EXTERNAL) korrekt initialisiert werden. Das verhindert, dass sich die intern generierte Spannung für den Aref-pin und die von außen angelegten Spannung am selben pin in die Quere kommen und so den Mikrocontroller zerstören. Doch nun zum Sketch:
// ARDUINO_SD_Card_Datalogger_EXTERNAL_1a#define PAUSE 1000 // Pausenwert für die Anzeigevoid setup() { Serial.begin(9600); // Serielle Schnittstelle initialisieren while (!Serial); // Auf den Serial-Monitor warten // Wir beziehen uns jetzt auf den von IOREF gelieferten Wert analogReference(EXTERNAL); /*Achtung: Der Aufruf der analogReference-Funktion muss über EXTERNAL immer vor dem ersten Aufruf der analogRead-Funktion erfolgen!!! Ansonsten kann der Mikrocontroller zerstört werden. */}void loop() { Serial.println(analogRead(A0)); // Ausgabe des gemessenen Wertes delay(PAUSE); // Kurze Pause}
Hier zu meine Frage..Ich habe in meinen Codes analogReference nicht verwendet, was für eine Spannung nimmt da der Arduino.?Und wie muss man da die Auflösung rechnen (U/1024)??sagen wir analogReference(DEFAULT);da wir ja als Referenz die Speisespannung des Arduino gesetzt. Bei mir 5V dannsensorwert = analogRead(sensor) / (5 / 1024)stimmt das so??oder sagen wir analogReference(INTERNAL);da wir die interne Spannung des Arduino UNO gesetzt. UNO 1.1Vwie sieht es dann hier aussensorwert = analogRead(sensor) / (1.1 / 1024)währe das so richtig??als letztes analogReference(EXTERNAL);da wir die Spannung des VREF Pins am Arduino UNO gesetzt. zB 3.3Vwie sieht es dann hier aussensorwert = analogRead(sensor) / (VREF / 1024) *********************************************************
AD-Wandler = Analog/Digital-Wandler = ADC
In BASCOM wird ADC initialisiert mit
Config Adc = Single (eine Messung) , Prescaller = 64 (Frequenzteiler 16MHz/64=250kHz) , Referenze = Avcc (pin-Aref wird intern auf AVcc = Vcc = Ub = 5V gelegt, ACHTUNG pin-Aref darf extern nicht beschaltet sein.)
Config Adc = Free (fortlaufende Messungen) , Prescaller = 32 (Frequenzteiler 16MHz/32=500kHz) , Referenze = Aref (die an pin-Aref angelegte externe Spannung ist die Referenz, z.B Referenz-IC) Config Adc = Free , Prescaller = 64 , Referenze = Internal (die im uC intern vorhande 1,1V Referenz-Spannung wird an pin-Aref gelegt ACHTUNG pin-Aref darf extern nicht beschaltet sein. Was bedeutet der Indikator BANDGAPREF 14
BASCOM
Referece = AVcc
Reference = Internal ' die interne 1,1V Referenzspannung wird an pin-Aref gelegt
D = Getadc(14) ' interne 1,1V Referenz an ADC Kanal14 mit Getadc(14) startet man eine Messung wird die internen Referenz-Spannung am internen Kanal C14 gemessen und weist den rohWert der Word-Variablen (auch Integer-Variable) D zu (10bit 0..1023)
IDC
#define BANDGAPREF 14
analogReference(INTERNAL);
Geheimkanal Kanal 08 (ADC8 / C8) er erlaubt es den internen Temperatur-Sensor der an dem Kanal 8 des ADC liegt zu messen.
20 °C 309mV 25°C 314mV
Temperatur-Sensor-IC Genauigkeit nur 10°C daher immer selbst kalibrieren
Problem: Ich lese den Geheimkanal 14, ich lese den Geheimkanal 8, ich lese den Kanal pin-A0 alle nacheinander aus. Das Ergebnis, überall die gleichen Werte, immer gleich mit dem am pin-A0 ausgelesenen Wertes. Das heißt rohWerte von 0 bis 1023 Hallo Herr Prenninger, ich habe etwas rumprobiert, das Problem konnte ich bestätigen. Zuerst hatte ich einen Rechenfehler in BASCOM in Verdacht. Deshalb habe ich die Einstellungen für Hwstack, Swstack usw. eingefügt. Keine Änderung. Dann fiel auf, dass auch bei der funktionierenden Variante der erste Wert noch nicht korrekt ist. Neue Theorie: Das Messen von Kanal 14 schaltet die Referenz erst ein, andere Kanäle schalten sie wieder aus. Und es wird jedesmal etwas Zeit benötigt, bis die Referenz voll da ist. Von so einer Einschwingzeit steht auch etwas im Datenblatt. Also muss man in diesem Fall den Kanal AD14 zweimal messen, einmal zum Einschalten der Referenz und dann nach einer kurzen Pause für die eigentliche Messung. Jetzt funktioniert es korrekt. Ich werde es auch auf meiner Homepage und im Elektor-Forum erwähnen. Vielen Dank für Ihre Fehlersuche! Burkhard Kainka mailto:[email protected] '----------------------------------------
Datenlogger-Prg. muß ich noch entsprechend ändern fritz
FEHLER noch enthalten.
USW USW.
https://github.com/afeld/templogger/blob/master/lighttemplogger.pde
http://www.snip2code.com/Snippet/66961/Pressure-Temperature-Logger-for-Arduino-
*********************************************************
Step 5: Auto-calibrating supply-independent thermometerI came up with an idea to use temperature sensor and leds to indicate the temperature value. I found LadyAda-s tutorial http://www.ladyada.net/learn/sensors/tmp36.html, and now i want to add leds, so that when the temperature is under 0 degrees the blue led is on, when the temp is over 0 degrees the green led is on and when it is over 20 degrees the red led is on. Actually I have no idea, how to integrate leds to the temperature code. Maybe someone here can help.. This example is similar to the one above except that now we use a special trick where we read the analog value of a fixed reference voltage inside the chip and then use that to make a precise calculation. This also means it will work right no matter what voltage the Arduino is running at! Schritt 5: Auto-Kalibrierung Versorgung unabhängige Thermometer Ich kam mit einer Idee, Temperatursensor und LEDs zu verwenden, um den Temperaturwert anzugeben. Ich fand Ladyada-s Tutorial http://www.ladyada.net/learn/sensors/tmp36.html, und jetzt möchte ich LEDs hinzufügen, so dass, wenn die Temperatur unter 0 Grad die blaue LED leuchtet, wenn die Temperatur über 0 Grad die grüne LED auf, und wenn es über 20 Grad ist die rote LED leuchtet. Eigentlich habe ich keine Ahnung, wie man LEDs auf die Temperatur-Code zu integrieren. Vielleicht kann hier jemand helfen .. Dieses Beispiel ist ähnlich zu der oben mit der Ausnahme, dass jetzt verwenden wir einen Trick, wo wir den analogen Wert aus einer festen Referenzspannung innerhalb des Chips zu lesen und dann verwenden, um eine genaue Berechnung durchzuführen. Das bedeutet auch, es wird rechts, egal welche Spannung der Arduino am Laufen ist Arbeit! //TMP36_Pin_Variables_1aint sensorPin = 0; //the analog pin the TMP36's Vout (sense) pin is connected to//the resolution is 10 mV / degree centigrade with a//500 mV offset to allow for negative temperatures#define BANDGAPREF 14 // FALSCH special indicator that we want to measure the bandgap/* setup() - this function runs once when you turn your Arduino on. We initialize the serial connection with the computer */void setup(){ Serial.begin(9600); //Start the serial connection with the computer //to view the result open the serial monitor delay(500);}void loop() // run over and over again{ // get voltage reading from the secret internal 1.05V reference int refReading = analogRead(BANDGAPREF); Serial.println(refReading); // now calculate our power supply voltage from the known 1.05 volt reading float supplyvoltage = (1.05 * 1024) / refReading; Serial.print(supplyvoltage); Serial.println("V power supply"); //getting the voltage reading from the temperature sensor int reading = analogRead(sensorPin); // converting that reading to voltage float voltage = reading * supplyvoltage / 1024; // print out the voltage Serial.print(voltage); Serial.println(" volts"); // now print out the temperature float temperatureC = (voltage - 0.5) * 100 ; //converting from 10 mv per degree wit 500 mV offset //to degrees ((volatge - 500mV) times 100) Serial.print(temperatureC); Serial.println(" degress C"); // now convert to Fahrenheight float temperatureF = (temperatureC * 9 / 5) + 32; Serial.print(temperatureF); Serial.println(" degress F"); delay(1000); //waiting a second} http://forum.arduino.cc/index.php/topic,39636.0.html http://www.instructables.com/id/Temperature-Sensor-Tutorial/step5/Auto-calibrating-supply-independent-thermometer/ http://forum.arduino.cc/index.php?topic=39636.0;wap2 *********************************************************
templogger / lighttemplogger.pde
https://github.com/afeld/templogger/blob/master/lighttemplogger.pde ********************************************************* // The_analog_pins_that_connect_to_the_sensors#define tempPinRef 0 // analog 0#define tempPin1 1 // analog 1#define tempPin2 2 // analog 2#define BANDGAPREF 14 // FALSCH special indicator that we want to measure the bandgap#define aref_voltage 3.3 // we tie 3.3V to ARef and measure it with a multimeter!#define bandgap_voltage 1.1 // this is not super guaranteed but its not -too- offfloat ReadBandGap(){ // Log the estimated 'VCC' voltage by measuring the internal 1.1v ref analogRead(BANDGAPREF); delay(10); int refReading = analogRead(BANDGAPREF); return supplyvoltage = (bandgap_voltage * 1024) / refReading;}
********************************************************* Found this post while trying to figure out how to make the Libellium microSD Shield/SDuFAT combo work on my Duemilanove as well. My problem seems to be with the log file on the SD card filling up before all the characters have been used. Will try mowcius's tip using "ETX" and hope that it works. Since SDuFAT only writes strings, I used the floatToString library from Tim Hirzel (http://www.arduino.cc/playground/Main/FloatToString) to convert my temp sensor (LM35CZ) readings into strings which were then saved on my 2GB MicroSD card w/ the Libellium shield. Here's the code: (if anyone can offer some suggestions regarding my log file problem http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1261141357/7, please let me know) Gefunden Beitrag bei dem Versuch, herauszufinden, wie man die microSD Libellium Schirm / SDuFAT Combo auf meinem Duemilanove sowie zu machen. Mein Problem scheint mit der Log-Datei auf der SD-Karte tanken vor alle Zeichen verwendet worden sein. Versuchen mowcius Tipp mit "ETX" und hoffen, dass es funktioniert. Seit SDuFAT schreibt nur Zeichenfolgen, habe ich die floatToString Bibliothek von Tim Hirzel (http://www.arduino.cc/playground/Main/FloatToString) meinem Temperatursensor (LM35CZ) Lesungen in Strings, die dann auf meine 2GB MicroSD gespeichert wurden, zu konvertieren Karte w / der Libellium Schild. Hier ist der Code: (wenn jemand einige Vorschläge in Bezug auf meine Log-Datei-Problem http://www.arduino.cc/cgi bin/yabb2/YaBB.pl?num=1261141357/7 anbieten können, lassen Sie es mich wissen)
Sketch:
// SD_Card_und_FAT_Formatierung_1a#include "SDuFAT.h" // needed to write data to SD card#include "floatToString.h" // needed to convert float values to strings used by SDuFat// define the pin that powers up the SD card#define MEM_PW 8#define BANDGAPREF 14 // FALSCH indicator that we want to measure the bandgap// help string to be sent to the serial port#define HELP "H help\nL file info\nD delete\nP append string\nW init file and write\nR dump to serial\nA append text\n"// variable used when reading from serialbyte inSerByte = 0;// initialize variables for sensorsint SensorPin01 = 0;int itNum = 1;void setup(void){ // on my MicroSD Module the power comes from a digital pin // I activate it at all times pinMode(MEM_PW, OUTPUT); digitalWrite(MEM_PW, HIGH); // configure the serial port to command the card and read data Serial.begin(19200);}void loop(void){ // get voltage reading from the internal 1.1V reference analogReference(INTERNAL); analogReference(INTERNAL); int RefReading = analogRead(BANDGAPREF); // first reading RefReading = analogRead(BANDGAPREF); // second reading RefReading = analogRead(BANDGAPREF); // third reading //Serial.println(RefReading); float SupplyCorrection = (1.05 * 1024) / RefReading; int Sensor01 = analogRead(SensorPin01); float Voltage01 = 100 * (Sensor01 * SupplyCorrection) / 1024; //Serial.println(Voltage01); // Arduino expects one of a series of one-byte commands // you can get some help by sending an 'H' over the serial port if (Serial.available() > 0) { int result = 0; char buffer[25]; SD.println("temp.txt",""); // adds line break each time serial port query is activated inSerByte = Serial.read(); switch (inSerByte) { case 'H': Serial.println(HELP); result = 3; // special output for help message break; case 'L': result = SD.ls("temp.txt"); break; case 'R': result = SD.cat("temp.txt"); break; case 'W': result = SD.write("temp.txt"); break; case 'A': result = SD.append("temp.txt"); break; case 'P': //result = SD.println("temp.txt",floatToString(buffer, testNum, 5)); result = SD.println("temp.txt",floatToString(buffer, Voltage01,5)); break; case 'D': result = SD.del("temp.txt"); break; default: result = 2; // value for unknown operation break; } // print a status message for the last issued command // for help (result == 3) won't print anything if (result == 1) SD.printEvent(ERROR, "temp.txt"); else if (result == 2) SD.printEvent(WARNING, "unknown command"); else if (result == 0) SD.printEvent(SUCCESS, "temp.txt"); } //delay(100); char buffer[25]; SD.print("temp.txt",floatToString(buffer,itNum,0)); SD.print("temp.txt"," "); SD.println("temp.txt",floatToString(buffer, Voltage01,5)); itNum = itNum++;} http://forum.arduino.cc/index.php?topic=8061.20;wap2 ********************************************************* Arduino Pins - Analog Pins and Analog Reference VoltageArduino Pins - Pins Analog-und Analog-ReferenzspannungArduino haben 6 analoge markierten Stifte als Analog 0 bis 5. Analog Stifte werden meist verwendet, um analoge Sensoren gelesen und in den Kanälen 6 Analog Digital Converter (ADC) gesendet. Der ADC wird die Spannung (0V bis 5V) auf ganze Zahlen von 0 bis 1023 (10 Bit Auflösung) zu konvertieren. Dies kann mit dem analogRead ()-Funktion ausgeführt werden. Wenn die analogen Sensoren haben einen engen Spannungsbereich, können Sie die analogReference () verwenden, um den Eingangsbereich und die Auflösung zu ändern. The analogReference() can be change from the default analog reference of 5V ( or 3.3V for some boards ) to either an INTERNAL analog reference or EXTERNAL analog reference. Internal analog reference will use the internal 1.1V when converting from voltage of integer of 0 - 1023. If the AREF (Analog Reference) pins is connected, it will USE the external reference voltage even if you issue the command analogReference(INTERNAL); External analog reference will use the external AREF pin and take the reference voltage of whatever voltage that pins is connected to. You can use this method with a voltage divider to get 2.5V for the analog reference voltage. An example is to connect two resistors of same value (example 100 ohm each) to the 5V pin and tap in the middle to get the 2.5V into the AREF pin. As normal resistor have a 5% tolerance value, it is not very accurate unless you use metal-film resistors with 1% tolerance value for better accuracy. All the 6 analog pin can be used as General Purpose Input/Output (GPIO) pins like digital pin using label of A0 to A5. Use the command, pinMode(A0, OUTPUT) to set the analog pin to OUTPUT mode. After the mode is set to OUTPUT, you can use the digitalWrite() functions for these pins. *** analogRead will not work correctly when set to OUTPUT due to the internal pull-up resistor. You need to use the pinMode to set it back to INPUT before using the analogRead() function. Die analogReference() kann Wechsel von der Standard-Analog-Referenz von 5V (oder 3,3 V für einige Bretter), um entweder eine interne analoge Referenz oder externen analogen Referenz. Interne Analogsollwert wird die interne 1,1 V zu verwenden, wenn der Umwandlung von Spannung ganze Zahl von 0 - 1023 Wenn die AREF (Analog Referenz) Stifte angeschlossen ist, wird es die externe Referenzspannung verwenden, selbst wenn Sie den Befehl analogReference (INTERN) auszugeben; Externen analogen Sollwert wird die externe AREF Pin verwenden und die Referenzspannung gleich welcher Spannung, die Stifte angeschlossen ist. Sie können diese Methode mit einem Spannungsteiler verwenden, um 2,5 V für den analogen Referenzspannung zu erhalten. Ein Beispiel ist, zwei Widerstände gleichen Wert (zB 100 Ohm pro Stück) an den 5V-Pin zu verbinden, und tippen Sie in der Mitte, um die 2,5 V in den AREF Pin zu bekommen. Widerstand als normal haben eine Toleranz von 5%-Wert, ist es nicht sehr genau, wenn Sie Metallfilm -Widerstände mit 1% Toleranzwert für eine bessere Genauigkeit zu verwenden. Alle 6 analoge Stift kann als General Purpose Input / Output (GPIO) Pins wie Digitalstift mit Etikett A0 bis A5 verwendet werden. Verwenden Sie den Befehl, pinMode (A0, OUTPUT), um das analoge Stift-Ausgabemodus eingestellt. Nach der Modus auf Ausgang gesetzt, können Sie die digital ()-Funktionen für diese Stifte zu verwenden. *** AnalogRead wird nicht korrekt funktionieren, wenn an OUTPUT aufgrund der internen Pull-up-Widerstand eingestellt. Sie müssen die pinMode, bevor Sie das analogRead ()-Funktion verwenden, um es wieder eingestellt, INPUT. http://arduino-for-beginners.blogspot.co.at/2011/01/arduino-pins-analog-pins.html ********************************************************* Arduino > ReferenzspannungArduino: Referenzspannung und Analog-Digital-Umwandler VorbemerkungDer Standard Arduino verfügt über 6 analoge Eingänge (A0 bis A5). Der ADC/ADU - Analog (to) Digital Converter - wandelt die anliegende Spannung in digitale Signale um. Diese Spannung wird mit einer Referenzspannung verglichen, die nicht mehr als 5 Volt betragen darf (Gefahr der Beschädigung), aber niedriger liegen kann. Meist wird die den Arduino versorgende Spannung (5 bzw. 3,3 Volt, modellabhängig) als Referenz herangezogen. Diese einfache Lösung ist in vielen Fällen ausreichend, hat aber auch Nachteile. Wird der Arduino z.B. per Batterie versorgt und die Versorgungsspannung sinkt, verändert sich auch unsere Referenz. Auch Servos und/oder Relais können zu kurzfristigen Schwankungen führen. Eine andere Möglichkeit ist die Verwendung der internen Referenzspannung, die meist 1,1 Volt (Uno etc.), beim Mega jedoch 2,56 Volt beträgt. Alternativ können wir dem ADC eine eigene externe Referenzspannung zur Verfügung führen (Pin AREF), die natürlich niemals 5 Volt übersteigen sollte. Der beim Arduino verwendete ADC hat 10 Bit, d.h. eine Auflösung von 1024 Stufen (0 bis 1023). Der Wert 0 entspricht einer Spannung von 0 Volt, der Wert 1023 der Referenzspannung. Einige Informationen findet ihr auch in der Arduino Reference. Wenn wir 5 Volt = 5000 mV - genauer 4,995 Volt (vernachlässige ich jetzt mal) - durch 1024 teilen, erhalten wir einen Wert von 4,88 mV je Schritt. Bei einer Referenzspannung von 3,3 Volt hingegen 3,22, bei 2,56 Volt sogar nur 2,5 mV. Es kann also sinnvoll sein, mit einer niedrigeren Referenzspannung zu arbeiten, wenn eine genauere Auflösung notwendig sein sollte.. Allerdings müssen natürlich ggf. die Sensoren mitspielen, weshalb die interne Referenzspannung von 1,1 Volt auch selten genutzt wird.
Externe Refererenz mit Zener-DiodeNatürlich muß bei einer Verwendung der externen Referenzspannung (AREF) diese stabil sein. Hierfür verwenden wir entweder eine Zener-Diode oder einen Spannungsregler z.B. aus der 78xx-Serie. Zur Zener-Diode: Sieht dann ungefähr so aus ....
Den notwendigen Widerstandswert könnt ihr auf reuk.co.uk berechnen lassen. Eh' eine empfehlenswerte Seite! Externe Refererenz mit Zener-Diode (abschaltbar)Der gewünschte Spannungsabfall an der Zener-Diode verkürzt natürlich die Laufzeit beim Betrieb an Batterien. In vielen Fällen können wir diese Problematik in den Griff bekommen, indem wir die AREF bei Bedarf einfach ausschalten. Ein gutes Beispiel dafür ist eine Wetterstation, die z.B. die gewünschten Daten nur alle 15 Minuten oder sogar stündlich erfassen soll. Hierzu benutzen wir einfach einen freien digitalen Pin und schalten diesen kurz vor dem Auslesen der Sensordaten ein (HIGH) und danach wieder aus (LOW):
Die Darstellungen wurden natürlich wieder einmal mit fritzing erstellt. wird fortgesetzt
Die meisten Arduino verfügen über einen 10 Bit ADC/ADU (Analog-Digital-Umsetzer). Am analogen Eingang anliegende Spannungen zwischen 0 bis 5 Volt werden in diese Spannung repräsentierende Integerwerte von 0 bis 1023 umgewandelt. Bei einer Betriebsspannung von 5 Volt haben wir also eine Auflössung von 4,88 mV (5000 / 1024), bei einer Betriebsspannung von 3,3 Volt eine Auflösung von 3,22 mV. -->
Jede Abweichung der Betriebsspannung vom Sollwert liefert uns ein "falsches" Messergebnis. Beispiel: Bei 5 Volt repräsentiert der Wert 623 eine an ein einem Analogeingang anliegende Spannung von ~ 3040 mV, bei einer Referenzspannung von 4900 mV nur ~ 3024. Immerhin eine Abweichung von mehr als 0,5 Prozent. Bei Anwendungen, in denen es um eine hohe Genauigkeit geht (Temperatur, Entfernung usw.) kann diese "Toleranz" schon eine bedeutende Rolle spielen (2,5 cm Abweichung auf einer Entfernung von 5 Metern). Bei Stromversorgung per USB ist dies kein ganz seltenes Problem, zudem die verwendeten USB-Kabel selbst ihren Teil betragen können (Impedanz). Beim Arduino Yün, der über keinen integrierten Spannungsregler verfügt, ist dieses Problem noch größer. Auf einem meiner Yŭn lagen am 5 Volt-Pin nur 4,6 Volt an. Dies bedeutet, das wir uns schon mit einer Abweichung von knappen 8 Prozent herumschlagen müssen. Gedanken über die Genauigkeit eines Sensors müssen wir uns spätestens jetzt kaum mehr machen. Was tun? Zum einen können wir eine externe Referenzspannung nutzen, andererseits aber auch auf Arduino-Bordmittel zurückgreifen: Moderne Arduino verfügen über 2 Pins, die uns bei der Lösung des Problems helfen können:
Also: Am Pin IOREF geben die aktuellen Arduino die "echte" Spannung aus. Am Pin AREF wird die Referenzspannung für die analogen Pins eingelesen. Verbinden wir jetzt diese beiden Pins und und rufen die Funktion auf, arbeiten wir ab sofort mit der realen Referenzspannung. Achtung: Ohne diesen Befehl vor dem ersten analogRead() kann die Verbindung zwischen IOREF und AREF zur Zerstörung des Boards führen! Siehe auch analogReference.
Hier der Sketch Arduino Spannungsreferenz für analoge Eingänge
Bei 5 Volt repräsentiert der Wert 623 eine an ein einem Analogeingang anliegende Spannung von ~ 3040 mV, bei einer Referenzspannung von 4900 mV nur ~ 3024. Immerhin eine Abweichung von mehr als 0,5 Prozent. Bei Anwendungen, in denen es um eine hohe Genauigkeit geht (Temperatur, Entfernung usw.) kann diese "Toleranz" schon eine bedeutende Rolle spielen (2,5 cm Abweichung auf einer Entfernung von 5 Metern). Bei Stromversorgung per USB ist dies kein ganz seltenes Problem, zudem die verwendeten USB-Kabel selbst ihren Teil betragen können (Impedanz). Beim Arduino Yün, der über keinen integrierten Spannungsregler verfügt, ist dieses Problem noch größer. Auf einem meiner Yŭn lagen am 5 Volt-Pin nur 4,6 Volt an. Dies bedeutet, das wir uns schon mit einer Abweichung von knappen 8 Prozent herumschlagen müssen. Gedanken über die Genauigkeit eines Sensors müssen wir uns spätestens jetzt kaum mehr machen. Was tun? Zum einen können wir eine externe Referenzspannung nutzen, andererseits aber auch auf Arduino-Bordmittel zurückgreifen: Moderne Arduino verfügen über 2 Pins, die uns bei der Lösung des Problems helfen können: pin-Aref liefert die Spannungsreferenz für die analogen Eingänge pin-IOref ist die Referenz für die I/O-Ports (eigentlich 5 Volt, 3,3 Volt beim Arduino Due) Am pin-IOref geben die aktuellen Arduino die "echte" Spannung aus. Am pin-Aref wird die Referenzspannung für die analogen Pins eingelesen. Verbinden wir jetzt diese beiden Pins und und rufen die Funktion auf, arbeiten wir ab sofort mit der realen Referenzspannung. Achtung: Ohne diesen Befehl vor dem ersten analogRead() kann die Verbindung zwischen IOREF und AREF zur Zerstörung des Boards führen! Siehe auch analogReference. Hier der Code: Hinweis:Sollte ihr euren Arduino mit 5 Volt betreiben, die Sensoren aber mit 3,3 Volt versorgt haben, könnt ihr natürlich auf die 3,3 Volt als analoge Referenzspannung zurückgreifen. In diesen Fällen liegt der Sollwert (3,3 Volt) in der Regel sehr nah am Effektiv-Wert, so daß keine weiteren Maßnahmen notwendig sind. Einfach mal durchmessen. Einen interessanten Beitrag zu diesem Thema findet ihr hier (englischsprachig). Habt Spaß! P.S.: Dank an Erik, der mich zum Schreiben dieses Artikels angeregt hat (auch wenn ihm dieses vielleicht nicht bewußt sein mag ...). DIN A4 ausdrucken ********************************************************* Impressum: Fritz Prenninger, Haidestr. 11A, A-4600 Wels, Ober-Österreich, mailto:[email protected] ENDE |