This is default featured slide 5 title

Go to Blogger edit html and find these sentences.Now replace these sentences with your own descriptions.

viernes, 1 de septiembre de 2017

GRAFICANDO SEÑAL DEL ADC DE ARDUINO EN PROCESSING PARTE 1

GRAFICANDO SEÑAL DEL ADC DE ARDUINO EN PROCESSING PARTE 1




En este tutorial veremos cómo graficar el voltaje leido por el adc de arduino en processing. Aquí usaremos la comunicación serial para mandar el valor de la conversión a processing para que se pueda graficar.

Aquí el truco consiste en ir leyendo y almacenando los valores en un array cuyo tamaño es igual al ancho de la pantalla creada en processing. Cada vez que llegue un nuevo valor desde arduino a processing iremos eliminando el el valor mas antiguo del array y almancenando en dicha posicion el valor actual. Esto hará que la gráfica se vaya desplazando.

El código en arduino se muestra a continuación:

void setup()
{
Serial.begin(9600);
}

void loop()
{

int valor=analogRead(A0);
Serial.println(valor);

}




El código en processing se muestra a continuación:

///////////////////////////////////////////////////////////
// TALLER DE ARDUINO 2014
// Grafica de una señal de voltaje
//////////////////////////////////////////////////////////
import processing.serial.*;

float adc0; //variable que almacena el valor del adc0 actual
float[] xvals; // arreglo que almacena los valores del adc0 de arduino
float voltaje; //variable que contiene el voltaje actual medido
Serial port; // creamos un objeto serial puerto

void setup()
{
size(400, 400); //frame de 400x400

// la longitud del arreglo sera el ancho del frame
xvals = new float[width];
// creamos una variable font y asignamos un tipo de font
PFont font;
font = loadFont("Arial-Black-30.vlw");
textFont(font); //cargamos el font a nuestro texto
///////////////////////////////////////////////////////

//defininimos parametros para la comunicacion serial
port = new Serial(this, "COM21", 9600);
port.bufferUntil('\n');
////////////////////////////////////////////////////
}


void draw()
{
background(0); //fondo negro
strokeWeight(2);
stroke(0,255,255);


//////////////////////////////////////////////////////////
// deplazamos a la izquierda nuestro arreglo //
// con el objetivo de introducir un nuevo valor al final//
//////////////////////////////////////////////////////////

for(int i=1;i<width;i++)
{
xvals[i-1]=xvals[i];

}
/////////////////////////////////////////////////////////
//graficamos la señal
//////////////////////////////////////////////////////////
for(int i=1;i<width;i++)
{
strokeWeight(5);
stroke(255,0,0);
point(i, height -xvals[i]);//invertimos

}
//nota: recordar que el eje y en processing es invertido
//por ello hay que hacer height-xvals
//////////////////////////////////////////////////////////

//mostramos los voltajes correspondientes a las señales
fill(255,255,0);
textAlign(CENTER);
text(voltaje+" VOLTIOS",200,320);
///////////////////////////////////////////////////////////

}


///////////////////////////////////////////////////////////
//////////////////EVENTO POR SERIAL////
///////////////////////////////////////////////////////////

void serialEvent (Serial port)
{
//leemos los datos hasta encontrar un '\n'
//almacenamos en string cadena
String cadena = port.readStringUntil('\n');

//si la cadena no esta vacia(es decir que recibio datos) entonces
if (cadena!= null)
{
//quitamos los espacios en blanco de la cadena en caso los tenga
cadena = trim(cadena);

float senal=float(cadena);
voltaje = map(senal, 0, 1023, 0, 5);
//mapeamos el valor leido del adc (0-1023) a la escala de nuestro frame
//los valors se mostraran en el ejey "y", asi que debemos escalar respecto a height
adc0 = map(senal, 0, 1023, 0, height);

}
//añadimos los nuevos valores que han llegado al final de arreglo
xvals[width-1]=adc0;

}



Aqui mostramos un video de lo que sería :

jueves, 31 de agosto de 2017

INDICADOR ANALÓGICO CON ARDUINO Y PROCESSING

INDICADOR ANALÓGICO CON ARDUINO Y PROCESSING



En este tutorial veremos como hacer un indicador analógico con arduino y processing. 

El indicador consiste en una aguja que va moviéndose de acuerdo al nivel de tensión que lee el conversor analógico digital de Arduino.

Para generar el movimiento de la aguja tenemos que pensar en coordenadas "R" y "teta" (R es el radio del indicador y teta es el angulo que se desplaza la aguja).

Entonces, lo que debemos hacer es simplemente dibujar una linea recta en processing donde la coordenada inicial sera el centro del indicador analógico (X,Y) y la coordenada final tendrá como como componentes: (X+R*cos(teta),Y+R*sn(teta)).

Haciéndolo de esta manera, la posición de la aguja ira cambiando con respecto al angulo teta. Por esa razon, el valor digital leido por el adc[0-1023 ] tendrá que que ser mapeado para un rango de angulo de [0 a 180 grados].

El código en arduino será el siguiente:


void setup()
{
Serial.begin(9600);
}

void loop()
{

int valor=analogRead(A0);
Serial.println(valor);

}

El código en processing será el siguiente:


//indicador analogico de voltaje
import processing.serial.*;
Serial port; // creamos un objeto serial puerto

float voltaje; //variable que contiene el voltaje actual medido
float angulo; //angulo proporcional al voltaje que se esta midiendo
int x, y; //coordenadas iniciales de la aguja indicadora
int radio; //radio de la aguja indicadora
PImage img; //creamos el objeto imagen que importaremos
PFont font;

void setup()
{
size(340, 400);
img = loadImage("gauge2.png");
font = loadFont("ArialMT-30.vlw");
textFont(font); //cargamos el font a nuestro texto


x = 170;//puntos centrales de la circunferencia
y = 170;
radio = 110; //radio de la circunferencia

///////////////////////////////////////////////////////
//defininimos parametros para la comunicacion serial
port = new Serial(this,"COM21", 9600);
port.bufferUntil('\n');
////////////////////////////////////////////////////

}


void draw()
{

background(0);
stroke(255,0,0);
point(x,y);
image(img,20,20);
//formateando a dos decimales
String volts = nf(voltaje, 2, 2);
println(volts);

line(x,y, x+radio*cos(radians(angulo)), y+radio*-sin(radians(angulo)));
line(x-1,y-1, x+radio*cos(radians(angulo)), y+radio*-sin(radians(angulo)));
line(x-2,y-2, x+radio*cos(radians(angulo)), y+radio*-sin(radians(angulo)));

fill(255,255,0);
textAlign(CENTER);

text(volts+" VOLTIOS",175,370);

delay(30);

}

se puede osbservar en el video:


SISTEMAS MULTITAREA CON MÁQUINAS DE ESTADO

SISTEMAS MULTITAREA CON MÁQUINAS DE ESTADO 

CONTROLADO EN ENCENDIDO/APAGADO DE UN LED CADA 100 ms CON MÁQUINAS DE ESTADO



Recordando el tutorial pasado, debemos definir cada tarea a realizar como una máquina de estados. En este ejemplo solo queremos realizar una única tarea (controlar el encendido/apagado de un led cada 100 ms) por lo tanto programaremos una única máquina de estados. 

La programación de una máquina de estados consiste en usar la estructura de control switch case en la cual los casos posibles para este ejemplo serán solo dos: led encendio o led apagado.

const int ESTADO_LED_1_ENCENDIDO = 1;

const int ESTADO_LED_1_APAGADO = 2;


Debemos recordar también que la máquina irá conmutando entre sus posibles estados (los cuales deben ser definidos desde un inicio). Para realizar la conmutación se hará uso del timer 0 funcionando en modo ctc, el cual provocará una interrupción cada un 1ms. 


Entonces, cada 1ms ocurre una interrupción y eso hará que automáticamente saltemos a la rutina de servicio de interrupcion. Dentro de esa rutina haremos que un contador de valor 100 se decremente cada vez que se ingrese a dicha rutina (lo cual quiere decir que este contador se decrementa cada 1ms y por ello su valor será cero cuando hayan pasado 100ms).

El valor del contador se irá verificando dentro del lazo void loop y servirá como condición para que la maquina de estados conmute de estado. Si el led estaba encendido entonces se apagará y si estaba apagado se encenderá

Aparentemente es mucho código para hacer parpadear un led;sin embargo, a futuro nos trae mas ventajas ya que podremos añadir mas tareas por realizar y estas se ejecutaran de manera independiente (definiendo cada tarea como una máquina de estados distinta). Entonces podriamos por ejemplo generar una melodia con tone mientras un led parpadea a 100ms, otro led parpadea a 200ms, sondeamos un pulsador con debouncing y monitoreamos un sensor con el adc. Ya en el siguiente tutorial veremos cómo incluir mas tareas a nuestro sistema.


el código: 

#define t1 100
volatile unsigned int time1;

//variables para la tarea1
///////////////////////////////////////////////
const int PIN_LED_1 = 13;
const int ESTADO_LED_1_ENCENDIDO = 1;
const int ESTADO_LED_1_APAGADO = 2;
int estadoLed1 = ESTADO_LED_1_ENCENDIDO;


void controlarEstadoLed1();
void encenderled1();
void apagarLed1();
void inicializarLed1();
void controlarEstadoLed1Encendido();
void controlarEstadoLed1Apagado();
void configTimer0();

ISR(TIMER0_COMPA_vect)
{

if(time1>0) --time1;

}



void setup()
{
inicializarLed1();
configTimer0();
}

void loop()
{
controlarEstadoLed1();

}


void configTimer0()
{
cli();//paramos interrupciones

//configurando timer0 para 1ms
TCCR0A = 0;// set entire TCCR0A register to 0
TCCR0B = 0;// same for TCCR0B
TCNT0 = 0;//initialize counter value to 0
// seteamos el registro de comparacion para lograr 1ms
OCR0A = 248;// = (16*10^6) / (2000*64) - 1 (must be <256)
// activamos modo CTC
TCCR0A |= (1 << WGM01);
// Seteamos CS01 y CS00 para usar pre-escalador en 64
TCCR0B |= (1 << CS01) | (1 << CS00);
// activamos interrupcion por comparación exitosa
TIMSK0 |= (1 << OCIE0A);
sei();//activamos interrupcion
}

//funciones definidas para la tarea1
//////////////////////////////////////////////
void controlarEstadoLed1()
{
switch (estadoLed1)
{
case ESTADO_LED_1_ENCENDIDO:
controlarEstadoLed1Encendido();
break;
case ESTADO_LED_1_APAGADO:
controlarEstadoLed1Apagado();
break;
}
}
void controlarEstadoLed1Encendido()
{
if (time1==0)
{
apagarLed1();
time1=t1;
estadoLed1 = ESTADO_LED_1_APAGADO;
}
}

void controlarEstadoLed1Apagado()
{
if (time1==0)
{
encenderLed1();
time1=t1;
estadoLed1 = ESTADO_LED_1_ENCENDIDO;
}
}



void inicializarLed1()
{
pinMode(PIN_LED_1, OUTPUT);
encenderLed1();
}

void encenderLed1()
{
digitalWrite(PIN_LED_1, HIGH);
}
void apagarLed1()
{
digitalWrite(PIN_LED_1, LOW);
}
Podemos realizar la simulación en proteus para confirmar que el led cambia de estado cada 100ms

miércoles, 30 de agosto de 2017

USANDO EL TIMER 0 CON ARDUINO










Como se mencionó en el tutorial pasado, debemos lograr que el procesador conmute entre las tareas cada cierto tiempo, de manera que pueda ir avanzado con cada una de las tareas pendientes. Para hacer conmutación entre las tareas usaremos el timer 0 configurado en modo CTC y con interrupción por comparación exitosa en OCR0A.

jueves, 24 de agosto de 2017

PUNTERO A UNA ESTRUCTURA

PUNTERO A UNA ESTRUCTURA

Podemos usar un puntero para acceder a los datos miembro de una estructura
struct disco disco1;
struct disco *ptr;
ptr=&disco1; 
Un ejemplo se muestra a continuación:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{

struct disco{
char autor[20];
char tituloDisco[20];
float precio;
int numeroDeCanciones;

};

struct disco disco1;
struct disco *ptr;
ptr=&disco1; //puntero a la estructura disco

ptr->precio=20.34;
ptr->numeroDeCanciones=15;

strcpy(ptr->autor,"the beatles");
strcpy(ptr->tituloDisco,"revolver");

printf("el precio del disco es : %.2f\n",ptr->precio);
printf("el numero de canciones es : %d\n",ptr->numeroDeCanciones);
printf("el autor del disco es : %s\n",ptr->autor);
printf("el titulo del disco es : %s\n",ptr->tituloDisco);

system("PAUSE");
return 0;
}

CURSOS PRESENCIALES

CURSOS PRESENCIALES








PROGRAMACIÓN CONCURRENTE CON ARDUINO

PROGRAMACION CONCURRENTE CON ARDUINO



la progrmaacion---

asdmasdmañslmdasd
asldmañsmdñasd

el codigo se observa a continuacion:




#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"

int main(void)
{
// Configuramos el reloj del sistema
SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
// habilitamos uart0 y el puerto A
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
// PA0 rx PA1 tx
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
//configuración: velocidad, paridad,bit de stop
UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));

//mensaje carácter por caracter
UARTCharPut(UART0_BASE, 'I');
UARTCharPut(UART0_BASE, 'N');
UARTCharPut(UART0_BASE, 'G');
UARTCharPut(UART0_BASE, 'R');
UARTCharPut(UART0_BASE, 'E');
UARTCharPut(UART0_BASE, 'S');
UARTCharPut(UART0_BASE, 'A');
UARTCharPut(UART0_BASE, 'R');
UARTCharPut(UART0_BASE, ' ');
UARTCharPut(UART0_BASE, 'T');
UARTCharPut(UART0_BASE, 'E');
UARTCharPut(UART0_BASE, 'X');
UARTCharPut(UART0_BASE, 'T');
UARTCharPut(UART0_BASE, 'O');
UARTCharPut(UART0_BASE, ' ');


while(1)
{
if(UARTCharsAvail(UART0_BASE))
UARTCharPut(UART0_BASE, UARTCharGet(UART0_BASE));
}

}

EL CODIUGO HA TERMINADO