 ATTINY85 tiene sensor de temperatura interno Estoy trabajando en uno de mis proyectos de video blog RTFMs (echa un vistazo a http://rtfms.com ) que requiere de detección de temperatura en un embalaje muy pequeño. Naturalmente, mi elección es ATTINY85 - un chip increíble poco de AVR que, además de otros bienes (como 6 canales de PWM, etc interfaz de serie) tiene un sensor de temperatura interna. Así que me decidí a usar uno. Eso no fue fácil, pero después de unas horas de los foros de excavación y hojas de datos que se me ocurrió una clase que hace el trabajo con una fiabilidad impresionante y precisión.
En primer lugar para ejecutar el código que necesita un Arduino-Tiny ( http://code.google.com/p/arduino-tiny/ ) núcleo y algún tipo de proveedor de Internet. Estoy utilizando Arduino Duemilanove como ISP. Ver a mis RTFMs blog para más detalles acerca de cómo hacer que funcione de esta manera, cómo cargar central correcta, etc que yo sepa todos los núcleos populares no tendrán ningún problema con este código. Yo sólo recomiendo Arduino-Tiny, debido a su rica funcionalidad que se puede utilizar para liberar más energía de la ATTINY85. La solución consta de dos archivos que se pueden copiar en su proyecto. Sólo tienes que CopyPaste de esta página: 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 / * * Basado en las muestras: * - El sensor de temperatura interno tiene la desviación horrible. Su producción varía mucho (+ / -10 grados por segundo), por lo que requiere * Un poco de "suavizado". Estoy eliminando los valores extremos y en funcionamiento de rodadura media en el resto. Esto devuelve ok * Los resultados de 20 muestras y mucho más. Se puede reducir el número de muestras para reducir el tiempo de respuesta, pero esta * Disminuirá la precisión. * - La linealidad es buena y aproximadamente el 1.0 como la hoja de datos prometió * - La necesidad de compensar se calcula para cada chip por separado y siempre en c'tor * * Con el fin de calaculate el gancho de compensar hasta la terminal a la patilla 2 (Serie TX) 9600 8N1 y el uso Temperature.print * () llamada al método. Esto imprimirá lecturas de temperatura. Coincidir en contra de su * Calibrado termómetro unido al chip. Ajuste telecomunicaciones en c'tor si es necesario. * Véase el capítulo 17.12 de la hoja de ATTINY85 para más detalles un poco más * / clase InternalTemperatureSensor { int desplazamiento; coeficiente de flotación; int lecturas [TEMPERATURE_SAMPLES]; int pos; público: InternalTemperatureSensor (float k, int o): desplazamiento (o), el coeficiente de (k), pos (0) {} / / Que llamar cada vez que necesita para preparar el chip para leer el sensor (es decir, en la configuración) / / Si está utilizando otros centros de retención, además de la temperatura lo llaman antes de cada lectura de la temperatura void init (); / / Devuelve el promedio de la temperatura actual en LSB int in_lsb (); / / Devuelve el promedio de la temperatura actual en grados Celsius int in_c (); / / Devuelve el promedio de la temperatura actual en grados Fahrenheit int archivo_entr (); / / Devuelve el promedio de la temperatura actual en grados Kelvin int in_k (); / / Devuelve la temperatura actual prima la lectura del sensor int prima (); / / Imprime las lecturas de temperatura actuales en varios formatos anular la impresión (); }; # Endif / / _INTERNAL_TEMPERATURE_SENSOR_H_ InternalTemperatureSensor.pde # Include "InternalTemperatureSensor.h" void InternalTemperatureSensor :: init () { / / AnalogReference (INTERNAL1V1); / / ATTINY85 ficha P140 (17.13.2), P137 (17.12) / / Configurar ADMUX ADMUX = B1111; / / Seleccionar el sensor de temperatura ADMUX & = ~ _BV (ADLAR); / / el botón derecho del ajuste resultado ADMUX | = _BV (REFS1); / / Conjunto de tensión Ref. ADMUX & = ~ (_BV (REFS0) | _BV (REFS2)); / / a 1.1V / / Configurar ADCSRA ADCSRA & = ~ (_BV (unaFecha) | _BV (ADIE)); / / Desactivar Autotrigger, deshabilitar interrupciones ADCSRA | = _BV (ADEN); / / Enable ADC ADCSRA | = _BV (ADSC); / / Inicia primera conversión / / Muestras de semillas int raw_temp; while (((= raw_temp prima ()) <0)); for (int i = 0; i <TEMPERATURE_SAMPLES; i + +) { lecturas [i] = raw_temp; } } int InternalTemperatureSensor in_lsb :: () { int readings_dup [TEMPERATURE_SAMPLES]; int raw_temp; / / Recordar la muestra if ((raw_temp = prima ())> 0) { lecturas [pos] = raw_temp; pos + +; pos =% TEMPERATURE_SAMPLES; } / / Copiar las muestras for (int i = 0; i <TEMPERATURE_SAMPLES; i + +) { readings_dup [i] = lecturas [i]; } / / Burbuja extremos a los extremos de la matriz int = extremes_count TEMPERATURE_SAMPLES / EXTREMES_RATIO; int de intercambio; for (int i = 0; i <extremes_count; + + i) {/ / por ciento de las iteraciones de ordenamiento de burbuja en la pequeña N funciona más rápido que Q-sort for (int j = 0; j <TEMPERATURE_SAMPLES: 1; j + +) { if (readings_dup [i]> readings_dup [i +1]) {/ / se puede hacer con 3 XORs y de intercambio no se si te gusta la fantasía intercambiar = readings_dup [i]; readings_dup [i] = readings_dup [i +1]; readings_dup [i +1] = cambiar; } } } / / Promedio del centro de la matriz int sum_temp = 0; for (int i = extremes_count; i <TEMPERATURE_SAMPLES - extremes_count; i + +) { sum_temp + = readings_dup [i]; } volver sum_temp / (TEMPERATURE_SAMPLES - extremes_count * 2); } int InternalTemperatureSensor in_c :: () { volver in_k () - 273; } int InternalTemperatureSensor archivo_entr :: () { volver in_c () * 9.5 + 32; } int InternalTemperatureSensor in_k :: () { volver in_lsb () + offset;! / / para Simplicidad estoy usando k = 1, utilice la siguiente línea si desea que K = 1,0 / / Return (int) (in_lsb () * coeficiente) + offset; } int InternalTemperatureSensor prima :: () { if (ADCSRA y _BV (ADSC)) { return -1; Else {} int ret = ADCL | (ADCH << 8); / / Obtener el resultado de la conversión anterior ADCSRA | = _BV (ADSC); / / Inicia nueva conversión return ret; } } InternalTemperatureSensor vacío :: print () { Serial.print ("> R:"); Serial.print (prima (), DEC); Serial.print ("L"); Serial.print (in_lsb (), DEC); Serial.print ("K"); Serial.print (in_k (), DEC); Serial.print ("C:"); Serial.print (in_c (), DEC); Serial.print ("F"); Serial.print (archivo_entr (), DEC); Serial.println ("#"); } Uso La temperatura InternalTemperatureSensor (1,0, TEMPERATURE_ADJUSTMENT) / / El argumento de 1,0 se tiene en cuenta por defecto, ver los comentarios c'tor void setup () { temperature.init (); / / Llamar a init () en la configuración o cada vez que después de modificar o ADCSRA ADMUX } void loop () { / / Temperature.print (); / / descomentar la de depurar la salida del sensor a través de conexión en serie int war_sensor_data temperature.raw = () / / Esto devuelve la salida del sensor apenas utilizables int temperature_in_celsius temperature.in_c = (), la temperatura / / Con esto se vuelve más fácil de usar en grados Celsius } Explicación ATtinyX5 utiliza ADC4 para la lectura de datos desde el sensor interno. En el método init () toda la magia necesaria con los registros se lleva a cabo para preparar el sistema para la lectura de estos datos. Es necesario llamar a este método cada vez que desee configurar y ADMUX ADCSRA para recuperar los datos del sensor de temperatura. Si el único canal de ADC se utiliza en el programa es ADC4 el sensor de temperatura, entonces usted sólo debe llamar en setup (), es decir, una sola vez. Esto reduce el tiempo de lectura de la temperatura procedimiento por lo menos por dos factores. Método InternalTemperatureSensor :: prima () devuelve los datos en bruto del sensor. Desafortunadamente estos datos es apenas utilizables. Para ilustrar el problema de echar un vistazo a la salida de InternalTemperatureSensor :: print () método de depuración. La primera columna es lo que los rendimientos de los sensores. La tasa de salida es de aproximadamente 5 líneas por segundo, por lo que el plazo de 2 segundos, el sensor de valores de retorno con 18 grados de diferencia.
 ATTINY85 internos Lecturas para Sensores de Temperatura Con el fin de realizar este método InternalTemperatureSensor datos más utilizable :: in_lsb se promedio móvil y elimina los extremos de la entrada. El resultado se puede ver en la imagen de arriba: la salida in_lsb marcado como L: es la forma más fácil de usar. Es más exacto también. Puede ajustar los parámetros de promedio móvil, pero en general no recomiendo hacer TEMPERATURE_SAMPLES menos de 20 y mayor de 50 años. Si se trata de menos de 20, entonces la desviación crece de manera significativa. Hacer TEMPERATURE_SAMPLES mayor de 50 no mejora la precisión, pero la memoria residuos y ralentiza los cálculos. También EXTREMES_RATIO define la cantidad de valores extremos se cortó, no lo hacen menos de 2 (que eliminará todos los valores). Por lo que es más efectiva que TEMPERATURE_SAMPLES prevenir la eliminación de los extremos de las muestras. Además de estos 3 métodos básicos una utilidad pocos in_c métodos (), in_k (), archivo_entr () se proporcionan. Vuelven la temperatura en grados Celsius, Fahrenheit y Kelvin. Un problema más con el sensor interno es que no está calibrada, por lo que para cada chip tiene que utilizar el método de impresión () para la salida de la lectura y ajustar el segundo parámetro del constructor para que coincida con esos valores con su termómetro calibrado. El valor de -13 en el código fuente sólo funciona para uno de mis ATtinies, no hay garantía de que funcione para los demás. En general, el sensor interno es utilizable, pero no esperes mucho de ella. Los sensores externos son todavía mucho mejor. Esta entrada se publicó en el hardware , robótica . |