Mostrando entradas con la etiqueta atmega328. Mostrar todas las entradas
Mostrando entradas con la etiqueta atmega328. Mostrar todas las entradas

viernes, 25 de octubre de 2024

Base de tiempo - 1 Segundo con Arduino ATMEGA328

  Página principal

Base de tiempo
1 Segundo
Arduino ATMEGA328

Después de haber realizado el Generador de DCF77 con el Arduino, me dí cuenta que algunos relojes no sincronizaba bien.
El caso es que debía tener una base de tiempos muy precisa, y con la función de delay
() no servía.
Pensando y mirando montajes anteriores míos, encontré entre mis montajes uno que utilizaba interrupciones internas mediante contadores.

Para este montaje se utilizan los contadores de 16bits, en modo CTC

19.9.2 -Modo de borrado del temporizador en comparación (CTC)
En los modos de borrado del temporizador en comparación (CTC) (modo 4 o 12, WGMn[3:0]=0x4 o 0xC), los registros OCRnA o ICRn se utilizan para manipular la resolución del contador: el contador se pone a CERO cuando el valor del contador (TCNTn) coincide con el OCRnA (si WGMn[3:0]=0x4) o el ICRn (WGMn[3:0]=0xC). El OCRnA o el ICRn definen el valor superior del contador, por lo tanto también su resolución. Este modo permite un mayor control de la frecuencia de salida de comparación. Simplifica la operación de conteo de eventos externos.
El valor del contador (TCNTn) aumenta hasta que se produce una comparación con OCRnA o ICRn, y luego se borra el TCNTn.


ISR(TIMER1_COMPA_vect)
{
  if(playRun==true)  rutina100();   
}


setup()
{
.............
.............
  // Interrupciones cada 0,1 Segundos
    cli();
    TCCR1A=0;
    TCCR1B=0;   
#if MODO_SEG == 0   // 0=999.762.128 nS 1=999.762.876
      OCR1A=1562; 
      TCCR1B |= (1<<WGM12);   //  0 1 0 0 CTC OCR1A Immediate MAX
      TCCR1B |= (1<<CS10);    // clk I/O /1024 (From prescaler)
      TCCR1B |= (1<<CS12);
#endif
#if MODO_SEG == 1   // 1=1.000.081.262 nS  0=1.000.0828
      OCR1A=6253;   //6252 DIV-256
      TCCR1B |= (1<<WGM12);   //  0 1 0 0 CTC OCR1A Immediate MAX
      TCCR1B |= (1<<CS12); // clk I/O /256 (From prescaler)
#endif  
#if MODO_SEG == 2   // DIV-64
      OCR1A=25031;
                      // 25020    1.000.282.772 nS
                      // 25015    1.000.082.800 nS
                      // 25013 DIV-64   1.000.003.00 nS
                      // 25013 DEDO     1.000.241.871
                      //       DEDO     1.000.121.011
                      // 25013 otro reloj 999.289.372 nS
                      // 25032 otro reloj 1.000.052.634 nS
                      // 25031 otro reloj 1.000.012.119 nS
      TCCR1B |= (1<<WGM12);   //  0 1 0 0 CTC OCR1A Immediate MAX
      TCCR1B |= (1<<CS10); // clk I/O /64 (From prescaler)
      TCCR1B |= (1<<CS11);
#endif
  TIMSK1=(1<<OCIE1A);     // Timer/Counter1, Output Compare A Match Interrupt Enable 
  sei(); 
}


En el código se crea un a interrupción cada 0.1 Segundos.
Con un contador hasta 10, se crea un incremento de 1 Segundo.
Al utilizar los prescaler de   /1024, /265, /64 , podemos aumentar la resolución.
La mejor resolución la conseguimos al utilizar la división 64 , o eso debería ocurrir.





DIV 1024 16000000/1024=15625/10=1562 999.762.128 nS
DIV 256 16000000/256=62500/10=6250 1.000.081.262
DIV 64 16000000/64=250000/10=25000 25020    1.000.282.772 nS
25015    1.000.082.800 nS
25013    1.000.003.000 nS
25013    1.000.241.871 ns    DEDO    
25013    1.000.121.011 ns   DEDO2    

25013    999.289.372 nS    otro reloj
25032   1.000.052.634 nS  otro reloj
25031   1.000.012.119 nS  otro reloj

Todos los tiempos de este montaje dependen de la precisión del cristal de cuarzo a 16 MHz.
Es claro que para el circuito del Arduino nano, no creo que empleen un cristal demasiado exacto.

Entre dos Arduinos nano existe una variación de 14 microsegundos.

Con el mismo módulo nano, si colocamos el dedo sobre el cristal de cuarzo, la variación llega alcanzar 118 microsegundos.
Esto puede ser debido al aumento de temperatura y a la variación de capacidad que induce el dedo.

Vamos a realizar unos cálculos sobre la variación de tiempo en un reloj después de 3 meses, en el caso de 1.000.003.000 nS.

1 Segundo ->3 microSegundos
1h -> 10800 uS
1 dia ->259200 uS   (0.259 S.)
3 meses->23 Segundos

Conclusión:
Se puede y no se puede utilizar el ATMEGA328 como base de tiempos de un reloj.
Lo primero que debemos hacer es ajustar el temporizador para cada circuito nano, y obtener la la mejor precisión, o tener un cristal de 16MHz muy preciso.
También tenemos que tener cuidado la temperatura del entorno del Arduino nano.
Para las medidas he utilizado un analizador de señal Saleae Logic , y no estoy seguro de su precisión, creo que es alta.

Programa Arduino

Espero que os haya gustado este pequeño análisis.

Saludos.
Juan Galaz





martes, 12 de octubre de 2021

Generador de vídeo PAL con ATmega328.

  Página principal


Generador de vídeo  PAL
ATmega328 -> Video
Visualizar  temperatura y humedad en TV
 
Arduino


Cuando el vídeo compuesto PAL/NTSC empieza a  no usarse, incluso algunos televisores no tienen entrada de video compuesto, he encontrado una página donde explica como generarlo con un procesador ATMEGA 328.
Existen otros montajes para generar video compuesto mediante ATMEGA328, pero no son buenos como este.
    http://searle.x10host.com/MonitorKeyboard/index.html
Este montaje solo genera vídeo, y su control se realiza con dos líneas mediante el protocolo I2C.
Los modos de vídeo pueden ser:

40 Character normal
80 Character normal
40 Character bold
80 Character bold
40 Character normal double-height
80 Character normal double-height
40 Character bold double-height
80 Character bold double-height
Modo gráfico 160x100

La conexión al dispositivo maestro en mi montaje se realiza mediante I2C de dos líneas, pero existe la posibilidad de realizarlo mediante 4, y 8 líneas, con lo cual será más rápida su comunicación.
Para mas detalles os recomiendo que visitéis su página, esta muy bien explicado todas su configuraciones.
También tiene otros muchos proyectos interesantes, gracias
Grant Searle .

Para mi proyecto he utilizado un arduino nano que lee el sensor DHT22  (AM2302), para luego mandar los datos de temperatura y humedad al circuito de generación de vídeo.
Como no tenía la versión del 74HC166 he utilizado el modelo 74LS166, existe diferencias en la impedancia de entrada, pero después de probarlo funciona.

Circuito original.


Circuito para interface I2C de dos líneas, y generación de video PAL.

Como quería hacer prácticas con el programa KiCad lo realizado también para este programa.

Esquema con KiCad.



Circuito impreso con KiCad.


Vista 3D con KiCad.

El circuito impreso no lo he probado, por lo que no garantizo que esté bien, lo he realizado a modo de práctica.


 El sensor de temperatura se conecta a un arduino, para luego mandar los datos al generador de vídeo.


Circuito montado y funcionando.


Visualización de la señal de video compuesto en un televisor.

PROGRAMA

Para programar el ATmega328 he utilizado un arduino en modo programador.
En mi anterior artículo (simuld.html) explico como programar el microcontrolador con un arduino.
Una vez montado el circuito programador debemos grabar el programa con la orden:

avrdude -C/usr/share/arduino/hardware/tools/avrdude.conf -v -v -patmega328p -cstk500v1 -P/dev/ttyUSB0 -b19200 -U flash:w:SBCVideo.hex:i -U lfuse:w:0xf7:m -U hfuse:w:0xd9:m -U efuse:w:0xff:m

Este proyecto está realizado en Debian 10.
Espero que disfrutéis haciendo este proyecto.

Saludos.
Juan Galaz


Bibliografía:

simuld.html
http://searle.x10host.com/MonitorKeyboard/index.html

martes, 24 de agosto de 2021

Grabar ATmega328 con ArduinoISP. Record ATmega328 with ArduinoISP

 

SimulIDE


Grabar fichero *.HEX en Atmega328

mediante Arduino utilizando avrdude


 


En anteriores artículos de SimulIDE había realizado una serie de proyectos con el Atmega328.
Había utilizado para programar el ensamblador, C, y Basic.
En el simulador funcionaba perfectamente, pero a los electrónicos nos gusta probar los circuitos físicamente, el ver parpadear un LED físico nos alegra.
El fichero generado es un fichero con extensión  .HEX , que es el código máquina que se carga en el microcontrolador.
En este artículo explico como cargar este código en el Atmega328 mediante un arduino.

Hace unos años cuando empezaba a utilizar los microcontroladores Atmega*** realicé un artículo de como realizar grabadores PROGRAMADOR.
El mas utilizado al final fue el USBASP , se conectaba directamente al puerto USB.
El que quiera puede realizarlo, es fácil, y el que quiera puede comprarlo por internet, es bastante barato.

En este proyecto enseño como programar un microcontrolador tipo Atmega328 mediante un arduino nano, aunque sirve cualquier  arduino.
Para este proyecto he utilizado el entorno Arduino IDE 1.0.5 , es el que viene de serie en Linux Debian 10.

Lo primero es transformarlo en un grabador mediante un programa que viene de ejemplo llamado:  ArduinoISP.


Compilamos el programa y lo cargamos en nuestro arduino.

Conectamos nuestro arduino al Atmega328 que queramos programar, y añadir una serie de componentes.

Esquema eléctrico.


Gráfico de componentes.


Circuito montado.

Para esta demostración he elegido el parpadeo de un LED colocado en la patilla 9 del Atmega328, que corresponde al puerto de salida B1.

hola.c

/*

* blink

* Juan Galaz

* seta43.duckdns.org

* seta43.blogspot.com

* 2021

*/


#define F_CPU 16000000L


#include <avr/io.h>

#include <util/delay.h>



int main (void)

{

DDRB = 0xff;

PORTB = 0x03;


while(1)

{

PORTB = 0x03;

_delay_ms(400);

PORTB = 0x00;

_delay_ms(500);

}

return 0;

}


Makefile

MCU=atmega328

F_CPU=16000000

CC=avr-gcc

OBJCOPY=avr-objcopy

CFLAGS=-std=c99 -Wall -g -Os -mmcu=${MCU} -DF_CPU=${F_CPU} -I.

TARGET=hola

SRCS=hola.c

all:
 ${CC} ${CFLAGS} -o ${TARGET}.bin ${SRCS}

${OBJCOPY} -j .text -j .data -O ihex ${TARGET}.bin ${TARGET}.hex

flash:

avrdude -C/usr/share/arduino/hardware/tools/avrdude.conf -v -patmega328p -cstk500v1 -P/dev/ttyUSB0 -b19200 -Uflash:w:${TARGET}.hex:i

flash2:

avrdude -C/usr/share/arduino/hardware/tools/avrdude.conf -v -patmega328p -cstk500v1 -P/dev/ttyUSB0 -b19200 -U flash:w:${TARGET}.hex:i -U lfuse:w:0xff:m -U hfuse:w:0xd9:m -U efuse:w:0xff:m

clean:

rm -f *.bin *.hex


Podemos observar que he creado dos tipos de grabaciones, flash y flash2.
El flash no modifica los FUSES del Atmega328, si estamos seguros de como están los fuses utiliza esta opción.
El flash2 coloca los fuses para que funcione con el el crystal de cuarzo externo. Esta opción solo es necesaria la primera vez que programemos el Atmega328.
También hemos supuesto que el arduino se encuentra en: /dev/ttyUSB0 , debiís estar seguro que este es vuestro caso.
Después de haber compilado el programa con el simuIDE, pasamos a consola y nos colocamos en el directorio donde se encuentra el fichero hola.hex.
Ahora solo nos queda teclear make flash , o make flash2 dependiendo del caso.

Consola
make flash

avrdude -C/usr/share/arduino/hardware/tools/avrdude.conf -v -patmega328p -cstk500v1 -P/dev/ttyUSB0 -b19200 -Uflash:w:hola.hex:i
.....
....

Writing | ################################################## | 100% 0.31s

avrdude: 182 bytes of flash written
avrdude: verifying flash memory against hola.hex:
avrdude: load data flash data from input file hola.hex:
avrdude: input file hola.hex contains 182 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.20s

avrdude: verifying ...
avrdude: 182 bytes of flash verified

avrdude: safemode: lfuse reads as FF
avrdude: safemode: hfuse reads as D9
avrdude: safemode: efuse reads as FF
avrdude: safemode: Fuses OK (E:FF, H:D9, L:FF)

avrdude done.  Thank you.


Si todo fue bien veremos como comienza a parpadear el LED.

Como podemos observar para programar un ATmega328 mediante un arduino con la conexión ISP debemos unir pines entre dos ATmega328. Esto como podéis entender es altamente peligroso, un pin puede estar en estado alto y otro en estado bajo, esto puede generar una avería en alguno de los chip.
Para solucionar este tema he añadido resistencias de 330 ohmios en las líneas de comunicaciones ISP, con lo cual se soluciona este problema.
Para probar está modificación, he realizado un simple semáforo.


He comprobado que al programar con el programa arduinoISP , en la primera programación funciona bien, pero cuando se desconecta físicamente el arduino, y se vuelve a conectar nos daba error.
Solución:
Antes de mandar el fichero HEX , pulsar el botón reset en el arduino, y mientras está pulsado el reset mandar el programa a grabar.
Se suelta el reset, y vemos que se carga correctamente el programa en el ATmega328.
Este problema me ocurre en Linux, no he probado en Windows.


Espero que les guste esta serie de montajes.
Todos estos pasos se pueden ver bien en el vídeo demostrativo.

VIDEO DEMOSTRATIVO.

SOURCE

Saludos.
Juan Galaz





jueves, 29 de julio de 2021

simulIDE , gcBasic, atmega328,avr

 

SimulIDE




El programa simuIDE  está bastante conseguido, y una de sus posibilidades es utilizar el programa GcBasic .
El programa GcBasic es un compilador de Basic para poder programar microcontroladores PIC y AVR.
En principio el GcBasic estaba pensada para PIC pero posteriormente se realizó para AVR, por lo cual la mayoría de los ejemplos son para PIC.
Lo curioso de este programa es que esta realizado en Basic, y para obtener los binarios debemos compilarlos con FreeBasic.
En mi caso utilizo Debian 10, y antes debo bajar las fuentes de FreeBasic y compilar.
    https://www.freebasic.net/
Después de compilar FreeBasic nos toca bajar las fuentes de GcBasic y compilar.
    http://gcbasic.sourceforge.net/Typesetter/index.php/Home
Terminado este proceso tenemos el fichero binario que se ejecutará en Linux, y a la vez poderse utilizar en SimulIDE.




He creado un video de como programo en Basic el Atmega328.

https://youtu.be/7r6W4W6KElU



Saludos.
Juan Galaz





lunes, 11 de marzo de 2013

Arduino-Reduciendo consumo-Parte 2

Página principal

Arduino
Reduciendo consumo
Atmega328 power low
Parte 2
Reloj - DS1302
xsetaseta@gmail.com

En esta segunda parte de como reducir el consumo de mi reloj arduds ,se utilizara la técnica de hacer dormir el ATMEGA328 cuando no se necesite.Este modo se llama SLEEP_MODE_PWR_DOWN, el oscilador externo se para.

SMCR – Sleep Mode Control Register

Existen varias maneras de despertar al ATMEGA328, y una de ellas es el
Watchdog(perro guardián),  es la forma que vamos a utilizar para que despierte el ATMEGA328. El Watchdog utiliza un oscilador  de 128 kHz, separado del reloj principal.
Mediante prescaler podemos hacer que se active en diferentes tiempos, para este caso utilizaré un prescaler a 0.5 Segundos.


Table 10-2. Watchdog Timer Prescale Select

El programa funciona de la siguiente forma:
1.- Se activa el
Watchdog en el setup a 0.5 S.
2.-Empieza el bucle del programa principal.
3.-Se pone el microprocesador a dormir en modo
SLEEP_MODE_PWR_DOWN.
4.-Si se rebasa el tiempo de 0.5 S., se activa el Watchdog y se produce una interrupción.
5.-Se ejecuta el programa de la interrupción.
6.-A la vuelta de la interrupción se sigue ejecutando el programa del bucle principal.
7.-Se vuelve al punto 2 .

Para conseguir aún más consumo he desactivado el conversor A/D de la siguiente forma:
ADCSRA = ADCSRA & B01111111;
ACSR = B10000000;


También existe la posibilidad de deshabilitar las líneas de entrada para ahorrar algo de corriente, pero en mi caso las necesito.
//DIDR0 = DIDR0 | B00111111;
He comentado esta parte para que no se realice.

Programa arduino


Montaje del circuito.

Para poder medir el consumo del circuito por partes y quitar el consumo de los componentes de la placa arduino, he sacado el Atmega en un modulo board. También he añadido un conversor USM->rs232 para poder programar el microcontrolador.


Tabla de consumos

Conversor A/D activado y frecuencia a 16Mhz.

5 V
4 V
4,5 V con diodo  quedando 3,88V
Batería 3,7 V
Atmega 328 + LCD
2,3 mA
1,43 mA
1,50mA (Picos 2,4 mA)
1,42mA(Picos 2,5 mA)
Atmega 328
0,44 mA(Picos 2,2 mA)
0,35 mA(Picos 1,36 mA)
1,36 mA(Picos 1,46 mA)
0,34mA(Picos 1,46 mA)

Conversor A/D desactivado.

5 V
4,5 V con diodo  quedando 3,88V
Batería 3,7 V
Atmega 328 + LCD (0,5-16Mhz)
2 mA(Picos 2,6 mA)

1,17 mA(Picos 1,24 mA)
Atmega (0,5-16Mhz) 0,123 mA

0,08 mA(Picos 1,50 mA)
Atmega 328 + LCD (16Mhz)
1,29 mA(Picos 2,30 mA)
1,20 mA(Picos 2,20 mA)
Atmega 328 (16Mhz)
0,08 mA(Picos 1,17 mA)
0,08 mA(Picos 1,50 mA)

Los picos de corriente corresponden a una mínima porción de tiempo, al despertar del micro cada segundo.

Conclusión:
El consumo del circuito (Atmega328+LCD) en el mejor de los casos es de 1,20 mA .Como podemos observar se encuentra muy penalizado por el LCD, que solo él consume 1,1 mA.
En una situación real donde el circuito se encuentra alimentado por 3 pilas alcalinas de 1,5V (2890mAh) , en total 4,5V, con un diodo en serie que nos quedaría 3,88V. Si consume 1,29mA el circuito, el tiempo máximo de autonomía sera 2240 Horas, 93 días.
Por otro lado si solo se utiliza el Atmega328 quitando el LCD,  la autonomia sería 36125 horas, 1505 días, 4 años.
Lo que verdaderamente aumentaría la autonomía, sería encontrar un LCD de bajo consumo.
Todo esto es bastante teórico, las baterías se autodescargan con el tiempo.
Los picos de corriente aunque sean cortos, disminuyen la autonomía. Existe la posibilidad de poner el Watchdog a un tiempo máximo de 8 segundos, con lo cual el microcontrolador estará dormido mucho más tiempo y aumenta la autonomía del circuito. No he querido tocar el programa principal, para poder ver los segundos, aunque disminuya algo la autonomía.

He de destacar que la diferencia de consumo entre variar la frecuencia y tenerla fija a 16Mhz es mínima. Tiene un motivo, si el micro va despacio, tardará más en ejecutar el programa, y por lo tanto consumirá más. A la inversa pasa lo mismo, es una cuestión de preferencia.

Espero que haya ayudado a aumentar la autonomía de vuestros circuitos.
Para la realización del programa he utilizado código de distinto sitios, modificando a mi gusto ciertas partes, no soy el autor de ciertas líneas del programa.

Saludos.
Juan Galaz


Bibliografía:
http://www.gammon.com.au/forum/?id=11497
http://www.surprisingedge.com/low-power-atmegatiny-with-watchdog-timer/
http://blog.dosbotones.com/2011/09/reducir-el-consumo-de-arduino.html
http://www.sparkfun.com/tutorials/309
http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/
http://www.engblaze.com/hush-little-microprocessor-avr-and-arduino-sleep-mode-basics/
http://www.fiz-ix.com/2012/11/low-power-arduino-using-the-watchdog-timer/
http://jeelabs.org/2009/05/16/power-consumption-more-savings/