В этой статье мы рассмотрим проект на основе платы Arduino, в котором мы будем передавать данные на веб-сервер с помощью технологии GPRS. Этот проект относится к проектам интернета вещей (IoT), в котором мы будем использовать для связи с “внешним миром” технологию GPRS, реализованную в GSM модуле SIM900A.
В этом проекте мы будем с помощью буквенно-цифровой панели 4х4 вводить некоторый текст и затем передавать его на сайт SparkFun с использованием Arduino и GPRS. На сайте SparkFun вы потом сможете посмотреть переданный текст из любой точки земного шара где есть сеть интернет. Также в проекте мы использовали ЖК дисплей 16х2 чтобы на нем также отображать передаваемые данные. Также вы можете посмотреть аналогичные проекты на Arduino, рассмотренные на нашем сайте:
- мониторинг влажности и температуры через интернет;
- мониторинг местоположения автомобиля;
- мониторинг сердечного ритма через интернет;
- мониторинг загрязнения воздуха через интернет.
Необходимые компоненты
- Плата Arduino Uno (купить на AliExpress).
- GSM модуль SIM900A (купить на AliExpress).
- SIM карта.
- ЖК дисплей 16х2 (купить на AliExpress).
- 4х4 матричная клавишная панель (купить на AliExpress).
- Макетная плата.
- Соединительные провода.
- Источник питания с напряжением 12 В.
Использование GPRS в GSM модуле
В этом проекте мы использовали обычный GSM модуль с SIM картой для GPRS соединения. Технология GPRS в нашем проекте ответственна за передачу данных на сервер Sparkfun. Ранее на нашем сайте мы уже рассматривали передачу данных на веб-сервер с помощью Arduino и Wi-Fi модуля ESP8266, здесь же мы вместо технологии Wi-Fi применим технологию GPRS. Более подробно все описанные в статье процессы можно посмотреть на видео, приведенном в конце статьи.
GPRS расшифровывается как General Packet Radio Services и переводится как пакетная радиосвязь общего назначения. Данная технология способна обеспечивать выход в сеть интернет и работать со скоростями передачи данных 56-114 кбит/с.
При этом нет необходимости покупать какой то отдельный модуль для работы с GPRS поскольку она реализована в обычном GSM модуле. Для управления GSM модулем мы будем использовать так называемые AT команды. Далее рассмотрены некоторые из этих команд доступные для модуля SIMCOM SIM900A (на самом деле их достаточно много, информацию по ним легко найти в сети интернет), которые нам понадобятся в данном проекте.
Для передачи данных на веб-сервер с помощью технологии GPRS нам, прежде всего, необходимо инициализировать GSM модуль.
Команды для инициализации GSM модуля
1 2 3 4 |
AT : эта команда используется для проверки того отвечает ли GSM модуль или нет AT+CPIN? : эта команда используется для проверки того вставлена ли SIM карта в GSM модуль или нет ATE0 : эта команда отключает эхо, то есть чтобы модуль не повторял в ответ команды, которые мы ему передаем ATE1 : эта команда используется для включения эхо |
Команды для инициализации GPRS интернет соединения
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
AT+CIPSHUT : закрыть TCP порт, что означает прекращение всех соединений AT+CGATT? : проверка имеет ли SIM карта интернет соединение или нет AT+CSTT = "APN","userName","Pass" : соединение с интернет (ex; AT+CSTT="airtelgprs.com","","") AT+CIICR : соединение с беспроводной сетью. Проверяемая SIM карта должна иметь предоплаченный объем данных или положительный баланс AT+CIFSR : получить IP (иногда без этой команды GSM не будет работать поэтому желательно ее использовать) AT+CIPSTART = ”TCP”,”SERVER IP”,”PORT” : эта команда используется для создания TCP соединения с сервером который мы прописываем в поле SERVER IP AT+CIPSEND : эта команда используется для передачи данных на сервер. After input, this command server asks for data. |
После ввода данных мы передаем 26 на сервер. Если все нормально, то данные будут успешно загружены на сервер и SparkFun (сервер в нашем рассматриваемом случае) отвечает что все нормально или произошла ошибка.
Объяснение работы проекта
Процесс передачи данных с помощью технологии GPRS, реализованной в GSM модуле, достаточно прост. В нашем проекте мы будем передавать некоторую строку на сервер, набранную на клавиатуре (клавишной панели). Эта же самая строка будет высвечиваться на экране ЖК дисплея. После этого мы будем нажимать клавишу D/OK чтобы передать введенную строку на сервер. Структурная схема работы проекта изображена на следующем рисунке.
В этом проекте мы использовали алфавитно-цифровую клавишную панель для ввода символов или цифровых значений в Arduino. Более подробно о работе с подобной панелью можно прочитать в этой статье. Клавиша 0/clear запрограммирована для ввода пробела.
Работа схемы
Схема устройства представлена на следующем рисунке.
Для передачи данных на сервер SparkFun мы должны подключить клавишную панель и GSM модуль к плате Arduino, которая будет принимать данные (строку) от клавишной панели и передавать команды на GSM/GPRS модуль. GSM/GPRS модуль используется для подключения к сети интернет и передачи данных на сервер Sparkfun. Контакты GSM модуля Rx и Tx непосредственно подключены к контактам D3 и D2 платы Arduino (земля платы Arduino и земля GSM модуля должны быть соединены друг с другом).
ЖК дисплей 16x2 используется для отображения строк, которые мы будем передавать на сервер, и отображения некоторых статусных сообщений. Его контакты Rs, en, d4, d5, d6 и d7 соединены с контактами 14, 15, 16, 17, 18 и 19 платы Arduino соответственно. Клавишная панель 4x4 используется для ввода строк в Arduino и ее контакты строк R1, R2, R3, R4 непосредственно подключены к контактам 11,10, 9, 8 платы Arduino, а контакты столбцов C1, C2, C3, C4 – к контактам 7, 6, 5, 4 платы Arduino.
Также мы подключили контакт Tx GSM модуля к контакту Tx платы Arduino для целей отладки проекта с помощью монитора последовательной связи (serial monitor).
Исходный код программы
Исходный код программы этого проекта может быть немного сложным для понимания начинающими, но если вы изучите другие аналогичные проекты на нашем сайте, ссылки на которые приведены в начале статьи, то, я думаю, вы сможете понять и код этой программы.
В коде этой программы мы использовали библиотеку для работы с клавишной панелью, с помощью которой мы потом сможем осуществлять ввод с панели и цифр, и букв. То есть каждая клавиша панели у нас получилась многофункциональной и с помощью всего 10 клавиш мы будем вводить все символы алфавита и все цифры.
То есть ли мы нажмем клавишу 2 на панели (ABC2), то на экране ЖК дисплея высветится ‘A’. Если мы нажмем эту клавишу снова, то ‘A’ на экране ЖК дисплея заменится на ‘B’, а если еще раз – то на ‘C’. Если мы подождем некоторое время после нажатия клавиши курсор на экране ЖК дисплея автоматически переместится на следующую позицию. Аналогично и для других клавиш на панели. То есть наша алфавитно-цифровая клавишная панель фактически будет работать как клавиатура на старых кнопочных телефонах.
В программе мы подключили библиотеку Keypad.h и инициализировали массив символов для клавиш.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#include <Keypad.h> // библиотека для подключения клавиатуры (клавишной панели) const byte ROWS = 4; //четыре строки const byte COLS = 4; //четыре столбца int x=0; int y=0; int n=0; int minValue=0; int maxValue=0; char keyPress=0; int keyPressTime=100; String msg=""; char hexaKeys[ROWS][COLS] = { {'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'*','0','#','D'} }; byte rowPins[ROWS] = {11, 10, 9, 8}; //соединения с контактами строк клавиатуры byte colPins[COLS] = {7, 6, 5, 4}; // соединения с контактами столбцов клавиатуры |
Далее мы в программе запрограммировали функцию getkey для ввода символов.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
void getkey(int minValue, int maxValue, char keyPress) { int ch=minValue; int pressed=1; char key=keyPress; lcd.noBlink(); for(int i=0;i<keyPressTime;i++) { if(key==keyPress) { lcd.setCursor(x,y); lcd.print(alpha[ch]); ch++; if(ch>maxValue) ch=minValue; i=0; } .... ..... |
Далее функции void initGSM() и void initGPRS() используются для инициализации GSM модуля и GPRS.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
void initGSM() { connectGSM("AT","OK"); connectGSM("ATE1","OK"); connectGSM("AT+CPIN?","READY"); } void initGPRS() { connectGSM("AT+CIPSHUT","OK"); connectGSM("AT+CGATT=1","OK"); connectGSM("AT+CSTT=\"airtelgprs.com\",\"\",\"\"","OK"); connectGSM("AT+CIICR","OK"); delay(1000); Serial1.println("AT+CIFSR"); delay(1000); } |
Следующая часть кода используется для создания URL и передачи данных на сервер через этот URL.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
else if(key == 'D') { lcd.clear(); lcd.noBlink(); lcd.print("Sending Data"); lcd.setCursor(0,1); lcd.print("To Server"); url="GET /input/"; url+=publicKey; url+="?private_key="; url+=pvtKey; url+="&log="; url+=msg; url+=" HTTP/1.0\r\n\r\n"; String svr=Start+","+ip+","+port; delay(1000); connectGSM(svr,"CONNECT"); delay(1000); int len = url.length(); String str=""; str=SendCmd+len; sendToServer(str); |
После этого мы сможем передавать любые данные на сервер SparkFun при помощи технологии GPRS, чтобы потом можно было просматривать эти данные из любой точки Земли. Процесс создания страницы на SparkFun, где мы будем просматривать данные с помощью сети интернет, подробно показан на видео, приведенном в конце статьи.
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 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
#include <SoftwareSerial.h> // подключаем библиотеку последовательной связи чтобы с ее помощью потом подключать gsm модуль SoftwareSerial Serial1(2, 3); // RX, TX // connect gsm Tx at D2 and Rx at D3 #include<LiquidCrystal.h> // библиотека для работы с ЖК дисплеем LiquidCrystal lcd(14,15,16,17,18,19); // контакты Arduino, к которым подключен ЖК дисплей String pvtKey="wY9DPG5vzpH99KNrNkx2"; // приватный ключ (private key) для передачи данных на sparkfun String publicKey="w5nXxM6rp0tww5YVYg3G"; // публичный ключ (public key) для открытия страницы sparkfun String url=""; String ip="\"data.sparkfun.com\""; // sparkfun server ip or url int port=80; // sparkfun server port String SendCmd="AT+CIPSEND="; // sending number of byte command String Start="AT+CIPSTART=\"TCP\""; // TCPIP start command // строки и переменные //String msg=""; String instr=""; String str_sms=""; String str1=""; int i=0,temp=0; #include <Keypad.h> // библиотека для подключения клавиатуры (клавишной панели) const byte ROWS = 4; // четыре строки const byte COLS = 4; // четыре столбца int x=0; int y=0; int n=0; int minValue=0; int maxValue=0; char keyPress=0; int keyPressTime=100; String msg=""; char hexaKeys[ROWS][COLS] = { {'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'*','0','#','D'} }; byte rowPins[ROWS] = {11, 10, 9, 8}; //connect to the row pinouts of the keypad byte colPins[COLS] = {7, 6, 5, 4}; //connect to the column pinouts of the keypad Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); String alpha="1!@_$%?ABC2DEF3GHI4JKL5MNO6PQRS7TUV8WXYZ9* 0#"; void setup() { Serial1.begin(9600); // инициализация последовательного порта 1 для GSM lcd.begin(16,2); // инициализация ЖК дисплея lcd.print("Sending Data "); lcd.setCursor(0,1); lcd.print("to Server"); delay(2000); lcd.clear(); lcd.print("Circuit Digest"); lcd.setCursor(0,1); lcd.print("Saddam Khan"); delay(2000); lcd.clear(); lcd.print("Initializing GSM"); initGSM(); // инициализация GSM модуля lcd.clear(); lcd.print("Initializing GPRS"); initGPRS(); // инициализация GPRS в GSM модуле lcd.clear(); lcd.print("System Ready"); delay(2000); } void loop() { int n=0; lcd.clear(); lcd.noCursor(); while(1) { lcd.cursor(); char key = customKeypad.getKey(); if(key=='1') getkey(0, 6, key); if(key=='2') getkey(7, 10, key); else if(key=='3') getkey(11, 14, key); else if(key=='4') getkey(15, 18, key); else if(key=='5') getkey(19, 22, key); else if(key=='6') getkey(23, 26, key); else if(key=='7') getkey(27, 31, key); else if(key=='8') getkey(32,35, key); else if(key=='9') getkey(36, 40, key); else if(key=='*') getkey(41, 41, key); else if(key=='0') getkey(42, 43, key); else if(key=='#') getkey(44, 44, key); else if(key == 'C') { x--; lcd.setCursor(x,y); lcd.print(" "); n--; msg[n]=' '; lcd.setCursor(x,y); } else if(key == 'D') { lcd.clear(); lcd.noBlink(); lcd.print("Sending Data"); lcd.setCursor(0,1); lcd.print("To Server"); url="GET /input/"; url+=publicKey; url+="?private_key="; url+=pvtKey; url+="&log="; url+=msg; url+=" HTTP/1.0\r\n\r\n"; String svr=Start+","+ip+","+port; delay(1000); connectGSM(svr,"CONNECT"); delay(1000); int len = url.length(); String str=""; str=SendCmd+len; sendToServer(str); Serial1.print(url); delay(1000); Serial1.write(0x1A); delay(1000); lcd.clear(); lcd_status(); // clearmsg(); n=0; i=0; x=0; y=0; msg=""; } } } void getkey(int minValue, int maxValue, char keyPress) { int ch=minValue; int pressed=1; char key=keyPress; lcd.noBlink(); for(int i=0;i<keyPressTime;i++) { if(key==keyPress) { lcd.setCursor(x,y); lcd.print(alpha[ch]); ch++; if(ch>maxValue) ch=minValue; i=0; } key=customKeypad.getKey(); delay(10); } if(pressed) { x++; msg+=alpha[ch-1]; n++; if(x>15) { x=0; y=1; } } pressed=0; lcd.blink(); } void lcd_status() { lcd.clear(); lcd.print("Data Sent to"); lcd.setCursor(0,1); lcd.print("Server"); delay(2000); lcd.clear(); } void sendToServer(String str) { Serial1.println(str); delay(1000); } void initGSM() { connectGSM("AT","OK"); connectGSM("ATE1","OK"); connectGSM("AT+CPIN?","READY"); } void initGPRS() { connectGSM("AT+CIPSHUT","OK"); connectGSM("AT+CGATT=1","OK"); connectGSM("AT+CSTT=\"airtelgprs.com\",\"\",\"\"","OK"); connectGSM("AT+CIICR","OK"); delay(1000); Serial1.println("AT+CIFSR"); delay(1000); } void connectGSM (String cmd, char *res) { while(1) { Serial.println(cmd); Serial1.println(cmd); delay(500); while(Serial1.available()>0) { if(Serial1.find(res)) { delay(1000); return; } } delay(1000); } } /* Public URL http://data.sparkfun.com/streams/w5nXxM6rp0tww5YVYg3G Public Key (публичный ключ w5nXxM6rp0tww5YVYg3G Private Key (приватный ключ) wY9DPG5vzpH99KNrNkx2 Храните этот ключ в секрете, вы не сможете его восстановить в случае потери Delete Key xxxxxxxxxxxxx Этот ключ используется один раз. Также храните этот ключ в секрете, вы не сможете его восстановить в случае потери Logging using query string parameters Format: http://data.sparkfun.com/input/[publicKey]?private_key=[privateKey]&log=[value] Example: http://data.sparkfun.com/input/w5nXxM6rp0tww5YVYg3G?private_key=wY9DPG5vzpH99KNrNkx2&log=22.21 */ |