SIPIU
Participantes:
Renata de Camillo Corrêa BernardesResumo do projeto:
Sistema de Identificação de Problemas de Infraestrutura UrbanaDescrição do projeto:
Grandes centros urbanos apresentam inúmeros problemas de infraestrutura, os quais influenciam diretamente na qualidade de vida de sua população. Levando em conta agilizar a identificação e localização de problemas, o SIPIU, busca identificar, localizar e cadastrar diversos problemas de infraestrutura urbana em prol de agilizar seus reparos. Dentre os problemas os mais comuns estão: vazamentos de água e esgoto, buracos e imperfeições no asfalto e calçadas, terrenos baldios irregulares e entulho em locais proibidos.
Pensando em mapear as cidades de modo eficiente, seria necessário pessoas que percorrem longas distâncias durante seu turno de trabalho. Os garis, que atuam profissionalmente na limpeza das vias públicas, se adequariam a essa categoria. A cidade de São Paulo possui 13 mil profissionais nesse ramo, que percorrem 7.8 quilômetros de vias por dia.
O hardware seria acoplado nos carrinhos utilizados por esses profissionais, de modo que ao identificar um problema, ele através de chaves e botões ativaria o GPS e escolheria a categoria do problema. Esses dados são enviados para a nuvem, onde os responsáveis pelos reparos teriam acesso rapidamente e podem pensar em medidas para realizar as ações necessárias.
Dentro do conceito de IoT (internet das coisas) os garis com seus coletores de dados (carrinhos) gerariam uma grande quantidade de dados relevantes que seriam transmitidos diretamente a nuvem em um portal IoT que armazenaria esses dados para um sistema de analise que geraria automaticamente ordens de serviço para os órgãos competentes equacionarem os problemas reportados. A integração dos sistemas facilita também a geração de relatórios de eficiência da solução dos problemas e se eles foram efetivamente equacionados. Utilizando algoritmos de “machine learning” essa massa de dados históricos pode preditar ações futuras (por exemplo no mês de maio há uma incidência nos últimos 3 anos de aumento de buracos nas vias em 40%) e seus devidos orçamentos.
Overview do projeto:
Contato:[email protected]
A apresentação a seguir introduz e explicita todos os conceitos do projeto e sua relevância e colaboração no âmbito social, clique na imagem para acessar.
Histórico do desenvolvimento:
Diagrama de blocos inicial do sistema a ser desenvolvido:
Essa semana o kit chegou e comecei a planejar e dar os primeiros passos do projeto. O primeiro a ser feito é estudar as possibilidades de comunicação entre a OM13070: LPCXpresso4337, que possui duas seriais, e os módulos 3G e GPS. E começar a desenvolver o código e fazer vários testes para ir adequando as necessidades.
Carreguei todo o ambiente da IDE LPCXpresso v8.2.0 no Windows 8 e rodei o programa para piscar o led. Funcionou perfeitamente! Usei como referência o artigo do Embarcados: Primeiros Passos com a LCPXpresso4337.
Continuando os testes iniciais, conectei a placa OM13082: LPC General Purpose Shield na placa OM13070: LPCXpresso4337, com ela é possível realizar várias funções. A que eu achei mais interessante foi utilizar o LCD, com ele posso fazer vários testes e printar alguns resultados ou parâmetros importantes para o projeto.
Pensando na instalação do sistema nos carrinhos dos garis, fui em busca de maiores informações e das dimensões para que fosse possível começar a desenvolver um modelo do que virá a ser o protótipo.
Essa semana foram feitos diversos testes com o GPS e o Modem 3G! A próxima etapa é fazer com que eles se comuniquem com a OM13070: LPCXpresso4337. E também integrá-los com a plataforma IoT!
O teste com o GPS JN3 foi um sucesso, foram transmitidos as localizações corretas e com isso facilita a passagem dos dados para o microcontrolador.
Fiz um diagrama de blocos funcional para ajudar na hora de programar.
A comunicação entre a OM13070: LPCXpresso4337 e os módulos 3G e GPS é serial. O código da OM13070: LPCXpresso4337 foi feito na plataforma mbed, onde já foi feita a comunicação serial entre ele e os módulos. O próximo passo é fazer a interface com o usuário, onde ele escolherá o tipo de problema que encontrou e acionará a comunicação.
Já o Modem 3G, foi programado em Phyton para receber uma string com os dados a serem transmitidos e conectar-se ao DeviceWise, a plataforma IoT aonde os dados são tratados, aonde fica fácil acompanhar os dados coletados.
Como os dados ficam centrados na plataforma IoT, é possível pegá-los facilmente e expô-los em uma plataforma. Está sendo desenvolvido um site responsivo, utilizando HTML, CSS e Javascript, onde será possível ter de forma fácil e rápida os últimos dados coletados, o problema encontrado, latitude, longitude, sua localização no mapa e a data da coleta, assim, o usuário poderá encaminhar as informações para o órgão responsável.
Foi desenvolvido o esquema 3D do protótipo do SIPIU, nele é possível observar a posição que o sistema ficaria no carrinho e a interface do usuário, por meio de dois push bottons para selecionar a opção do problema e outro que serviria de confirmação. O esquema foi desenvolvido no programa SketchUp.
O código para a LPCXpresso4337 está quase pronto! Usando o display e o joystick é possível selecionar o problema que o usuário encontrou. Assim, quando ele seleciona o problema, é lido na entrada serial, a string que vem do GPS indicando sua localização exata. Com isso, é enviado para o Modem 3G um string com o status, problema em questão, junto com a string do GPS. O código encontra-se no tópico software abaixo.
Fiz um vídeo mostrando o funcionamento e a interface do sistema:
O site do SIPIU ficou pronto! Nele é possível ver na página home o último dado enviado, e sua localização no mapa. Na página histórico é possível consultar a tabela com outros dados coletados.
Business Plan
Desenvolvi o plano de negócios, definindo as características e estratégias do SIPIU. Nele contém também o estudo da sua viabilidade, onde foi calculado, de forma aproximada, os custos para implementação do sistema. Para acessar o Business Plan clique aqui.
Como parte da documentação, estratégia de negócio e divulgação, desenvolvi um catálogo que explica de forma rápida sobre o sistema. O catálogo pode ser acessado aqui.
Evolução do sistema
Com a instalação no Brasil da Rede SIGFOX uma rede mundial de LPWAN focada em IoT, o sistema SIPIU pode ser alterado facilmente para operar nessa rede.
A grande vantagem está no fato de redução de custo do hardware e do custo de operação do sistema. Outra grande vantagem é o baixo consumo de energia , fazendo com que equipamento opere com a mesma bateria por 1 a 2 anos.
Para o estudo utilizamos o componente da NXP para essa finalidade: OL2385.
Desafios encontrados durante o desenvolvimento
Os principais desafios encontrados durante o desenvolvimento do SIPIU, foram:
- integração do hardware e a comunicação entre os equipamentos;
- programação web, principalmente na parte de Javascript;
- patentear o projeto, não consegui informações adequadas até agora.
Hardware:
O hardware é constituído pelo microcontrolador, que no caso será utilizada a placa OM13070: LPCXpresso4337 Development Board da NXP:
Placa OM13082: LPC General Purpose Shield da NXP:
Modem 3G DD3G – 910 da Duodigit:
GPS JN3 da Telit:
Será utilizada comunicação serial entre o módulo 3G e o processador NXP, comunicação serial/SPI entre o módulo GPS e o processador NXP. O painel seria de fácil utilização, onde as chaves seriam numeradas e identificadas de acordo com cada tipo de problema observado.
Esquema elétrico da montagem do hardware:
Software/Firmware:
O Código da placa OM13070: LPCXpresso4337 está sendo contruído na plataforma mbed. Ela é bem fácil de ser usada, basta escolher o tipo de hardware a ser utilizado, e ao compilar o código obtem-se um arquivo em binário que é passado diretamente para a placa. Para isso utilizei como base o artigo Primeiros passos com a placa LPCXpresso4337 no mbed.
O código encontra-se abaixo, utilizou-se as bibliotecas para o display e o joystick, configurações para a comunicação serial.
#include "mbed.h" #include "ST7567.h" #include "PCAL9555.h" ST7567 lcd(D11, D13, D12, D9, D10); // mosi, sclk, reset, A0, nCS Serial pc(USBTX, USBRX); //configura a comunicação serial Serial micro(TX, RX); //confira a entrada de dado do GPS PCAL9555 gpio_exp(SDA, SCL); // configura o joystick GpioBusIn joystick(gpio_exp, X0_0, X0_1, X0_2, X0_3, X0_4); int selectionArrow (char,int); //funcao que posiciona a seta void lcdStart(); //funcao que inicializa o lcd enum key_num { //configuracoes do joystick Key_Up = (1 << X0_4), Key_Down = (1 << X0_0), Key_Center = (1 << X0_1), }; int main() { int mainState = 18; // posicao inicial da seta char direction; //variavel se define se a seta sobe ou desce char gps[80], location[80]; lcd.set_contrast(0x35); //configura contraste do Display lcd.cls(); //Limpa Display lcdStart(); //inicializa o display micro.format(8, Serial::None, 1); //configuracoes da comunicacao serial com o GPS micro.baud(4800); pc.format(8, Serial::None, 1); pc.baud(9600); while(true) { // loop principal int keys = joystick.read(); //leitura do joystick int state; //armazena a posicao if ((keys & Key_Up) == 0){ //se a seta de selecao subir direction = 'U'; state = selectionArrow(direction,mainState); //chama a funcao para movimentar a flecha mainState = state; //retorna a posicao atual } if ((keys & Key_Down) == 0){ //se a seta de selecao descer direction = 'D'; state = selectionArrow(direction,mainState); //chama a funcao para movimentar a flecha mainState = state; //retorna a posicao atual } if (micro.readable()) { //recebe a string da localizacao do problema location= micro.scanf(gps); break; } if ((keys & Key_Center) == 0){ //quando o usuario da enter na opcao desejada switch (mainState){ //dependendo da opção envia para o modem 3G uma string diferente case 18 : pc.printf("1#%c", location); break; case 34 : pc.printf("2#%c", location); break; case 50 : pc.printf("3#%c", location); break; } lcd.cls(); //limpa o display lcd.locate(0, 34); //Posiciona na terceira linha lcd.printf("TRANSMITINDO DADOS..."); wait(20); //delay de 20 segundos para dar o tempo de transmissao lcd.cls(); //limpa o display lcd.locate(16, 34); //Posiciona na terceira linha lcd.printf("DADOS ENVIADOS"); wait(2); lcdStart(); //funcao que inicializa o lcd } wait(0.2); } } int selectionArrow(char key, int actualState){ //funcao que posiciona a flecha de acordo com a opcao do usuario if (key == 'U') { //para subir if (actualState > 18){ lcd.locate(0, actualState); lcd.printf(" "); actualState -= 16; lcd.locate(0, actualState); lcd.printf(">>"); return actualState; } } if (key == 'D') { //ou para descer if (actualState >= 18 && actualState < 50){ lcd.locate(0, actualState); lcd.printf(" "); actualState += 16; lcd.locate(0, actualState); lcd.printf(">>"); return actualState; } } return actualState; } void lcdStart () { lcd.locate(0, 1); //posiciona na primeira linha lcd.printf("SELECIONE O PROBLEMA"); //Escreve mensagem na primeira linha lcd.locate(16, 18); //Posiciona a segunda linha lcd.printf("BURACO NO ASFALTO"); //Escreve mensagem na segunda linha lcd.locate(16, 34); //Posiciona a terceira linha lcd.printf("VAZAMENTO DE AGUA"); //Escreve mensagem na terceira linha lcd.locate(16, 50); //Posiciona a quarta linha lcd.printf("ENTULHO"); //Escreve mensagem na quarta linha lcd.locate(0, 18); //Posiciona a segunda linha lcd.printf(">>"); //Escreve a seta na segunda linha }
O Modem 3G foi programado em Python, ou seja, foi configurado para receber uma string com todos os dados necessários e os mesmos são enviados para a plataforma IoT.
Esse primeiro código inicializa o Modem, e o prepara para identificar qual operadora o simcard que foi inserido pertence. Depois faz passo a passo a conexão e o envio do dado, e vai informando o processo.
import time import SER import MDM import GPIO import DW_send import binascii print 'Import OKrn' SER.send('Rodando') def Config_Oper(): #Busca a operadora e configura APN print 'CONFIG_APN' print 'Get Operadorarn' res='' res = MDM.send('AT#LSCRIPTr', 2) res = MDM_receive(2) res = res.upper() print res tesc = res.find ('CONFIG_APN.PY') if (tesc==-1): print 'apn defalt' res='' res = MDM.send('AT+COPS?r', 2) res = MDM_receive(2) res = res.upper() print res ip='zap.vivo.com.br' usr='vivo' psw='vivo' tes = res.find ('VIVO') if (tes == -1): ip='claro.com.br' usr='claro' psw='claro' tes = res.find ('CLARO') if (tes == -1): ip='tim.br' usr='tim' psw='tim' tes = res.find ('TIM') if (tes == -1): ip='oi.com.br' usr='oi' psw='oi' tes = res.find ('OI') if (tes == -1): op1 = 0 print 'Operadora desconhecida' if (tesc!=-1): print 'arquivo apn' import CONFIG_APN ip,usr,psw = CONFIG_APN.config() if(ip==''): res = MDM.send('AT#REBOOTr', 2) return (ip,usr,psw) def MDM_receive(timeout): # Recebe resposta dos comandos AT res = '' start = time.time() while (time.time() - start < timeout): res = res + MDM.read() return res def Conect(ip, usr, psw): # Faz a conexão e ganha um endereço de IP tent=0 con=1 print 'configure PDP context with APN %s, username %s, password %s' % (ip, usr, psw) res='' res = MDM.send('AT+CGDCONT=1,"IP","' + ip + '"r', 2) res = MDM_receive(2) res = res.find ('OK') if (res == -1): print 'error setting PDP contextr' if (usr != ''): print 'set GPRS usernamer' res='' res = MDM.send('AT#USERID="'+ usr + '"r', 2) res = MDM_receive(2) res = res.find ('OK') if (res == -1): print 'error setting GPRS usernamer' if (psw != ''): print 'set GPRS passwordr' res='' res = MDM.send('AT#PASSW="'+ psw + '"r', 2) res = MDM_receive(2) res = res.find ('OK') if (res == -1): print 'error setting GPRS passwordr' print 'activate GPRS contextr' while(tent<=20)&(con==1): print 'iniciando tentativa ' + str(tent) + ' ...' res='' res = MDM.send('AT#GPRS?r',2) res = MDM_receive(2) res = res.upper() print res tes = res.find ('#GPRS: 0') tes1 = res.find ('#GPRS: 1') tes2 = res.find ('#GPRS: 2') print tes print tes1 print tes2 if(tes==2): res='' res = MDM.send('AT#GPRS=1r',2) res = MDM_receive(4) print res res = res.find ('OK') if(res==2): print 'conectado' if (res == -1): print res con=1 print 'Impossivel conectarr' if(tes1==2): con=0 if(tes2==2): res='' res = MDM.send('AT#GPRS=0r',2) res = MDM_receive(4) res = res.find ('OK') con=1 if(tent==20)&(con==1): res='' res = MDM.send('AT#LSCRIPTr', 2) res = MDM_receive(2) res = res.upper() print res tesc = res.find ('CONFIG_APN.PY') if(tesc!=-1): res='' res = MDM.send('AT#DSCRIPT="CONFIG_APN.py"r', 2) res = MDM_receive(2) res = res.upper() print res tesc = res.find ('OK') if(tesc==2): res = MDM.send('AT#REBOOTr', 2) tent=tent+1 print 'all settings doner' return con print 'SIPIU_INICIO' op1 = 0 sim1 = 0 tent1 = 0 ok = 0 repete = 0 while((sim1==0)&(tent1<=20)): print 'iniciando tentativa ' + str(tent1) + ' ...' res = MDM.send('AT+CREG=0,0r', 2) res = MDM_receive(2) res = res.upper() print res print 'Get Operadorarn' res = MDM.send('AT+CPIN?r', 2) res = MDM_receive(2) res = res.upper() print res tes = res.find ('ERROR') if (tes == -1): print 'Aguardando registrorn' res = MDM.send('AT+CREG?r', 2) res = MDM_receive(2) res = res.upper() print res tes = res.find ('+CREG: 0,1') print tes if (tes == 2): print 'Registrado' sim1=1 ip,usr,psw = Config_Oper() print 'APN' print ip print 'User' print usr print 'Password' print psw tent1=tent1+1 #print op1 if(sim1==1): ok=Conect(ip, usr, psw) print 'Chama DW Send' sim1=DW_send.DW_connect() if(sim1==0): print 'Nao foi possivel conectar' print 'Doner' print ok while(repete<=10): MDM.send('AT#DWCONN?r', 0); res = MDM_receive(1); res = res.upper() tes = res.find ('#DWCONN: 1,2') repete=repete+1 if (tes==2): print 'Modem ja conectado no DW' conect = 1 print 'Enviando Dados...' DW_send.Status_reg1() if (repete==10): sim1=DW_send.DW_connect() repete=0 if (tes!=2): print 'Nao foi possivel enviar Dados' res = MDM.send('AT#REBOOTr', 2)
O segundo código faz a conexão do Modem com a plataforma IoT, o Devicewise. Nele são inseridos as informações necessárias para fazer login na plataforma e poder ser feita a comunicação.
import time import SER import MDM import binascii ################################# APP_TOKEN = # inserir aqui o app token SER.set_speed('9600','8N1') ################################# def MDM_receive(timeout): # Recebe respostas de comandos AT res = '' start = time.time() while (time.time() - start < timeout): res = res + MDM.read() return res def SER_receive(timeout): # Recebe respostas da Serial res = '' fora = '0' start = time.time() while (fora=='0'): res = res + SER.read() if(res[:-1].endswith('x0d')): fora='1' SER.send(res) return res def DW_connect(): #Conecta no DeviceWise sim1=0 tent=0 MDM.send('AT#DWCFG=open-api.devicewise.com,0,' + APP_TOKEN + 'r', 0) res = MDM_receive(5) res = res.upper() tes = res.find ('OK') if(tes!=(-1)): print 'APP_TOKEN_OK1' MDM.send('AT#DWCONN?r', 0) res = MDM_receive(5) res = res.upper() print res tes = res.find ('#DWCONN: 1,2') if (tes==2): print 'Modem ja conectado no DW' sim1=1 if (tes!=2): MDM.send('AT#DWCONN=0r', 0) res = MDM_receive(5); res = res.upper() tes = res.find ('#DWCONN: 0,0') if (tes==2): print 'Tentando reconectar' DW_connect() while (sim1==0 & tent<=10): print 'APP_TOKEN_OK2' MDM.send('AT#DWCONN=1r', 0) res = MDM_receive(5) print res res = res.upper() tes = res.find ('OK') if(tes!=(-1)): sim1=0 tent=tent+1 if(tes!=(-1)): print 'DW_connect_OK' sim1=1 return sim1 def gravalog(msg): #Envio de LOG para o DW. MDM.read() MDM.send('AT#DWSEND=0,log.publish,msg,' + str(msg) + 'r', 0) time.sleep(2) #Fim do bloco gravalog. def Status_reg1(): # Aguarda receber evento e coordenadas SER.send('*') a = SER_receive(10) print a cord=a.split('#') if (a!=''): print 'dado da resposta' print a MDM.send('AT#DWSEND=0,property.publish,key,Status,value,' + str(cord[0]) + 'r', 0) res = MDM_receive(20) print res print 'dado enviado' MDM.send('AT#DWSEND=0,property.publish,key,Latitude,value,' + str(cord[1]) + 'r', 0) res = MDM_receive(20) print res print 'dado enviado' MDM.send('AT#DWSEND=0,property.publish,key,Longitude,value,' + str(cord[2]) + 'r', 0) res = MDM_receive(20) print res print 'dado enviado' if (a==''): print 'Sem resposta do medidor'
Com o Modem conectado ao Devicewise, podemos observar os dados coletados e sua evolução, e a situação do modem. Nela também é possível fazer alterações remotas.
Através da plataforma IoT é possível referenciar o site, que está sendo desenvolvido, com todos os dados coletados, e que gera a localização exata em um mapa dinâmico.
Todos os códigos encontram-se no meu perfil do Github.
Referências:
1 – http://www.embarcados.com.br/primeiros-passos-com-lpcxpresso4337/
2 – http://www.embarcados.com.br/lpcxpresso4337-no-mbed/
3 – https://cloud.m2mair.com/app/login
4 – http://www.nxp.com/
5 – http://duodigit.com.br/
6 – http://www.telit.com/
7 – http://www.sketchup.com/pt-BR/download
8 – https://www.mbed.com/en/
9 – https://www.sigfox.com/
10 – http://www.nxp.com/documents/leaflet/OL2385LWPWRLF.pdf
11 – https://github.com/renatadecamillo/SIPIU