Interface com sensores e o IoT Car

Azure IoT Hub

Essa é a segunda parte de uma série de três artigos focada no desenvolvimento de uma aplicação de IoT. Nela será abordada a leitura de sensores e o envio dos dados obtidos para a nuvem. O sistema embarcado escolhido para este propósito foi uma solução de SBC customizado da Toradex: o CoM Colibri VF61 + Placa Base Iris. Como um retrospecto, a figura 1 apresenta um diagrama de blocos que ilustra a proposta da aplicação desenvolvida nesta série de artigos como um todo.

 

Diagrama em blocos da aplicação do IoT Car
Figura 1: Diagrama em blocos da aplicação

 

Para mais informações, o primeiro artigo da série contém detalhes sobre o projeto, guiando o usuário pela configuração do serviço Hub IoT e o posterior envio de dados usando o sistema embarcado Toradex.

 

 

Adicionando módulos de sensores à placa Iris

 

Os sensores usados neste projeto para gerar dados e o módulo para conectar com a internet via wifi são:

  • MPU-6050 giroscópio + acelerômetro e temperatura;
  • HC-SR04 módulo sensor de distância;
  • IKeyes GPS shield v1.2;
  • WL250N USB WiFi.

 

O MPU-6050 já tem um módulo do Kernel para interface com aplicações do Linux (Kernel versão 4.4.0 revisado para os CoM's Toradex Vybrid). No documento deste link há um fragmento de device tree necessário para habilitar a interface de hardware do sensor. Uma vez que este módulo não está habilitado no Kernel por padrão, há a necessidade de incluí-lo. Neste caso, este artigo tem instruções detalhadas sobre como configurar, compilar e atualizar o Kernel do sistema embarcado. Uma vez que o MPU-6050 possui o mesmo endereço de I²C do RTC presente no módulo (0x68), a solução mais fácil encontrada para solucionar essa questão foi conectar o pino AD0 do MPU-6050 à alimentação +3,3V, o que felizmente muda seu endereço para 0x69.

 

O HC-SR04 tem um módulo postado no Github, portanto foi feito um "fork" deste projeto e o módulo foi modificado e compilado para a versão 4.4.0 do Kernel, usada na Colibri VF61. Tanto o código modificado quanto o módulo compilado para o CoM Toradex podem ser encontrados aqui.

 

A comunicação do módulo GPS é feita via UART e sua interface com o Linux por meio do serviço GPSD. Mais informações sobre o GPSD podem ser encontradas aqui. Se você tem interesse em compilar sua própria imagem, há uma receita do OpenEmbedded disponível para o serviço GPSD. Neste caso, o artigo do Raul Munoz sobre OpenEmbedded e o artigo do Cleiton Bueno sobre Yocto podem ser de grande valia.

 

Com o objetivo de configurar o GPSD, carregar o módulo do HC-SR04 e começar a enviar dados para a nuvem sempre que houver um reboot ou o sistema for iniciado, foi criado um serviço que chama um script de inicialização. Assumindo que o repositório do Github para este artigo já está clonado na placa, é possível acessar o arquivo do serviço (car.service) e o script de inicialização (init.sh). Para que isto funcione, alguns passos devem ser seguidos: primeiramente, o repositório do Github deve estar dentro do repositório /home/root. Então o arquivo car.service deve ser copiado em /lib/systemd/system e o serviço habilitado. Os passos a seguir descrevem o processo feito do início:

 

[email protected]:~# git clone https://github.com/leograba/azure-iot-car.git 
[email protected]:~# cd azure-iot-car 
[email protected]:~# cp car.service /lib/systemd/system 
[email protected]:~# systemctl enable car.service 

 

Se houver a necessidade de parar o serviço após o boot, ou seja, parar de enviar mensagens para o Hub IoT, o seguinte comando deve ser executado:

 

[email protected]:~# systemctl stop car.service 

 

O adaptador USB WiFi WL250N pode ser usado diretamente, porém é preciso configurar a rede à qual ele deve se conectar. Instruções para configurar a conexão são encontradas aqui.

 

No que diz respeito à conexão entre os módulos e a placa base Iris, somente pinos do conector x16 - a barra de pinos - foram usados. O datasheet técnico da Iris tem informações úteis sobre interfaces, conectores, etc, e há também o datasheet do SoM Colibri VF61, para consultas mais aprofundadas, quando necessário. A tabela 1 apresenta a correspondência entre os pinos da Iris e os pinos dos módulos. A figura 2 ilustra a conexão do MPU-6050 e do HC-SR04 em um estágio inicial de desenvolvimento.

 

Tabela 1:Conexão entre os sensores e a placa base Iris

Barra de pinos(x16)

Descrição

Módulo

Pino

5

I²C SDA

MPU 6050

SDA

6

I²C SCL

MPU 6050

SCL

7

GND

MPU 6050 / HC-SR04 / GPS

GND / GND / GND

12

+5V

MPU 6050 / HC-SR04 / GPS

VCC / VCC / 5V

17

GPIO

HC-SR04

Trig

18

GPIO

HC-SR04

Echo

31

UART_B-Rx

GPS

Tx

32

UART_B-Tx

GPS

Rx

33

+3.3V

HC-SR04

AD0

 

 

Conectando o MPU-6050 e o HC-SR04 à Iris
Figura 2: Conectando o MPU-6050 e o HC-SR04 à Iris

 

 

O IoT Car

 

Depois que todos os módulos foram interfaceados ao sistema embarcado Toradex, o próximo passo foi embarcá-lo em um carro de controle remoto, conforme ilustrado na figura 3. É um processo direto, mas algumas considerações podem ser úteis.

 

O protótipo do IoT car
Figura 3: O protótipo do carro IoT

 

Uma vez que o GPS tem uma antena ativa, o módulo em si foi colocado embaixo do sistema Toradex e então a antena foi fixada ao teto do carro, pelo lado de fora. Para acomodar o sensor de distância, um par de furos foi feito no para-choque, conforme também pode ser observado na figura 3. O módulo do acelerômetro foi firmemente fixado a uma placa de circuito do carro, uma vez que a orientação da PCB é paralela ao chão, possibilitando o uso dos dados do módulo sem calibração adicional (embora em uma aplicação real a calibração possa ser necessária).

 

Com relação à alimentação do sistema embarcado, uma bateria LiPo de duas células (2S – 7,4V), com 1200mAh de capacidade, foi escolhida. Considerando que o consumo de corrente do sistema é de cerca de 200mA e que uma regra prática para descarga de baterias LiPo é que não se deve descarregar mais do que 80% da capacidade, então o sistema pode funcionar por até 4,8 horas. A figura 4 apresenta o IoT Car finalizado:

 

IoT Car
Figura 4: IoT Car

 

 

Lendo os sensores e enviando para a nuvem

 

Os dados do MPU-6050 e do HC-SR04 podem ser obtidos por meio da leitura de arquivos, enquanto para obter os dados do GPS há um módulo do Node chamado Bancroft que se comunica com o GPSD.

 

Com relação ao módulo HC-SR04, o valor retornado pelo módulo do Kernel é o tempo em microssegundos entre enviar um pulso de ultrassom e recebê-lo de volta. Para converter este valor para metros, ele deve ser multiplicado pela velocidade do som no ar (aproximadamente 340m/s) e então dividido por 2E6, que converte de microssegundos para segundos e divide o valor por 2, uma vez que metade do tempo corresponde à emissão do ultrassom e a outra metade ao eco. Simplificando:

 

distância = (valor_lido*velocidade_som)/2000000

 

Os dados do MPU-6050 têm valores de escala, uma vez que a resolução das aquisições pode ser configurada. O sensor de temperatura também tem um valor de offset inerente a cada sensor diferente. Para o propósito deste artigo, a configuração padrão do MPU-6050 será adotada e, para converter as leituras, a abordagem geral pode ser utilizada:

 

valor_ajustado = (leitura+offset)*escala

 

Após a conversão, as unidades são: aceleração - m/s²; giroscópio - °/s e; temperatura - °C.

 

O módulo GPS do Node retorna um objeto com valores no formato apresentado no exemplo abaixo, no qual a velocidade está em m/s e a timestamp em horário Unix:

 

{ 
timestamp: 1311296682000,  
latitude: 45.456445, 
longitude: -73.569651667, 
altitude: 28.9, 
  speed: 11, 
  track: 10.3788, 
  geometries: {     type: 'Point',    coordinates: [ -73.569651667, 45.456445, 28.9 ] } 
} 

 

A aplicação que faz a leitura dos dados e os envia para o Hub IoT é uma versão modificada da aplicação utilizada na parte 1, send_data.js. O arquivo que corresponde à aplicação aqui apresentada é o send_data_from_sensors.js e pode ser encontrado no repositório do Github que foi clonado previamente na placa. As principais considerações sobre o código modificado são que o módulo Bancroft emite eventos sempre que os dados do GPS são atualizados; e os caminhos para acessar os sensores são /sys/bus/iio/devices/iio:device2/ para o MPU-6050 e /sys/class/hcsr04/ para o HC-SR04. Abaixo, algumas partes do código serão explicadas.

 

Em primeiro lugar, as constantes de offset e escala são obtidas de maneira síncrona, prevenindo que o código leia um sensor e tente calcular um valor antes que o offset/escala esteja definido. Também são declaradas as variáveis que receberão os dados a serem enviados para a nuvem:

 

//Lê as constantes de offset e escala do MPU-6050 
var temp_offset = +fs.readFileSync('/sys/bus/iio/devices/iio:device2/in_temp_offset'); 
var temp_scale = +fs.readFileSync('/sys/bus/iio/devices/iio:device2/in_temp_scale'); 
var accel_scale = +fs.readFileSync('/sys/bus/iio/devices/iio:device2/in_accel_scale'); 
var anglvel_scale = +fs.readFileSync('/sys/bus/iio/devices/iio:device2/in_anglvel_scale'); 
var gps_coordinates ;//variável que recebe as informações do GPS 
// Dados a serem enviados para a nuvem 
var timenow, temperature, Distance, Acceleration = {}, Gyroscope = {};

 

Então, os eventos do GPS que são importantes para a aplicação são manipulados. Sempre que as coordenadas são atualizadas, elas são salvas em uma variável e, se a conexão com o módulo é perdida, é feita uma tentativa de reconexão:

 

// eventos do GPS 
bancroft.on('location', function (location) {//atualiza a variável com as coordenadas do GPS 
  location.geometries = "point"; 
  gps_coordinates = location; 
  console.log('got new location', gps_coordinates); 
}); 

bancroft.on('disconnect', function (err) {// se o GPS é desconectado 
  bancroft = new Bancroft();// tenta reconectar uma vez 
  console.log('trying to reconnect gps...'); 
});

 

A última parte de execução do código é a chamada das funções que lêem os sensores e que enviam dados para o Hub IoT em um loop. Loops separados foram usados para cada processo, buscando deixar o código mais flexível - por exemplo, caso haja a necessidade de fazer um log da leitura dos sensores em um arquivo de backup com maior frequência do que os dados são enviados para a nuvem:

 

// Loops que chamam as funções para ler sensores e enviar os dados para a nuvem 
sendInterval.handlerGet = setInterval(getAllSensors, sendInterval.timerGet); 
sendInterval.handlerSend = setInterval(sendToIotHub, sendInterval.timerSend); 

 

A função getAllSensors() chamada acima será omitida, mas seu funcionamento é simples: ela atualiza a variável que guarda o tempo no qual os dados começaram a ser lidos e então chama a função readSensor() para cada uma das medidas possíveis - distância, temperatura, aceleração nos 3 eixos e giroscópio nos 3 eixos. ReadSensor(), por sua vez, simplesmente lê um arquivo e imprime o erro no terminal, se este for o caso; no mais, ela funciona de forma análoga à função de acesso ao sistema de arquivos readFile().

 

//Função que lê dados de um sensor 
function readSensor(path, callback) { 
  fs.readFile(path, function (err, data) { 
    if(err){//se dados não puderam ser lidos 
      console.log("Error reading sensor: " + err); 
      callback(err, null);//passa o erro para a callback 
      return; 
    }
    callback(null, data);//callback sem erros 
  }); 
}

 

A função sendToIotHub() transforma o último conjunto de dados lidos em uma string codificada no formato JSON, encapsula a string em uma mensagem, imprime uma mensagem de feedback no terminal e envia os dados para o Hub IoT. Ela é também a última parte do código a ser descrita no artigo, e pode ser observada abaixo:

 

function sendToIotHub() { 
  // Adiciona os dados a uma string codificada em JSON 
  var data = JSON.stringify({ 
    ObjectName: 'toradex2', 
    ObjectType: 'SensorTagEvent', 
    temp: temperature, 
    acceleration: Acceleration, 
    gyroscope: Gyroscope, 
    gps: gps_coordinates, 
    distance: Distance, 
    boardTime: timenow 
  }); 
 
  var message = new Message(data);// Encapsula a mensagem a ser enviada 
  message.properties.add('myproperty', 'myvalue'); 
  console.log('sending message to the IoT Hub: ');// Mensagem de feedback 
  console.log(data); 
  client.sendEvent(message, printResultFor('send'));// Envia para o Hub IoT 
}

 

 

Considerações e próximos passos

 

Até agora, na primeira parte desta série de artigos, os objetivos do projeto e uma visão geral sobre a internet das coisas foram apresentados. Em seguida, o serviço Hub IoT do Azure foi configurado para receber mensagens enviadas pelo sistema embarcado Toradex (e também enviar mensagens, embora isto não seja explorado neste projeto), algumas considerações sobre o envio de dados do sistema embarcado foram feitas e, finalmente, foi apresentado um meio que permite obter os dados da nuvem, com o objetivo de verificar que tudo está funcionando conforme o esperado.

 

Então, o presente artigo teve como foco o sistema embarcado do projeto. Ele começou com os passos realizados para a interface dos sensores/módulos à Colibri VF61 + Placa Base Iris e finalizou com detalhes sobre a aplicação em Node.

 

Com tudo isso funcionando, os pontos a serem explorados no próximo artigo são o uso do Azure Stream Analytics e do Microsoft Power BI para filtrar dados e disponibilizá-los de maneira fácil de ser compreendida, com o objetivo de facilitar o trabalho de extração de insights e a geração de business intelligence. Aproveito também para agradecer à equipe do Grupo Viceri pela exímia competência no que diz respeito ao Azure e business intelligence e, portanto, pela ajuda nestes quesitos, assim como pela parceria no desenvolvimento do projeto descrito nesta série de artigos. Espero que este artigo tenha sido útil e nos vemos em breve na parte 3!

Outros artigos da série

<< Enviando dados para a nuvem com Azure IoT HubUsando serviços de nuvem para coletar business intelligence >>
NEWSLETTER

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Obrigado! Sua inscrição foi um sucesso.

Ops, algo deu errado. Por favor tente novamente.

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Deixe um comentário

avatar
 
  Notificações  
Notificar