[Aporte] Comunicacion GPRS

Hola,

En este post, lo que vamos a ver es como realizar una comunicación GPRS utilizando el modem de Telit el GL865 quad, utilizando un microcontrolador LPC1114 que utiliza como procesador un ARM CORTEX M0, en esta instancia sea creado una librería necesaria para manipular el modem GL865.

GL865.jpg


Características del Modem:

*Soporta protocolos GSM\GPRS stack 3GPP
*Soporta frecuencias GSM\GPRS 850/900/1800/1900 Mhz
*En el PCB contiene un Conector para antena de 3.5 mm
*En el PCB contiene ya un socket para la SIM


Principal Idea de Comunicación GPRS:

GL8652.jpg


Como se ve en la imagen de arriba, el procedimiento para recibir datos de nuestro modulo al PC, se requiere los siguientes pasos:

*Haber Configurado el GL865 con el APN, USER y PASSWORD.
*Haber Configurado el GL865 con la IP y PORT del HOST (en este caso la IP es la publica de nuestro Modem y el PUERTO)
*Realizar un Nateo de nuestra IP local (la computadora que va a recibir los datos) en el Modem o Router.
*Realizar el Algoritmo en algún lenguaje que se encarge de recibir los datos en IP y PORT asignado en el modem GL865.

El APN es el acceso a la red que es necesaria para la conexion a la internet, algunas APN requieren usuario y contraseña.

La librería que se ha realizado para manejar el Modem GL865 en el Microcontrolador es la que se muestra en la imagen siguiente:

GL8653.jpg


Nosotros solo requerimos introducir los parametros Socket, APN, USER, PASS, HOST(IP y PORT),
para después llamar la función 'Connect' para que realice una rutina de envío de comandos AT.
Si el Modem se ha conectado a la red y al HOST entonces solo es cuestión de estar revisando la conexión antes de enviar los datos.

El diagrama en general de como es la conexión es el siguiente:

GL8654.jpg


Código:
#include	<lpc11xx.h>
#include	"GL865.h"
#include	"SetClock48Mhz.h"

/*Variables*/

uint8_t timeout=0;

/* Struct for the New Nework */

GL865Nework Mynework;

/*Main Function*/


int main(void){
	
	/*Set to 48Mhz*/
	
	SetClockTo48Mhz();
	
	/*Set Serial by Software to Debug*/
	
	SetSoftUART(SoftUARTBaudRate);
	
	/*Set Serial by Hardware to GL865*/
	
	SetUartTo(HardUARTBaudRate);
	
	/*Set Nework & Host & Init Pin of Reset*/
	
	Mynework.Socket=1;
	Mynework.APN="MYAPN";
	Mynework.USER="MYUSER";
	Mynework.PASS="MYPASS";
	Mynework.HOST="MyIP";
	Mynework.PORT="MyPort";
	GL865_Reset_Init;
	
	/*Can it connect?*/
	
	soft_write_string_rom("ModemGL865 is Connecting...\r");
	
	if(!ModemGL865_Connect(Mynework)){
		soft_write_string_rom("ModemGL865 was not Connected to Red!!\r");
		while(1);
	}

	soft_write_string_rom("ModemGL865 Connected to the Host\r");
	
	while(1){
		
		/*Connection is OK?*/
		
		if(!ModemGL865IsConnected(Mynework)){
		
			for(timeout=0;timeout<10;timeout++){
				delay_ms(200);
			}
		
			ModemGL865_write("HOLA MUNDO",10);
			soft_write_string_rom("Data sent = HOLA MUNDO\r");
			
		}else{

			soft_write_string_rom("ModemGL865 Reconnect to the Host\r");
			
			while(!ModemGL865_Connect(Mynework))
				continue;
			
			soft_write_string_rom("ModemGL865 Connected to the Host\r");
			
		}
	}
}

El codigo de python es el siguiente:

Código:
'''
Created on 08/05/2014

@author: jorge
'''
import socket


ip="192.168.1.95"
port=7777

sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sock.bind((ip,port))

print("Connect...",ip,",",port)
while True:
    print("Waiting for data...",ip,",",port)
    data,addr = sock.recvfrom(1024)
    print("Data -> ",data)

Link de Descarga de proyecto:

http://www.mediafire.com/download/f2e9ddcr1ixted6/GL865_GPRS_RFID.zip

100_0947.JPG


Saludos!
 
Yo estuve probando hace poco un método más eficiente para manejar los estados en el SIM900, pero le falta trabajo.

El código principal:

PHP:
// Programa de prueba para visualizar el funcionamiento del módulo SIM900 con la máquina de estados.
// Desarrollo basado en la placa de control TPHC.
// Programador: Moyano Jonathan.
// Versión: 0.1 Revisión: 0.01
// Fecha: mayo de 2014.

// Incluimos los encabezados necesarios.
#include "PlantillaPIC18F46K22.h"
// Incluimos las librerías del modem GSM.
#include "SIM900_SMS.c"

// Recepción de datos del modem GSM.
#int_RDA

void RDA_isr()
{
USART_buffer[USART_nextRec]=fgetc(SIM900);
if(USART_buffer[USART_nextRec]!=0x0A)USART_nextRec++;
if(USART_nextRec==bytes_for_USART_buffer)USART_nextRec=0;
}

// Variables globales.
int8 estado=0x00;
int8 x=0x00;

// Estados de la máquina.
#define ENCENDIDO    0x00
#define RESP         0x01
#define START        0x02
#define ECO_OFF      0x03
#define TEXT_MODE    0x04
#define SIM_MEM      0x05
#define SMS_MODE     0x06

#define CONFIG_OK    0x07
#define CONFIG_ERROR 0x08

#define GSM_DEBUG

// Programa principal.

void main(void){

// Inicialización de puertos y configuraciones primarias.
configurar_parametros();

while(true){

 switch(estado){
        
        case ENCENDIDO:
        
            POWER_ENA_SIM900_OFF  // Apagamos la fuente del SIM900.
            POWERKEY_OFF          // SIM900 -> Apagado.
            delay_ms(5);          // Esperamos 5ms.
            POWER_ENA_SIM900_ON   // Encendemos la fuente del SIM900.
            delay_ms(100);        // Esperamos 100ms.
            POWERKEY_ON           // SIM900 -> Enciende.
            delay_ms(1500);       // Esperamos 1,5 seg.
            POWERKEY_OFF          // PRWKEY=0;
            delay_ms(2000);       // Esperamos 2 segundos hasta establecer conexión con el operador.
            
             // Le indica a la máquina de estados que el módulo fué encendido y
             // que puede proseguir con la comunicación.
             estado=RESP;                              
             // Habilitamos interrupciones.
             enable_interrupts(int_RDA);             
             // Limpiamos el buffer de recepción.
             inicializo_buffer_USART();
             #if defined(GSM_DEBUG)
             fprintf(DEBUG,"SIM900 Encendido !\r\n"); 
             #endif
             break;
             
         case RESP:
              
              fprintf(SIM900,"AT\r\n");                      // CMD: Comando de verificación.             
              delay_ms(200);                                 // Espero 200ms para ver la respuesta al comando.          
              if(respuesta_CMD_SIM900(USART_buffer,"OK",2)){ // Si la respuesta es OK, el comando se confirma.
              estado=START;                                  // Pasa al siguiente estado.
              #if defined(GSM_DEBUG)
              fprintf(DEBUG,"Responde comandos !\r\n"); 
              #endif
              }
                else{                                        // Caso contrario...
                
                #if defined(GSM_DEBUG)
                 fprintf(DEBUG,"Reiniciar !\r\n");           
                 #endif
                  estado=ENCENDIDO;                          // Reinicia el módulo SIM900.
                    
                  // Si tenemos que reiniciar más de 5 veces, hay un error en el hardware.
                   if(x>=0x05){
                    x=0x00; 
                     estado=CONFIG_ERROR; 
                     // Apagamos la fuente del SIM900.
                     POWER_ENA_SIM900_OFF  
                     // SIM900 -> Apagado.
                     POWERKEY_OFF   
                     LED_GSM_OK_OFF                    // Apaga el led que indica que el módulo fue inicializado correctamente.
                     LED_GSM_ERROR_ON                  // Enciende el el led que indica error en la inicialización.
                     #if defined(GSM_DEBUG)
                      fprintf(DEBUG,"Error hardware !\r\n");
                      #endif
                      }
                    x++;
                    
                  }
                  
                   break; 
         
         case START:
              
              // Envío comando para determinar si el módulo está registrado.
              fprintf(SIM900,"AT+CGREG?\r\n"); 
              // Espero 200ms para ver la respuesta al comando.
              delay_ms(200);
              // Si el registro se completa exitosamente, pasa el siguiente estado.
              if(respuesta_CMD_SIM900(USART_buffer,"+CGREG: 0,1",11)){
              estado=ECO_OFF;
              #if defined(GSM_DEBUG)
              fprintf(DEBUG,"Registrado !\r\n"); 
              #endif
              }
                else{
                
                // Caso contrario enviamos un comando de verificación estado = RESP.
                #if defined(GSM_DEBUG)
                 fprintf(DEBUG,"No registrado !\r\n");
                 #endif
                  estado=RESP;}
                   break; 
                   
              case ECO_OFF:
              
              fprintf(SIM900,"ATE0\r\n");                      // CMD: Eco OFF.
              delay_ms(500);                                   // Espero 500ms para ver la respuesta al comando.             
              if(respuesta_CMD_SIM900(USART_buffer,"OK",2)){   // Si la respuesta es OK, el comando se confirma.
              estado=TEXT_MODE;                                // Pasa al siguiente estado.
              #if defined(GSM_DEBUG)
              fprintf(DEBUG,"Eco Off !\r\n"); 
              #endif
              }
                else{
                // Caso contrario enviamos un comando de verificación estado = RESP.
                #if defined(GSM_DEBUG)
                 fprintf(DEBUG,"No responde !\r\n"); 
                 #endif
                  estado=RESP;}
                   break; 
                   
                   
              case TEXT_MODE:
              
              fprintf(SIM900,"AT+CMGF=1\r\n");                 // CMD: Configuramos modo texto.
              delay_ms(500);                                   // Espero 500ms para ver la respuesta al comando.             
              if(respuesta_CMD_SIM900(USART_buffer,"OK",2)){   // Si la respuesta es OK, el comando se confirma.
              estado=SIM_MEM;                                  // Pasa al siguiente estado.
              #if defined(GSM_DEBUG)
              fprintf(DEBUG,"Modo Texto !\r\n"); 
              #endif 
              }
                else{
                // Caso contrario enviamos un comando de verificación estado = RESP.
                 #if defined(GSM_DEBUG)
                 fprintf(DEBUG,"No responde !\r\n"); 
                 #endif 
                  estado=RESP;}
                   break;
                   
              
              case SIM_MEM:
              
              fprintf(SIM900,"AT+CPMS=\"SM\",\"SM\"\r\n");     // CMD: Selecciono la mememoria SIM para recibir y leer SMS.
              delay_ms(500);                                   // Espero 500ms para ver la respuesta al comando.             
              if(respuesta_CMD_SIM900(USART_buffer,"OK",2)){   // Si la respuesta es OK, el comando se confirma.
              estado=SMS_MODE;                                 // Pasa al siguiente estado.
              #if defined(GSM_DEBUG)
              fprintf(DEBUG,"SMS --> SIM --> SMS !\r\n"); 
              #endif
              }
                else{
                // Caso contrario enviamos un comando de verificación estado = RESP.
                 #if defined(GSM_DEBUG)
                 fprintf(DEBUG,"No responde !\r\n"); 
                 #endif
                  estado=RESP;}
                   break;
                   
              
       case SMS_MODE:
              
       fprintf(SIM900,"AT+CNMI=2,1,0,0,0\r\n");         // CMD: Los mensajes de texto, una vez recibidos son enviados a la memoria SIM.
       delay_ms(500);                                   // Espero 500ms para ver la respuesta al comando.             
       if(respuesta_CMD_SIM900(USART_buffer,"OK",2)){   // Si la respuesta es OK, el comando se confirma.
       estado=CONFIG_OK;                                // Pasa al siguiente estado.
       LED_GSM_OK_ON                                    // Enciende el led que indica que el módulo fue inicializado correctamente.
       LED_GSM_ERROR_OFF                                // Apaga el el led que indica error en la inicialización.
       #if defined(GSM_DEBUG)
       fprintf(DEBUG,"SMS recibe/almacena SIM !\r\n"); 
       #endif
       }
        else{
         // Caso contrario enviamos un comando de verificación estado = RESP.
         #if defined(GSM_DEBUG)
          fprintf(DEBUG,"No responde !\r\n"); 
           #endif 
         estado=RESP;}
         break;
               
        }
    
    // Limpiamos el buffer de recepción.
    inicializo_buffer_USART();
}

 }

Librería para el modem:

PHP:
// Librería de funciones para gestionar mensajes de texto.
// Módulo GSM: SIM900.
// Progrmador: Moyano Jonathan.
// Fecha: Mayo de 2014.
// Versión: v1.8 Revisión: Rev 1.8.
// Versión del CCS: v4.140 2014.
// Incluimos librerías necesarias.

#include "string.h"
#include "SIM900_SMS.h"  

// Desarrollo de funciones de usuario.

int8 respuesta_CMD_SIM900(int8 *buffer[],char *cmd,int8 cmd_len){

// Variable local.
short respuesta=0x00;

// Deshabilitamos interrupciones.
disable_interrupts(int_RDA);

ptr=strstr(buffer,cmd);              // Busca el comando OK en el buffer.
    if(strncmp(ptr,cmd,cmd_len)==0)  // Si lo encuentra.. 
       {respuesta=0x01;}             // respuesta válida --> 0x01.     
   else{respuesta=0x00;}             // Si no lo encuentra, respuesta errónea --> 0x00. 
   
// Habilitamos interrupciones.
enable_interrupts(int_RDA);

 return(respuesta);                  // Retornamos con la respusta al comando.

}

Encabezado de la librería del modem:

PHP:
// Librería de funciones para gestionar mensajes de texto.
// Módulo GSM: SIM900.
// Progrmador: Moyano Jonathan.
// Fecha: Mayo de 2014.
// Versión: v1.8 Revisión: Rev 1.8.
// Versión del CCS: v4.140 2014.

// Incluimos librerías necesarias.
#include "stdlib.h"

// Declaramos funciones de usuario.

// Función:   Busca la respuesta deseada del SIM900.
// Parámetro: Comando de respuesta deseado del SIM900.
// Devuelve:  OK -> 0x01 (respuesta deseada) ERROR -> 0x00 (No responde a lo que se solicita)

int8 respuesta_CMD_SIM900(int8 *buffer[],char *cmd,int8 cmd_len);

Encabezado principal:

PHP:
// Plantilla de programación para el microcontrolador PIC18F46K22.
// Programador: Moyano Jonathan.
// Fecha: Agosto de 2013.
// Versión: v0.1 Revisión: 1.0

// Incluimos el header con las definiciones del microcontrolador utilizado.
#include <18F46K22.h> 
// Conversor de 10 bits con justificación a la derecha.
#device ADC=10
// Declaración para trabajar con punteros a constantes.
#device PASS_STRINGS=IN_RAM
// Configuramos velocidad de operación (64Mhz - 16 Mips).
#use delay(clock=64000000) 

// Configuramos los fusibles de programación.

#FUSES NOWDT                    // No utilizamos el perro guardían.
#FUSES FCMEN                    // Monitor de reloj activado.
#FUSES PUT                      // Temporizador de encendido.
#FUSES NOBROWNOUT               // No activamos el reset por bajo voltaje.
#FUSES NOPBADEN                 // Deshabilitamos el módulo conversor ADC del puerto B.
#FUSES PRIMARY_ON               // Oscilador primario, habilitado.
#FUSES HSH                      // Modo de oscilador: Alta potencia, alta velocidad: 16Mhz - 25Mhz.
#FUSES PLLEN                    // PLL habilitado.
#FUSES MCLR                     // Pin Master Clear habilitado.
#FUSES STVREN                   // Si se rebalsa o llena el stack el microcontrolador se resetea.
#FUSES NOLVP                    // No utilizamos bajo voltaje para programación.
#FUSES NOXINST                  // Set de instruccciones ampliado, desactivado.
#FUSES NODEBUG                  // No utilizamos código para debug.
#FUSES NOPROTECT                // Código no protejido contra lecturas.
#FUSES NOCPB                    // Sector de booteo no protejido.
#FUSES NOCPD                    // Sin protección de código en la EEPROM.
#FUSES NOWRT                    // Memoria de programa no protejida contra escrituras.
#FUSES NOWRTC                   // Registros de configuración no protegido contra escritura.
#FUSES NOWRTB                   // Bloque de booteo no protejido contra escritura.
#FUSES NOWRTD                   // Memoria EEPROM no protejida contra escritura.
#FUSES NOEBTR                   // Memoria no protejida contra lectuas de tablas de memoria.
#FUSES NOEBTRB                  // Bloque de booteo no protejido contra lectura de tablas de memoria.


// Declaro funciones utilizadas.

void configurar_parametros(void);    // Configuramos parámetros principales.
void  inicializo_buffer_USART(void); // Borramos el buffer de recepción.
void  inicializo_buffer_AUX(void);   // Borramos el buffer auxiliar.
void make_all_pins_digital(void);    // Inicializa todos los pines como E/S digital.

// Variables utilizadas.

#define bytes_for_USART_buffer 110                  // Tamaño del buffer de la USART [110 bytes].
volatile int8 USART_buffer[bytes_for_USART_buffer]; // Buffer de la USART.
#define bytes_for_USART_AUX 20                      // Tamaño del buffer auxiliar [30 bytes].
volatile int8 USART_AUX[bytes_for_USART_AUX];       // Buffer auxiliar.
volatile int8 USART_nextRec=0;                      // Contador de caracteres recibidos.
int8 i=0x00;                                        // Variable auxiliar.
char *ptr;                                          // Puntero auxiliar.

// Definimos los pines utilizados en las comunicaciones.

#define SIM900_RX  PIN_C7  // SIM900/TX --> PIC18F46K22/RX.
#define SIM900_TX  PIN_C6  // SIM900/RX <-- PIC18F46K22/TX.
#define DEBUG_TX   PIN_B6  // PIC18F46K22/TX --> PC/RX.
#define RS485_TX   PIN_D6  // RS485/TX --> UconnectME Sense/RX.
#define RS485_RX   PIN_D7  // RS485/RX <-- UconnectME Sense/TX.
#define DEBUG_RX   PIN_B7
#define I2C_SDA    PIN_B5
#define I2C_SCL    PIN_B4

#use rs232(baud=9600, xmit=SIM900_TX,rcv=SIM900_RX,errors,stream=SIM900)  // EUSART1 - SIM900.

#use rs232(baud=9600, xmit=RS485_TX,rcv=RS485_RX,errors,stream=RS485)     // EUSART2 - RS485.

#use rs232(baud=9600, xmit=DEBUG_RX,rcv=DEBUG_TX,errors,stream=DEBUG)     // USART1 - DEBUG.

#use i2c(Master, SDA=I2C_SDA, SCL=I2C_SCL)                                // Memoria EEPROM, RTC.

// Definimos los pines de E/S.

#define LED_GSM_OK        PIN_D0
#define LED_GPRS_OK       PIN_C3
#define LED_SD_OK         PIN_D3
#define LED_GSM_ERROR     PIN_D1
#define LED_SD_ERROR      PIN_D2
#define POWERKEY          PIN_C5
#define POWER_SIM900_ENA  PIN_C4

// Macros de E/S.

#define LED_GSM_OK_ON        output_high(LED_GSM_OK);
#define LED_GPRS_OK_ON       output_high(LED_GPRS_OK);
#define LED_SD_OK_ON         output_high(LED_SD_OK);
#define LED_GSM_ERROR_ON     output_high(LED_GSM_ERROR);
#define LED_SD_ERROR_ON      output_high(LED_SD_ERROR);

#define LED_GSM_OK_OFF       output_low(LED_GSM_OK);
#define LED_GPRS_OK_OFF      output_low(LED_GPRS_OK);
#define LED_SD_OK_OFF        output_low(LED_SD_OK);
#define LED_GSM_ERROR_OFF    output_low(LED_GSM_ERROR);
#define LED_SD_ERROR_OFF     output_low(LED_SD_ERROR);
#define POWERKEY_ON          output_high(POWERKEY);
#define POWERKEY_OFF         output_low(POWERKEY);
#define POWER_ENA_SIM900_ON  output_high(POWER_SIM900_ENA);
#define POWER_ENA_SIM900_OFF output_low(POWER_SIM900_ENA);

// Funciones de usuario.

void configurar_parametros(void){

// Configura todos los pines como digitales.
make_all_pins_digital(); 
// Inicializamos el buffer de la UART.
inicializo_buffer_USART();
// Habilitamos las interrupciones globales.
enable_interrupts(GLOBAL);

}

void inicializo_buffer_USART(void){ 

 USART_nextRec=0; // Inicializo el contador de datos entrantes.
  for(i=0; i<=bytes_for_USART_buffer; i++){ // Borro el contenido del buffer de datos.
   USART_buffer[i]='\0';}
   
}

void  inicializo_buffer_AUX(void){

// Borro el contenido del buffer auxiliar.
for(i=0; i<=bytes_for_USART_AUX; i++){ 
   USART_AUX[i]='\0';}

}

void make_all_pins_digital(void) 
{ 

#byte ANSELA = 0xF38 
#byte ANSELB = 0xF39 
#byte ANSELC = 0xF3A 
#byte ANSELD = 0xF3B 
#byte ANSELE = 0xF3C 

ANSELA = 0x00; 
ANSELB = 0x00; 
ANSELC = 0x00; 
ANSELD = 0x00; 
ANSELE = 0x00; 

}
 
Atrás
Arriba