Embedded peripheral set — GSM+GPRS networking module (GA6-B)

Directory

module introduction

Pay attention to the WeChat public account–Star Aid Studio Send keywords (GA6-B)

Precautions for use

Transplanted and used (there is no transplanted code in the data code, you need to transplant it yourself)

1. Serial configuration

esp8266.h

esp8266.c

2. Write the function code of GA6-B

GA6-B.h

GA6-B.c

3. Modification of key parameters

4. Main function reference

If you need a complete template routine, please consult the blogger

Module introduction

GA6-B Mini is a small networking module with a built-in TCP/IP protocol stack, which can connect to the Internet and communicate with external devices through serial ports. It is widely used in smart home, Internet of Things, smart agriculture, remote control and other fields. GA6-B Mini is small and light, easy to integrate and use, and has the advantages of fast transmission rate, good stability, and low power consumption. GA6-B Mini also provides supporting development tools and SDK, which is convenient for users to carry out secondary development and customized design. Compared to the GA6-B, the GA6-B Mini is smaller and has more simplified functions, but still retains high performance and reliability. It is suitable for various scenarios, such as smart home, vehicle-mounted devices, sensors, etc., allowing you to control devices anytime and anywhere to realize a smart life. In short, GA6-B Mini is a small, portable, high-performance WiFi module with flexible and diverse expansion interfaces and rich development tools. It is widely used in the field of IoT and is an ideal choice for IoT application development and customized design.

Follow the WeChat public account–Star Aid Studio and send keywords (GA6-B)

Precautions for use

1. The module supports 2g/3g/4g cards. There is one that needs special attention. If the module needs to send text messages or connect to the Internet, you need to use a China Mobile phone card. Other operators are not very good. I personally tested it.

2. You can judge whether the module is available by the light on the module. Observe the green indicator light on the module. If it flashes quickly, then the registration is not successful. If it is off for 0.5 seconds and it is on for 2 seconds, it is obvious that the time of being on is longer than that of being off. , so long to determine the success of the registration.

3. There may be many unstable problems when the VCC voltage of the module is lower than 5v, so please ensure that the voltage is sufficient for 5V before use, but I also encountered a rated voltage of about 5.2-5.3V to power the module during use. It will automatically restart all the time, and it will also pull down the MCU to restart together. The only solution is to lower the voltage. The rated voltage is preferably between 4.9-5.1V, and the module runs most stably.

Transplanted and used (there is no transplanted code in the data code, you need to transplant it yourself)

1. Serial port configuration

First of all, we need to configure our serial port. This module can be configured with a baud rate of 115200. Here I use serial port 3. You can also modify the serial port by yourself. The main configuration code is as follows (compatible with ESP8266)

esp8266.h

#ifndef _ESP8266_H_
#define _ESP8266_H_
/*------------------------------------------------ -*/
/* */
/* Header file to operate Wifi function */
/* */
/*------------------------------------------------ -*/
#include "git.h"
// MCU header file
#include "stm32f10x.h"

#define REV_OK 0 // Receive completion flag
#define REV_WAIT 1 // Receive incomplete flag

void ESP8266_Init(void);
void Usart3_Init(unsigned int baud);
void ESP8266_Clear(void);

void ESP8266_SendData(unsigned char *data, unsigned short len);

unsigned char *ESP8266_GetIPD(unsigned short timeOut);
void Usart3_SendString(unsigned char *str, unsigned short len);

_Bool ESP8266_SendCmd(char *cmd, char *res, u16 time);
_Bool ESP8266_WaitRecive(void);

#endif

esp8266.c

// network device driver
#include "esp8266.h"
#include "onenet.h"
// hardware driver
#include "delay.h"
#include "usart.h"
// C library
#include <string.h>
#include <stdio.h>

unsigned char esp8266_buf[256];
unsigned short esp8266_cnt = 0, esp8266_cntPre = 0;

//================================================== ==========
// Function name: ESP8266_Clear
//
// Function function: clear the cache
//
// Entry parameters: none
//
// return parameter: none
//
//\tillustrate:
//================================================== ==========
void ESP8266_Clear(void)
{

memset(esp8266_buf, 0, sizeof(esp8266_buf));
esp8266_cnt = 0;
}

//================================================== ==========
// Function name: ESP8266_WaitRecive
//
// Function function: Wait for the receiving to complete
//
// Entry parameters: None
//
// Return parameter: REV_OK-Receive completed REV_WAIT-Receive timeout not completed
//
// Explanation: Circular call to detect whether the reception is complete
//================================================== ==========
_Bool ESP8266_WaitRecive(void)
{

if (esp8266_cnt == 0) // If the receiving count is 0, it means that there is no receiving data, so jump out directly and end the function
return REV_WAIT;

if (esp8266_cnt == esp8266_cntPre) // If the last value is the same as this time, it means the reception is complete
{
esp8266_cnt = 0; // clear receive count

return REV_OK; // return receive completion flag
}

esp8266_cntPre = esp8266_cnt; // set to be the same

return REV_WAIT; // return receive incomplete flag
}

//================================================== ==========
// Function name: ESP8266_SendCmd
//
// Function function: send command
//
// Entry parameter: cmd: command
// res: the return instruction that needs to be checked
//
// Return parameters: 0-success 1-failure
//
//\tillustrate:
//================================================== ==========
_Bool ESP8266_SendCmd(char *cmd, char *res, u16 time)
{
Usart3_SendString((unsigned char *)cmd, strlen((const char *)cmd));

while (time--)
{
if (ESP8266_WaitRecive() == REV_OK) // if received data
{
// printf("%s\\
", esp8266_buf);
if (strstr((const char *)esp8266_buf, res) != NULL) // if keywords are retrieved
{
ESP8266_Clear(); // Clear cache

return 0;
}
}

delay_ms(10);
}

return 1;
}

//================================================== ==========
// Function name: ESP8266_SendData
//
// Function function: send data
//
// Entry parameters: data: data
// len: length
//
// return parameter: none
//
//\tillustrate:
//================================================== ==========
void ESP8266_SendData(unsigned char *data, unsigned short len)
{
char cmdBuf[32];

ESP8266_Clear(); // Clear the receive buffer
sprintf(cmdBuf, "AT + CIPSEND=%d\r\\
", len); // send command
if (!ESP8266_SendCmd(cmdBuf, ">", 200)) // can send data when receiving '>'
{
}
Usart3_SendString(data, len); // Send device connection request data
}

//================================================== ==========
// Function name: ESP8266_GetIPD
//
// Function function: Get the data returned by the platform
//
// Entry parameter: waiting time (multiplied by 10ms)
//
// Return parameter: the original data returned by the platform
//
// Note: The formats returned by different network devices are different, and need to be debugged
// For example, the return format of ESP8266 is " + IPD,x:yyy" x represents the data length, yyy is the data content
//================================================== ==========
unsigned char *ESP8266_GetIPD(unsigned short timeOut)
{
// char *ptrIPD = NULL;
do
{
if (ESP8266_WaitRecive() == REV_OK) // if receiving is complete
{
return (unsigned char *)(esp8266_buf);
}

delay_ms(5); // delay waiting
} while (timeOut--);

return NULL; // The timeout has not been found yet, return a null pointer
}

//================================================== ==========
// Function name: ESP8266_Init
//
// Function function: Initialize ESP8266
//
// Entry parameters: none
//
// return parameter: none
//
//\tillustrate:
//================================================== ==========
void ESP8266_Init(void)
{
char str[125];
delay_ms(250);

delay_ms(250);
// GPIO_WriteBit(GPIOB, GPIO_Pin_6, Bit_SET);
// delay_ms(500);

ESP8266_Clear();

printf("AT\r\\
");
while (ESP8266_SendCmd("AT\r\\
\r", "OK", 200))
delay_ms(300);

printf("CWMODE\r\\
");
while (ESP8266_SendCmd("AT + CWMODE=1\r\\
", "OK", 200))
delay_ms(300);

printf("AT+CWDHCP\r\\
");
while (ESP8266_SendCmd("AT + CWDHCP=1,1\r\\
", "OK", 200))
delay_ms(300);

printf("CWJAP\r\\
");
memset(str, 0, sizeof(str));
sprintf(str, "AT + CWJAP="%s","%s"\r\\
", SSID, PASS);
while (ESP8266_SendCmd(str, "GOT IP", 200))
delay_ms(300);

printf("CIPSTART\r\\
");
memset(str, 0, sizeof(str));
sprintf(str, "AT + CIPSTART="TCP","%s",%d\r\\
", ServerIP, ServerPort);
while (ESP8266_SendCmd(str, "CONNECT", 200))
delay_ms(500);
printf("ESP8266 Init OK\r\\
");
}

/*
***************************************************** ***********
* Function name: Usart3_Init
*
* Function function: serial port 3 initialization
*
* Entry parameters: baud: set baud rate
*
* Return parameter: None
*
* Description: TX-PB10 RX-PB11
***************************************************** ***********
*/
void Usart3_Init(unsigned int baud)
{

GPIO_InitTypeDef gpio_initstruct;
USART_InitTypeDef usart_initstruct;
NVIC_InitTypeDef nvic_initstruct;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);

// PA2 TXD
gpio_initstruct.GPIO_Mode = GPIO_Mode_AF_PP;
gpio_initstruct.GPIO_Pin = GPIO_Pin_10;
gpio_initstruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, & gpio_initstruct);

// PA3 RXD
gpio_initstruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
gpio_initstruct.GPIO_Pin = GPIO_Pin_11;
gpio_initstruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, & gpio_initstruct);

usart_initstruct.USART_BaudRate = baud;
usart_initstruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // No hardware flow control
usart_initstruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // receive and send
usart_initstruct.USART_Parity = USART_Parity_No; // no parity
usart_initstruct.USART_StopBits = USART_StopBits_1; // 1 stop bit
usart_initstruct.USART_WordLength = USART_WordLength_8b; // 8 data bits
USART_Init(USART3, & usart_initstruct);

USART_Cmd(USART3, ENABLE); // enable serial port

USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); // Enable receive interrupt

nvic_initstruct.NVIC_IRQChannel = USART3_IRQn;
nvic_initstruct.NVIC_IRQChannelCmd = ENABLE;
nvic_initstruct.NVIC_IRQChannelPreemptionPriority = 1;
nvic_initstruct.NVIC_IRQChannelSubPriority = 1;
NVIC_Init( &nvic_initstruct);
}

//================================================== ==========
// Function name: USART2_IRQHandler
//
// Function function: serial port 2 send and receive interrupt
//
// Entry parameters: None
//
// return parameter: None
//
//\tillustrate:
//================================================== ==========
void USART3_IRQHandler(void)
{

if (USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) // receive interrupt
{
if (esp8266_cnt >= sizeof(esp8266_buf))
esp8266_cnt = 0; // Prevent the serial port from being maxed out
esp8266_buf[esp8266_cnt++] = USART3->DR;

USART_ClearFlag(USART3, USART_FLAG_RXNE);
}
}

/*
***************************************************** ***********
* Function name: Usart_SendString
*
* Function function: Serial port data sending
*
* Entry parameters: USARTx: serial port group
* str: the data to send
* len: data length
*
* Return parameter: None
*
*\tillustrate:
***************************************************** ***********
*/
void Usart3_SendString(unsigned char *str, unsigned short len)
{

unsigned short count = 0;
// printf("%s\\
", str);
for (; count < len; count ++ )
{
USART_SendData(USART3, *str + + ); // send data
while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET)
; // wait for send to complete
}
}

2.GA6-B function code writing

1. After configuring the serial port, we need to start writing the main code of our networking module, which mainly includes two parts of networking and sending text messages. First, I will share with you a website that can convert strings into PUDs.

Website link for converting text messages http://smstools3.kekekasvi.com/topic.php?id=288

2. Just enter your own relevant information, click Convert to get the conversion information below, we need to use it if we send Chinese text messages

3. Our sample code is as follows, you can selectively copy, it will be useful to you, here we directly modify the link code of ESP8266, the cloud platform we connect to is still onenet, because we are involved in data processing It is the cJSON library, so the required cJSON code can be downloaded from the official website by yourself (of course, if you don’t want to use cJSON, you can directly modify this processing part). The main code is as follows

GA6-B.h

#ifndef __GA6_H_
#define __GA6_H_

// MCU header file
#include "stm32f10x.h"
#include "git.h"
#include "cjson.h"
#include "string.h"
#include <stdio.h>
// device status code
#define COMMUNITE_ERROR -1
#define NO_SIM_CARD_ERROR -2
#define SIM_CARD_NO_REG_ERROR -3
#define CALL_ERROR -4
#define AT_CPMS_ERROR -5
#define AT_CMGF_ERROR -6
#define AT_CSCS_ERROR -7
#define AT_CMGS_ERROR -8
#define END_CHAR_ERROR -9
#define AT_CGATT_ERROR -11
#define AT_CGACT_ERROR -12
#define AT_CIPSTART_ERROR -13
#define AT_CIPSEND_ERROR -14
#define AT_CIPMUX_ERROR -15
#define AT_CIPQSEND_ERROR -16
#define AT_CSTT_ERROR -17
#define AT_CIICR_ERROR -18
#define AT_CGATT1_ERROR -50
#define EAT0_ERROR -51

// initialization
void GA6_B_Init(void);
// send message
void GA6_SendData(unsigned char *data, unsigned short len);
// send command
_Bool GAB_SendCmd(char *cmd, char *res, u16 time);
// send text message
int GA6_Send_GMS(U8 cmd);
// parse json data
mySta massage_parse_json(char *message);
// save to flash
void sace_flash_phone(U8 cmd);
// Read data saved in flash
void Load_Data(void);
#endif

GA6-B.c

// network equipment
#include "esp8266.h"
#include "led.h"
// protocol file
#include "GA6_B.h"
#include "mqttkit.h"
#include "delay.h"
// hardware driver
#include "usart.h"
#include "flash.h"
// C library
#include <string.h>
#include <stdio.h>

extern Device_Satte_Typedef device_state_init; // device state
extern unsigned char esp8266_buf[256];

//================================================== ==========
// Function function: use GA6 to send a message
//================================================== ==========
void GA6_SendData(unsigned char *data, unsigned short len)
{
ESP8266_Clear(); // Clear the receive buffer
Usart3_SendString(data, len); // Send device connection request data
}
//================================================== ==========
// Function function: send instructions to GA6
//================================================== ==========
_Bool GAB_SendCmd(char *cmd, char *res, u16 time)
{
char str[256];
sprintf(str, "%s\r\\
", cmd);

Usart3_SendString((unsigned char *)str, strlen((const char *)str));

while (time--)
{
if (ESP8266_WaitRecive() == REV_OK) // if received data
{
// printf("%s\\
", esp8266_buf);
if (strstr((const char *)esp8266_buf, res) != NULL) // if keywords are retrieved
{
ESP8266_Clear(); // Clear cache
return 0;
}
}
delay_ms(10);
}
return 1;
}
//================================================== ==========
// Function function: Initialize GA6-8
//================================================== ==========
void GA6_B_Init(void)
{
char str[125];
delay_ms(250);

ESP8266_Clear();

printf("Test whether the communication is successful... ...\r\\
"); // Serial port output information
State_TOGGLE;
while (GAB_SendCmd("AT", "OK", 200))
delay_ms(300);

printf("Query whether the card is plugged in... ...\r\\
"); // Serial port output information
State_TOGGLE;
memset(str, 0, sizeof(str));
sprintf(str, "AT + CPIN?");
while (GAB_SendCmd(str, "READY", 200))
delay_ms(300);

printf("Turn off the echo function... ...\r\\
"); // Serial port output information
State_TOGGLE;
memset(str, 0, sizeof(str));
sprintf(str, "ATE0");
while (GAB_SendCmd(str, "OK", 200))
delay_ms(300);

printf("Please wait for the transparent transmission to be set... ...\r\\
"); // Serial port output information
State_TOGGLE;
memset(str, 0, sizeof(str));
sprintf(str, "AT + CIPMODE=1");
while (GAB_SendCmd(str, "OK", 200))
delay_ms(300);

printf("connect to server\r\\
");
State_TOGGLE;
memset(str, 0, sizeof(str));
sprintf(str, "AT + CIPSTART="TCP","%s",%d", ServerIP, ServerPort);
while (GAB_SendCmd(str, "CONNECT", 200))
delay_ms(300);
State_TOGGLE;
printf("GA6_B OK\r\\
");
// Sys_Restart();//Software reset
}

//================================================== ==========
// Function function: send SMS
//================================================== ==========
// PDU conversion refer to this webpage: http://smstools3.kekekasvi.com/topic.php?id=288
// Note: (1) Keep the SMS center number blank, that is, do not fill it in. (2) Add + 86 to the recipient's number, for example: + 8615815555555 (3) Select 16 for the number of characters (4) Do not copy more spaces in the content of the PDU message
char *AT_CMGS1 = "AT + CMGS=37"; // Used to store AT + CMGS=XX command, XX value should refer to the converted result value on the web page
// Equipment abnormal alarm, please pay attention!
//char *pdu_content1 = "0011000D91685188833199F80008FF168BBE59075F025E3862A58B66FF0C8BF751736CE8FF01";
char *pdu_content1 = "0011000D91689179140610F20008FF168BBE59075F025E3862A58B66FF0C8BF751736CE8FF01";
char *AT_CMGS2 = "AT + CMGS=47"; // Used to store AT + CMGS=XX command, XX value should refer to the converted result value on the web page
// The old man has left the service area, please pay attention!!
char *pdu_content2 = "0011100D91685188833199F80008002080014EBA5DF279BB5F00670D52A1533A002C8BF791CD70B951736CE800210021";

int GA6_Send_GMS(U8 cmd)
{
char str[2];
char end_char[2];

end_char[0] = 0x1A;
end_char[1] = '\0';
// exit connection mode
// GAB_SendCmd(" + + + ", NULL, 250);
printf("Set the storage location, do not judge the return value\r\\
");
State_TOGGLE;
while (GAB_SendCmd("AT + CPMS="SM","ME","SM"", "OK", 200) )
delay_ms(300);
printf("configured as PDU mode\r\\
");
State_TOGGLE;
while (GAB_SendCmd("AT + CMGF=0", "OK", 200))
delay_ms(300);

switch (cmd)
{
case 1:
//printf("The elderly need help, please pay attention!!\r\\
");
//sprintf(str, "AT + CMGS=%d", device_state_init.CMGS1_NUM);
while (GAB_SendCmd(AT_CMGS1, ">", 200))
delay_ms(300);
break;
case 2:
//printf("The old man has left the service area, please pay attention!!\r\\
");
//sprintf(str, "AT + CMGS=%d", device_state_init.CMGS2_NUM);
while (GAB_SendCmd(AT_CMGS2, ">", 200))
delay_ms(300);
break;
}

switch (cmd)
{
case 1:
// The elderly need help, please pay attention!!
printf("%d %s\\
", device_state_init.CMGS2_NUM, pdu_content1);
GA6_SendData((unsigned char *)pdu_content1, strlen((const char *)pdu_content1));
break;
case 2:
// The old man has left the service area, please pay attention!!
printf("%d %s\\
", device_state_init.CMGS2_NUM, pdu_content2);
GA6_SendData((unsigned char *)pdu_content2, strlen((const char *)pdu_content2));
break;
}
printf("OK\\
");
while (GAB_SendCmd(end_char, "OK", 300))
delay_ms(300);

return 1;
}
// parse json data
mySta massage_parse_json(char *message)
{

cJSON *cjson_test = NULL; // detect json format
cJSON *cjson_data = NULL; // data
const char *massage;
// define the data type
u8 cjson_cmd; // command, direction

/* Parse the entire JSO data */
cjson_test = cJSON_Parse(message);
if (cjson_test == NULL)
{
// parsing failed
printf("parse fail.\\
");
return MY_FAIL;
}

/* Extract JSON data (key-value pairs) according to the name in turn */
cjson_cmd = cJSON_GetObjectItem(cjson_test, "cmd")->valueint;
/* parse nested json data */
cjson_data = cJSON_GetObjectItem(cjson_test, "data");

switch (cjson_cmd)
{

case 0x01: // message package
device_state_init.APP = 2;
device_state_init.Drug1 = cJSON_GetObjectItem(cjson_data, "drug1")->valueint;
device_state_init.Drug2 = cJSON_GetObjectItem(cjson_data, "drug2")->valueint;
device_state_init.Drug3 = cJSON_GetObjectItem(cjson_data, "drug3")->valueint;
device_state_init.Drug4 = cJSON_GetObjectItem(cjson_data, "drug4")->valueint;
device_state_init.Drug5 = cJSON_GetObjectItem(cjson_data, "drug5")->valueint;
device_state_init.Drug6 = cJSON_GetObjectItem(cjson_data, "drug6")->valueint;
W_Test();
break;
case 0x02: // data packet
device_state_init.APP = 3;

break;
case 0x03: // data packet
device_state_init.APP = 4;

break;
case 0x04: // message package
device_state_init.APP = 2;
device_state_init.CMGS1_NUM = cJSON_GetObjectItem(cjson_data, "ATCMGS")->valueint;
memset(pdu_content1, 0, strlen(pdu_content1)); // Clear
massage = cJSON_GetObjectItem(cjson_data, "pduContent")->valuestring;
if (massage != NULL)
{
printf("mag:%s\\
", massage);
pdu_content1 = (char *)massage;
// printf("%d %s\\
", device_state_init.CMGS1_NUM, pdu_content1);
device_state_init.CSM_OK = 1;
return MY_SUCCESSFUL;
}
break;
default:
break;
}

/* Clear all the data of the JSON object (the entire linked list) */
cJSON_Delete(cjson_test);

return MY_SUCCESSFUL;
}
// save to flash
void sace_flash_phone(U8 cmd)
{
switch (cmd)
{
case 1:

break;
case 2:

break;
default:
break;
}
}
// Read data saved in flash
void Load_Data(void)
{


if (device_state_init.CMGS1_NUM == 0)
{
device_state_init.CMGS1_NUM = 0;
}


if (device_state_init.CMGS2_NUM == 0)
{
device_state_init.CMGS2_NUM = 0;
}

if (pdu_content1 == NULL)
{
pdu_content1 = "0";
}

if (pdu_content2 == NULL)
{
pdu_content2 = "0";
}
printf("%d %s\\
", device_state_init.CMGS1_NUM, pdu_content1);
printf("%d %s\\
", device_state_init.CMGS2_NUM, pdu_content2);
// If it is the last time, you need to judge whether to subtract 1 here according to the time of the recorded treatment to avoid cheating
}

3. Modification of key parameters

1. To modify the text message information, you only need to replace the key information in the text message part with the data converted from our web page.

2. Server address

You only need to put in the ip and port number of the server, and the address of onenet is as follows

4. Main function reference

1. Just refer to our function function by itself

If you need a complete template routine, please consult the blogger

END