Capturando e Analisando Dados

A idéia é exportar os dados capturados através do Arduíno e enviados pela porta serial do PC num arquivo texto para posterior análise (leitura e visualizações) usando o Matlab.

Capturando dados da porta serial

Primeiramente vamos usar um simples código em Python capaz de ler dados de uma porta serial, 2 colunas de dados "float" (4 casas decimais) e gravar estes dados num arquivo texto, seguindo o mesmo formato (uma cópia), até que o usuário digite uma tecla e isto provoque o fim da captura de dados e fechamento do arquivo texto com os dados capturados.

Para ler dados de uma porta serial e gravar esses dados em um arquivo texto, você pode usar a biblioteca pyserial para a comunicação serial. Aqui está um exemplo de como você pode fazer isso:

  1. Primeiro, certifique-se de que você tem a biblioteca pyserial instalada. Você pode instalá-la usando o seguinte comando:

  2. Aqui está o código Python para ler os dados da porta serial e gravar em um arquivo texto até que o usuário pressione uma tecla:

Código: capture_serial_data.py

Explicação do Código

  1. Importações e Configurações:

    • Importamos as bibliotecas necessárias: serial para comunicação serial, threading para gerenciamento de threads e os para manipulações do sistema operacional.
    • Configuramos a porta serial (porta_serial) e a taxa de baude (taxa_baude).
  2. Função espera_tecla:

    • Esta função simplesmente espera que o usuário pressione Enter para definir a variável global capturando como False, o que irá parar a captura de dados.
  3. Função captura_dados:

    • Abre a porta serial e o arquivo texto para escrita.
    • Em um loop, lê linhas da porta serial, decodifica-as e escreve no arquivo até que capturando seja definido como False.
  4. Controle da Captura:

    • Usamos uma variável global capturando para controlar o loop de captura.
    • Iniciamos a captura em uma thread separada para que o programa possa continuar rodando enquanto captura os dados.
    • Chamamos espera_tecla para esperar a entrada do usuário.
    • Após a entrada do usuário, esperamos a thread de captura finalizar com join().

Execução

Para executar este código:

  1. Certifique-se de que sua porta serial está correta.
  2. Execute o script Python.
  3. O programa começará a capturar dados da porta serial e escrever no arquivo dados_capturados.txt.
  4. Pressione Enter para parar a captura.

Este código deve funcionar no macOS e também em outras plataformas, desde que a biblioteca pyserial esteja instalada e configurada corretamente.

Teste:

Executando:

Arquivo exemplo gerado: dados_capturados_LDR.txt:

Obs.: Note que foi criado um programa em C para o Arduíno ( captura_dados_delay_1ms.ino ) para capturar dados do seu conversor A/D à taxa de 1 ms (sem usar ISR). Isto é, o código aloca dinamicamente a maior quantidade de memória disponível para um vetor onde os dados amostrados serão temporariamente armazenados. Este código mostra o instante inicial em que foi iniciada e finalizada a captura de dados, e assim é possível determinar a taxa de amostragem atingida. Depois que a captura de dados é finaliza, os dados armazenados neste vetor e outras informações relevantes são exportadas pela porta serial. Considerar que enviar dados pela porta serial pode consumir mais tempo que o menor período de amostragem que poderia ser obtido usando o Arduíno.

FFT sobre dados capturados

Recordando de Usando função fft do Matlab...

O arquivo gerado anteriormente (dados_capturados_LDR.txt) pode ser editado (num editor de textos comum) para ficar apenas com 2 colunas numéricas separadas por espaço em branco. O Matlab pode ser usado para ler este arquivo usando o comando:

Supondo que neste caso, foi criado um novo arquivo chamado: dados_LDR_1ms.txt. O comando anterior lê os dados do arquivo para o vetor . Este arquivo contêm os dados apenas do sinal bruto, sem nenhum escalonamento (valores inteiros variando entre 0 à 1023 já que o A/D do Arduíno é de 10-bits). Este arquivo em particular contêm 674 amostras que em teoria foram capturados à uma taxa de 1 ms (1 KHz). Gastou-se 749 mili-segundos para gerar estes dados, o que significa que o código usado no Arduíno para captura destes dados, não trabalhou na taxa desejada de 1 mili-segundo entre amostras, mas sim:

segundos ou, Hz.

A figura abaixo mostra o resultado temporal desta amostra de dados:

sinal_LDR_1ms_amostras_validas

Obs.: O sinal brutro (variando entre 0 à 1024) foi re-escalonado para a faixa de 0 à 5 Volts.

Enfim, considerando-se esta taxa de amostragem, ignorando algumas amostras iniciais (x=x(49:length(x));), resultando em 626 pontos amostrados, foi obtido o seguinte espectro deste sinal:

espectro_sinal_LDR

Nota-se o componente DC de Volts (conforme esperado) e outros componentes menores até a faixa dos 1,5 Hz:

espectro_sinal_LDR_zoom

Percebe-se um pico de 3,467 mV de pico ocorrendo em 120,75 Hz e outros próximos desta frequência:

espectro_sinal_LDR_ruidos

Porém note que este pico em 120 Hz é de apenas 3,5 mV, uma amplitude muito baixa se comparado com o nível CD do sinal (frequência zero) de aproximadamente 3,0 Volts; (ou dB).

Note ainda que a "resolução" (passo) frequencial do gráfico espectral está em: Hz.

Uma análise mais "visual" do sinal no domínio tempo parece revelar um "ripple" de 14,648 mV de pico ocorrendo na frequência aproximada de 128,55 Hz, ou a cada 7 amostras aproximadamente:

sinal_LDR_1ms_ripple

O que significa que eventualmente um filtro de média móvel de 7 ou 8 passos seria suficiente para filtrar o componente oscilatório presente neste sinal.

 


🌊 Fernando Passold 📬 ,