GSM модули в настоящее время находят широкое применение в разнообразных проектах тематики интернета вещей. При этом они гораздо менее зависимы от окружающих условий чем, к примеру, модули Wi-Fi или Zigbee, которые, к тому же, отличаются достаточно высокой стоимостью и малым радиусом действия. При этом GSM модули отличаются высокой надежностью и большой дальностью действия. Конечно, GSM модули не могут передавать большие объемы информации с высокой скоростью, но они отлично подходят для приложений, в который требуется сбор информации от датчиков с небольшими объемами передаваемых данных.
В данной статье мы рассмотрим подключение GSM модуля SIM800C к плате STM32F103C8 (Blue Pill) и передачу/прием с его помощью коротких текстовых сообщений (SMS). Передаваемые и принимаемые SMS будут отображаться на экране ЖК дисплея 16х2. Управлять передачей/приемом SMS мы будем с помощью двух кнопок, подключенных к плате STM32F103C8.
Ранее на нашем сайте мы уже рассматривали ряд проектов с использованием GSM модулей SIM900, SIM900A, SIM800 и т.д. Наиболее популярными из них являются следующие:
- подключение GSM модуля к микроконтроллеру AVR;
- мобильный телефон на основе Arduino и GSM модуля;
- автоматическая система полива растений на основе Arduino;
- передача данных на веб-сервер с использованием Arduino и GPRS/GSM;
- интерактивный автоответчик на Raspberry Pi и GSM модуле SIM800L.
Также на нашем сайте вы можете посмотреть все проекты с использованием GSM модулей.
Необходимые компоненты
- Отладочная плата STM32F103C8 (STM32 Blue Pill) (купить на AliExpress).
- GSM модуль SIM800C (купить на AliExpress).
- ЖК дисплей 16x2 (купить на AliExpress).
- Кнопка – 2 шт.
- Потенциометр 10 кОм (купить на AliExpress).
- Макетная плата.
- Соединительные провода.
Реклама: ООО "АЛИБАБА.КОМ (РУ)" ИНН: 7703380158
Почему мы выбрали GSM модуль SIM800C?
SIM800C – это широко используемый GSM модуль с последовательным интерфейсом, способным работать от напряжения в 3.4V-4.4V. Модуль SIM800C может работать в четырех диапазонах частот – 850/900/1800/1900 МГц и отличается низким энергопотреблением. С его помощью можно совершать голосовые вызовы и передавать/принимать SMS. Управлять работой модуля можно с помощью AT команд. Модуль SIM800C поддерживает одну SIM карту и имеет последовательный порт (контакты TX & RX) с интерфейсом RS232.
Для питания модуля SIM800C используется адаптер постоянного тока на 12V. SIM карта вставляется с обратной стороны модуля. При этом учтите что модуль не имеет поддержки технологии 4G, поэтому не вставляйте в него SIM карту, поддерживающую данную технологию.
Подключение GSM модуля SIM800C к плате STM32F103C8
Распиновка платы STM32F103C8 приведена на следующем рисунке.
Для подключения GSM модуля SIM800C к плате STM32F103C8 мы использовали первый последовательный порт платы (UART), расположенный на ее контактах A9 и A10. Всего плата STM32F103C8 содержит три последовательных порта, они обозначены на представленной схеме синим цветом.
AT команды
Для управления различными функциями GSM модуля (голосовые вызовы, текстовые сообщения и т.д.) могут быть использованы AT команды. Список наиболее часто используемых AT команд представлен на следующем рисунке.
Схема проекта
Схема подключения GSM модуля SIM800C к плате STM32F103C8 (Blue Pill) представлена на следующем рисунке.
Схема соединений между платой STM32F103C8 и GSM модулем SIM800C приведена в следующей таблице.
Плата STM32F103C8 | GSM модуль SIM800C |
PA9 (TX) | RX |
PA10 (RX) | TX |
GND | GND |
Схема соединений между платой STM32F103C8 и ЖК дисплеем 16х2 приведена в следующей таблице.
№ контакта ЖК дисплея | Обозначение контакта ЖК дисплея | Контакт платы STM32 |
1 | Ground (Gnd) | Ground (G) |
2 | VCC | 5V |
3 | VEE | средний контакт потенциометра |
4 | Register Select (RS) | PB11 |
5 | Read/Write (RW) | Ground (G) |
6 | Enable (EN) | PB10 |
7 | Data Bit 0 (DB0) | No Connection (NC) |
8 | Data Bit 1 (DB1) | No Connection (NC) |
9 | Data Bit 2 (DB2) | No Connection (NC) |
10 | Data Bit 3 (DB3) | No Connection (NC) |
11 | Data Bit 4 (DB4) | PB0 |
12 | Data Bit 5 (DB5) | PB1 |
13 | Data Bit 6 (DB6) | PC13 |
14 | Data Bit 7 (DB7) | PC14 |
15 | LED Positive | 5V |
16 | LED Negative | Ground (G) |
Две кнопки с помощью подтягивающих резисторов 10 кОм подключены к контактам PA0 и PA1 платы STM32F103C8. Внешний вид собранной конструкции проекта представлен на следующем рисунке.
Объяснение программы для платы STM32
Полный код программы приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.
Плату STM32F103C8 можно программировать через USB порт, FTDI плату или программатор ST-LINK. В нашем проекте мы будем загружать в нее программу через USB порт.
Первым делом в программе подключим библиотеку для работы с ЖК дисплеем и укажем контакты платы STM32F103C8, к которым подключен ЖК дисплей. Также создадим объект для работы с дисплеем.
1 2 3 |
#include <LiquidCrystal.h> const int rs = PB11, en = PB10, d4 = PB0, d5 = PB1, d6 = PC13, d7 = PC14; LiquidCrystal lcd(rs, en, d4, d5, d6, d7); |
Далее укажем тип ЖК дисплея (16х2) и покажем на его экране приветственное сообщение.
1 2 3 4 |
lcd.begin(16,2); lcd.print("STM32 WITH GSM"); lcd.setCursor(0,1); lcd.print("SIM800C"); |
Установим режим работы для контактов, к которым подключены кнопки, на ввод данных.
1 2 |
pinMode(PA0,INPUT); pinMode(PA1,INPUT); |
Инициализируем 1-й последовательный порт на скорость работы 9600 бод.
1 |
Serial1.begin(9600); |
Также запрограммируем функции для передачи и приема сообщений.
Передача сообщений
Данная функция будет использоваться для передачи SMS на заданный телефонный номер. Для этого на GSM модуль будет подаваться AT команда, переводящая его в текстовый режим.
Для перевода GSM модуля в текстовый режим будет использоваться AT команда AT+CMGF=1.
1 |
Serial1.println("AT+CMGF=1"); //Sets the GSM Module in Text Mode |
После этого с помощью AT команды AT+CMGS будем осуществлять передачу SMS через последовательный порт serial1 с указанием телефонного номера, на который нужно будет передать SMS.
1 |
Serial1.println("AT+CMGS=\"+91XXXXXXXXXX\"\r"); // Replace x with mobile number |
Сообщения будут передаваться с помощью AT команд каждую секунду, после передачи сообщения нам необходимо передавать на GSM модуль ASCII код комбинации клавиш CTRL+Z.
1 2 3 |
delay(1000); Serial1.println("Hi Circuit Digest from GSM Module"); // The SMS text you want to send Serial1.println((char)26);// ASCII code of CTRL+Z |
После этого мы будем отображать на экране ЖК дисплея 16х2 сообщение “SMS sent”.
1 |
lcd.print("SMS SENT"); |
Прием сообщений
В этой функции мы будем принимать текстовые сообщения и отображать их на ЖК дисплее.
1 |
Serial1.println("AT+CNMI=2,2,0,0,0"); |
После приема GSM модулем SMS в его последовательном порту кроме этого самого SMS будет содержаться и другая информация: время, дата и т.д. Поэтому нам необходимо вычленить текст SMS из этого потока данных. Мы будем делать это при помощи подсчета символов двойных кавычек (“) в полученном потоке данных. После 6-го такого символа в принятом потоке данных будет содержаться текст SMS.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
while(1) { if(Serial1.available()) { do { while ( !Serial1.available() ); } while ( '"' != Serial1.read() ); do { while ( !Serial1.available() ); } while ( '"' != Serial1.read() ); do { while ( !Serial1.available() ); } while ( '"' != Serial1.read() ); do { while ( !Serial1.available() ); } while ( '"' != Serial1.read() ); do { while ( !Serial1.available() ); } while ( '"' != Serial1.read() ); do { while ( !Serial1.available() ); } while ( '"' != Serial1.read() ); while ( !Serial1.available() ); receive = Serial1.read(); while ( !Serial1.available() ); receive = Serial1.read(); lcd.clear(); while(1) { while ( !Serial1.available() ); receive = Serial1.read(); if ( receive == '\r' ) break; else lcd.write(receive); } } } |
Тестирование работы проекта
Для передачи SMS в нашем проекте просто нажмите на левую кнопку схемы. SMS отправится на номер, указанный в коде нашей программы.
Для приема текстового сообщения нажмите правую кнопку. В результате этого мы примем SMS и оно отобразится на экране ЖК дисплея.
Более подробно работу проекта вы можете посмотреть на видео, приведенном в конце статьи.
Исходный код программы (скетча)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
#include <LiquidCrystal.h> //библиотека для работы с ЖК дисплеем const int rs = PB11, en = PB10, d4 = PB0, d5 = PB1, d6 = PC13, d7 = PC14; // контакты платы STM32, к которым подключен ЖК дисплей LiquidCrystal lcd(rs, en, d4, d5, d6, d7); int receive = 0; void setup() { lcd.begin(16,2); //устанавливаем ЖК дисплей в режим 16х2 pinMode(PA0,INPUT); //режим работы контактов, к которым подключены кнопки, на ввод данных pinMode(PA1,INPUT); lcd.print("STM32 WITH GSM"); // показываем на дисплее приветственное сообщение lcd.setCursor(0,1); lcd.print("SIM800C"); Serial1.begin(9600); // устанавливаем скорость для обмена данными с GSM модулем delay(1000); lcd.clear(); } void loop() { lcd.clear(); lcd.setCursor(0,0); lcd.print("S to Send sms"); lcd.setCursor(0,1); lcd.print("R to Receive sms"); delay(100); int a = digitalRead(PA0); //считываем состояние кнопки int b = digitalRead(PA1); if (a == 1) // если нажата первая кнопка { SendMessage(); } else if( b == 1) // если нажата вторая кнопка { RecieveMessage(); } } void SendMessage() //функция для передачи сообщения { lcd.clear(); lcd.print("Sending sms"); delay(1000); Serial1.println("AT+CMGF=1"); // переводим GSM модуль в текстовый режим (Text Mode) delay(1000); Serial1.println("AT+CMGS=\"+91XXXXXXXXXX\"\r"); // замените ххх на свой телефонный номер delay(1000); Serial1.println("Hi Circuit Digest from GSM Module"); // текст SMS который вы хотите передать delay(100); Serial1.println((char)26);// ASCII код комбинации клавиш CTRL+Z delay(1000); lcd.clear(); lcd.print("SMS SENT"); delay(1000); } void RecieveMessage() //функция для приема сообщений { lcd.clear(); lcd.print("Receiving sms"); Serial1.println("AT+CNMI=2,2,0,0,0"); // AT Command to recieve a live SMS delay(1000); while(1) { if(Serial1.available()) { do { while ( !Serial1.available() ); } while ( '"' != Serial1.read() ); do { while ( !Serial1.available() ); } while ( '"' != Serial1.read() ); do { while ( !Serial1.available() ); } while ( '"' != Serial1.read() ); do { while ( !Serial1.available() ); } while ( '"' != Serial1.read() ); do { while ( !Serial1.available() ); } while ( '"' != Serial1.read() ); do { while ( !Serial1.available() ); } while ( '"' != Serial1.read() ); while ( !Serial1.available() ); receive = Serial1.read(); while ( !Serial1.available() ); receive = Serial1.read(); lcd.clear(); while(1) { while ( !Serial1.available() ); receive = Serial1.read(); if ( receive == '\r' ) break; else lcd.write(receive); } } } } |
На русском смс модуль посылает?
Ну его сообщения все равно переводятся в коды ASCII, поэтому да, передает
А что в программе от stm32 ? Чистый Wiring
Ну это же проще и удобнее чем писать на специфичном коде для stm32. Для поставленных в этом проекте задач использования Wiring вполне хватает. К тому же Wiring хорошо знаком тем, кто переходит на stm32 с платформы Ардуино
поздравляю вы сделали дорогой пейджер
с симкой
Ну это же обучающий проект, на его основе вы можете сделать более продвинутый функционал для своего реального проекта