Termómetro de dos dígitos



El autor hizo este termómetro LED de dos dígitos como regalo de cumpleaños para el hijo de su amigo. Tiene solo dos años y ya está leyendo los números, pero las letras no. Ahora puede descubrir la temperatura fuera de la ventana por su cuenta. El sensor en el termómetro es un chip DS18B20 que funciona según el protocolo 1-Wire, y el microcontrolador es del tipo ATtiny84. El tablero es cuadrado con un lado de 25 mm, en tamaño es comparable a una moneda de 50 peniques. El autor planea colocar el tablero en una funda impermeable y colocarlo fuera de la ventana. La indicación se enciende brevemente cada 24 segundos, y las baterías CR2032 duran aproximadamente un año.
El termómetro funciona en el rango de -19 a +99 ° C. Si es necesario, el signo menos y uno se muestran simultáneamente en el orden superior. Fuera de rango, se muestran las letras Lo o Hi. Puede "enseñar" al dispositivo a mostrar temperaturas inferiores a -19 ° C utilizando un segmento con un punto como un signo menos.

Según este esquema, el dispositivo se ensambló previamente en una placa de pruebas:



Todas las salidas del microcontrolador están involucradas, se utiliza el generador de reloj incorporado de 8 MHz. El prototipo fue el siguiente:



El prototipo usó DS18B20 en el paquete TO-92, ATtiny84 en el paquete PDIP y un indicador 3621AS de 3.6 pulgadas. Luego, el autor desarrolló el tablero en Eagle y lo ordenó en PCBway. Aquí el microcontrolador ya está en la caja SOIC, el sensor está en la caja µSOP y las resistencias, condensadores y la pantalla son del tamaño 0805. Todo, excepto la pantalla, está soldado con un secador Youyue 858D + a una temperatura de 250 ° C.

Tanto el prototipo como la placa de circuito impreso tienen indicadores con un ánodo común. El dispositivo está hecho en dos versiones, con indicadores de colores rojo y amarillo. Rojo - en KDPV, amarillo - aquí:



Un soporte para una celda de litio de 20 mm (cualquiera con una designación que comience con 20, es decir, 2016, 2025 o 2032) está soldado en la parte posterior:



El firmware está escrito de modo que el microcontrolador esté en modo de suspensión la mayor parte del tiempo y se active tras la interrupción del temporizador de vigilancia. En la implementación de la interfaz 1-Wire, este tiempo operativo del mismo autor está involucrado. El temporizador-contador de 16 bits del microcontrolador que funciona a una frecuencia de 1 MHz consume mucho tiempo:

void OneWireSetup () { TCCR1A = 0<<WGM10; // Normal mode TCCR1B = 0<<WGM12 | 2<<CS10; // Normal mode, divide clock by 8 } 

La subrutina DelayMicros () proporciona un retraso de un número específico de microsegundos, según el registro de comparación de salida OCR0A:

 void DelayMicros (unsigned int micro) { TCNT1 = 0; TIFR1 = 1<<OCF1A; OCR1A = micro; while ((TIFR1 & 1<<OCF1A) == 0); } 

La rutina DisplayTemperature () lee el valor de temperatura del sensor y lo muestra. Como solo hay un sensor en el bus, puede ignorar el número de serie y simplemente dar el comando Omitir ROM, después de lo cual se envían los siguientes comandos a cualquier dispositivo:

 void DisplayTemperature () { cli(); // No interrupts if (OneWireReset() != 0) { sei(); DisplayError(0); // Device not found } else { OneWireWrite(SkipROM); OneWireWrite(ConvertT); while (OneWireRead() != 0xFF); OneWireReset(); OneWireWrite(SkipROM); OneWireWrite(ReadScratchpad); OneWireReadBytes(9); sei(); // Interrupts if (OneWireCRC(9) == 0) { int temp = DataWords[0]; Display((temp+8)>>4); // Round to nearest degree } else DisplayError(1); // CRC error } } 

En respuesta a la solicitud, el sensor devuelve el valor de temperatura en forma de un entero con signo de 16 bits en unidades iguales a 1/16 grados. El número se redondea al grado entero más cercano y se muestra llamando a la rutina Display ().

La subrutina DisplayError () muestra errores en la interacción del microcontrolador con el sensor en el bus 1-Wire:

 void DisplayError (int no) { Buffer[0] = Error; Buffer[1] = no; } 

E0: sensor no detectado, E1: error de CRC.

Los datos para la indicación dinámica se toman de la matriz Buffer []. Por ejemplo, para mostrar el número 20, debe hacer:

 Buffer[0]=2; Buffer[1]=0; 

El contador de temporizador 0 genera interrupciones a una frecuencia de 125 Hz, que es suficiente para eliminar el parpadeo. Primero, el temporizador se configura en setup () "

 TCCR0A = 2<<WGM00; // CTC mode; count up to OCR0A TCCR0B = 0<<WGM02 | 4<<CS00; // Divide by 256 OCR0A = 250-1; // Compare match at 125Hz TIMSK0 = 0; // Interrupts initially off 

La rutina de manejo de interrupciones coincidentes durante la comparación llama a la rutina DisplayNextDigit () y luego cuenta en la dirección opuesta:

 ISR(TIM0_COMPA_vect) { DisplayNextDigit(); Ticks--; } 

La subrutina DisplayNextDigit () lee datos de la celda correspondiente en la matriz Buffer [] e incluye los segmentos deseados en el bit de visualización correspondiente. El programa usa #define para elegir entre un indicador con un cátodo o ánodo común. Si todos los segmentos se iluminan inmediatamente después del encendido, el tipo de pantalla no coincide con el especificado en el firmware. Para un cátodo común, la subrutina debe reemplazarse con lo siguiente:

 void DisplayNextDigit () { PORTB = PORTB | 1<<digit; // Turn old digit off digit = digit ^ 1; // Toggle between 0 and 1 char segs = charArray[Buffer[digit]]; PORTA = segs; // Lit segments high PORTB = PORTB & ~(1<<digit); // Turn new digit on } 

Finalmente, la rutina Display () produce un número de dos dígitos para escribir en la matriz Buffer []:

 void Display (int n) { int units = n % 10; int tens = n / 10; int temp0 = tens; int temp1 = abs(units); if (tens < -1) {temp0 = Lo; temp1 = Lo+1; } else if (tens > 9) {temp0 = Hi; temp1 = Hi+1; } else if (tens == -1) temp0 = Minus1; else if ((tens == 0) && (units >= 0)) temp0 = Blank; else if ((tens == 0) && (units < 0)) temp0 = Minus; Buffer[0] = temp0; Buffer[1] = temp1; } 

También tiene en cuenta los casos de mostrar el signo menos junto con la unidad en el orden superior, así como los mensajes sobre la temperatura fuera del rango.

Para el máximo ahorro de energía posible, los generadores de reloj ADC, USI y ADC están deshabilitados, y el modo de suspensión PWR_DOWN está habilitado:

  ADCSRA &= ~(1<<ADEN); // Disable ADC to save power PRR = 1<<PRUSI | 1<<PRADC; // Turn off clocks to USI & ADC to save power set_sleep_mode(SLEEP_MODE_PWR_DOWN); 

El programa principal muestra la temperatura durante décimas de segundo, luego activa el modo de suspensión. Resultó que este es el tiempo mínimo de indicación, conveniente para la lectura. Dos segundos antes de que se muestre la temperatura, el punto parpadea brevemente:

 void loop () { Buffer[0] = DP; Buffer[1] = Blank; DisplayOn(12); WDDelay(6); // Sleep for 1 second Buffer[0] = Blank; Buffer[1] = DP; DisplayOn(12); WDDelay(6); // Sleep for 1 second DisplayTemperature(); DisplayOn(12); WDDelay(9); // Sleep for 8 seconds WDDelay(9); // Sleep for 16 seconds WDDelay(9); // Sleep for 24 seconds } 

La pantalla permanece apagada durante 24 segundos debido a tres llamadas de vigilancia durante 8 segundos cada una. Con el indicador en funcionamiento, el consumo de corriente es de 6.6 mA, en modo de suspensión: 4.7 μA, el consumo de corriente promedio es de 1/240 * 6.6 mA. La capacidad típica de la celda CR2032 es de 225 mAh, por lo que es suficiente para (225 / 6.6) x 240/24 = 340 días, un poco menos de un año.

Los rangos de temperatura de los componentes son los siguientes: microcontrolador e indicador - de -40 a + 85 ° C, resistencias y condensador - de -55 a +125 ° C, baterías - de -20 a +70 ° C. Un elemento con un rango de temperatura extendido BR2032 operará en el rango de -30 a +85 ° C.

El microcontrolador es compatible con Arduino con este desarrollo de Spence Konde. En el IDE, seleccione ATtiny24 / 44/84 en la sección ATTinyCore del menú del tablero. Luego debe configurar las siguientes opciones, sin prestar atención al resto:

 Chip: "ATtiny84" Clock: "8 MHz (internal)" BOD: "BOD Disabled" Pin Mapping: "Clockwise (like damellis core)" 

El programa se carga con el clip de prueba de Pomona, se coloca en la parte superior del microcontrolador y se conecta al programador SparkFun Tiny AVR. Primero debe seleccionar Burn Bootloader, luego Cargar.

Enlaces: el texto completo del programa , la pizarra y el programa en GitHub , la pizarra en OSHpark .

Source: https://habr.com/ru/post/454220/


All Articles