GSM/GPRS модуль SIM300, может применяться в устройствах, где необходима связь на большие расстояния. К примеру, роботом в Москве человек управляет сидя в Краснодаре! Или фермер включает водяной насос на рисовом поле из своего дома, расположенного за несколько километров от поля! Есть несколько вариантов связи с устройством:
Простая связь на основе SMS сообщений:
Включение/выключение устройства при помощи простых SMS команд. Для управления устройством можно использовать любой мобильный телефон.
Охранная/пожарная сигнализация, которая информирует хозяина о чрезвычайной ситуации в доме при помощи SMS.
Связь на основе вызовов:
“Умная” охранная/пожарная сигнализация, которая вызывает полицию или пожарных и сообщает о чрезвычайной ситуации при помощи заранее записанных голосовых сообщений.
Связь с использованием интернета (GPRS):
Пользователь может управлять устройством с любого ПК/планшета/мобильного телефона, подключенного к интернету. К примеру, информационные дисплеи, установленные на трассах, управляются из центральной диспетчерской.
Робот, управляемый через интернет. Такой робот доступен с любого устройства подключенного к интернету из любой точки мира.
Портативные устройства, установленные в транспортных средствах, которые подключаются к интернету с помощью GPRS модуля SIM300 и добавляют текущую позицию (с помощью GPS (Global Position System, Глобальная Система Позиционирования)) на сервер. Эти данные сохраняются с базу данных на сервере вместе с идентификатором автомобиля. Для просмотра маршрута автомобиля можно соединиться с сервером с компьютера при помощи World Wide Web (Всемирной Паутины).
Преимущества использования модуля SIM300
Набор SIM300 Kit является полностью самостоятельным модулем с разъёмом SIM-карты, блоком питания и т.д. Этот модуль может быть легко связан с дешевыми микроконтроллерами AVR/PIC/8051. Связь с микроконтроллером осуществляется через асинхронный последовательный порт. Это основной тип последовательной связи, который аппаратно поддерживается большинством микроконтроллеров. Данные передаются бит за битом и собираются в байты. На высоком уровне это выглядит как простой текстовый поток. Всего потоков два: один от микроконтроллера к SIM300 и другой от SIM300 к микроконтроллеру. Команды передаются как простой текст.
Если вы никогда не использовали последовательную передачу данных и не слышали о ней, то желательно разобраться в её работе и попрактиковаться на более простых примерах.
Связь с модулем SIM300 при помощи AVR UART
Аппаратная часть микроконтроллера, используемая для последовательной связи, называется UART, и мы используем его для связи с модулем SIM300 (Также он может использоваться для связи с другими устройствами, например считывателями RFID, GPS модулями, сканерами отпечатков пальцев и т.д.). UART является очень распространенным способом связи в мире электроники, мы написали для него чистую и простую библиотеку, которую мы применяем во всех своих проектах с использованием UART.
Поскольку байт от SIM300 может прийти на микроконтроллер в любое время, то, что произойдет, если микроконтроллер занят чем-то другим? Чтобы решить эту проблему, мы сделали буферизацию входящих данных, основанную на прерываниях. Буфер находится в оперативной памяти микроконтроллера. У него есть функция, позволяющая определить количество байт в очереди.
Ниже приведены функции библиотеки AVR USART:
void USARTInit(uint16_t ubrrvalue)
Инициализация аппаратной части AVR USART. Значением параметра ubrrvalue устанавливается желаемая скорость передачи данных. По умолчанию скорость передачи данных для SIM300: 9600 бит/сек. Для микроконтроллера AVR работающего на частоте 16 МГц значение ubrrvalue для такой скорости должно быть 103.
char UReadData()
Чтение одного символа из очереди. Если в очереди ничего нет, то ответ 0.
void UWriteData(char data)
Записывает один байт данных на линию Tx, используя функцию UWriteString ().
uint8_t UDataAvailable()
Сообщает количество данных в очереди FIFO.
void UWriteString(char *str)
Записывает строку в Си стиле, оканчивающуюся нуль символом в линию Tx.
Пример 1: UWriteString(«Hello World !»);
Пример 2: char name[]=»Avinash !»; UWriteString(name);
void UReadBuffer(void *buff,uint16_t len)
Копирует содержимое FIFO буфера в память, определенную buff, количество скопированных данных определяется параметром len. Если по UART в FIFO буфер пришло меньше данных, чем надо (в соответствии с параметром len), то оставшееся место будет заполнено нулями.
Примеры:
char gsm_buffer[128];
UReadBuffer(gsm_buffer,16);
Приведенный выше пример будет считывать 16 байт данных (если они есть) из FIFO буфера в переменную gsm_buffer. Обратите внимание, что gsm_buffer выделен массив 128 байт, поскольку позже нам может потребоваться более 16 байт. Таким образом, этот буфер можно будет использовать для чтения до 128 байт в дальнейшем.
Функция, показанная выше, обычно применяется вместе с UDataAvailable ().
while(UDataAvailable()<16)
{
//Do nothing
}
char gsm_buffer[128];
UReadBuffer(gsm_buffer,16);
Фрагмент кода показанный выше, ждет пока в буфере накопится 16 байт данных, а далее считывает их.
void UFlushBuffer()
Отменяет ожидание данных FIFO буфером. Прежде чем отправлять новую команду GSM модулю, сначала отмените ожидание данных FIFO буфером.
Приведенные выше функции используются для отправки и получения текстовых команд от GSM модуля SIM300.
Набор AT команд для SIM300
Теперь, года Вы знакомы с основами библиотеки AVR USART и её использованием для инициализации USART, отправки и получения данных, настало время, чтобы изучить команды модуля SIM300 и как отправлять их и принимать ответы. SIM300 имеет несколько функций: отправка текстового сообщения, звонок и т.д. Каждая из этих функций выполняется после определённой команды, и SIM300 имеет свой набор команд.
Все команды SIM300 начинаются с префикса AT+ и заканчиваются Carriage Return (сокращенно , возврат каретки). ASCII код CR — 0x0D (десятичное 13). Все команды, которые вы отправляете SIM300, будут возвращаться по TX линии SIM300. То есть если вы отправляете команду 7 байт (включая завершающий CR), то вы сразу получите эти 7 байт в буфер по UART. Если вы не получили её, то это значит, что-то не в порядке!
Первая функция, которую мы изучим будет SIM300Cmd(const char *cmd), она выполняет следующие действия:
- Пишет команды, заданные параметром cmd.
- Добавляет CR после команды.
- Ожидает возврата команды, и если она приходит до тайм-аута, она отвечает SIM300_OK (константа, определенная в sim300.h). Если возврата ждали слишком долго, а его не было, она отвечает SIM300_TIMEOUT.
Примечание: Все зависимые функции SIM300 хранятся в файле sim300.c. Образцы и константы хранятся в sim300.h
Работа с SIM300Cmd ()
int8_t SIM300Cmd(const char *cmd)
{
UWriteString(cmd); //Send Command
UWriteData(0x0D); //CR
uint8_t len=strlen(cmd);
len++; //Add 1 for trailing CR added to all commands
uint16_t i=0;
//Wait for echo
while(i < 10*len)
{
if(UDataAvailable() < len)
{
i++;
_delay_ms(10);
continue;
}
else
{
//We got an echo
//Now check it
UReadBuffer(sim300_buffer,len); //Read serial Data
return SIM300_OK;
}
}
return SIM300_TIMEOUT;
}
За командой обычно следует ответ. Форма ответа такая: <CR><LF><response><CR><LF>
LF — Line Feed, его ASCII код 0x0A (10 в десятичной системе)
Таким образом, во время ожидания ответа после отправки команды могут случиться три вещи:
- Ответа нет в течении длительного времени. Вероятной причиной может быть то, что SIM300 не подключен к микроконтроллеру.
- Ответ получен, но не тот, который ожидался. Причиной может быть неисправность последовательной линии, неверно установленная скорость передачи данных или микроконтроллер, работающий с неверной частотой.
- Получен правильный ответ.
К примеру, команда Get Network Registration (Регистрация в сети) выполняется следующим образом: Command String (Команда): «AT+CREG?«
Response (Ответ): +CREG: , OK
Вы видите правильный ответ 20 байт. То есть после отправки команды «AT + CREG?» необходимо ждать получения 20 байт или пока истечет определенное время. Второе условие выполняется во избежание зависания, если SIM300 неисправен. То есть вместо того, чтобы вечно ждать ответа, будет выдана ошибка, если SIM300 отвечает слишком долго (это называется тайм-аут)
Если получен правильного ответа, то мы анализируем переменную для получения информации о регистрации в сети.
В зависимости от текущего состояния регистрации в сети значение может быть: 0 — Не зарегистрирован, сейчас SIM300 не ищет нового оператора для регистрации. 1 — Зарегистрирован в домашней сети. 2 — Не зарегистрирован, сейчас SIM300 ищет нового оператора для регистрации. 3 — В регистрации отказано. 4 — Неизвестно. 5 — Зарегистрирован, роуминг.
Работа с SIM300GetNetStat ()
int8_t SIM300GetNetStat()
{
//Send Command
SIM300Cmd(«AT+CREG?»);
//Now wait for response
uint16_t i=0;
//correct response is 20 byte long
//So wait until we have got 20 bytes
//in buffer.
while(i<10)
{
if(UDataAvailable()<20)
{
i++;
_delay_ms(10);
continue;
}
else
{
//We got a response that is 20 bytes long
//Now check it
UReadBuffer(sim300_buffer,20); //Read serial Data
if(sim300_buffer[11]==’1′)
return SIM300_NW_REGISTERED_HOME;
else if(sim300_buffer[11]==’2′)
return SIM300_NW_SEARCHING;
else if(sim300_buffer[11]==’5′)
return SIM300_NW_REGISTED_ROAMING;
else
return SIM300_NW_ERROR;
}
}
//We waited so long but got no response
//So tell caller that we timed out
return SIM300_TIMEOUT;
}
Точно так же реализована функция: int8_t SIM300IsSIMInserted()
При другом типе ответов мы не знаем заранее точный размер ответа как в приведенной выше команде. К примеру, это команда Get Service Provider Name(Получение названия оператора (провайдера)), где длина имени оператора неизвестна заранее. Это может быть MTS, Beeline и т.п.. Для решения этой проблемы мы пользуемся тем, что перед и после ответа находится CR LF. Таким образом, мы просто записываем в буфер все символы до тех пор, пока мы не встречаем CR, что означает конец ответа.
Для упрощения обработки таких команд, мы сделали функцию
SIM300WaitForResponse (uint16_t timeout)
Эта функция ждет ответа от SIM300 (конец ответа обозначается CR) и сообщает размер ответа, в то время, когда сам ответ копируется в глобальную переменную sim300_buffer [].
Если ответ не получен до тайм-аута, то ответ 0. Время тайм-аута в миллисекундах можно задать параметром timeout. Она не считает запаздывающие LF или последние OK , они остаются в UART FIFO буфере. Потому перед возвратом мы используем команду UFlushBuffer (), чтобы удалить их из буфера.
Работа с SIM300WaitForResponse (uint16_t timeout)
int8_t SIM300WaitForResponse(uint16_t timeout)
{
uint8_t i=0;
uint16_t n=0;
while(1)
{
while (UDataAvailable()==0 && n
Работа с SIM300GetProviderName (char *name) Функция выполняет следующие действия:
Подобным образом реализованы следующие функции:
- uint8_t SIM300GetProviderName(char *name)
- int8_t SIM300GetIMEI(char *emei)
- int8_t SIM300GetManufacturer(char *man_id)
- int8_t SIM300GetModel(char *model)
uint8_t SIM300GetProviderName(char *name)
{
UFlushBuffer();
//Send Command
SIM300Cmd(«AT+CSPN?»);
uint8_t len=SIM300WaitForResponse(1000);
if(len==0)
return SIM300_TIMEOUT;
char *start,*end;
start=strchr(sim300_buffer,'»‘);
start++;
end=strchr(start,'»‘);
*end=’