Postagem em destaque

Controle PID de Potência em Corrente Alternada - Arduino e TRIAC - Parte I

Este post é o primeiro de uma série de seis que escrevi tratando de controle de potência e PID (controle proporcional, integral e derivativo...

domingo, 19 de agosto de 2012

No Parque, 19/08/12, domingão, hora extra

Hoje, domingão, patroa viajando... hora extra no Parque! Dois projetos:

- O ex-aluno Fábio com a sua "mão biônica", da qual tratamos meses atrás. Agora ele já tem os sensores, servos, caixa (de papelão, ainda protótipo), e o software prontos. Só queria ajuda para tirar uns "tremeliques" dos dedos, devido a ruídos diversos desses que sempre nos aparecem. Foi só montar uma combinação de filtros no software para para curarmos o "Parkinson" da mão biônica do Fábio. Aliás, isso dá um post: dia desses escrevo sobre como estabilizar a leitura de sensores rebeldes.

Abaixo, fotos e filme da façanha. Os dedos são acionados por sensores de flexão que serão depois colados a uma luva que será calçada e movimentada pelo operador. E tudo isso à distância porque o Fàbio vai botar comunicação RF nesse miolo.


Conjunto feito pelo Fábio, sensores, Arduino e caixa contendo os motores e suportando a mão.


Motores de passo instalados na parede da caixa.


A mão, ou The Thing...


Sensores ainda instalados na protoboard. Posteriormente serão acoplados à luva.
Abaixo, tudo funcionando.



A outra diversão da manhã foi uma dupla que ligou ontem à noite com uma ideia de acionar um motor "brushless" com Arduino. Não tinha a menor "loção" do que fosse um motor sem escovas, mas...

Abaixo imagens dessa luta. Por enquanto, 10x3 para o motor... pelo menos até sabadão que vem!


Até osciloscópio apareceu, mas teve jeito não. Ficou prá semana que vem...




sábado, 18 de agosto de 2012

No Parque, 18/08/12 - leitor de código de barras, heliostato, fibra ótica...

Hoje o Arduino no Parque foi movimentado! Vários projetos interessantes, antes das 8:00 da matina já tinha gente. O William chegou cedo de Suzano, com o seu projeto de leitura de código de barras com o Arduino, de que falei no último post. Além disso tinha um projeto de alunos da FATESF com seu projeto de um heliostato, o Euclides querendo hackear um controle remoto da Net e uma dupla da Unip que está fazendo um projeto de comunicação via fibra ótica usando PIC.  Levei ainda o meu projeto com a plaquinha de som para a turma ver.

Ou seja... diversão pura!

Ao fim dos trabalhos, algumas pedreiras, vários progressos:

- Controle remoto do Euclides: parece que o controle remoto da Net é encriptado, ou seja, nadica da gente conseguir ler com o sensor que tínhamos.

- Heliostato: com os palpites da turma que estava por lá, a dupla tomou várias decisões de projeto, e a turma foi-se para implementar.

- A comunicação por fibra ótica andou pouco. A gente testou hipóteses e tal, mas a comunicação bidirecional na fibra não rolou. Ficou pra semana que vem.

- Por fim o projeto do código de barras: o William trouxe um shield Ethernet e um display LCD. A ideia é ler o código de barras, mostrar o resultado no LCD e em seguida "publicar na internet" o código lido.

A gente quaaaase conseguiu: conseguimos funcionar o LCD e o shield Ethernet. Como o leitor de código de já tinha funcionado, era "só" juntar tudo. O tempo era curto de novo, ia rolar uma oficina de Arduino em casa a partir das 14:00. Conseguimos fazer os três circuitos funcionarem com tudo ligado. Conseguimos ler o código de barras e mostrar no LCD. Na hora mostrar pela rede, através de um roteador, nada...

Aí acabou-se o tempo. O William ficou com a incumbência de terminar de ajustar o software e enviar o esquema da confusão no Fritzing.

Abaixo, fotos da bagunça e um filminho da montagem do leitor de código de barras com o display LCD.


A protoboard compartilhada, com o Euclides testando o controle remoto e o relógio de cegos com a plaquinha falante. Ao lado, circuito de leitor de código de barras.



A turma praticando:


E o vídeo:



quinta-feira, 9 de agosto de 2012

No Parque, 5/8/12, leitor de código de barras com o Arduino


Dia desses o Rafael Galeanu, de Suzano entrou em contato comigo querendo ajuda num projeto que consistia basicamente em comandar um leitor de código de barras pelo Arduino. Ele já tinha o leitor, um modelo handheld da Bematech , o BR310, e também já tinha comprado um shield de USB, necessário para fazer o Arduino conversar com o leitor.

Sugeri a ele que comparecesse ao Arduino no Parque, mas ele está trabalhando no fim de semana, então mandou o William Silva, que trouxe os “equipamentos”.

Sábado foi um pouco complicado, tive que sair no meio da diversão para uma reunião de início de semestre na Anhanguera. Só depois do meio dia me encontrei com o William, só que havia outras pessoas por ali esperando, então tive que deixar ele apanham sozinho por um tempo. Ainda por cima tinha um aniversário de criança pelas 16h, então meu alvará arduínico nesse sábado iria somente até às 15h30min.

Esse é o leitor BR310. O modelo que usamos é mais antigo, portanto mais feinho.
Quanto tive como colocar a mão na massa, vi que o orifício era bem inferior ao que tinha pensado. Prá começar a plaquinha USB que ele tinha era da SparkFun. Quando fui pesquisar o software, drivers etc no site, o dito tinha um link para uma outra placa, como se o driver da outra placa servisse na deles. Achei esquisito, baixei, rodei e..., não funcionou, o único sinal devida que o shield deu foi acender o LED. 

Plaquinha da SparkFun. Link:  https://www.sparkfun.com/products/9947

Pesquisa dali e daqui, vi que a plaquinha da SparkFun tinha uma diferença da placa do cara, que era que o pino D7 do shield deveria ser conectado ao pino de reset, e na plaquinha da SparkFun isso não acontecia. Ao conectar um no outro, o shield já entrou no ar.

Ligo então o BR310 na plaquinha e... nada, de novo. Nem acendeu. Ligo no PC e acende, então deve ser algo com o Arduino e/ou o shield. Google de novo, e surge a dica: o Arduino, qdo alimentado pelo PC, muitas vezes não disponibiliza ao shield USB energia suficiente para acionamento dos equipamentos a ele (shield) conectados. Desmonta-se o multímetro, pega-se a bateria de 9V e... leitor aceso! Sinal que havia terminado a parte fácil...


Plaquinha com o jumper conectando o pino 7 digital ao reset. O ideal é depois fazer isso com solda, por baixo da placa, prá não ficar essa alça voando sobre o shield.


Conjunto acoplado ao leitor, com o cartão de testes.

Agora vinha destrinchar a comunicação entre o Arduino e o Bematech. Acontece que o protocolo USB é o ó do boró. Isso não quer dizer que ele seja ruim, longe disso, aliás eu acho que ele é a interface mais chique que apareceu nos últimos anos. É rápido, confiável e flexível e por isso a indústria embarcou nele com força. Acontece que... ele é complicado, do ponto de vista da implementação. Tanto assim que o povo do Arduino preferiu transformar, através de driver, a porta USB dos nossos micros em uma porta serial, protocolo esse muito mais limitado e consequentemente muito mais simples de se lidar. O driver que o Arduino usa cuida de toda a complexidade do USB para nós. No nosso caso, isso não era uma opção...

Uma vez que o hardware funcionou (ou pareceu funcionar), agora é o software. Baixei do site http://www.circuitsathome.com, o tal que a SparkFun indica, uma lib para lidar com a parte "baixo nível". Em seguida, estudamos a respeito de como interagir com os dispositivos conectados à USB. Um rolo total. Tenta dali e daqui, desconfiei que o leitor poderia simular um teclado, que é um device hoje USB. Cheguei então na interface USB tipo HID (Human Interface Device), que é a dos teclados.

Carreguei o programa no Arduino, apontei o leitor para um cartão com um código e atirei (apertei o gatilho do bicho). Olha que belezinha:


A saída são os códigos lidos do cartão em diversos formatos. Ou seja... mais um leão morto!

Eu não vou postar o código aqui, contrariando a regra de ouro desse site, porque de fato eu não escrevi nem uma linha, ou seja, o programa e as libs são do sujeito do Circuits@Home. É "só" fazer o download, instalar e adivinhar o resto...

Dessa vez não tem filminho no YouTube, porque o alvará acabou antes, tive que me mandar para a festa da Rafaela. Mas o William e o Rafael prometeram trazer a tralha de novo dia desses prá gente terminar o projeto, aí eu filmo.




terça-feira, 7 de agosto de 2012

Arduino: Parla!

Tempos atrás, em abril especificamente, comprei uma placa de som chamada GinSing, da http://www.ginsingsound.com/. Quando eu já havia me esquecido da dita, eis que a Receita Federal me comunica que eu poderia retirá-la nos Correios, pagando para isso um imposto equivalente ao custo da plaquinha...

Fui lá na semana passada e retirei-a. No fim de semana comecei a utilizá-la. Ela é construída em torno de um CI chamado BabbleBot, que é um sintetizador de sons muito poderoso, com seis canais e uma gama de efeitos invejável.

Eu resolvi "investir" nessa plaquinha porque qdo eu era adolescente eu fiz algumas montagens de circuitos para efeitos especiais em som de danceterias, houve um tempo em que eu alugava os troços que eu montava e também um "jogo de luzes" para festas. Não que eu tenha a intenção de me tornar um DJ tardio, mas acho que a plaquinha será útil para games, robots e outras brincadeiras.

Resolvi começar a testá-la pelo que mais chama a atenção: a capacidade de síntese de voz. Criei então um modelo relógio digital para deficientes visuais, que poderiam, ao pressionar um botão, ouvir as horas faladas pelo relógio.

Pois taí o bicho funcionando:


A plaquinha funciona em quatro modos: efeitos sonoros, sintetizador de voz, modelagem de instrumentos e modulador sonoro.

No modo sintetizador de voz trabalha com Allophones, que são fonemas codificados, quer dizer, um tipo de alfabeto fonético. Com ele a gente consegue compor frases fonéticas. Os fonemas são mais ou menos específicos da linguagem, no caso, inglês,  mas dá para falar em português, ainda que com um sotaque americano. Fiz alguns testes. Como esse foi o primeiro uso, fiz em inglês. Mas já testei em português também, fica bem inteligível, em outros posts vou usar a nossa inculta e bela.

A plaquinha tem recursos de pausas, entonações, consegue até mesmo cantar. Mas essas features ficam para outros posts.

Abaixo, como é regra nesse blog, o código fonte comentado.

#include "LiquidCrystal.h"
// essa é a classe que interfaceia com a plaquinha
GinSing       GS;                                  

// abaixo os pinos de comunicação. Uma boa característica dessa placa é que
// tem jumpers para configurar os pinos, com duas alternativas para cada,
// o que adiciona muita flexibilidade na combinação com outros shields.

#define rcvPin  4                           
#define sndPin  3                           
#define ovfPin  2                                  


 // botão para acionar a voz
#define sayTimePin 10

// como não tenho um chip de timer, o relógio é iniciado com essa gambi abaixo
long __hour = 21;long __minutes = 12;
long initialSecs = __hour * 3600 + (__minutes * 60);
long _now;
long _hour;
long _minutes;
long _secs;

// esse ponteiro vai para a estrutura de voz, qdo a classe for criada
GinSingVoice * voice = 0x0;                         

// inicializa o display
LiquidCrystal lcd(12, 11, 9, 8, 7, 6); 

// define os sons dos números com os fonemas
GSAllophone one[] = {_W,_U,_NE,_ENDPHRASE};
GSAllophone two[] = {_T,_UE,_ENDPHRASE};
GSAllophone three[] = {_THH,_R,_EE,_ENDPHRASE};
GSAllophone four[] = {_F,_OR,_ENDPHRASE};
GSAllophone five[] = {_F,_IE,_V,_ENDPHRASE};
GSAllophone six[] = {_SE,_I,_KE,_SE,_ENDPHRASE};
GSAllophone seven[] = {_SE,_E,_V,_I,_NE,_ENDPHRASE};
GSAllophone eight[] = {_AE,_T,_ENDPHRASE};
GSAllophone nine[] = {_NE,_IE,_NE,_ENDPHRASE};
GSAllophone ten[] = {_T,_E,_NE,_ENDPHRASE};
GSAllophone eleven[] = {_I,_LE,_E,_V,_E,_NE,_ENDPHRASE};
GSAllophone twelve[] = {_T,_W,_E,_LE,_V,_ENDPHRASE};
GSAllophone thirteen[] = {_TH,_ER,_T,_EE,_NE,_ENDPHRASE};
GSAllophone fourteen[] = {_F,_OR,_T,_EE,_NE,_ENDPHRASE};
GSAllophone fifteen[] = {_F,_I,_F,_T,_EE,_NE,_ENDPHRASE};
GSAllophone sixteen[] = {_SE,_I,_KE,_SE,_T,_EE,_NE,_ENDPHRASE};
GSAllophone seventeen[] = {_SE,_E,_V,_I,_NE,_T,_EE,_NE,_ENDPHRASE};
GSAllophone eighteen[] = {_AE,_T,_EE,_NE,_ENDPHRASE};
GSAllophone nineteen[] = {_NE,_IE,_NE,_T,_EE,_NE,_ENDPHRASE};
GSAllophone twenty[] = {_T,_W,_E,_NE,_T,_EE,_ENDPHRASE};
GSAllophone thirty[] = {_TH,_ER,_T,_EE,_ENDPHRASE};
GSAllophone fourty[] = {_F,_OR,_T,_EE,_ENDPHRASE};
GSAllophone fifty[] = {_F,_I,_F,_T,_EE,_ENDPHRASE};
// palavras
GSAllophone hour[] = {_OU,_R,_ENDPHRASE};
GSAllophone minute[] = {_M,_I,_NE,_I,_T,_ENDPHRASE};
GSAllophone second[] = {_SE,_E,_PITCHDN,_KO,_PITCHDN,_U,_NE,_OD,_ENDPHRASE};
GSAllophone hours[] = {_OU,_R,_SE,_SE,_ENDPHRASE};
GSAllophone minutes[] = {_M,_I,_NE,_I,_T,_SE,_SE,_ENDPHRASE};
GSAllophone seconds[] = {_SE,_E,_PITCHDN,_KO,_PITCHDN,_U,_NE,_PITCHDN,_OD,_SE,_SE,_ENDPHRASE};


void setup (){
  Serial.begin
(9600);
  
Serial.println(initialSecs);

// "pega" a interface de voz
  
voice = GS.getVoice();                            

// inicializa o LCD
  
cd.begin(16, 2);
  
lcd.clear();
  
pinMode(sayTimePin,INPUT);
  
GS.begin ( rcvPin, sndPin, ovfPin );             


}

void loop (){
  
// escreve a hora
  
printTime();
  
delay(1000);
  
// se apertou-se o botão, diz a hora
  
if (digitalRead(sayTimePin) == HIGH)
  
{
    sayTime
();
  
}
}


// calcula a hora atual
void calcTime(){
  _now
= initialSecs + (millis()/1000);
  
_hour = _now / 3600;
  
_minutes = (_now / 60) - (_hour * 60);
  
_secs = _now % 3600 - (_minutes * 60);}


// escreve a hora no display
void printTime(){
  calcTime
();
  
lcd.clear();
  
lcd.print(_hour); lcd.print(":"); lcd.print(_minutes); lcd.print(":"); lcd.print(_secs);

}

// diz a hora, considerando inclusive o plural/singular das palavras
void sayTime(){
  voice
->setNote( C_2 );
  
sayTimeNumbers(_hour);
  
if (_hour > 1)
    
say(hours);
  
else
    
say(hour);
  
sayTimeNumbers(_minutes);  
  
if (_minutes > 1)
    
say(minutes);
  
else
    
say(minute);
  
sayTimeNumbers(_secs);  
  
if (_secs > 1)
      
say(seconds);
  
else
    
say(second);

}

void say(GSAllophone phrase[])
{
  
// diz o texto em phrase
  
voice->speak( phrase);
  
// espera o fim da fala
  
delay ( voice->getMillis( phrase ) );   

}

void sayANumber(byte num)
{
  
// diz um determinado número
  
Serial.println(num);
  
switch(num)
  
{
    
case  1say(one); break;
    
case  2: say(two); break;
    
case  3: say(three); break;
    
case  4: say(four); break;
    
case  5: say(five); break;
    
case  6: say(six); break;
    
case  7: say(seven); break;
    
case  8: say(eight); break;
    
case  9: say(nine); break;
    
case 10: say(ten); break;
    
case 11: say(eleven); break;
    
case 12: say(twelve); break;
    
case 13: say(thirteen); break;
    
case 14: say(fourteen); break;
    
case 15: say(fifteen); break;
    
case 16: say(sixteen); break;
    
case 17: say(seventeen); break;
    
case 18: say(eighteen); break;
    
case 19: say(nineteen); break;
    
case 20: say(twenty); break;
    
case 30: say(thirty); break;
    
case 40: say(fourty); break;
    
case 50: say(fifty); break;
  
}
}


// diz os números do tempo
void sayTimeNumbers(byte number){
  
int n=number / 10;
  
if (n > 1)
  
{
    sayANumber
(n * 10);
    
n=number % 10;
    
sayANumber(n);
  
}
  
else
    
sayANumber(number);