martes, 2 de octubre de 2012

GPS - Monitor de señal. Arduino

GPS - Monitor de señal.
Arduino
xsetaseta@gmail.com


Después de realizar un monitor de GPS con un PC, me dispongo a realizar un monitor con un arduino.
Teniendo toda la información de mi anterior programa http://seta43.duckdns.org/gps.html la realización en el arduino me a resultado muy fácil.
Además de procesar los datos del GPS los manda por la línea serie al ordenador a 38400bps.
Se conecta un LCD al arduino y se utiliza la librería LiquidCrystal.h .He utilizado la conexión estándar de 4bits según viene en la librería.
  The circuit:
 * LCD RS pin to digital pin 12
 * LCD Enable pin to digital pin 11
 * LCD D4 pin to digital pin 5
 * LCD D5 pin to digital pin 4
 * LCD D6 pin to digital pin 3
 * LCD D7 pin to digital pin 2
 * LCD R/W pin to ground
 * 10K resistor:
 * ends to +5V and ground
 * wiper to LCD VO pin (pin 3)



Esquema con el programa fritzing.



Montaje realizado y funcionando.
Video  funcionando http://www.youtube.com/watch?v=uIa1Pc7ilTw&feature=plcp

Salida de gps con señales TTL.

Programa para el arduino.
/*
xsetaseta@gmail.com
 seta comunicaciones
 
 */

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

char VARI[100];
int contador;
boolean stringComplete = false;
//char hora[10];
byte pantalla;

struct DATOSGPS{
char cadena[16];
};
struct DATOSGPS datosgps[22];

void split (char separador)
{
 int x,xx,y,z;
z=sizeof(VARI);
y=0; 
xx=0;
for(x=0;x<z;x++)
 {
datosgps[y].cadena[xx]=VARI[x];
if(VARI[x]==0) break;
if( separador==VARI[x])
 {
 datosgps[y].cadena[xx]=0;
 xx=0;
 y++;
 }
 else
 {
 xx++;
 }
 }
}


void insert(int n,char caracter)
{
 int x;
x=sizeof(VARI);
for(;x>n;x--)
{
VARI[x]=VARI[x-1];
}
VARI[x]=caracter;
}

void setup() {
  // initialize both serial ports:
  lcd.begin(16, 2);
  Serial.begin(38400);
}


void serialEvent()
{
  while (Serial.available())
  {
    char inChar = (char)Serial.read();
    VARI[contador]=inChar;  
    if (inChar == '\n')
        {
          stringComplete = true;
          VARI[contador]=0;
        } 
    contador++;   
  }
}

void loop() {
 if (stringComplete)
    {
      WriteComand();
    }
}

void WriteComand()
{
  if(!strncmp(VARI,"$GPGGA",6))
      {
        Serial.print("OK->");
        Serial.println(VARI);

      split(',');
    if(pantalla==0)
     {
       pantalla=1;
       lcd.clear();
//Hora      
       strcpy(VARI,datosgps[1].cadena);
       insert(2,':');
       insert(5,':');
       VARI[8]=0;
       Serial.println(VARI);
       lcd.setCursor(0, 0);
       lcd.print(VARI);
       
         
      if(datosgps[6].cadena[0]!='0')
  {
            lcd.setCursor(0, 1);
       lcd.print("");
  }
else
  {
    lcd.setCursor(0, 1);
       lcd.print(" ");
  }    

     }
     else
     {      
      pantalla=0; 
      lcd.clear();
      strcpy(VARI,datosgps[2].cadena);
      insert(2,' ');
      Serial.print(VARI);
      lcd.setCursor(0, 0);
      lcd.print(VARI);
      
      strcpy(VARI,datosgps[3].cadena);
      Serial.println(VARI);
      lcd.setCursor(10, 0);
      lcd.print(VARI);
      
      strcpy(VARI,datosgps[4].cadena);
      insert(3,' ');
      Serial.print(VARI);
      lcd.setCursor(0, 1);
      lcd.print(VARI);
      
      strcpy(VARI,datosgps[5].cadena);
      Serial.println(VARI);
      lcd.setCursor(11, 1);
      lcd.print(VARI);
      }
     }
  contador=0;
  stringComplete = false;
      
}


Un saludo.
Juan Galaz

jueves, 13 de septiembre de 2012

GPS - Monitor de señal. SDL y Gambas

GPS - Monitor de señal.
SDL y Gambas

Siempre he querido hacer algún montaje con gps, y ahora en este articulo me pongo manos a la obra.
Dispongo de un modulo gps modelo HOLUX M-1200, que se enlaza al móvil mediante Bluetooth, funcionando a las mil maravillas.
El Holux dispone de otro tipo de comunicaciones, modo serie, utiliza los cables del usb (D- y D+) como señales serie funcionando a: Baud rate : 38400 bps Data bit : 8 Parity : N Stop bit : 1.
Las señales funciona en niveles de CMOS Level, por lo cual podemos utilizar multitud de montajes o aparatos que trabajan con esas señales.
Puedes comprar por internet cables adaptadores (GR230-A2)- (GR230-A1).
También puedes utilizar adaptadores de mis anteriores circuitos. terser.html
En mi caso voy a utilizar un antiguo cable de un teléfono móvil que adapta USB-SerieTTL.

USB-SerieTTL


Usando un adaptador Bluetooth

Los programas realizados leen los datos transmitidos por el gps. Cuando encuentra la línea que empieza por $GPGGA  la captura y trata los datos segun la norma NMEA.
GGA —Global Positioning System Fixed Data




El primer programa realizado está hecho en Gambas una especie de Visual Basic para Linux, es fácil de hacerlo debido a su IDE y su apariencia es limpia.

Programa en Gambas
En el programa se selecciona el tipo de conexión ya sea mediante usb o serie, y con solo dar al botón start empieza a recibir datos del gps. En este programa no tiene registro de datos, es solo visualización.

El segundo programa está realizado mediante la librería SDL, es una librería para realizar juegos pero se puede utilizar para distintos propósitos.


Funcionamiento en Linux
Programa Linux
Funcionamiento en Windows
Programa Windows
En este programa realizado mediante la librería SDL el interfaz serie hay que ponerlo como argumento del programa. Si no ponemos argumento, el valor por defecto del interfaz de comunicaciones es /dev/ttyUSB0 para Linux y COM4 para Windows.
He incorporado un registro de datos que se almacenan en el fichero gpsreg.txt donde se almacena las coordenada y la fecha.

Lo que me satisface más, es el poder compilar para las dos plataformas, Linux o Windows, con solo cambiar la directiva YesWindows 0 por #define YesWindows 1 .
Como he dicho en el anterior trabajo, la programación se ha realizado en Linux  con el IDE Anjuta, y en Dev-C++ bajo Windows.


Un saludo.
Juan Galaz

Bibliografía:

http://www.muchotrasto.com/gps.php

NMEAReferenceManual.pdf

lunes, 25 de junio de 2012

Arduino Control de 12 salidas y 6 entradas analógicas

Página principal

Arduino
Control de 12 salidas y 6 entradas analógicas
 mediante rs232
Librería SDL
xsetaseta@gmail.com

Esta es la continuación de mi anterior trabajo Arduino ,Control de salidas mediante rs232 .
En el PC se ha realizado un programa mediante la librería SDL donde se muestra el estado de 6 entradas analógicas  con un piloto verde y el valor en voltios, y 12 salidas digitales.
Como lenguaje he utilizado el C, hubiese sido mas fácil hacerlo en Visual Basic en Windows y en Gambas bajo Linux, pero mi meta era hacerlo multiplataforma y utilizar el mismo código para ambas plataformas.
Para mandar las ordenes al arduino se puede utilizar la consola del programador de arduino o cualquier otro programa de comunicaciones como por ejemplo CuteCom o minicom en  Linux.
Para pedir el valor del pin analógico 0 se realiza mediante la orden IANA0, y la placa arduino devuelve ANA0=valor, siendo un valor entre 0 y 1023. El valor 1023 corresponde a el valor de Vcc, alrededor de 5V. El programa en el PC lo transforma a voltios reales medidos. Existe variación en el valor de Vcc dependiendo si se alimenta a través del USB o a través de un alimentación externa. Esta diferencia origina una diferencia en el valor medido. Para solucionar este problema he puesto la posibilidad de seleccionar el tipo de alimentación.
Para activar el pin Digital13 se manda al arduino la orden 1Dig13, entonces el arduino pone el pin Digital13 a 5V. Si recibe la orden 0Dig13 el arduino pone la salida Digital13 a 0V.



Programa en el PC funcionando.

PROGRAMA , fuentes y programas compilados para Windows y Linux.

Lo que me satisface más, es el poder compilar para las dos plataformas, Linux o Windows, con solo cambiar la directiva YesWindows 0 por #define YesWindows 1 .
Como he dicho en el anterior trabajo, la programación se ha realizado en Linux  con el IDE Anjuta, y en Dev-C++ bajo Windows.


Un saludo.
Juan Galaz

lunes, 18 de junio de 2012

Página principal

Arduino
Control de entradas mediante rs232
Librería SDL
xsetaseta@gmail.com

Esta es la continuación de mi anterior trabajo Arduino ,Control de salidas mediante rs232 .
Ahora mi pretensión es hacer un monitor de las 18 entradas del arduino, mandado la información mediante conexión serie rs232 al PC. En el PC se ha realizado un programa mediante la librería SDL donde se muestra el estado de cada entrada  con un piloto verde.
Como lenguaje he utilizado el C, hubiese sido mas fácil hacerlo en Visual Basic en Windows y en Gambas bajo Linux, pero mi meta era hacerlo multiplataforma y utilizar el mismo código para ambas plataformas.

El funcionamiento del programa en la parte de arduino es la siguiente:
Cuando se quiere leer el puerto PORTB del micro, se manda una orden desde el PC "IPORTB" al arduino mediante la conexión rs232. En el arduino se procesa esta orden devolviendo el valor del puerto como "PORTB=valor" donde valor es el número leído en el PORTB. Funciona como un cliente-servidor, uno pide y el otro contesta. Existe otro modo llamado "AUTO"  que transmite los valores de los tres puerto cada segundo. Este modo se activa o desactiva mediante la orden AUTO y NOAUTO.
Para mandar las ordenes al arduino se puede utilizar la consola del programador de arduino o cualquier otro programa de comunicaciones como por ejemplo CuteCom o minicom en  Linux.

  if(!strcmp(entrada,"IPORTB"))
      {
       Serial.print("PORTB=");
       Serial.println(PINB);
       goto salir1;
      }
     
    if(!strcmp(entrada,"IPORTC"))
      {
       Serial.print("PORTC=");
       Serial.println(PINC);  
       goto salir1;
      }
    if(!strcmp(entrada,"IPORTD"))
      {
        Serial.print("PORTD=");   
        Serial.println(PIND);   
       goto salir1;
      }

Ejemplo de una parte del programa del arduino.

En la parte del PC como se ha dicho antes se realizó el programa mediante la librería multiplataforma SDL. La monitorización de las entradas se realizan mediante luces verdes en forma de led que se encienden o se apagan dependiendo del estado de las 18 entradas de el arduino. También he querido añadir un pequeño sonido cuando se detecta un cambio en cualquiera de las entradas.
He añadido 3 velocidades de lectura de los puertos 1 Segundo, 0,5 Segundos y 0,3 Segundos. Este es el retardo máximo entre el cambio de estado de una entrada y su representación en la pantalla del PC.
El programa admite el argumento del puerto de comunicaciones. En caso de no poner ningún argumento, asume en Linux  "/dev/ttyUSB0"  y en Windows "COM3" .
Para manejar el puerto bajo Windows he visitado www.mcbtec.com  donde existe un buen tutorial.


El programa funcionando.

Programa


Lo que me satisface más, es el poder compilar para las dos plataformas, Linux o Windows, con solo cambiar la directiva YesWindows 0 por #define YesWindows 1 .
Como he dicho en el anterior trabajo, la programación se ha realizado en Linux  con el IDE Anjuta, y en Dev-C++ bajo Windows.

Antes de nada he de pedir perdón por la forma de programar que tengo, un poco desordenada y poco optimizada en algunos casos. También he probado formatear el código fuente mediante programas al efecto, pero el resultado no me satisfacía demasiado.



Un saludo.
Juan Galaz

domingo, 10 de junio de 2012

Arduino Control de salidas mediante rs232 Librería SDL

Página principal

Arduino
Control de salidas mediante rs232
Librería SDL
xsetaseta@gmail.com

Mi primer motivo para este trabajo era aprender la librería multiplataforma libSDL. Es una librería que se hizo mayormente para juegos, pero se puede emplear para otros muchos trabajos, y yo la he empleado para gobernar las salidas de arduino mediante el interfaz serie. En total se manejan 18 salidas digitales, en las cuales si se quiere se puede manejar mediante relés o optoacopladores tensiones de 220V, ver  http://seta43.duckdns.org/ar_ir.html para mas detalles.
El programa de arduino consiste un que se lee constantemente el puerto serie. Cuando se recibe una orden "1Dig13" el arduino interpreta que tiene que poner a 5V la salida de arduino Digital13. Si recibe la orden "0Dig13" el arduino pone la salida Digital13 a 0V.
Para mandar las ordenes al arduino se puede utilizar la consola del programador de arduino o cualquier otro programa de comunicaciones como por ejemplo CuteCom o minicom en  Linux.

/*
  SETA43
  xsetaseta@gmail.com
  31/05/2012

*/

char entrada[100];
//char VARI[100];
int contador;
boolean stringComplete = false; 

void setup() {
  // initialize serial:
  Serial.begin(9600);
  for(contador=3;contador<=19;contador++)  pinMode(contador, OUTPUT);
  contador=0;
}

void loop() {
  if (stringComplete)
    {
    if(!strcmp(entrada,"0An0"))digitalWrite(14, LOW);
    if(!strcmp(entrada,"1An0"))digitalWrite(14, HIGH);
   
    if(!strcmp(entrada,"0An1"))digitalWrite(15, LOW);
    if(!strcmp(entrada,"1An1"))digitalWrite(15, HIGH);
   
    if(!strcmp(entrada,"0An2"))digitalWrite(16, LOW);
    if(!strcmp(entrada,"1An2"))digitalWrite(16, HIGH);
   
    if(!strcmp(entrada,"0An3"))digitalWrite(17, LOW);
    if(!strcmp(entrada,"1An3"))digitalWrite(17, HIGH);
   
    if(!strcmp(entrada,"0An4"))digitalWrite(18, LOW);
    if(!strcmp(entrada,"1An4"))digitalWrite(18, HIGH);
   
    if(!strcmp(entrada,"0An5"))digitalWrite(19, LOW);
    if(!strcmp(entrada,"1An5"))digitalWrite(19, HIGH);
   
   
   
    if(!strcmp(entrada,"0Dig13"))digitalWrite(13, LOW);
    if(!strcmp(entrada,"1Dig13"))digitalWrite(13, HIGH);
   
    if(!strcmp(entrada,"0Dig12"))digitalWrite(12, LOW);
    if(!strcmp(entrada,"1Dig12"))digitalWrite(12, HIGH);
   
    if(!strcmp(entrada,"0Dig11"))digitalWrite(11, LOW);
    if(!strcmp(entrada,"1Dig11"))digitalWrite(11, HIGH);
   
    if(!strcmp(entrada,"0Dig10"))digitalWrite(10, LOW);
    if(!strcmp(entrada,"1Dig10"))digitalWrite(10, HIGH);
   
    if(!strcmp(entrada,"0Dig9"))digitalWrite(9, LOW);
    if(!strcmp(entrada,"1Dig9"))digitalWrite(9, HIGH);
   
    if(!strcmp(entrada,"0Dig8"))digitalWrite(8, LOW);
    if(!strcmp(entrada,"1Dig8"))digitalWrite(8, HIGH);
   
    if(!strcmp(entrada,"0Dig7"))digitalWrite(7, LOW);
    if(!strcmp(entrada,"1Dig7"))digitalWrite(7, HIGH);
   
    if(!strcmp(entrada,"0Dig6"))digitalWrite(6, LOW);
    if(!strcmp(entrada,"1Dig6"))digitalWrite(6, HIGH);
   
    if(!strcmp(entrada,"0Dig5"))digitalWrite(5, LOW);
    if(!strcmp(entrada,"1Dig5"))digitalWrite(5, HIGH);
   
    if(!strcmp(entrada,"0Dig4"))digitalWrite(4, LOW);
    if(!strcmp(entrada,"1Dig4"))digitalWrite(4, HIGH);
   
    if(!strcmp(entrada,"0Dig3"))digitalWrite(3, LOW);
    if(!strcmp(entrada,"1Dig3"))digitalWrite(3, HIGH);
   
    if(!strcmp(entrada,"0Dig2"))digitalWrite(2, LOW);
    if(!strcmp(entrada,"1Dig2"))digitalWrite(2, HIGH);
   
/*    sprintf(VARI,"-E->%s<-",entrada);
    Serial.print(VARI);   
    Serial.println("-Otra-");
*/   
    Serial.print("->");
    Serial.println(entrada);
    contador=0;
    stringComplete = false;
  }
}


void serialEvent()
{
  while (Serial.available())
  {
    char inChar = (char)Serial.read();
    entrada[contador]=inChar; 
    if (inChar == '\n')
        {
          stringComplete = true;
          entrada[contador]=0;
        }
    contador++;
   
  }
}

Programa en el arduino.

Ahora nos toca hacer el programa en la parte del PC utilizando la librería SDL.
Como lenguaje he utilizado el C, hubiese sido mas fácil hacerlo en Visual Basic en Windows y en Gambas bajo Linux, pero mi meta era hacerlo multiplataforma y utilizar el mismo código para ambas plataformas.
La programación se ha realizado en Linux mediante el Entorno Integrado de Desarrollo Anjuta, es fácil y muy cómodo, existen multitud de tutoriales de como hacerlo.
Para aprender a utilizar la librería SDL he utilizado lo siguiente:

http://www.libsdl.org/
http://www.lazyfoo.net/SDL_tutorials/index.php
http://petra.euitio.uniovi.es/~i1766818/TUTOR/TUTOR10.htm
http://www.losersjuegos.com.ar/referencia/libros/...
http://acuv.webs.upv.es/index.php?option=com_content&view=article&id=199:tutorial-sdl-hagamos-un-qbongq&catid=8:general&Itemid=12

Libros:
*Tutorial de libSDL para la programación de  videojuegos.             Antonio García Alba.
*SDL Library Documentation.
*SDL: Primeros pasos -Programación de Vídeo Juegos- Fco. Javier Pérez Pacheco

He creado botones y luces mediante bitmap, creo que han quedado bien.
Cuando pulsas el un boton en el programa, se manda una orde al arduino mediante la conexión serie y a la vez se enciende una especie de Led rojo. Si se pulsa otra vez el Led se apaga.


El programa funcionando.

Cuanto tuve terminado el programa bajo Linux, inicie la programación en Windows.
He utilizado del entorno de compilación Dev-C++, es bueno y gratis.
Para ponerlo a funcionar con la librería SDL he utilizado el tutorial:
http://www.losersjuegos.com.ar/referencia/articulos/instalar_devcpp
es un tutorial muy bueno para configurarlo.
Tuve algunos problemas con las librerías que no las encontraba, y las tuve que poner a mano.

En el programa he tenido que colocar directivas de compilación #ifdef para separar el código de Linux del de Windows.

Ejemplo:
#define YesWindows 0

#if YesWindows
char MODEMDEVICEdefault[]= "COM3";
#else
char MODEMDEVICEdefault[]= "/dev/ttyUSB0";
#endif



Fichero del programa

El mayor problema que he tenido es la programación del puerto serie, en Linux no me dió ningún problema.
En Windows me resetea la placa android al inicio del programa, después funciona perfectamente, pero no he encontrado ningún motivo aparente, a no ser el driver de convertidor de serie->USB.


El programa admite el argumeto del puerto de comunicaciones. En caso de no poner ningún argumento, asume en Linux  "/dev/ttyUSB0"  y en Windows "COM3" .


Los dos circuitos android funcionando.

En definitiva librería SDL me a gustado mucho y sirve perfectamente como multiplataforma, con solo cambiar en mi caso #define YesWindows 0 por #define YesWindows 1 el programa se compila en ambas plataformas.

Un saludo.
Juan Galaz

jueves, 24 de mayo de 2012

Mini emisor de FM

Página principal

Viejos montajes
Mini emisor de FM
xsetaseta@gmail.com

Frases célebres. "Como ha cambiado el futuro" ...María 7 años, mi hija.

Allá el siglo pasado, sobre 1992.....
El que no haya hecho un mini emisor de FM que tire la primera piedra.
Está realizado en torno a dos transistores, uno como oscilador de AF y otro como amplificador de micro.
Como debía en todo momento saber que el emisor funcionaba, coloque un par de CI del tipo CMOS que consumen poco, de tal forma que emitían un pequeño pitido cada 65 segundos, es una especie de baliza.
Todo esto estaba alimentado a través de una batería de 2,48V. La autonomía no era demasiada, pero mas que suficiente para el cometido empleado.
El conjunto estaba metido en una pequeña caja, de la cual sobresalía un cable que hacia la función de antena.
La estabilidad de la frecuencia era buena, salvo cuando la batería empezaba a estar baja.
El alcance es de unos cientos de metros, dependiendo de los obstáculos.


Esquema de micro emisor.



El circuito montado en su caja.


Pistas del circuito impreso.


Un Saludo.
SETA43


Juan Galaz

miércoles, 16 de mayo de 2012

Frecuencímetro y medidor de capacidad Prescaler 1.3GHz

Página principal

Frecuencímetro y medidor de capacidad
Prescaler 1.3GHz
  16f628
Frequency_counter - capacity meter
Programación en C y Ensamblador
xsetaseta@gmail.com

Con esto se termina la serie de artículos relativo a  medidores de frecuencia y capacidad.
Para terminar pongo dos entradas al frecuencímetro, una de alta sensibilidad y otra con un prescaler que alcanza 1.3GHz.
Como prescaler he utilizado el circuito integrado U664, es un divisor de 64. En el esquema figura U893BSE, es un integrado compatible con el.



Esquema del circuito.


Distribución de componentes en el circuito impreso.
Circuito impreso Archivo


Midiendo la frecuencia de un cristal de 32768 HZ, es el standar en cristales para relojes.


Midiendo la frecuencia de un cristal de 12MHz.


Midiendo la frecuencia de transmisión de un WALKIE TALKIE mediante 3 espiras colocadas cerca de la antena.


Midiendo la capacidad de un condensador de 47pF.

El que quiera ponerlo en una caja deberá colocar un conmutador entre los 3 tipos de entrada, TTL, Alta sensibilidad 100 ohmios, prescaler 1.3GHZ, medidor de capacidad. Esto lo dejo al gusto de cada uno.

Sigo manteniendo las dos líneas de programación, en C y ASM, teniendo algunas diferencias.
Para cambiar de escala debemos que mantener el pulsador apretado hasta que nos muestre en el LCD "Cambiando escala ",
C ASM
0-65500 Hz 0-16MHz  1S
0-655 KHz 0-16MHz  0.1S
0-6.5 MHZ 0-65MHZ  0.4S
0-65 MHz 1.3GHz Prescaler
1.3GHz Prescaler Medidor C 
Medidor C
Ejemplo: 32768 Hz Ejemplo:  0. 000.032.768 Hz
frecapCx.hex frecapAx.hex
Entre los dos tipos, yo me decanto por el hecho con la rutina en ensamblador (ASM) es mucho mas precisa.
Hubiese sido aún mas preciso utilizando un cristal de 16MHz, pero como el primer montaje lo hice con uno de 4 MHZ no he querido cambiar nada, además si se querría tarar perfectamente deberíamos colocar un condensador ajustable en el cristal del microcontrolador. Creo de todas formas que es bastante preciso.

No me pidáis los códigos fuente, hasta dentro de 1 año no los libero.
Al que le interese el Chip 16F628 con el programa grabado, lo vendo por 6€ incluido el porte.
Me ha llegado una partida de 16F648 que es de 4k en vez de 2k, pero el programa funciona igualmente.



Como ya ha pasado el tiempo, pongo a disposición los códigos fuente.
Programa en C.
Programa en C con código ensamblador.


Saludos.
SETA43

Juan Galaz