Neste tutorial iremos demonstrar uma forma prática para montar um sistema de monitoramento remoto para utilização em áreas onde não há sinal de redes Wifi utilizando um modulo GPRS (General Packet Radio Service) / GSM (Global System for Mobile Communications). A imagem abaixo ilustra uma visão geral da montagem.
Os dados obtidos nesta aplicação serão enviados a um banco de SQL, na nuvem, e indicados através de um gráfico utilizando APIs escritas em PHP e HTML. Um sistema de Login também foi implementado para reservar o acesso somente aos autorizados.
MATERIAIS
- (1x) Arduino Nano (Atmega 328);
- (1x) Módulo GSM / GPRS Goouuu Tech IOT-GA6;
- (1x) Conversor DC/DC buck/boost ou Boost (Dependendo da bateria de alimentação) para 2A de pico;
- (1x) Sensor de temperatura e umidade DHT22;
- (2x) Resistor de 4,7K Ohms;
- (1x) Protoboard;
- Cabos para ligação em protoboard.
Tecnologia GSM / GPRS
O que é sinal GSM?
O GSM (Global System for Mobile Communications, ou Sistema Global para Comunicações Móveis) é um sistema para comunicação móvel surgido na Europa nos anos 80 com o intuito de padronizar os métodos e tecnologias de modulação e serviços oferecidos aos usuários.
É uma tecnologia digital de transmissão de dados e utiliza um modelo de modulação denominado 0,3MSK que é uma variante do FSK (Frequency Shift Key). Foi implantado no Brasil em 2002 com uma tecnologia ocupando 200 KHz de Largura de faixa para cada canal de comunicação e permitindo 8 usuários por canal dependendo do padrão implantado.
O que é sinal GPRS?
A segunda geração de telefônica celular, já digital, implantada através do GSM transmitia dados pela tecnologia de comutação de circuitos, isto é, uma conexão entre dois aparelhos era estabelecida e em seguida a comunicação era feita de forma ininterrupta ponto a ponto através de um canal de comunicação. Não permitia a transmissão de dados por pacotes como era um requisito principal do protocolo IP.
Diante da necessidade, a tecnologia GPRS (General Packet Radio Services ou Serviços Gerais de Pacotes por Rádio) foi criada com a finalidade de possibilitar o tráfego de dados por pacotes para que as redes de telefonia celular pudessem ser integradas às redes de internet. O sistema GSM integrado ao GPRS recebeu então o nome de geração 2.5G. O GPRS permite taxas de transferência em torno de 40 kbps.
Com o advento do GPRS, passou a se utilizar a comunicação de dados por comutação de pacotes nos dispositivos móveis, onde a informação é dividida em vários pacotes na origem, transmitida e remontada no destino. Cada pacote leva o endereço do destino bem como a informação para montagem do mesmo no dispositivo final. Cada pacote é transmitido pela rede de telefonia celular (e internet se for o caso), até chegar ao destino, através de caminhos diferentes (estipulados pelos roteadores). A própria Internet é baseada nesse princípio, de quebra em pacotes, para envio de dados entre origem e destino. A vantagem deste método é que os recursos de transmissão são utilizados apenas quando os usuários estão enviando ou recebendo dados. Ao invés de dedicar um canal para um usuário por um determinado período de tempo, como na comutação por circuitos, o canal pode ser compartilhado entre vários usuários.
Modens GSM / GPRS
Os modems GSM / GPRS foram criados no intuito de disponibilizar formas de comunicação sem fio a dispositivos antes dependentes de linhas telefônicas cabeadas.
Um módulo ou modem GSM é um equipamento que opera sobre as redes wireless das operadoras de telefonia celular. Seu comportamento é parecido com os antigos modems de discagem, onde a troca de dados se dava sobre uma linha telefônica cabeada. Outra semelhança está nos comandos AT (Abreviação de Attention) utilizados em ambas plataformas e com set de comandos com funcionalidades semelhantes.
De forma parecida a um aparelho de telefonia celular, os modens / modulos GSM necessitam de um cartão SIM para operar através da rede de uma operadora.
Já um modem GPRS (General Packet Radio Service) é nada mais do que um modem GSM com capacidade de transmissão de dados utilizando os protocolos de internet tradicionais como o IP (Internet Protocol), UDP (User Data Protocol), PPP (Point-to-Point Protocol) e conexões com o X25 (Protocolo para redes comutadas por pacotes). A imagem do módulo utilizado neste tutorial está indicada abaixo.
MÓDULO GOOUUU TECH
O módulo que utilizamos neste tutorial foi fabricado pela empresa chinesa Goouuu Tech. Ideal para aplicações M2M (Machine to Machine) onde equipamentos “conversam” com outros dispositivos.
Este módulo é compacto, leve e de baixo custo comparado a outros da mesma categoria como o SIM800L da SIM Com ou o A6 da empresa AI Thinker. Outra vantagem deste módulo é a operação Quad band, ou seja, este módulo pode operar com todas as operadoras de telefonia do mundo, sendo as frequências em GSM 850 MHz, EGSM 900 MHz, DCS 1800 MHz e PCS 1900 MHz.
O módulo utilizado neste Tutorial está operando com um SIM card da TIM na frequência de 1800 MHz. Uma imagem da descrição dos pinos está indicada abaixo.
Abaixo destacamos algumas especificações técnicas deste módulo:
- Temperatura de operação: -30°C a +80°C
- Temperatura limite de operação: -40 a -30 °C e +80 a +85°C
- Tensão de operação: 3,5V a 4,2V (Para o módulo standalone)
- Tensão de boot: > 3,5V
- Consumo no modo Sleep: 0,9 mAh
- Consumo registrado no pico de transmissão de 400mA
- Quad Band (850, 900, 1800, 1900 MHz)
- Suporta chamada de voz
- Suporta SMS
- GPRS máximo download de 85,6Kbps e 42,8Kbps de upload
- Possui duas portas seriais: Comandos AT e Download de firmware
- Suporta analógico e digital áudio sendo HR, FR, EFR AMR e codificação de voz.
De todas as características, a que mais importa para esta aplicação é a de aceitar comandos AT de forma standard e a de enviar dados via GPRS.
Os documentos referentes ao desenvolvimento desta placa estão neste link. O set de comandos AT será explicado na sessão referente ao algoritmo proposto.
Particularmente, analisando o esquemático deste módulo de desenvolvimento em particular, observei que para as plataformas da mesma categoria, a apresentada neste tutorial é a mais estável pois apresenta um circuito (SMF05C) para proteção contra ESD nos terminais de conexão com o SIM card, um conversor Buck utilizando o MP1584 na própria placa para regulagem da tensão de alimentação em 4,2V para o módulo, permitindo assim a liberdade de alimentação da placa até em 28V e também um MOSFET tipo N para o reset do modem diretamente pelo terminal do microcontrolador. O esquema de desenvolvimento desta placa está indicado abaixo.
ESQUEMA DE LIGAÇÃO
O esquema de montagem desta aplicação está indicado abaixo. O módulo utilizado pode ser alimentado com 5V pois já possui embarcado um circuito DC/DC Buck que reduz para 4.2V o nível de tensão. Nível este comum aos modens GPRS.
Para alimentação geral, o usuário deve definir qual conversor irá utilizar em função da alimentação. Se utilizar baterias de Li-On, com valor típico de 3,8V, deverá montar um conversor Boost para elevar a 7V o nível de tensão e conectá-lo a entrada Vin do Arduino.
Lembramos também que no momento da transmissão dos dados os modens podem apresentar picos de até 2A por um instante pequeno de tempo dependendo da “força” do sinal. Logo as baterias ou fontes de alimentação devem ter esta capacidade de fornecimento de corrente.
Durante os testes, a porta USB do computador não foi suficiente para alimentar este módulo durante a transmissão de dados. Foi necessário montar uma fonte externa.
Outro ponto importante a se observar são os valores dos resistores do divisor de tensão. O valor máximo para a entrada de um canal AD do Atmega328 é 5V, logo a configuração destes resistores não pode permitir uma tensão maior na saída do divisor em função da tensão de alimentação da entrada do conversor.
Algoritmo – Lado Arduino
O algoritmo que implementa este sistema de obtenção dos dados está destacado abaixo. Várias funções e comentários foram elaboradas com o intuito de facilitar o entendimento da lógica aplicada.
Link para download de todos os arquivos: https://git.io/fjDsf
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 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 |
/*************************************************************************** Arduino Lab 21 - Envio de dados para um servidor remoto via GPRS **************************************************************************** -- IDE do Arduino Versão 1.8.9 -- Autor: Eduardo Avelar -- Blog: easytromlabs.com -- email: contato@easytromlabs.com -- Julho, 2019 ****************************************************************************/ #include <String.h> #include <SoftwareSerial.h> #include "DHT.h" SoftwareSerial A6board (8, 9); // RX e TX #define DEBUG // Define o debud de dados pela porta serial #define OK 1 #define NOTOK 2 #define TIMEOUT 3 #define RST 3 // Pino do microcontrolador ligado ao reset do modulo #define voltPin A7 // Pino que recebe o valor de tensão da bateria #define LED_PIN 13 // Led de sinalização de final de transmissão #define DHTPIN 2 // Pino digital ao qual está conectado o DHT #define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321 #define SERIALTIMEOUT 3000 // Variáveis para Globais int contador = 0; char end_c[2]; float voltage; float denominator; float umidade; float temperatura; int resistor1 = 4700; int resistor2 = 4700; DHT dht(DHTPIN, DHTTYPE); int signalPower = 0; int avaregaPower = 0; // Protótipo das funções bool A6begin(); String A6read(); void reset(); int getSignalStrength(); bool sendToRemoteServerGSM(float hum, float temp, float volt, int pot); String returnStringFromModemComand(String ATcommand, int responseDelay); byte A6waitFor(String response1, String response2, int timeOut); byte A6command(String command, String response1, String response2, int timeOut, int repetitions); //-------------------------------------------------------------------------------------- // Função para configuração //-------------------------------------------------------------------------------------- void setup() { A6board.begin(9600); // the GPRS baud rate Serial.begin(9600); // Serial baud rate pinMode(RST, OUTPUT); pinMode(LED_PIN, OUTPUT); end_c[0] = 0x1a; end_c[1] = '\0'; dht.begin(); reset(); #ifdef DEBUG Serial.println("Leitura de um sensor de umidade e temperatura e envio para um servidor"); #endif // R2 / (R1 + R2) denominator = (float)resistor2 / (resistor1 + resistor2); } //-------------------------------------------------------------------------------------- // Função principal, looping infinito //-------------------------------------------------------------------------------------- void loop() { signalPower = getSignalStrength(); avaregaPower += signalPower; umidade = dht.readHumidity(); // Realiza a leitura de himidade temperatura = dht.readTemperature(); // Realiza a leitura da temperatura em °C voltage = analogRead(voltPin); // Realiza a aquisição da tensão da bateria voltage = (voltage / 1024) * 5.0; // Converte o valor para um range de tensão de 0 a 5 Vdc voltage = voltage / denominator; // converte o valor para o range de entrada - Máximo 10V para o divosor de tensão if (isnan(umidade) || isnan(temperatura)) { #ifdef DEBUG Serial.println("Falha na leitura com o sensor!"); #endif return; } // Em telecomunicação, a sigla RSSI (Received Signal Strength Indicator) // é a medida da potencia presente em um sinal de rádio recebido // Para transformar em dmb, basta: dbm = (2 * RSSI) - 113 para redes 2G #ifdef DEBUG Serial.print("Qualidade do sinal: "); Serial.print(signalPower); Serial.println(" RSSI"); Serial.print("Bateria: "); Serial.print(voltage); Serial.println(" V"); Serial.print("Umidade: "); Serial.print(umidade); Serial.println(" %\t"); Serial.print("Temperatura: "); Serial.print(temperatura); Serial.println(" *C "); Serial.print("Valor do contador: "); Serial.println(contador); Serial.println(); #endif contador ++; delay(10000); if (contador == 3) { // Aguarda 10 ciclos para enviar os dados para o servidor avaregaPower = avaregaPower / 3; // Realiza uma média aritmética com o valor da potencia #ifdef DEBUG Serial.print("Potencia média: "); Serial.println(avaregaPower); Serial.println("Enviando para o servidor..."); #endif sendToRemoteServerGSM(umidade, temperatura, voltage, avaregaPower); // Envia para o servidor contador = 0; digitalWrite(LED_PIN, HIGH); delay(1000); digitalWrite(LED_PIN, LOW); } } //-------------------------------------------------------------------------------------- // Função para iniciar o modem com os comandos corretos //-------------------------------------------------------------------------------------- bool A6begin() { A6board.println("AT+CREG?"); // Solicita o Status da rede byte hi = A6waitFor("1,", "5,", 1500); // Possíveis Respostas-> 1: Registrado na rede local, de origem ; 5: Registrado em modo roaming while ( hi != OK) { // Prende o firmware modem até que ele se registre a uma rede A6board.println("AT+CREG?"); hi = A6waitFor("1,", "5,", 1500); } if (A6command("ATE0", "OK", "yy", 5000, 2) == OK) { // Desabilita o modo ECHO do modem if (A6command("AT+CMEE=2", "OK", "yy", 5000, 2) == OK) { // Habilita a indicaão completa de erros do modem return OK; } else { return NOTOK; } } } //-------------------------------------------------------------------------------------- // Envia dados para um servidor remoto //-------------------------------------------------------------------------------------- bool sendToRemoteServerGSM(float hum, float temp, float volt, int pot) { String host = "iot-minasgerais.000webhostapp.com"; A6command("AT+CIPSTATUS", "OK", "yy", 10000, 2); // VERIFICA O STATUS DA CONEXÃO IP A6command("AT+CGATT?", "OK", "yy", 20000, 2); // VERIFICA SE ESTAMOS CONECTADOS A REDE A6command("AT+CGATT=1", "OK", "yy", 20000, 2); // SE NÃO ESTIVER CONECTADO A REDE, CONECTA A6command("AT+CIPSTATUS", "OK", "yy", 10000, 2); // VERIFICA O STATUS DA CONEXÃO IP A6command("AT+CGDCONT=1,\"IP\",\"timbrasil.br\"", "OK", "yy", 20000, 2); // CONECTA A REDE GPRS DA TIM BRASIL COM O APN timbrasil.br A6command("AT+CIPSTATUS", "OK", "yy", 10000, 2); // STABELECE O LINK PDP - PACKEGE DATA PROTOCOL A6command("AT+CGACT=1,1", "OK", "yy", 10000, 2); // ATIVA O CONTEXTO DO PDP (PACKET DATA PROTOCOL) A6command("AT+CIPSTATUS", "OK", "yy", 10000, 2); // VERIFICA NOVAMENTE O STATUS DA CONEXAO A6command("AT+CIFSR", "OK", "yy", 20000, 2); // SOLICITA O IP LOCAL A6command("AT+CIPSTATUS", "OK", "yy", 10000, 2); // VERIFICA O STATUS DA REDE NOVAMENTE A6command("AT+CIPSTART=\"TCP\",\"" + host + "\",80", "CONNECT OK", "yy", 25000, 2); // INICIA A CONEXAO DO TIPO TCP, NA PORTA 80, E ESPERA A RESPOSTA "CONNECT OK" A6command("AT+CIPSTATUS", "OK", "yy", 10000, 2); // SOLICITA O STATUS DA REDE NOVAMENTE A6command("AT+CIPSEND", ">", "yy", 10000, 1); // ABRE A PORTA PARA ENVIAR OS DADOS ATRAVEZ DE UMA CONEXAO TCP delay(500); // Formata a URL, no realizando uma requisição GET, do protocolo HTTP (Tamanho máximo de 255 caracters) A6board.print("GET /salvar.php"); // Envia uma solicitação do tipo GET no protocolo HTTP para a página salvar.php A6board.print("?hum="); // Formata a URL, parametro hum A6board.print(hum); // Carrega o valor da umidade A6board.print("&temp="); // Formata a URL, parametro temp A6board.print(temp); // Carrega o valor da temperatura A6board.print("&volt="); // Formata a URL, parametro volt A6board.print(volt); // Carrega o valor da tensão da bateria de alimentação do GPRS A6board.print("&pot="); // Formata a URL, parametro pot A6board.print(pot); // Carrega o valor da potencia do sinal do rádio do GPRS A6board.print(" HTTP/1.1"); // Protocolo utilizado para transferencia dos dados A6board.print("\r\n"); // Carrier return e new line A6board.print("HOST: "); // Formatação da url, parametro HOST A6board.print(host); // Carrega a string com o endereço do HOST A6board.print("\r\n"); // Carrier Return e new line A6board.print("\r\n"); // Carrier Return e new line novamente. Necessário para o HTTP #ifdef DEBUG Serial.print("GET /salvar.php"); Serial.print("?hum="); Serial.print(hum); Serial.print("&temp="); Serial.print(temp); Serial.print("&volt="); Serial.print(volt); Serial.print("&pot="); Serial.print(pot); Serial.print(" HTTP/1.1"); Serial.print("\r\n"); Serial.print("HOST: "); Serial.print(host); Serial.print("\r\n"); Serial.print("\r\n"); #endif A6command(end_c, "HTTP/1.1", "yy", 30000, 1); unsigned long entry = millis(); A6command("AT+CIPSTATUS", "OK", "yy", 10000, 2); // SOLICITA O STATUS DA CONEXAO NOVAMENTE A6command("AT+CIPCLOSE", "OK", "yy", 15000, 1); // FECHA A CONEXAO TCP IP A6command("AT+CIPSTATUS", "OK", "yy", 10000, 2); // SOLICITA O STATUS DA CONEXAO NOVAMENTE delay(100); #ifdef DEBUG Serial.println("-------------------------FIM------------------------------"); #endif } //-------------------------------------------------------------------------------------- // Gera um reset no módlo GPRS //-------------------------------------------------------------------------------------- void reset() { #ifdef DEBUG Serial.println("Start"); #endif digitalWrite(RST, HIGH); delay(5000); digitalWrite(RST, LOW); delay(500); if (A6begin() != OK) { #ifdef DEBUB Serial.println("Erro!"); Serial.println("Reiniciando novamente..."); #endif reset(); } } //-------------------------------------------------------------------------------------- // Função para capturar as respostas esperadas pelo modem //-------------------------------------------------------------------------------------- byte A6waitFor(String response1, String response2, int timeOut) { unsigned long entry = millis(); // Armazena o valor da variável millis para saber quanto tempo estará dentro da função, relizar o timout int count = 0; // Variável para o contador String reply = A6read(); // Realiza a leitura da resposta do modem byte retVal = 99; // Variável para o retorno do { reply = A6read(); // Realiza uma primeira leitura #ifdef DEBUG if (reply != "") { Serial.print((millis() - entry)); Serial.print(" ms "); Serial.println(reply); } #endif } while ((reply.indexOf(response1) + reply.indexOf(response2) == -2) && millis() - entry < timeOut ); // Tenta localizar as strings de resposta utilizando indexOf() if ((millis() - entry) >= timeOut) { // Confere se o tempo foi excedido retVal = TIMEOUT; } else { if (reply.indexOf(response1) + reply.indexOf(response2) > -2) retVal = OK; // Tenta localizar novamente se as strings passadas como parametro estão presentes else retVal = NOTOK; } return retVal; } //------------------------------------------------------------------------------------------------ // Função para enviar os comandos AT para o modem e aguarda as respostas passadas como parametro //------------------------------------------------------------------------------------------------ byte A6command(String command, String response1, String response2, int timeOut, int repetitions) { byte returnValue = NOTOK; byte count = 0; while (count < repetitions && returnValue != OK) { A6board.println(command); #ifdef DEBUG Serial.print("Command: "); Serial.println(command); #endif if ( A6waitFor(response1, response2, timeOut) == OK ) { returnValue = OK; } else { returnValue = NOTOK; } count++; } return returnValue; } //-------------------------------------------------------------------------------------- // Função que retorna uma String de resposta do modem //-------------------------------------------------------------------------------------- String A6read() { String reply = ""; if (A6board.available()) { // Se algum dado estiver disponível na serial, reply = A6board.readString(); // Realiza a leitura do dado disponível na serial } return reply; // Retorna a String de resposta } //-------------------------------------------------------------------------------------- // Função que solicita o valor da potência do sinal de recepção do modem //-------------------------------------------------------------------------------------- int getSignalStrength() { String modemResponse = returnStringFromModemComand("AT+CSQ", 1000); // Envia o comando solicitando a qualidade do sinal char res_to_split[modemResponse.length()]; // Variável que carrega o valor do tamanho da resposta do modem, para formar um buffer modemResponse.toCharArray(res_to_split, modemResponse.length()); // Copia os caracteres da String dentro do buffer "res_to_split" do tamanho "modemResponse.length()" // strstr() -> Função que lê a string e agaurda a ocorrencia da string entre "" if ((strstr(res_to_split, "ERROR") == NULL) | (strstr(res_to_split, "99") == NULL)) { // Confere se algumas das Strings enrtre " " está presente char *ptr_token; // Cria um apontador (ponteiro) do tipo Char ptr_token = strtok(res_to_split, ":"); // Essa função retorna o endereço do primeiro delimitador ("Token" :) passado pelo segundo parametro, da string "res_to_split" ptr_token = strtok(NULL, ":"); // Passamos o valor NULL para a função strtok() para que ela continue trabalhando com a string anterior ptr_token = strtok(ptr_token, ","); // Essa função retorna o endereço do primeiro delimitador ("Token" ,) passado pelo segundo parametro String final_result = ptr_token; // Armazena em "final_result" o conteudo apontado por "ptr_token" final_result.trim(); // Elimina qualquer "espaço" em branco dentro da string int intResult = final_result.toInt(); // Realiza um Type Cast de String para int, com o valor da potencia do sinal return intResult; } else { return (NULL); } } //-------------------------------------------------------------------------------------- // Função que retorna uma string em função do comando enviado //-------------------------------------------------------------------------------------- String returnStringFromModemComand(String ATcommand, int responseDelay) { A6board.println(ATcommand); // Envia o comando AT delay(responseDelay); // Aguarda o tempo passado como parametro String result = ""; // Cria uma String para armazenar o resultado while (A6board.available()) { // Enquanto houver algum dado disponivel na serial char c = A6board.read(); // Armazena os dados lidos result += c; // Monta uma String com os dados de resposta } return result; // Retorna a resposta do modem. } |
Algoritmo – Lado Servidor
A API para desenvolvimento do servidor é composta por 10 arquivos e uma imagem que é apresentada na tela de login.
A descrição da montagem do banco de dados foi apresentada nos dois vídeos explicativos deste tutorial. São precisamente dois bancos de dados, sendo um deles denominado usuario, onde serão armazenados os dados para a credencial de acesso ao gráfico, e o outro denominado gprsArduinoTest que receberá todos os dados enviados pelo Arduino. Destacamos aqui somente o arquivo index.php . Os outros arquivos estão indicados na pasta do repositório deste tutorial no github.
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 |
<?php session_start(); ?> <!doctype html> <html lang="pt-br"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE-edge"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" content=""> <meta name="author" content="Eduardo Avelar - EasyTrom Labs - Based on Bootstrap"> <meta name="generator" content="Jekyll v3.8.5"> <link rel="icon" type="image/png" href="Favicon.png"/>> <title>Sistema de acesso - EasyTrom Labs</title> <!-- Bootstrap core CSS --> <link href="bootstrap.min.css" rel="stylesheet"> <style> .bd-placeholder-img { font-size: 1.125rem; text-anchor: middle; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } @media (min-width: 768px) { .bd-placeholder-img-lg { font-size: 3.5rem; } } </style> <!-- Estilo curstomizado para este template --> <link href="signin.css" rel="stylesheet"> </head> <?php // Destroi as variáveis especificadas unset($_SESSION['iduser'], $_SESSION['nameuser']); ?> <body class="text-center"> <div class="container"> <form class="form-signin" method="post" action="proc_login.php"> <img class="mb-4" src="Favicon.png" alt="" width="100" height="100"> <h1 class="h3 mb-3 font-weight-normal">Login de usuarios</h1> <label for="inputEmail" class="sr-only">Endereço de email</label> <input type="email" id="inputEmail" class="form-control" placeholder="Endereço de email" name="emailc" required autofocus><br> <label for="inputPassword" class="sr-only">Senha</label> <input type="password" id="inputPassword" class="form-control" placeholder="Senha" name="passwordc" required><br> <button class="btn btn-lg btn-primary btn-block" type="submit">Entrar</button> </form> <p class="text-center text-danger"> <?php if (isset($_SESSION['errorlogin'])) { echo $_SESSION['errorlogin']; unset($_SESSION['errorlogin']); } ?> </p> <p class="text-center text-danger"> <?php if (isset($_SESSION['secury'])) { echo $_SESSION['secury']; unset($_SESSION['secury']); } ?> </p> <p class="mt-5 mb-3 text-muted" >&copy; <a href="https://easytromlabs.com/" target="_blank">EasyTrom Labs</a></p> </div> </body> </html> |
Link para download de todos os arquivos: https://git.io/fjDsf
Conclusão
Neste tutorial discutimos a implementação de um sistema de obtenção dos dados remotamente utilizando a tecnologia GPRS, muito útil para áreas onde não há possibilidade de redes Wifi.
São vastas as gamas de aplicação da ideia apresentada neste tutorial, cabendo ao leitor expandir a aplicação e os conhecimentos.
10/09/2023 at 11:22
Cheers!
15/02/2023 at 08:26
Parabéns Eduardo Avelar.
Muito bom trabalho.
03/01/2022 at 10:04
Olá!
Ótimo tutorial.
Seria possível além de tudo que esta no projeto acrescentar um boot ou sms de alarme ao programa ?
Fico grato pela atenção
01/06/2022 at 18:29
Olá Thomaz, tudo bem?
Infelizmente nao tenho como dar manutenção ou acrescentar novas features neste código no momento.
27/01/2021 at 10:23
Excelente explicação! Consigo logar, inserir usuarios e dados no gprsArduinoTest mas não consigo visualizar o grafico e aparece o erro :
Conexao com o banco de dados feita com sucesso
Warning: Cannot modify header information – headers already sent by (output started at /storage/ssd2/390/16013390/public_html/conexao.php:11) in /storage/ssd2/390/16013390/public_html/proc_login.php on line 19
15/03/2021 at 17:26
Olá César.
Infelizmente eu não passei por estes problemas quando esta desenvolvendo esta pequena aplicação.
Acredito que atualmente possa havere alguma incompatibilidade dos módulos do PHP.
Verifique a compatibilidade e tambem verifique o seu provilégio de acesso ao banco de dados do seu provedor.
22/01/2021 at 17:07
Olá Eduardo,
Primeiramente parabéns, venho a dias a procurar algum material como este.
Eu tenho algumas dúvidas.
1) O módulo GSM utilizado é homologado pela anatel, já que se trata de sua origem chinesa?
Obs.: Pergunto pois já passei por algumas perdas de acesso ao sinal por bloqueio do IMEI do módulo pela anatel
2) Onde posso comprar um módulos desses, tem no brasil ou china mesmo?
3) E o custo deste módulo ?
22/01/2021 at 18:22
Olá,
Este módulo eu adquiri na china, especificamente no banggood.com.
Uma rápida pesquisada me motrou que temos dele no Brasil (https://www.casadarobotica.com/internet-das-coisas/comunicacao/gsm-e-gps/modulo-gsm-gprs-a6-mini-quad-band-arduino-raspberry-iot-ga6)
Este módulo não é homologado pela Anatel.
Se este for um requisito do seu projeto, aconselho a utilizar os módulos da Quectel (M26 por exemplo -> https://lcsc.com/product-detail/Communication-Modules-GNSS-Modules_Quectel-M26-Standard_C90634.html), Wavecom, SIM Com e outros. No entanto, estes são mais caros.
Para o quectel M26, tenho uma aplicação profissional que esta em operação a anos e o mesmo não apresentou bloqueios ainda.
Espero ter ajudado.
30/12/2020 at 09:39
Olá Eduardo, primeiramente parabéns pelo tutorial!! Ao ler o tutorial me ficou uma dúvida, normalmente a tensão lógica de interface do Arduino é de 5V porém o módulo GOOUUU TECH utiliza uma tensão lógica de interface de 3.3V então caso eu utilize um arduino com uma saída de 5v irei precisar utilizar um módulo para converter os 5v para 3.3v e só assim conectar ao módulo GOOUUU TECH, correto?
30/12/2020 at 13:12
Olá Cláudio, tudo bem?!
O correto é fazer exatamente o que voce descreveu. Você deve utilizar um conversor de nível de 5V para 3V3 para conexão entre o Arduino e o módulo.
No meu tutorial eu nao utilizei um conversor pois eu li em uma documentação de que os pinos do módulo eram 5V tolerantes. No entanto, nao encontrei essa documentação por agora.
Logo, aconselho você a utilizar o conversor de nível.
Espero ter ajudado.
Eduardo Avelar.
28/06/2020 at 23:07
Boa noite Eduardo!
Primeiramente parabéns, obrigado por publicar esse excelente material. Estou tentando reproduzir os testes, consegui hospedar o site, porem estou usando o Arduíno uno, o código começa a rodar e fica preso no loop que verifica o status da rede na função A6begin(), estou usando um chip comum da operadora Oi coloquei “gprs.oi.com.br”. já estou tentando três dias sem progresso, poderia por gente lesa me enviar a biblioteca do DHT, não consegui encontrá-la. Não sei se é o fato de estar usando o Arduíno uno o chip da Oi.
29/06/2020 at 07:52
Olá Daivisson,
Voce pode baixar a biblioteca para leitura do dht22 diretamene pela IDE do ARduino.
Pesquise por DHT22 e a Biblioteca da “Adafruit” será indicada, onde há suporte tambem para o DHT11, DHT22 e outros.
Quanto ao uso do GPRS, voce esta utilizando o mesmo modem que utilizei neste tutorial?
Tente enviar os comandos manualemnte, um a um, e observar os retonrnos.
Essas biblitecas observam os retornos do comando e, no método begin, o modem fica aguardando o registro na rede pelo comando “AT+CREG?”.
SE o modem não se registrar ou se nao for o mesmo retorno, o programa não vai avançar.
Espero ter ajudado.
Att,
Eduardo Avelar.
30/06/2020 at 10:25
Bom Dia Eduardo!
Sobre o modem a unica diferença é que ele tem um B no final “IOT-GA6-B”.
Mudei a velocidade para “A6board.begin(115200);”.
O código esta rodando até no final, algumas informações estão aparecendo corrompidas no serial do Arduíno. Pode ser a fonte de alimentação ? estou usando uma fonte de computador de 500w.
30/06/2020 at 10:34
Bom dia.
Esses modens consomem aproximadamente 2A de pico no momento da transmissão. Mas não acredito que seja esse o problema.
As portas de versão que está usando são compatíveis e tolerantes a 5v ttl? Você conferiu esse detalhe?
Outra opção é você ligar o seu modem a um conversor USB serial e enviar a sequência de comandos at manualmente o observar os retornos.
Alguma coisa com certeza está diferente nessa montagem sua.
Até mais
25/06/2020 at 12:56
Bom dia. Obrigado pelo excelente material. Muito didático e muito bem organizado.
Consegui acompanhar até a pagina da criação do database. Entretanto, não consigo acessar o banco de dados. A página “https://databases.000webhost.com/”, “phpMyAdmin” me pede username e password e já tentei várias, mas dá erro. É aquela mesma página que você, no video, entra por engano no tempo de 14:33.
Agradeço qualquer ajuda.
27/06/2020 at 00:28
Ola Aimore Dutra.
A interface do 000webhost muda sempre e a cada dia.
Atualmente por exemplo ela está bem diferente daquela da data que gravei esse vídeo, mais a funcionalidade phpMyAdmin ainda está lá.
A tela que você citou no minuto 14:33 aparece quando algum erro no login ou timeout ocorre. Eu também não consigo entrar no banco por ela.
O caminho correto é você fazer o login na plataforma, ir no gerenciador de arquivos e criar ou acessar o banco de dados utilizando o phpMyAdmin.
Espero ter ajudado.
27/06/2020 at 21:50
Obrigado, Eduardo, pela resposta rápida. Me desculpe, mas como posso entrar no banco de dados, pelo gerenciador de arquivos, como você disse? Ou seria gerenciador do banco de dados? Não consigo entrar no banco de dados pelo PhpMyAdmin. Ele dá erro, mesmo usando o username e password corretos. A página responde: “mysqli_real_connect(): (HY000/1045): ProxySQL Error: Access denied for user ‘id14203005_adn’@’2a02:4780:bad:c0de::19′ (using password: YES)”
Já troquei senha, deletei e recriei banco de dados, já deletei conta, recriei conta e não consigo sair da página de entrada do PhpMyAdmin. Já tentei outro computador, com outro sistema e nada. Tentei a função de “reparar”, também sem sucesso. Estou quase desistindo e arranjando outro webserver.
27/06/2020 at 22:08
Na tela de criação de banco de dados, quando clico no botão PhpMyAdmin do menu topdown “Manage” eu sou SEMPRE redirecionado para a pagina de login do PhpMyAdmin (bem vindo ao PhpMyAdmin) e não para o banco de dados, como no seu vídeo.
Me perdoe tomar seu tempo.
27/06/2020 at 23:35
Respondi para voce no seu email pessoal. Abraços
07/05/2020 at 23:39
Olá, bom dia
Criei um site no 000webhost.com, e também criei o banco de dados SQL.
Criei com sucesso as duas tabelas (gprsArduinoTest, usuário) e por mais que eu preencha os dados na tabela de usuários eu não consigo me logar no site.
poderia me ajudar
10/05/2020 at 08:33
Olá Everaldo.
Infelizmente eu nã tenho condições de dar suporte individual a todos que solicitam pois são muitas solicitações.
Voce deve assistir por completo o segundo video do tutorial com calma e atenção pois ele possui todos os detalhes que farão o seu login ser validado pela plataforma.
Estude bem o código e tente separar onde indica endereços ou particularidades do seu banco de dados como o db name, db user e password.
Devem ser esses minimos detalhes que estao te atrapalhando no momento.
Eu reproduzi este tutorial 3 vezes antes de montá-lo para ter certeza de que ele funcionaria.
Espero ter ajudado.
10/05/2020 at 12:54
Olá obrigado, após muitas tentativas eu descobri uma ferramenta dentro do próprio site, “reparar” site, após isso o site passou a funcionar e apareceu uma pasta a mais na pasta public_html, a pasta tmp.
A ferramenta “reparar” está em:
Configurações de site; Geral.
Obrigado
10/05/2020 at 13:00
Entendi.
Acredito que seja uma nova configuração adotada pelas ferramentas do site.
É bom você descrever que o problema que você teve já fica mapeado para outras pessoas.
Até mais.
10/05/2020 at 13:12
Ok, após fazer tudo conforme os vídeos, eu não conseguia me logar no site, nada ocorria e após usar a ferramenta eu consegui me logar e ter acesso ao gráfico das grandezas que eu havia “populado” na tabela gprsArduinoTest, e a tabela usuario, com nome, e-mail e senha.
Ao tentar entrar no site, não conseguia nem sequer obter um código de erro, tipo Erro: Usuario ou Senha Invalidos.
Após acionar a ferramenta “reparar”, tudo passou a funcionar como deveria.
Espero ter contribuído.
Atenciosamente
10/05/2020 at 13:13
Com certeza contribuiu.
Obrigado.
24/03/2020 at 23:13
You’re a really helpful website; could not make it without ya!
29/04/2020 at 09:03
Thank you.
Sorry for not be in English.
30/10/2019 at 11:09
Sensacional, parabéns e muito obrigado por compartilhar!
14/11/2019 at 21:01
Obrigado Matheus.
Continue nos acompanhando.