Simulación con Proteus

No podemos dejar pasar la simulación de Arduino, como sabemos hay un numero muy grande de placas de Arduino con diferentes configuraciones y potencia de proceso, pero muchas veces no tenemos la placa con nosotros, o simplemente es mas sencillo depurar un programa en la PC que subir una y otra vez el fuente a la placa Arduino.
En este caso y con la gran trayectoria que tiene el Proteus, vamos a hacer un pequeño tutorial de simulación de Arduino.

Como primer paso debemos descargar el proteus, tenemos una versión demo disponible en la web y también tenemos alguna otra opción educativa, etc..., en este caso dejare el link a la web de Labcenter Electronics, este es el Link a Download

Obviamente tendremos que descargar también el Arduino IDE para realizar la programación y la compilación del programa. 
Recordemos que el código compilado nos dará un fichero con extensión .hex, este sera el que incluiremos en el Proteus para la simulación.

Antes de comenzar con el Proteus, debemos tener las librerías de Arduino, si bien el proteus viene con los microcontroladores de Atmega, esta no es la forma en la que se presenta en Arduino, para ello buscamos la librería y nos traerá una representación gráfica del arduino que en su interior tiene el Atmega.

Lamentablemente para nosotros, no hay librerías oficiales para Arduino, librerías que bajemos del sitio de proteus, arduino, o algún repositorio oficial. 
En mi caso buscando en google con las palabras mágicas "Proteus Arduino Library" aparecieron varias opciones, tengamos en cuenta lo anterior, esta librería no es mas que un gráfico que representa el micro Atmega donde en su interior o en el contenedor del package hay un Atmega, por ello les digo que pueden usar directamente el atmega del proteus sin ninguna librería, pero de todas formas vamos a incluir la librería para ver las diferencias.
Después de buscar un poco encontré una en la pagina: http://www.electronicslovers.com/2015/12/arduino-nano-pro-mini-uno-12802560.html 
Pero pueden buscar otra que quieran.

El primer paso es descargar la librería, una vez descargada debemos ir a la ruta donde el Proteus guarda sus librerías y pegar en esa carpeta la que descargamos:

El archivo descargado:



La carpeta de la Liberia del Proteus en la PC:


Pegamos los archivos .IDX y .LIB en la carpeta LIBRARY:



Una vez terminado esto, abrimos el Proteus y buscamos Arduino en la librería:



NOTA: Claramente esta librería tiene solo dos modelos, aunque en la web decía que tenia mas, esto es lo que pasa al no tener librerías oficiales, pero pueden buscar otra librería e incluirla fácilmente.

Ahora podemos abrir el Arduino IDE, en mi caso voy a simularlo para un Arduino MINI porque es uno de los que trae la librería de Proteus.
Entramos a preferencias Archivo->Preferencias, y tenemos que tildar las opciones Compilación y Subir, dentro de Detalle de Salida, esta configuración nos mostrara en el spool del IDE el archivo temporal donde se encuentra el archivo compilado de forma temporal. 
Es recomendable no cerrar el ArduinoIDE hasta no copiar el .hex en otra carpeta para su simulación en proteus.



Realizamos el programa, en este caso el Blink LED para demostrar que funciona, y luego con la tilde de verificación vamos a compilar el código.


Como podremos ver en el spool tenemos la ruta donde esta Blink.ino.hex (el ultimo registro que vemos), debemos ir a buscar ese archivo y podríamos copiarlo en otro lado.

Primero vamos a tener que habilitar la opción de archivos o carpetas ocultas en el explorador de archivos:



Siguiendo la ruta mencionada mas arriba: C:\Users\NombreUsuario\AppData\Local\Temp\build61b4cef66da87d4ce238804c8e3422e1.tmp/Blink.ino.hex podremos encontrar nuestro archivo. 

Luego vamos al proteus y buscamos el archivo donde lo hemos copiado, y con doble click en el Arduino virtual del ISIS seleccionamos el .hex y simulamos el programa.


Ahora procedemos a la simulación:


Como podremos ver estamos analizando con el osciloscopio la señal que sale del pin 13 del Arduino como lo hemos programado en el IDE.


El Atmega328p

Como bien sabrán aquellos que siguen a Arduino, uno de los microcontroladores que mas van a encontrar en las plataformas de Arduino sera el Atmega328p.
Este es un micrcontrolador de la firma Atmel (ahora adquirida por Microchip) y esta basado en la arquitectura AVR.
AVR es una arquitectura basada en RISC (Computadora con conjunto de instrucciones reducidas), recordemos que la arquitectura de un microprocesador o microcontrolador, detalla la estructura interna del mismo y como se conforma la distribución, acceso y control de los diversos bloques que componen al microcontrolador.


Sin entrar mucho en detalles de Microprocesadores/Microcontroladores, ya que demandaría un curso dedicado solo a ese tema, podremos ver el interior de la arquitectura del Microprocesador (en el cuadro gris llamado "CPU" y agregándole los periféricos externos lo convertiremos en un microcontrolador.
La manera mas conveniente de estudiar este tema es empezando por técnicas digitales, siguiendo por lenguaje ensamblador y analizando sus registros, pilas, puertos, etc... Pero no es la idea del curso ya que la idea es aprender Arduino y este tema quedara para los que se interesen un poco mas en electrónica.

Siempre que estudiemos un microcontrolador, circuito integrado o algún componente electrónico, es recomendable que busquemos su hoja de datos "Datasheet" asignado para saber los parámetros eléctricos y su configuración.
En este caso dejare el link para la hoja de datos del microcontrolador Atmega328p.

Dentro de los packages (encapsulados) que se provee el Atmega328, vamos a encontrar el mas popular para los proyectos Diy que sera el PDIP, este podrá ser montado directamente en un protoboard (breadboard) o en una placa de prototipado o experimental.

La disposición de pines del encapsulado 28-PDIP sera la siguiente:


Como podremos ver en la imagen, tendremos 3 puertos (B, C y D), donde estos poseen múltiples configuraciones, como por ejemplo el PC4 donde hacemos referencia al puerto C pin numero 4 que aparte de funcionar como una entrada o salida, puede funcionar como un canal multiplexado del ADC (en este caso el canal 4) también funciona como uno de los pines de la interfaz I2C (en este caso el SDA) y también como interrupción (en este caso como PCINT12).
Esto nos demuestra que el microcontrolador puede ser configurado de múltiples maneras y puede configurar sus pines de diferentes maneras según su hardware se lo permita, claro que también podremos realizar algunos protocolos por software y asignarlo a pines que no están dedicados, por ejemplo podríamos tener un pin SDA en un pin PB5, que no posee esta propiedad por hardware pero podríamos hacer la trama por software y utilizarlo, lo que no podremos hacer es usar este PB5 como un canal ADC ya que es una propiedad intrínseca del microcontrolador.


Este es el diagrama de bloques interno del Atmega328p, con todos sus bloques y configuraciones internas para manipular vía firmware.

Ahora describiremos los parámetros eléctricos del microcontrolador que es necesario y muy útil al momento de diseñar nuestro hardware o utilizar algún modulo/shield externo.


Como podremos ver, dentro de lo que mas debería importarnos es la tensión de alimentación que sera de 5V y la corriente de salida de los pines I/O que sera de 20mA máximo, esto sera necesario saberlo ya que si conectamos un LED a su salida debemos calcular la resistencia del mismo y demás. Lo mismo que no podremos conectar un motor o alguna carga que sobre pase los 20mA o que sea inductiva para evitar problemas por ley Faraday-Lenz y FCEM.

El aspecto físico del mismo, sera el siguiente (para PDIP):


Por último, el conexionado para la placa Arduino con el Atmega328p sera la siguiente:



Arduino IDE

El primer paso para empezar con Arduino sera la descarga de su IDE, en el siguiente Link podrá descargar el software del site oficial, aunque siempre es mejor ingresar al sitio principal en el caso de que cambiaran de ruta el programa.


Tendremos opciones de descara para los tres sistemas operativos mas conocidos, y en Windows podremos descargar el archivo instalable como también el portable.
Existe una versión para Android que he probado y funciona bien pero no es oficial.
Aquí dejare el link a GooglePlay


NOTA: Hay que tener en cuenta que la placa de desarrollo posee un BridgeUSB en su interior que en su mayor cantidad de versiones es compatible con los OS mas conocidos, pero en Android solo funcionaran las mas conocidas como Atmega y FTDI.


Una vez descargado el IDE de Arduino procedemos a instalarlo o si bajamos la versión portable buscamos el ejecutable y lo abrimos.


Lo primero que podremos ver serán las opciones del IDE:

Archivo:


Editar:


Programa:


Herramientas:


Ayuda:

Los accesos rápidos:



Editor de Código:


Primeros Pasos:
El primer paso sera conectar nuestra placa Arduino a la computadora mediante el puerto USB.
Recordemos que la placa debe ser reconocida por el sistema operativo y debemos contar con los drivers del BridgeUSB, se supone que si instalamos Arduino IDE (no el portable), debe instalar los drivers básicos como Atmega y FTDI, hay otra variantes como MCP2200, CH340G, PL2303, etc..., Si nuestro Sistema Operativo no reconoce el BridgeUSB debemos descargar el driver del mismo y luego instalarlo en la PC, luego reiniciamos la PC y volvemos a conectar el Arduino.


Aqui podremos ver que se ha reconocido la placa Arduino UNO en el COM1 de la PC.
Una vez que el sistema operativo lo reconoce, podremos buscarlo dentro del entorno ArduinoIDE.


Luego de seleccionar el puerto vamos a seleccionar el tipo de placa, que como vimos antes en administrador de dispositivos, es un Arduino UNO, pero tenemos distintas opciones disponibles.


Una vez que tenemos nuestro entorno configurado podremos comenzar a codificar en nuestro editor de código fuente.
Como vimos en la imagen de los Accesos Rápidos, podremos presionar la tilde de verificación para saber que nuestro código fuente no tiene errores y una vez que nos aseguramos, podemos presionar la flecha que apunta hacia la derecha para Subir el código en la placa de desarrollo Arduino y quedara listo para utilizarlo.

Medición de señales simétricas con ADC

A menudo encontramos algún proyecto o la necesidad de medir una señal simétrica, como podría ser una señal senoidal o simplemente la corriente o tensión alterna en un circuito.
Después de haber realizado en otros post el método para rectificar de forma precisa una señal con corrección de cuadratura y demás, estoy analizando una manera diferente pero mas sencilla.
Esto no es nada nuevo, simplemente sabemos que el ADC de un microcontrolador no tiene la posibilidad de tomar muestras negativas de una señal, entonces una manera sencilla seria montar la señal simétrica en una continua, es decir, si tenemos una señal senoidal simétrica de 2Vpp (+/-1Vp) podríamos montarla en una continua de 2.5V y ahora esta señal tendría un máximo de 3.5Vp y un mínimo de 1.5Vp, de esta forma ya no tenemos valores negativos.



Como podremos ver en el siguiente oscilosgrama tenemos dos señales, la primera (amarilla) es la señal sin tratar, donde su gnd se encuentra en el punto medio, esta señal es de 10Vp, es decir 20Vpp, y con GND en el centro tendremos -10Vp GND +10Vp, esto no nos sirve para nuestro ADC, pero en la señal de abajo (azul) tenemos la señal senoidal simétrica que ha sido montada en una continua de 2.5V (la linea azul es GND, podemos ver como se ha elevado del GND), esta señal es de menor valor de amplitud porque se ha atenuado con un circuito resistivo para el ejemplo.

La fuente de señal V1, es nuestro generador senoidal que nos proporciona 10Vp y 50Hz.
Luego tendremos el divisor resistivo conformado con R1 y R2, en este caso divide por 11 veces, las resistencias R3 y R4 se utilizan para dividir la tensión de 5V en dos partes iguales, es decir tendremos 2.5V en su punto central, esta tensión sera la que sumaremos a la alterna de entrada, aquí montamos la alterna en los 2.5V.
El capacitor C1 proporciona una rama de baja impedancia para la señal alterna a GND.
El valor puede oscilar entre 1uF y 10uF.

En el caso de medir la tensión de linea (220Vac, 120Vac, 110Vac, etc...) lo ideal es aislar el sistema, pero en este caso no quedan muchas opciones, ya que la alterna que montaremos en la continua no puede tener la misma masa que la continua ya que sino no podría montarse, si miramos el siguiente circuito, se ha utilizado un transformador como aislación galvánica y también como reductor, podríamos usar un transformador de 220Vac a 9Vac por ejemplo, y luego atenuar el valor con resistencias, hay que tener en cuenta que el valor pico no debe pasar los 2V porque esto sumado a los 2.5V daría 4.5V y el máximo es 5V (aunque podemos poner protección en el ADC).


Bueno hasta ahora todo esta bien pero debemos modificar el programa en el microcontrolador, ya que como recordamos anteriormente, he mostrado como medir una señal TrueRMS en base a una formula de la raíz del promedio cuadrado de las muestras. 


Recordando esta formula, lo que hacemos es tomar medir con el ADC cada un determinado tiempo, cada valor del ADC lo elevamos al cuadrado y lo sumamos con el siguiente, una vez que tenemos todos los valores sumados, dividimos esa suma por la cantidad de valores o muestras tomadas, y a ese valor le aplicamos la raíz cuadrada.

En este circuito tenemos que tener en cuenta los 2.5V donde montamos la alterna, para ello vamos a sumar este valor a cada uno de los valores medidos y luego seguiremos calculando el valor eficaz de la misma forma.


El valor Vdc sera los 2.5V, que podríamos ponerlo como variable en el programa y podría ser otro canal ADC midiendo la referencia de forma dinámica para que se auto ajuste y siempre nos de un valor preciso.

Antes de entrar en un ejemplo de programación, he realizado algunos cálculos en la hoja de cálculos:

En este primer gráfico podremos ver el la forma de onda que responde a las columnas de datos para un ciclo completo.


La formula en la planilla será: =RAIZ((C5^2+C6^2+C7^2+C8^2+C9^2+C10^2+C11^2+C12^2+C13^2+C14^2+C15^2+C16^2+C17^2)/13)

Como podremos ver, en esta formula estamos tomando cada valor, elevándolo al cuadrado, sumándolo con el siguiente y a toda esa formula la dividimos por la cantidad de muestras que en este caso son 13, luego aplicamos la raíz cuadrada y nos da como resultado una Vrms de 0.733, claramente debería dar 0.707, pero sucede que son pocas muestras y esto mejora con la cantidad de muestras.

En cambio si implementamos la nueva formula con el offset de 2.5V quedara:


La formula en la planilla será: =RAIZ((((C22-2,5)^2)+((C23-2,5)^2)+((C24-2,5)^2)+((C25-2,5)^2)+((C26-2,5)^2)+((C27-2,5)^2)+((C28-2,5)^2)+((C29-2,5)^2)+((C30-2,5)^2)+((C31-2,5)^2)+((C32-2,5)^2)+((C33-2,5)^2)+((C34-2,5)^2))/13)

Como podremos ver, en esta formula estamos tomando cada valor restando el offset de 2.5V, elevándolo al cuadrado, sumándolo con el siguiente y a toda esa formula la dividimos por la cantidad de muestras que en este caso son 13, luego aplicamos la raíz cuadrada y nos da como resultado una Vrms de 0.733, al igual que la formula original nos da el mismo valor, por ende sera la que vamos a utilizar en nuestro algoritmo en el MCU.

En el programa realizaremos el mismo algoritmo de siempre pero agregaremos los 2.5V en las lineas 23 y 27, directamente en el valor de lectura del ADC, simplemente es ese el cambio.

  1. #include <16F883.h>
  2. #device adc=10
  3. #use delay(int=4000000)
  4. #define LCD_ENABLE_PIN  PIN_B2
  5. #define LCD_RS_PIN      PIN_B0
  6. #define LCD_RW_PIN      PIN_B1
  7. #define LCD_DATA4       PIN_B4
  8. #define LCD_DATA5       PIN_B5
  9. #define LCD_DATA6       PIN_B6
  10. #define LCD_DATA7       PIN_B7
  11. #include <LCD.C>
  12. #include <math.h>
  13. void main(){
  14.    setup_adc_ports(sAN0|sAN1|VSS_VDD);
  15.    setup_adc(ADC_CLOCK_DIV_2);
  16.    int16 i, adcZ=0;
  17.    float adc1=0, valorMax1=0, adc2=0, valorMax2=0;
  18.    float tension, corriente, potencia;
  19.    lcd_init();
  20.    while(true){
  21.       do{
  22.          set_adc_channel(0);
  23.          adcZ=read_adc()-512;
  24.          delay_us(20);
  25.       }while(adcZ<10);
  26.       for(i=0;i<300;i++){
  27.          set_adc_channel(0);
  28.          adc1=(read_adc()*5.0/1023.0)-2.5;
  29.          delay_us(33);
  30.          valorMax1=adc1*adc1+valorMax1;
  31.          set_adc_channel(1);
  32.          adc2=(read_adc()*5.0/1023.0)-2.5;
  33.          delay_us(33);
  34.          valorMax2=adc2*adc2+valorMax2;
  35.       }  
  36.       tension=sqrt(valorMax1/300);
  37.       corriente=sqrt(valorMax2/300);
  38.       potencia=tension*corriente;
  39.       lcd_gotoxy(1,1);
  40.       printf(lcd_putc,"RMS     W:%1.3f ",potencia);
  41.       lcd_gotoxy(1,2);
  42.       printf(lcd_putc,"V:%1.3f A:%1.3f ",tension, corriente);
  43.       valorMax1=0;
  44.       valorMax2=0;
  45.    }
  46. }

Podemos ver que se ha ingresado dos señales iguales midiendo 1Vp y haciendo una fuente de señal capacitiva, se hace evidente la variación de fase de corriente en función a la tensión.
En el circuito podemos ver el capacitor de 50nF y en el oscilograma podemos ver la fase de ambas señales.