Posts Tagged ‘ Microcontrolador ’

Python + Arduino (Parte 2)

Além de plotar gráficos, com o Python é possível criar interfaces para modificar parâmetros do microcontrolador, enviando dados pela porta serial.

Como já visto na Parte 1 deste assunto, é preciso instalar o PySerial além do Python.

Desta vez eu fiz em uns 30 minutos um programa para enviar ao Arduino um número de 0 a 255 (8-bit) que serve para mudar o valor da resistência de um potenciômetro digital que deveria estar ligado à um amplificador de som.

Estou sem o amplificador no momento, então, para visualizar as mudanças coloquei um led para acender com PWM dentro do programa do arduino.

/*
 * Exemplo de leitura serial com o Arduino
 * Colocar isso dentro de um loop do programa
 */

char palavra[10];
unsigned char valor;

if (Serial.available()) {
    delay(100);
    unsigned char n = 0;
    while (Serial.available() > 0) {
        palavra[n++] = (Serial.read());
        //Cuidado com escrita fora do array
    }
    palavra[n] = '\0';

    valor = atoi(palavra);

    /*Usar o 'valor' para fazer alguma coisa, 
      como acender um Led com PWM*/
}

Outro dia coloco vídeo do sistema funcionando.

Anúncios

Python + Arduino

Não, ainda não dá para programar em Python para o ATmega, mas dá para acessar a porta serial pelo Python.

Recentemente descobri a existência do PySerial, um módulo para fazer acesso às portas seriais pelo Python, que tem me ajudado bastante a processar dados adquiridos pelo meu microcontrolador.

A melhor parte é que você pode coletar dados e, com ferramentas como Numpy e Matplotlib fazer diversas transformações e plotar gráficos bem interessantes.

Por exemplo, tenho um display de LCD cuja intensidade de luz é controlada por PWM provido pelo Arduino. A intensidade é escolhida de acordo com um valor lido num divisor resistivo com um resistor de 4.7K e um foto-resistor (LDR) que varia de 0 a 20K.

Eu escrevi um pouco sobre LDR aqui.

Para fazer o PWM, a tensão é lida numa porta analógica e passa por uma função escolhida empiricamente para a intensidade de luz ficar adequada ao ambiente. Sabe aquela coisa de que você tá querendo dormir e tem sempre um led de computador, televisão, aparelho de DVD ou outros aceso? Neste caso, o display fica com um mínimo de luminosidade quando está escuro.

Abaixo um gráfico gerado pelo sensor, usando Python.

Tensão lida(Azul), PWM (Verde) X Horário do dia:

Coloquei no pastebin um pequeno script em Python para coletar dados e salvar num arquivo.

Modo de uso:
1) Primeiro modifique a porta serial para a que você usa. No Linux é “/dev/ttyUSB“, no Windows é “COM“. Escolha também a taxa de transmissão adequada. O meu Arduino fica variando de /dev/ttyUSB0 para /dev/ttyUSB1, por isso tem uma função que busca a porta aberta.

2) Chame o script passando o número de amostras (o microcontrolador deve mandar quebras de linhas entre as amostras) e o nome do arquivo a ser gerado. Exemplo:

$ python meu_script.py 1234 nome_do_arquivo.txt

Para interromper a amostragem, aperte Ctrl+C e os dados serão salvos no arquivo antes de terminar o programa.

Para número indeterminado de amostras, coloque 0. Vai ficar pegando dados até você apertar Ctrl+C.

Programa foi escrito para Python 3, mas a única modificação necessária para Python 2 é retirar a chamada de str() na função de amostragem, pois a aquisição de dados é feito em strings de bytes e não unicode.

Os dados são salvos no arquivo assim:

['123', '546', '789', ... ]

Para obtê-los novamente no Python, faça:

>>> minha_lista = eval(open('nome_do_arquivo.txt').read())

Se estiver usando valores inteiros, converta a lista:

>>> minha_lista = [int(i) for i in minha_lista]

Caracteres personalizados

Estava vendo um post do Hack a day que mostrava um relógio num display de texto com os caracteres personalizados.

Cada letra do display de texto, ao menos esses com controlador HD44780 ou similar, é uma pequena matriz de 8 linhas por 5 colunas, sendo que você apenas escolhe o carácter e o controlador preenche a matriz.

Para estilizar os caracteres, você precisa gravar novos na memória volátil do controlador do LCD, sendo que ela tem espaço apenas para 8 (0 a 7 da tabela ASCII, não podem ser impressos). Os outros não podem ser modificados.

A ideia aqui é juntar 3 colunas para formar um número grande. Para isso, é preciso criar os caracteres que vão ser usados para desenhar as partes do número, sendo que precisam ser bem genéricos para que caibam nos 8 espaços da memória.

No caso eu usei 5 caracteres. Os três acima e as versões invertidas dos dois últimos. E criei os números como abaixo:

Para criar cada um dos 5 caracteres estilizados, é preciso enviar ao LCD o formato de cada uma das 8 linhas com números de 0 a 31, onde cada bit acende um ponto da linha. Você pode usar notação binária (por exemplo 0b10101) ou colocar o número decimal correspondente, se achar mais fácil.

Com as bibliotecas do Arduino, pode ser feito algo como:

LiquidCrystal lcd(2, 3, 4, 8, 9, 10, 11);
byte meus_chars[][8] = {{31,31,31,31,31,31,31,31}, 
                        {31,31,0,0,0,0,0,0},   
                        {0,0,0,0,0,0,31,31},
                        {31,31,0,0,0,0,0,31},
                        {31,0,0,0,0,0,31,31}};

for (byte i=0; i<5; i++){
    lcd.createChar(i, meus_chars[i]);
}

//Exemplo de exibição do número 0
lcd.clear();
lcd << '\0' << '\1' << '\0';
lcd.setCursor(0,1);
lcd << '\0' << '\2' << '\0';

Falando nisso, baixe a biblioteca Streaming que faz overload do << para imprimir coisas no LCD ou na Serial.

Abaixo um vídeo dos números no display:
Meu display 16×2 ainda não chegou. Enquanto isso, continuo com esse 8×2.

Projeto com display LCD

Com o advento do Arduino, fazer sistemas caseiros de controle ficou bem mais fácil, pois a IDE desse microcontrolador traz diversas bibliotecas que precisam de pouca configuração para acessar outros hardwares.

No final de semana eu fiz um pequeno projeto onde a hora e temperatura eram apresentadas num display LCD de texto com espaço para 8 caracteres em cada uma das suas duas linhas.

Para medir a temperatura eu usei um termômetro digital da Dallas Semiconductor, o DS18B20, que tem precisão de 0.0625 grau e já vem calibrado de fábrica.

Esse termômetro é um hardware bastante interessante, pois usa um protocolo chamado 1-Wire que permite diversos aparelhos conectados num fio e pode ser alimentado de forma parasita (pelo próprio fio de comunicação). Inclusive eu testei com dois termômetros conectados no mesmo fio e ambos apresentavam sempre a mesma temperatura (com uma diferença de no máximo 0.1 grau).

Basicamente, eles funcionam com um endereçamento de 64 bits, fazendo com que não exista confusão na comunicação. Essa forma de utilização é conhecida como microlan.

Para ajustar o horário, a solução mais simples foi mandar um comando serial para o microcontrolador, já que ele está conectado à USB e não tinha botões para colocar.

Abaixo deixo um vídeo onde eu seguro o termômetro e a temperatura (que já estava alta pelo calor do verão) aumenta um pouco mais.

Esse relógio-termômetro é parte de um projeto bem maior que estou fazendo para uma matéria da faculdade. Em breve mais coisas vão aparecer aqui.

BRTOS

Para quem se interessa por microcontroladores e sistemas embarcados, aqui vai uma série de artigos sobre como construir um RTOS (Sistema operacional em tempo real) com código fonte para MSP430.

A série é escrita pelo Marcelo Barros no seu blog Jedizone e é bastante explicativa. Inclusive me deu algumas ideias para fazer o Projeto Integrado da faculdade.

Links:

Parte 1

Parte 2

Parte 3

Parte 4

Parte 5

Parte 6

Parte 7

Código fonte: http://code.google.com/p/basicrtos/

A motivação da série é fazer com que um microcontrolador possa executar diversas tarefas simultaneamente. Pode ser aplicado à qualquer uC desde que se tenha uma quantidade razoável de memória RAM.

Escrevendo na EEPROM

Um microcontrolador de 8-bit (PIC, AVR, Intel 8051) é formado, normalmente, por uma a CPU, uma memória de armazenamento para o programa que será executado (geralmente flash), memória RAM  e um punhado de uma memória para armazenamento “permanente” de dados.

Essa última memória normalmente é EEPROM (a EEPROM pode ser substituida por outras tecnologias, mas são as mais comuns nos microcontroladores).

A idéia inicial seria ter um pequeno espaço onde dados poderiam ser escritos pelo microcontrolador, para serem acessados mais tarde, preservando seu conteúdo mesmo sem energia elétrica. Algo que a memória Flash já faz, com a “única” diferença de ser escrita em blocos e não bit a bit, economizando espaço.

Antes de falar da EEPROM, vou falar um pouquinho de PROM e EPROM, nada que não seja encontrado na Wikipedia.

A memória PROM, como a sigla em inglês já diz, pode ser escrita uma única vez e, depois disso, se torna de “apenas leitura”. Em alguns casos, isso pode ser suficiente para aplicação em que ela está inserida, mas em outros, pode não ser interessante.

Se, numa empresa que vende sistemas microcontrolados descobrisse que existe um erro no programa armazenado na PROM dos seus microcontroladores, ela não poderia alterar antes de enviar aos clientes. Para isso, surgiu a EPROM, que pode ser apagada, como o E (erasable) do seu nome diz.

A EPROM pode ser apagada com o uso de luz ultra-violeta forte incidente em uma pequena janela no topo do encapsulamento do circuito integrado, sendo possível solucionar o problema anterior.

eprom

Por fim, vieram as EEPROM, título do post de hoje. Esse tipo de memória pode ser apagada eletricamente, podendo ser utilizada não só como armazenamento do programa do microcontrolador como um espaço onde o próprio pode usar como armazenamento que pode ser reescrito diversas vezes.

Essas diversas vezes em que a EEPROM pode ser reescrita resumem-se à aproximadamente 100 mil (é só ver no datasheet do seu microcontrolador para saber quanto dura a sua… isso pode variar bastante), que significa que, se seu sistema escreve na EEPROM muitas vezes, ela pode parar de funcionar corretamente em algum momento, fazendo com que seu programa não escreva mais nela (mesmo que ele não perceba que não está escrevendo). Isso acontece pela tensão muito mais alta que o normal aplicada para poder apagar o que estava escrito.

Aí você pode me dizer: Mas a memória flash onde o programa do microcontrolador está pode parar de funcionar com 10 ou 100 vezes menos operações de escrita! Claro, claro, mas teoricamente você coloca o programa nela e depois não muda com muita frequência. Seria muito difícil alguém precisar regravar a memória flash mil ou 10 mil vezes.

Por isso, volto à questão da EEPROM, que, como fica à critério do seu programa quantas vezes ele vai escrever nela, em um dado momento não vai mais funcionar. Lembre-se que um microcontrolador pode fazer alguns milhões de operações em um segundo, se forem todas de escrita na EEPROM, lá se vai a sua memória.

Uma possível solução para fazer uma rotina de escrita na EEPROM é, antes de escrever os dados, verificar se eles já não estão escritos naquele lugar.

Se seu programa faz uma leitura analógica, por exemplo, a cada tempo T e após salva essa leitura na EEPROM, pode acontecer de diversas vezes a última leitura ser idêntica à atual, fazendo com que você force uma escrita onde não seria preciso, diminuindo a vida útil da sua memória.

Darlington Transistor Array

Um problema comum de quem pretende usar um motor de passo em algum projeto com microcontrolador ou com uma FPGA, é o modo que ele funciona.

Para fazer um motor de passo girar, você precisa fazer um excitamento de bobinas na ordem em que elas devem atuar para girar o motor no tamanho do passo e no sentido certos.

Até aí, nada demais, só que um motor desses, mesmo um pequeno, precisa de 200 a 400mA de corrente para funcionar, o que pode fazer você queimar seu microcontrolador que, normalmente, fornece de 30 a 60mA em cada saída.

Na Wikipedia e pelo Google é possível encontrar informações sobre os motores de passo, tanto bipolares como unipolares, o que não é o assunto dessa postagem. Dê uma olhada, se não sabe como eles funcionam ou pra que servem.

Continuando sobre o problema da corrente máxima que o seu aparato produz, existe uma solução simples: Usar um circuito que forneça mais corrente, apenas mantendo o nível lógico da entrada.

Para fazer esse trabalho, os circuitos integrados mais usados são os que contém matrizes de pares de Darlington. Os mais fáceis de se encontrar são os da família ULN2000 e ULN2800, sendo que o ULN2003 e o ULN2803 são os mais comuns e são compatíveis com a família TTL.

Cada um desses integrados pode fornecer até 500mA em cada uma de suas saídas, que são formadas por apenas um transístor de Darlington. Eles podem enviar até 50V para a saída, também sendo útil em aparelhos que nescessitem de tensões mais altas.

A única diferença visível é que o ULN2003 usa um encapsulamento de 16 pinos, onde um pino é usado para Vcc (que será repassado ao motor ou outro aparelho), um para terra, além das 7 entradas de dados e 7 saídas. Já o ULN2803 usa um encapsulamento de 18 pinos, onde é possível adicionar mais uma entrada e uma saída, resultando em 8 de cada.

uln2003a

Particularmente, acho mais vantajoso, para controlar motores de passo, ter um ULN2803 já que seriam precisos 8 entradas e 8 saídas para controlar um segundo motor, algo que não seria possível no ULN2003. No entanto, isso depende do projeto de cada um.