quarta-feira, 28 de março de 2018

Testando MQTT-SN com Arduino + XBEE

Introdução:

    Este tutorial tem como objetivo montar um ambiente em que se possa testar o protocolo MQTT-SN. Para isso utilizaremos o RSMB (Really Small Message Broker) como base para testes de conexão, publicações e inscrições.


Materiais Necessários:

1x Arduino Mega
1x XBEE Arduino Shield
1x Arduino XBee (Configurado como Coordenator em MeshBee)
1x XBEE Explorer
1x Arduino XBee (Configurado como Router em MeshBee)

Obs: Seguir o tutorial Rede Mesh Xbee (https://bytespassivos.blogspot.com.br/2018/03/rede-mesh-xbee.html) para configurar os XBEE.


Passos:

1) Instalar a lib mqttsn
2) Fazer upload do código da Arduino
3) Compilar e instalar o RSMB
4) Criar arquivo de configuração do broker
5) Fazer o setup do ambiente
6) Testar a comunicação com o broker mqtt



1) Instalar a lib mqttsn

1. Fazer o download da lib mqttsn (https://github.com/boriz/MQTT-SN-Arduino)
2. Instalar na pasta de bibliotecas da Arduino (No meu caso Arduino/libraries)

$ cd ~/Downloads
$ git clone https://github.com/boriz/MQTT-SN-Arduino
$ cp MQTT-SN-Arduino/Arduino/libraries/mqttsn/ ~/Arduino/libraries/

2) Fazer upload do código da Arduino

1. Fazer o upload do código abaixo para a arduino:


#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <mqttsn-messages.h>

//////////////////////////////////////// MESHBEE.H DEFINES////////////////////////////////////////

#define API_DATA_LEN  20
#define API_PAY_LEN  (API_DATA_LEN + 5)
#define API_FRAME_LEN  (API_DATA_LEN + 9)

#define API_DATA_PACKET  0x02
#define API_START_DELIMITER  0x7E
#define OPTION_CAST_MASK  0x40   //option unicast or broadcast MASK
#define OPTION_ACK_MASK  0x80   // option ACK or not MASK

//////////////////////////////////////// MAIN DEFINES ////////////////////////////////////////

#define XBEE Serial3

#define API_DATA_LEN  20
#define API_PAY_LEN  (API_DATA_LEN + 5)
#define API_FRAME_LEN  (API_DATA_LEN + 9)


#define TOPIC_PUB "arduino/temp"
#define TOPIC_SUB "arduino/temp"

//////////////////////////////////////// MESHBEE.H ////////////////////////////////////////

uint8_t FrameID = 0;

// Create MeshBee frame (return frame lenght)
int MB_FrameCreate(uint8_t* data, int data_len, uint16_t dest_addr, uint8_t* frame, int frame_max_len, bool broadcast)
{
  // frame buffer is big enough?
  if ( frame_max_len < API_FRAME_LEN )
  {
    return -1;
  }
  
  // data is too long?
  // TODO: Split in multiple packets?
  if (data_len > API_DATA_LEN)
  {
    return -2;
  }
  
  // Frame buffer is fine. Clear it
  memset (frame, 0, frame_max_len); 
  
  // Header
  frame[0] = API_START_DELIMITER;  // Delimiter
  frame[1] = API_PAY_LEN;    // Length of the payload
  frame[2] = API_DATA_PACKET;    // API ID
  
  // Payload
  uint8_t cs = 0;  // CS=Sum of the payload
  cs += frame[3] = FrameID++;   // frame id  
  if (broadcast)
  {
    cs += frame[4] = OPTION_CAST_MASK; // option
  }
  cs += frame[5] = data_len; // data length
  
  // Data
  for (int i=0; i<data_len; i++)
  {
    cs += frame[6 + i] = data[i];    
  }
  cs += frame[6 + API_DATA_LEN] = (dest_addr >> 8) && 0xFF;  // Unicast address (16 bits)
  cs += frame[7 + API_DATA_LEN] = (dest_addr >> 0) && 0xFF;  // Unicast address (16 bits)
  frame[8 + API_DATA_LEN] = cs;
  
  return API_FRAME_LEN;
}


// Parse MeshBee frame (return data length)
int MB_FrameParse(uint8_t* frame, int frame_len, uint8_t* data, int data_max_len, uint16_t* src_addr)
{
  // got a full frame?
  if ( frame_len != API_FRAME_LEN )  
  {
    // TODO: May be a valid frame, keep reading?
    return -1;  
  }
  
  // Delimeter?
  if (frame[0] != API_START_DELIMITER)  // Delimiter
  {
    return -2;
  }
  
  // Payload length?
  if (frame[1] != API_PAY_LEN)  // Length of the payload
  {
    return -3;
  }
  
  // Right API ID?
  if (frame[2] != API_DATA_PACKET)  // API ID
  {
    return -4;
  }  
  
  // Payload
  int len;
  uint8_t cs = 0;  // CS=Sum of the payload
  cs += frame[3];   // frame id
  cs += frame[4];  // option
  
  // Enough space in the payload buffer?
  cs += len = frame[5];
  if (len > data_max_len)
  {
    return -5;
  }
  
  // Clear output buffer
  memset (data, 0, data_max_len);
  
  // Copy data to the buffer
  for (int i=0; i<API_DATA_LEN; i++)
  {
    if (i<len)
    {
      cs += data[i] = frame[6 + i];    
    }
    else
    {
      // Rest of the payload data (for checksum) 
      cs += frame[6 + i];
    }
  }
  *src_addr = (frame[6 + API_DATA_LEN] << 8) | frame[7 + API_DATA_LEN];  // Unicast address (16 bits)
  cs += frame[6 + API_DATA_LEN]; 
  cs += frame[7 + API_DATA_LEN];
  
  // Verify checksum
  if (cs != frame[8 + API_DATA_LEN])
  {
    return -6;
  }
  
  return len;
}


//////////////////////////////////////// MAIN ////////////////////////////////////////


MQTTSN mqttsn;
uint16_t u16TopicPubID;
uint16_t u16TopicSubID;
uint8_t u8Counter;

uint8_t FrameBufferIn[API_FRAME_LEN];
uint8_t FrameBufferOut[API_FRAME_LEN];

void setup()
{
  Serial.begin(9600);
  XBEE.begin(9600);
  
  ADMUX = 0xC8; // turn on internal reference, right-shift ADC buffer, ADC channel = internal temp sensor
  delay(100);  // wait a sec for the analog reference to stabilize
  
  u8Counter = 1;
  Serial.println("Setup done");   
}

 
void loop()
{ 
  // Check serila data
  CheckXBEE();
  
  // ------- MQTT-SN publis logic -------
  // Busy?
  if (mqttsn.wait_for_response())
  {
    // Busy. exit
    return;
  }
  
  // Connected?
  if (!mqttsn.connected())
  {
    // Not connected - connect
    mqttsn.connect(0, 10, "test1758");  // Flags=0, Duration=10
    Serial.println("Connect sent");   
    return;
  }
  
  // Topic registered?
  uint8_t index;
  u16TopicPubID = mqttsn.find_topic_id(TOPIC_PUB, &index);
  if (u16TopicPubID == 0xffff)
  {
    // Topic is not registered yet
    mqttsn.register_topic(TOPIC_PUB);
    Serial.println("Reg top sent");    
    return;  
  }
   
  // Topic is alredy registered, publish
  char str[50];
  char temp[10];
  float t = averageTemperature();
  itoa(t, temp, 10);
  sprintf(str, "%s (%i)", temp, u8Counter);
  Serial.print("Top id:");      
  Serial.print(u16TopicPubID);    
  Serial.print("; Val:");      
  Serial.println(str);      
  mqttsn.publish(0, u16TopicPubID, str, strlen(str));  // Flags=0         
  u8Counter++;
  delay(2000);
  
  // ------- MQTT-SN subscribe logic -------
  u16TopicSubID = mqttsn.find_topic_id(TOPIC_SUB, &index);
  if (u16TopicSubID == 0xffff)
  {
    // Topic is not registered yet
    mqttsn.subscribe_by_name(0, TOPIC_SUB);  // Flags=0   
    Serial.println("Sub top sent");    
    return;  
  }
  delay(2000);  
}


// gwinfo message callback
void MQTTSN_gwinfo_handler(const msg_gwinfo* msg)
{
  // Got a gateway response
  // The frame is still in the buffer - parse it
  
  Serial.println("GW info hand"); 
}


void MQTTSN_publish_handler(const msg_publish* msg)
{
  Serial.println("Sub pub hand"); 
}


// Callback funciton to send XBEE data
void MQTTSN_serial_send(uint8_t* message_buffer, int length)
{
  // Assuming that our gateway is at address 0 (coordinator)
  int len = MB_FrameCreate (message_buffer, length, 0x0000, FrameBufferOut, sizeof(FrameBufferOut), false);
  if (len > 0)
  {
    XBEE.write(FrameBufferOut, len);
    XBEE.flush();
  }
}


// XBEE event interrupt
void CheckXBEE()
{
  if (XBEE.available() > 0) 
  {
    // Wait till we got the whole packet or timeout
    long Start = millis();   
    int cnt =0;
    while (cnt < API_FRAME_LEN && (millis() - Start) < 100) 
    {
        while (XBEE.available() > 0) 
        {
            FrameBufferIn[cnt++] = (uint8_t)XBEE.read();
            
            // Reset timeout counter
            Start = millis();
        }
    }
    
    if (cnt == API_FRAME_LEN)
    {
      // Got the whole packet
      Serial.print("From ser:");  
      for (int i=0; i<cnt; i++)
      {        
        Serial.print (FrameBufferIn[i], HEX);
        Serial.print (" ");
      }
      Serial.println();   
  
      uint8_t pay[API_DATA_LEN];
      uint16_t src_addr;
      int pay_len = MB_FrameParse(FrameBufferIn, cnt, pay, sizeof(pay), &src_addr);
      if (pay_len > 0)
      {
        Serial.print("Ser payload:");  
        for (int i=0; i<pay_len; i++)
        {        
          Serial.print (pay[i], HEX);
          Serial.print (" ");
        }
        Serial.println(); 
        
        // Valid frame. Pare it
        mqttsn.parse_stream(pay, pay_len);
      }
    }
    else
    {
      // Timeout. 
      Serial.println("Chec ser timeout");  
    }
  }
}



// =================== Measure temperature =================== 
int readTemperature() 
{
  /*ADCSRA |= _BV(ADSC); // start the conversion
  while (bit_is_set(ADCSRA, ADSC)); // ADSC is cleared when the conversion finishes
  return (ADCL | (ADCH << 8)) - 342; // combine bytes & correct for temp offset (approximate)} 
  */
  return 42;
}

float averageTemperature()
{
  /*readTemperature(); // discard first sample (never hurts to be safe)

  float averageTemp; // create a float to hold running average
  for (int i = 1; i < 1000; i++) // start at 1 so we dont divide by 0
    averageTemp += ((readTemperature() - averageTemp)/(float)i); // get next sample, calculate running average

  return averageTemp; // return average temperature reading*/
  return readTemperature();
}


3) Compilar e instalar o RSMB

1. Fazer o download do RSMB (https://github.com/eclipse/mosquitto.rsmb)
2. Compilar o broker_mqtts da pasta mosquitto.rsmb/rsmb/src
3. Instalar o broker copiando o arquivo compilado broker_mqtts para o diretório /usr/bin/

$ cd ~/Downloads
$ git clone https://github.com/eclipse/mosquitto.rsmb
$ cd mosquitto.rsmb/rsmb/src/
$ make broker_mqtts

4) Criar arquivo de configuração do broker  

1. Crie um arquivo broker.cfgcom as confugurações abaixo:

$ nano ~/broker.cfg 

Obs: Copie e cole o conteúdo do broker.cfg abaixo. 
ctrl+o: Salva o arquivo
ctrl+x: Sai do editor. 
broker.cfg:
# will show you packets being sent and received
trace_output protocol      

#listener 1883 INADDR_ANY mqtt //Listen for MQTT Connections "Normal Broker"

listener 1883 INADDR_ANY mqtts //Listen for MQTT-SN Connections "Sensor Network Broker"

connection MY_MQTTSN_GATEWAY
 protocol mqtt
 address 198.41.30.241:1883 # 198.41.30.241 is the ip of iot.eclipse.org
 #address 127.0.0.1:1887 #local mosquitto broker
 topic # out


5) Fazer o setup do ambiente

1. Abra o primeiro terminal (ctrl+alt+t)
2. Encerre qualquer server que possa estar usando a porta 1883. No meu caso, quase sempre é o Mosquitto que esta ocupando essa porta.


 $ sudo killall mosquitto
3. Execute o broker_mqtts com o arquivo de configuração criado

$ cd ~/Downloads/mosquitto.rsmb/rsmb/src/
$ ./broker_mqtts ~/broker.cfg
4. Conecte a Arduino Mega (com o XBEE Router montado) ao PC (anote a porta serial ao qual está conectada)

5. Conecte o XBEE Explorer (com o XBEE Coordenator montado) ao PC (anote a porta serial ao qual está conectada)
 
5. Abra um segundo terminal

6. Execute o  Bridge Serial-UDP (~/Downloads/MQTT-SN-Arduino/serial-mqtts/ser_redir.py)
Obs: Antes de executar é necessário fazer as seguintes modificações no código:
SerPort = "/dev/ttyUSB0" (Deve ser a porta ao qual o XBEE Explorer está conectado)
Baud = 9600 (Baudrate configurado do XBEE Explorer)
BrokerHost = "127.0.0.1"
BrokerPort = 1883


$ cd ~/Downloads/MQTT-SN-Arduino/serial-mqtts/
$ python ser_redir.py
7. Aperte o botão de reset no shield XBEE.
Obs: Isso vai fazer com que a Arduino inicie o processo de conexão com o Gateway e sucessivamente com o broker online (iot.eclipse.org)

6) Testar a comunicação com o broker mqtt
1. Abra um terceiro terminal
2. Lance um cliente que se inscreva no tópico "arduino/temp"

$ mosquitto_sub -h iot.eclipse.org -p 1883 -t arduino/temp 
3. Se esse cliente estiver recebendo as publicações deste tópico então a conexão com o broker MQTT e o Gateway MQTT-SN estão funcionando corretamente.


Fontes:
[Para postar o código no post]
http://hilite.me/
https://www.engineersgarage.com/Tutorials/IoT-Communication-MQTT-SN-RSMB-Mosquitto-Broker
https://www.engineersgarage.com/Tutorials/RSMB-Broker-for-MQTT-SN

terça-feira, 27 de março de 2018

[Cookbook] Arduino recebendo comandos pela serial

 Permite enviar comandos para a Arduino pela serial.


1. Fazer o upload do código abaixo para a Arduino

// Buffer to store incoming commands from serial port
String inData;

void setup() { 
    Serial.begin(9600);
    Serial.println("Command input started.\n");

    Serial.println("Usage:\n\
                test - Print a test message\n\
                test2 - Print a test2 message\n");
}

void loop() {
    while (Serial.available() > 0)
    {
        char recieved = Serial.read();
        inData += recieved; 

        // Process message when new line character is received
        if (recieved == '\n'){
            Serial.print("Arduino Received: ");
            Serial.print(inData);
            //remove special characteres if this exists
            inData.remove(inData.lastIndexOf('\n'));
            inData.remove(inData.lastIndexOf('\r'));

            if(inData.equals("test")){
                Serial.println("TEST Command Executed");
            }
            else if(inData.equals("test2")){
                Serial.println("TEST2 Command Executed");
            }
            else Serial.println("Unknown Command!");

            inData = ""; // Clear recieved buffer
        }
    }

}
Fonte:
https://electronics.stackexchange.com/questions/45543/how-do-i-receive-an-entire-string-as-opposed-to-1-character-at-a-time-on-the-ard

quarta-feira, 21 de março de 2018

Problema com porta USB da Arduino


    Por padrão, o acesso a serial e portas USB no linux estão restritas ao usuário root e usuários no grupo dialout.

    Para ter dispositivos comunicando através da porta serial é necessário que o nosso usuário Linux pertença ao grupo dialout.

Passos:

1. Abra o terminal
2. Execute o seguinte comando, onde [usuário] se refere ao usuário que você quer adicionar ao grupo dialout.
$ sudo usermod -a -G dialout [usuário]

Para verificar os grupos ao qual o usuário pertece:
$ groups [usuário]



Fonte:
https://playground.arduino.cc/Linux/Debian

terça-feira, 20 de março de 2018

Rede Mesh Xbee

Introdução:
    Uma rede mesh com XBee permite que se tenha uma rede que se auto configure em caso de algum nodo sair da rede, ou caso algum novo nodo apareça. Contanto que exista uma caminho entre um "Router" e o "Coordenator" é possível envi
ar informação para uma "central".

Materiais necessários:
Coordenator:
1x XBee Explorer (para configurar a XBee)
1x Cabo USB Mini (para conectar ao XBee explorer)
1x XBee Série 2 (É dito que a S1 não suporta Rede Mesh)

Router:
1x Arduino Mega
1x XBee Série 2
1x Cabo USB A/B



Pré-requisitos:
1. Ter o XCTU instalado

Passos:
1) Configurar o módulo XBee como Coordenator
2) Configurar o módulo XBee como Router
3) Montar o setup de teste
4) Testar a rede trocando mensagens

1) Configuração do módulo XBee como Coordenator


2) Configuração do módulo XBee como Router



3) Montar o setup de teste

1. Montar O XBee Coordenator no XBee explorer.


2. Montar o XBee configurado como Router na shield e na Arduino e fazer a fiação como no diagrama abaixo:
Dout -> TX3
Din -> RX3
Montagem Arduino + Shield XBee + XBee
Foto da montagem

3. Fazer o Upload do código abaixo para a Arduino

void setup()
{
  Serial.begin(9600);
  Serial3.begin(9600);
}

void loop()
{
  if (Serial.available())
  { // If data comes in from serial monitor, send it out to XBee
    Serial3.write(Serial.read());
  }
  if (Serial3.available())
  { // If data comes in from XBee, send it out to serial monitor
    Serial.write(Serial3.read());
  }
}
4) Testar a rede trocando mensagens
1. Conectar o Coordenator no PC
2. Abrir o XCTU e Conectar e Escanear por dispositivos
3. Selecionar o XBee Coordenator (Item 1 da imagem abaixo)
4. Selecionar a aba de Terminal (Item 2 da imagem abaixo)
5. Conectar o modulo (Item 3)
6. Tudo que for digitado aqui (Item 4) será enviado para todos os módulos da rede mesh
7. Conecte a Arduino, com o XBee montado, ao PC
8. Abra a IDE da Arduino e então abra o serial monitor
9.  Agora será possível visualizar os dados enviados pelo coordenator
Obs: Tudo que for digitado no terminal da Arduino também aparece no Terminal do XCTU

Considerações finais
Essa rede pode comportar muitos novos Nodos, para isso, somente é necessário que mantenham as mesmas configurações de Router. 

Próximos passos
Introduzir o uso do protocolo MQTT-SN para aumentar a confiabilidade da rede e padronizar a comunicação entre os sensores da rede.
Analisar  o que acontece quando um novo nodo Coordenator aparece na rede.
Verifica o limite de nodos nesta rede.
Analisar a distância máxima entre 2 nodos.
Analisar o consumo de corrente e métodos par economizar bateria.

Problemas durante os passos
1. Sem o módulo XBee explorer não foi possível fazer com que o XCTU identificasse o XBee montado no shield do FilipeFlop. Aparentemente, este é uma shield mais simples em que só é possível fazer a Arduino se comunicar com o XBee e nada mais. O shield XBee da sparkfun permite configurar os módulos XBee apartir de um código previamente carregado na arduino. Porém o laboratório ainda não tem esta shield.
Solução: Utilizar o XBee Explorer para configurar as XBees.

2. XCTU não reconhece o XBee explorer, talvez por falta de drivers.
Solução: Intalar os driver Seguindo esse post: http://bytespassivos.blogspot.com.br/search?q=Instalar+drivers+FTDI



Fontes:
http://www.instructables.com/id/XBee-Mesh-Network-Construction/
https://www.filipeflop.com/blog/tutorial-wireless-arduino-xbee-shield/


segunda-feira, 19 de março de 2018

Instalar drivers FTDI

1) Download dos driver no site da FTDI
1. Faça o download do driver no link:
http://www.ftdichip.com/Drivers/D2XX.htm
No meu caso foi na linha "Windows" coluna "x64 (64-bit)".
2. Descompacte o arquivo baixado.

2) Instalação do driver
1. Abrir o Gerenciador de Dispositivos
2. Click direito no dispositivo não instalado (Provavelmente ele estará com uma exclamação amarela)
3. Selecionar "Atualizar Driver..."
4. Selecionar "Procurar software de driver no computador"
5. Clicar em "Procurar" e então encontre a pasta em que você descompactou o driver
6. Confirme se a opção incluir subpastas está marcada e então click em "Avançar" 
7. Pronto! Seu driver provavelmente estará instalado. Deve estar indicado a partir de agora um "COM" junto ao dispositivo no Gerenciador de Dispositivos

Possíveis problemas:
1. Fiz o processo mas ainda continua aparecendo a exclamação.
Solução: Tentar instalar o driver para este dispositivo com a exclamação seguindo os mesmos passos.

quinta-feira, 8 de março de 2018

Testando o módulo GPRS SIM800

    Este tutorial serve unicamente para prepara o módulo SIM800 para receber comandos AT e verificar se o mesmo está funcionando e se comunicando com a rede telefônica.

Materiais necessários:
1x Cartão SIM com crédito
1x Arduino de qualquer tipo
1x Modulo GPRS SIM800
1x jumpers
1x Fonte externa + regulador de tensão 5V

Passos:
1. Inserir o cartão SIM ao módulo
2. Conectar o modulo ao Arduino
3. Fazer o upload do código para o Arduino
4. Testar conexão entre Arduino e SIM800
5. Testar conexão entre SIM800 e rede de telefonia celular

1.Inserir o cartão SIM no módulo
    Insira o cartão SIM no módulo como na imagem a seguir:



2. Conectar o modulo ao Arduino usando o seguinte diagrama de pinos
Obs: A alimenção 5V  do modulo deve ser preferencialmente externa para evitar que o SIM800 reinicie quando conectar a rede de telefonia celular.
Obs2: Os pinos 10 e 11 serão utilizados pela biblioteca SoftwareSerial para simular os pinos TX e RX. Precisamos disso pois os pinos TX e RX do Arduino serão utilizados para enviar os comandos AT.
Diagrama de pinos
3. Fazer o upload do código para o Arduino
    Fazer o upload do seguinte código para o Arduino:

#include < SoftwareSerial.h >


#define TX_PIN 10
#define RX_PIN 11


SoftwareSerial softSerial(TX_PIN, RX_PIN);


void setup(){
  //Terminal para debug
  Serial.begin(9600);
  while (!Serial);


  //Comunicacao com o SIM800L
  softSerial.begin(4800);
  delay(1000);


  Serial.println("Debugging SIM800L!");
}


void loop(){
  //Print dos dados recebidos pelo modulo
  if (softSerial.available()){
    Serial.write(softSerial.read());
  }


  //Envio de comandos AT para o modulo
  if (Serial.available()){
    softSerial.write(Serial.read());
  }
}


4. Testar conexão entre Arduino e SIM800
    1. Abra o Terminal Monitor do Arduino IDE
    2. Seleciona a velocidade de Baud rate para 9600 e coloque o tipo de sufixo como "Nova linha"
    3. Digite AT na entrade de texto na parte superior do terminal e clique em Enviar (ou aperte enter)
    4. Se o modulo estiver dividamente conectado e alimentado será retornado a mensagem "OK"

5. Testar conexão entre SIM800 e rede de telefonia celular
    Para testar a conexão com a rede de telefonia celular insira os códigos da tabela a seguir e confirme se a resposta coincide com o esperado.
    Caso todos os códigos sejam executados sem erro e no final seja possível ver a string lida do servidor então a configuração do SIM800 com conexão com a internet está funcionando perfeitamente.

Comando AT Resposta Esperada Descrição
AT+SAPBR=3,1,"Contype","GPRS"OKDefine o tipo de conexão para GPRS
AT+SAPBR=3,1,"APN","claro.com.br"OKVai conectar com a rede de telefonia celular.
O APN depende da operadora.
CLARO:claro.com.br
TIM:timbrasil.br
VIVO:zap.vivo.com.br
OI:gprs.oi.com.br
AT+SAPBR =1,1OKAtiva o GPRS (Só precisa ser executado uma vez)
AT+SAPBR=2,1+SAPBR:1,1,"100.115.10.37"

OK
Consulte se a conexão for configurada corretamente, se o retorno for um endereço IP, então podemos prosseguir
AT+HTTPINITOKAtiva o modo HTTP (Só precisa ser executado uma vez)
AT+HTTPPARA="CID",1OKConfigura o identificador de perfil HTTP
AT+HTTPPARA="URL","http://api.thingspeak.com/channels/44232/feed/last.json"OKDefine a URL que iremos acessar
AT+HTTPACTION=0+HTTPACTION: 0,200,98

OK
Inicia o download de dados via HTTP GET
AT+HTTPREAD+HTTPREAD: 98
{"field1":"2380.4797000000","field2":"14072","created_at":"2015-10-08T12:37:08Z","entry_id":55492}

OK
Printa os dados lidos da via HTTP GET


Código para fazer teste de conexão automatizado (OPCIONAL)
    Para executar a inicialização automática digite * e tecle enter no terminal monitor.

#include < SoftwareSerial.h >

#define TX_PIN 11
#define RX_PIN 10
#define TIMEOUT 5000

SoftwareSerial softSerial(TX_PIN, RX_PIN);

int timeout(long _delay){
 int flag = 0;//marca se o modulo respondeu antes do timeout Acabar
 _delay = _delay/50;
 for(int i = 0; i<50 font="" i="">
  if(!softSerial.available())delay(_delay);
  else flag = 1;
  Serial.print('.');
 }
 Serial.print('\n');
 return flag;
}

void sendAtCmd(char* str){
  int i = 0;
 softSerial.println(str);

 //aguarda a resposta do modulo
 while (!softSerial.available()){
    delay(500);
    i++;
    if(i>=TIMEOUT/500){
      Serial.print(str);
      Serial.println(" REACHED TIMEOUT!");
      break;
    }
 }

 Serial.print(">>");
 while (softSerial.available()){
    Serial.write(softSerial.read());
 }
}

void initSim800(){
  Serial.println("Sim800L Auto Test Running...");
  sendAtCmd("AT+SAPBR=3,1,\"Contype\",\"GPRS\"");
  sendAtCmd("AT+SAPBR=3,1,\"APN\",\"claro.com.br\"");
  sendAtCmd("AT+SAPBR=1,1");
  timeout(2000);
  sendAtCmd("AT+SAPBR=2,1");
  timeout(2000);
  sendAtCmd("AT+HTTPINIT");
  sendAtCmd("AT+HTTPPARA=\"CID\",1");
  sendAtCmd("AT+HTTPPARA=\"URL\",\"http://date.jsontest.com\"");
  sendAtCmd("AT+HTTPACTION=0");
  timeout(15000);
  sendAtCmd("AT+HTTPREAD");
  timeout(2000);
  Serial.println("Sim800L Auto Test Done!");
}

void setup(){
  //Terminal para debug
  Serial.begin(9600);
  while (!Serial);

  //Comunicacao com o SIM800L
  softSerial.begin(4800);
  delay(1000);

  Serial.println("Debugging SIM800L!");
}

void loop(){
  //Print dos dados recebidos pelo modulo
  if (softSerial.available()){
    Serial.write(softSerial.read());
  }

  //Envio de comandos AT para o modulo
  if (Serial.available()){
    char ch = Serial.read();
    if(ch == '*'){
        initSim800();
    }
    else softSerial.write(ch);
  }
}


Possíveis problemas:
1. O comando AT não retorna nada e os comandos estão se acumulando exemplo de saída: ATatatAT.
Solução: Provavelmente o tipo de sulfixo está selecionado como "Nenhum fim-de-linha". Confirme se o tipo de sulfixo esta em "Nova linha". Os outros tipos também funcionam.

Fontes:
[Manual SIM800]
http://img.filipeflop.com/files/download/SIM800+Series_AT+Command+Manual_V1.09.pdf
[Conexão GPRS com HTML]
http://www.raviyp.com/embedded/194-sim900-gprs-http-at-commands
[APNs do Brasil]
https://www.arduinoecia.com.br/2015/11/acessar-internet-arduino-gsm-shield-sim900.html
[Como ter acesso a internet com módulo GPRSSIM900]
https://www.arduinoecia.com.br/2015/11/acessar-internet-arduino-gsm-shield-sim900.html

quarta-feira, 7 de março de 2018

Introdução ao Firebase

Firebase é uma plataforma de serviços na nuvem. Possui varios tipos de serviços para auxiliar o desenvolvimento back-end de aplicações web e mobile.

Serviços mais interessantes para IoT:
Autenticação – suporte para autenticação de usuários via e-mail, Facebook, GitHub, Google Sign-In e Twitter. Útil para fazer o login em um app ou aplicação web;
Database - um banco de dados NoSQL utilizado para armazenar dados JSON
Dynamic Links - deep links para possibilitar que o usuário acesse  links diferentes dependendo de qual dispositivo ele esta usando e quais aplicativos ele tem instalado. Útil para por em QRCodes e ter um controle de quem está acessando os links;
Real time - os dados são armazenados em tempo real no banco de dados
Storage - armazena as mídias do usuário, como áudio, imagens e vídeos;

Fontes:
https://blog.mastertech.tech/tecnologia/google-firebase-for-dummies-o-que-e-e-como-funciona-plataforma/