 ATtiny85 verfügt über einen internen Temperatursensor Ich bin auf einem meiner Projekte arbeiten aus RTFMs Video-Blog (check out http://rtfms.com ), die Temperatur erfordert Sensing in einem sehr kleinen Verpackungen. Natürlich ist meine Wahl ATtiny85 - eine wunderbare kleine Chip von AVR, dass neben anderen Gütern (wie 6ch PWM, serielle Schnittstelle usw.) verfügt über einen internen Temperatursensor. Also beschloss ich, ein zu verwenden. Das war nicht einfach, aber nach ein paar Stunden zu graben Foren und Datenblätter kam ich mit einer Klasse, die den Job mit sehr beeindruckend Zuverlässigkeit und Präzision tut.
Zunächst einmal, um diesen Code auszuführen, benötigen Sie einen Arduino-Tiny ( http://code.google.com/p/arduino-tiny/ ) Kern und eine Art von ISP. Ich bin mit Arduino Duemilanove als ISP. Siehe meine RTFMs Blog für mehr Details darüber, wie, damit es funktioniert auf diese Weise, wie man richtig Kern usw. AFAIK laden alle gängigen Kerne wird funktionieren mit diesem Code. Ich nur allgemein empfehlen Arduino-Tiny wegen seiner vielfältigen Funktionen, die verwendet werden, um mehr Macht zu entfesseln ATtiny85 werden können. Die Lösung besteht aus zwei Dateien, die Sie in Ihr Projekt kopieren können. Nur CopyPaste ihnen von dieser Seite: InternalTemperatureSensor.h # Ifndef _INTERNAL_TEMPERATURE_SENSOR_H_ # Define _INTERNAL_TEMPERATURE_SENSOR_H_ # Define TEMPERATURE_SAMPLES 30 # Define TEMPERATURE_ADJUSTMENT -13 # Define EXTREMES_RATIO 5 # Define MAXINT 32767 # Define MININT -32767 / * * Basierend auf Proben: * - Der interne Temperatursensor hat schreckliche Abweichung. Es ist viel Leistung variiert (+ / -10 ° / s), erfordert * Einige "Glättung". Ich Entfernen Extremwerte und Laufen rollenden AVG auf dem anderen. Es erscheint wieder ok * Ergebnisse auf 20 Proben und vieles mehr. Sie können verringern Zahl von Proben, um die Ansprechzeit zu verringern, aber dies * Wird nachlassen Präzision. * - Die Linearität ist in Ordnung und ungefähr 1,0 als Datenblatt versprochen * - Der Offset Notwendigkeit, für jeden Chip einzeln berechnet werden und sofern in c'tor * * Um calaculate den Offset-Haken bis zum Terminal 2 (Serial-TX) 9600 8N1 PIN und verwenden * Temperature.print ()-Methode. Dieser druckt Temperatur-Anzeigen. Spiel es gegen Ihre * Kalibrierten Thermometer auf dem Chip befestigt. Passen Sie Tos in c'tor, wenn nötig. * Siehe Kapitel 17,12 des ATtiny85 Datenblatt für ein bisschen mehr Details * / Klasse InternalTemperatureSensor { int offset; Koeffizient schweben; Lesungen int [TEMPERATURE_SAMPLES]; int pos; Öffentlichkeit: InternalTemperatureSensor (float k, int o): Offset (o), (k), Pos (0) {} / / Nennen Sie es jedes Mal, wenn Sie brauchen, um den Chip zu bereiten Sensor ausgelesen (dh im Setup) / / Wenn Sie mit anderen ADCs neben Temperatur nennen es vor jeder Temperaturmessung void init (); / / Gibt die aktuelle gemittelte Temperatur im LSB int in_lsb (); / / Gibt die aktuelle gemittelte Temperatur in Grad Celsius int in_c (); / / Gibt die aktuelle gemittelte Temperatur in Grad Fahrenheit int in_f (); / / Gibt die aktuelle gemittelte Temperatur in Kelvin int in_k (); / / Gibt die aktuelle Temperatur Lesen von RAW-Sensor int raw (); / / Gibt die aktuelle Temperaturmessungen in verschiedenen Formaten void print (); }; # Endif / / _INTERNAL_TEMPERATURE_SENSOR_H_ InternalTemperatureSensor.pde # Include "InternalTemperatureSensor.h" Leere InternalTemperatureSensor :: init () { / / AnalogReference (INTERNAL1V1); / / ATTiny85 Datenblatt P140 (17.13.2), P137 (17.12) / / Konfigurieren ADMUX ADMUX = B1111 / / Wählen Temperatursensor ADMUX & = ~ _BV (ADLAR); / / Rechts-Adjust-Ergebnis ADMUX | = _BV (REFS1); / / Set Ref Spannung ADMUX & = ~ (_BV (REFS0) | _BV (REFS2)); / / bis 1.1V / / Konfigurieren ADCSRA ADCSRA & = ~ (_BV (ADATE) | _BV (ADIE)); / / Disable Autotrigger, Disable Interrupt ADCSRA | = _BV (ADEN); / / Enable ADC ADCSRA | = _BV (ADSC); / / Start erste Konvertierung / / Seed-Proben int raw_temp; while (((raw_temp = raw ()) <0)); for (int i = 0; i <TEMPERATURE_SAMPLES; i + +) { Lesungen [i] = raw_temp; } } int InternalTemperatureSensor :: in_lsb () { int readings_dup [TEMPERATURE_SAMPLES]; int raw_temp; / / Erinnere mich an die Probe if ((raw_temp = raw ())> 0) { Lesungen [pos] = raw_temp; pos + +; pos% = TEMPERATURE_SAMPLES; } / / Kopieren Sie die Proben for (int i = 0; i <TEMPERATURE_SAMPLES; i + +) { readings_dup [i] = Messwerte [i]; } / / Blase Extreme an den Enden der Anordnung int extremes_count = TEMPERATURE_SAMPLES / EXTREMES_RATIO; int Swap; for (int i = 0; i <extremes_count; i + +) {/ / Prozent der Iterationen des Bubble-Sort auf kleinen N arbeitet schneller als Q-Sort for (int j = 0; j <TEMPERATURE_SAMPLES - 1; j + +) { if (readings_dup [i]> readings_dup [i +1]) {/ / könnte mit 3 XORs und kein Austausch vorgenommen werden, wenn Sie Lust gerne swap = readings_dup [i]; readings_dup [i] = readings_dup [i +1]; readings_dup [i +1] = tauschen; } } } / / Durchschnitt der Mitte des Arrays int sum_temp = 0; for (int i = extremes_count; i <TEMPERATURE_SAMPLES - extremes_count; i + +) { sum_temp + = readings_dup [i]; } zurück sum_temp / (TEMPERATURE_SAMPLES - extremes_count * 2); } int InternalTemperatureSensor :: in_c () { zurück in_k () - 273; } int InternalTemperatureSensor :: in_f () { zurück in_c () * 9/5 + 32; } int InternalTemperatureSensor :: in_k () { zurück in_lsb () + offset;! / / für Einfachheit mal ich bin mit k = 1, verwenden Sie die nächste Zeile, wenn Sie wollen, K = 1,0 / / Return (int) (in_lsb () * Koeffizient) + offset; } int InternalTemperatureSensor :: raw () { if (ADCSRA & _BV (ADSC)) { return -1; } Else { int ret = ADCL | (ADCH << 8); / / Holen Sie sich das vorherige Konvertierung Ergebnis ADCSRA | = _BV (ADSC); / / Start neuer Umwandlung Rückkehr ret; } } Leere InternalTemperatureSensor :: print () { Serial.print ("> R:"); Serial.print (raw (), Dezember); Serial.print ("L:"); Serial.print (in_lsb (), Dezember); Serial.print ("K:"); Serial.print (in_k (), Dezember); Serial.print ("C:"); Serial.print (in_c (), Dezember); Serial.print ("F:"); Serial.print (in_f (), Dezember); Serial.println ("#"); } Verwendung InternalTemperatureSensor Temperatur (1,0, TEMPERATURE_ADJUSTMENT); / / Der 1,0 Argument standardmäßig ignoriert wird, sehen die c'tor Kommentare void setup () { temperature.init (); / / Aufruf init () im Setup oder jedes Mal, nachdem Sie ADCSRA oder ADMUX ändern } void loop () { / / Temperature.print (); / / kommentieren Sie diese mit dem Sensor über die serielle Verbindung zu debuggen int war_sensor_data temperature.raw = (); / / das gibt kaum brauchbare Sensorausgang int temperature_in_celsius temperature.in_c = (); / / das gibt mehr nutzbare Temperatur in Grad Celsius } Erklärung ATtinyX5 verwendet ADC4 zum Lesen von Daten aus dem internen Sensor. In init ()-Methode alle notwendigen Magie mit den Registern wird getan, um das System zum Lesen dieser Daten vorzubereiten. Sie müssen diese Methode aufrufen, jedes Mal, wenn Sie wollen ADMUX und ADCSRA für das Abrufen der Temperatursensor Daten konfigurieren. Wenn das einzige ADC-Kanal, die Sie in Ihrem Programm ist der Temperatursensor die ADC4 dann sollten Sie nennen es nur in setup (), dh einmal. Dadurch verringert sich die Temperatur Lesevorgang Zeit mindestens um den Faktor zwei. Methode InternalTemperatureSensor :: raw () liefert die Rohdaten des Sensors. Leider wird diese Daten kaum nutzbar. Um das Problem zu veranschaulichen, nehmen Sie einen Blick auf die Ausgabe von InternalTemperatureSensor :: print () Debug-Methode. Die erste Spalte ist das, was der Sensor kehrt. Die Ausgabegeschwindigkeit beträgt ca. 5 Zeilen pro Sekunde, so dass innerhalb von 2 Sekunden die Sensor-Werte kam mit 18 Grad Unterschied.
 ATtiny85 Interner Temperatursensor Positionsanzeigen Um diese Daten besser nutzbar Methode InternalTemperatureSensor :: in_lsb nicht gleitender machen und entfernt die Extreme aus der Eingabe. Das Ergebnis, das Sie auf dem Bild oben sehen kann: die in_lsb Ausgabe als L markiert: Weg ist besser nutzbar. Es ist genauer zu. Sie können die Parameter gleitenden Durchschnitt, aber insgesamt nicht empfehlenswert machen TEMPERATURE_SAMPLES weniger als 20 und größer als 50 ist. Wenn es weniger als 20 ist dann Abweichung wächst deutlich. TEMPERATURE_SAMPLES machen mehr als 50 nicht verbessert, sondern Präzision Abfälle Speicherplatz und verlangsamt den Berechnungen. Auch EXTREMES_RATIO definiert, wie viel von Extremwerten wird zerhackt werden, machen es nicht weniger als 2 (also alle Werte zu eliminieren). Ist damit mehr als TEMPERATURE_SAMPLES wird wirksam verhindert das Entfernen Extremen aus den Proben. Zusätzlich zu diesen drei Kern-Methoden ein paar Hilfsmethoden in_c (), in_k (), sind in_f () zur Verfügung gestellt. Sie geben die Temperatur in Grad Celsius, Fahrenheit und Kelvin. Noch ein Problem mit dem internen Sensors ist, dass es nicht kalibriert, so dass für jeden Chip müssen Sie print ()-Methode verwenden, um den Messwert ausgeben und stellen Sie den zweiten Parameter des Konstruktors, um diese Werte mit Ihren kalibrierten Thermometer entsprechen. Der Wert -13 im Quellcode funktioniert nur bei einem meiner ATtinies, es gibt keine Garantie wird es für andere zu arbeiten. Insgesamt ist die interne Sensor ist brauchbar, aber nicht viel von ihm erwarten. Externe Sensoren sind immer noch viel besser. Dieser Beitrag erscheint in Hardware , Robotik . |