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...

sábado, 26 de julho de 2014

Hacking Genuis II - Software

Bom, vamos à parte "soft" da coisa, agora... nem foi muito difícil nada.

Adotando a abordagem desenvolvida por Jack, primeiro testei os botões. Para isso, nada como um "pograminha" específico.

// Define button pins in Arduino
#define bBlue   7
#define bRed    8
#define bGreen  9
#define bYellow 10

void setup()
{
  Serial.begin(9600);
// define pins as outputs
  pinMode(bBlue,OUTPUT);
  pinMode(bYellow,OUTPUT);
  pinMode(bGreen,OUTPUT);
  pinMode(bRed,OUTPUT);
}

void loop()
{
// wait  for a key pressed
  while(!Serial.available());
// read key
  char c=Serial.read();
// empty serial buffer
  while(Serial.available())
    Serial.read();
// Depending on the key sent, the software "press" the corresponding button
  switch(c)
  {
    case 'B':
      digitalWrite(bBlue,HIGH);
      delay(500);
      digitalWrite(bBlue,LOW);
      break;
    case 'Y':
      digitalWrite(bYellow,HIGH);
      delay(500);
      digitalWrite(bYellow,LOW);
      break;
    case 'G':
      digitalWrite(bGreen,HIGH);
      delay(500);
      digitalWrite(bGreen,LOW);
      break;
    case 'R':
      digitalWrite(bRed,HIGH);
      delay(500);
      digitalWrite(bRed,LOW);
      break;
  } 
}
Tão logo essa aplicação acima funcionou, parti prá próxima etapa, que era perceber o acendimento das lâmpadas, que eu sabia seria um pouco mais complicado.

De novo, uma aplicação específica foi usada:

// Analogic pins
#define lBlue 0    
#define lRed 1    
#define lGreen 2 
#define lYellow 3

int lampSignal = 0;

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

void loop()
{
  lampSignal=analogRead(lBlue);
  if(lampSignal<200)
     Serial.println("Blue");
  lampSignal=analogRead(lYellow);
  if(lampSignal<200)
     Serial.println("Yellow");
  lampSignal=analogRead(lRed);
  if(lampSignal<200)
     Serial.println("Red");
  lampSignal=analogRead(lGreen);
  if(lampSignal<200)
     Serial.println("Green");
  delay(200);

}
Como tinha que perceber a variação do sinal, que começava em +/- 3V (leitura de 600 no Arduino) e quando o botão era pressionado caía, fui ajustando o valor até chegar em 200. No fim acho que usei 250, mas de toda forma o programa acima mostrava na tela exatamente a cor que eu ou o Genius "apertávamos".

Por fim, juntando tudo, eis o programa completo, que chamei de GeniusFighter:

// Program states
#define stWait      0
#define stListening 1
#define stPlaying   2

//             Arduino       Genius
//             Analog port   Connector number - "see" color
#define blue   0             // 4
#define red    1             // 7
#define green  2             // 14
#define yellow 3             // 17

//              Arduino digital port - "press" button
#define pBlue   3
#define pRed    4
#define pGreen  5
#define pYellow 6

// Wait time to accept keypressed
#define lThreshold 200

// Max number of rounds in a game
#define maxRounds 128

int currentRound = 0;

long timeInterval = 350;

int status = stWait;

String colors[] = {"Blue","Red","Green","Yellow"};

byte sequence[maxRounds];

void clearSequence()
{
  for(int i=0; i<maxRounds;i++)
     sequence[i]=0;
}

// Check for a selected color, returning it in that case
int selectedColor()
{
  int i;
  for(i=blue;i<=yellow;i++)
    if(analogRead(i)<lThreshold)
      break;
  if(i<=yellow)
  {
    while(analogRead(i)<lThreshold)
      delay(50);
    return i;
  }
  else
  {
    delay(50);
    return -1;
  }
}

// Wait until a color is pressed
int waitForColor()
{
  int color=-1;
  while(color==-1)
    color=selectedColor();
  return color; 
}

// Listen the game, storing the color sequence
void listen()
{
  currentRound++;
//  int timeInterval=millis();
  for(int i=0;i<currentRound;i++)
  {
    sequence[i]=waitForColor();
    Serial.print(colors[sequence[i]]);
    if(i<(currentRound-1))
      Serial.print(',');
    if(((i+1) % 10) == 0)
      Serial.println();  
  }
  Serial.println();
//  timeInterval=(millis()-timeInterval) / currentRound;
//  Serial.println(timeInterval);
}

// Press a button corresponding to a color
void pressColor(int color)
{
  digitalWrite(color+3,HIGH); // 3 is the color pins offset: pBlue = 7
  delay(250);
  digitalWrite(color+3,LOW);
  delay(50);
}

// Play the stores sequence
void play()
{
  for(int i=0;i<currentRound;i++)
    pressColor(sequence[i]);
}

void setup()
{
  Serial.begin(57600);
  pinMode(pBlue,OUTPUT);
  pinMode(pYellow,OUTPUT);
  pinMode(pGreen,OUTPUT);
  pinMode(pRed,OUTPUT);
}

void loop()
{
// "Just" switch between states, processing each one
  switch(status)
  {
    case stWait:
      currentRound=0;
      Serial.println("Waiting game start...");
      sequence[currentRound]=waitForColor();
      currentRound++;
      status=stPlaying;
      break;
    case stListening:
      Serial.println("Listening...");
      listen();
      status=stPlaying;
      break;
    case stPlaying:
      delay(500);
      Serial.print("Playing ");
      Serial.print(currentRound);
      Serial.println(" colors...");
      play();
      status=stListening;
      break;
  }
}


É isso! O programa nem é tão complicado, e eu comentei de maneira que me pareceu didática. Não foi um projeto assim... xuxu beleza??? :) Abracadabraço, até a próxima.

Hacking Genius (Simon) I - Hardware

Nível 3 - 20

Dia desses ganhei um Genius, aquele game lá dos anos setenta que foi lançado no Brasil pela Estrela. Foi o primeiro game eletrônico que aportou por essas plagas. Custava uma grana, então só meus amigos riquinhos é que tinham, e eu jogava na casa deles.

Naquela época eu pensava: o que será que acontece quando chega-se ao fim do game? Aliás, quando será que se chega ao final?

Quando comecei a brincar de Arduino uma das primeiras coisas que fiz foi  um brinquedo que funcionava da mesma forma, como vcs podem ver aqui. Mas o mistério continuou, até que...

Tempos atrás um destes caiu nas minhas mãos. Resolvi então chegar ao fim do túnel, quer dizer, do game. Como não tenho competência para ganhar nem no modo mais fácil, resolvi hackeá-lo com a ajuda do Arduino.

A ideia foi arrumar uma maneira de "ler" as cores indicadas pelo game e "apertar" os botões correspondentes.

Para descobrir isso, primeiro foi necessário desmontar o bicho:


Essa é a placa do jogo. Simples, com dois CIs, um deles (MB4850) é o processador do game e o outro (SN7594N), comandado por esse, faz o acendimento das lâmpadas e também comanda o alto-falante.

O MB4850, é uma variação do processador TMS1100 da Texas Instruments, que foi programado pelo fabricante especificamente para o game. É que na época não tinha esse negócio de usuário programar chip, o chip era fabricado contendo a programação. Bons tempos esses dos Arduinos da vida, não?

É um processador de 4 bits(!), com 8 k bits de ROM e 256 bits de RAM. Aqui nesse link tem uma boa discussão sobre o Simon, os processadores etc. Pena que só achei isso depois do meu projeto terminado, teria apanhado menos... mas me divertido menos tb, não é verdade?


Observe que, como não haviam LEDs na quena época, o bicho usava lâmpadas incandescentes, parecidas com as que encontramos em carros mais antigos dentro do porta-luvas.

Vem até uma sobressalente lá dentro, just in case, como vc pode ver na foto abaixo (que não ficou lá essas coisas, reconheço).


A primeira providência foi bolar uma fonte de alimentação alternativa pro bicho, já que ele usa nada menos que 6 (seis!) pilhas, sendo duas delas daquelas grandonas que nem sei se são fabricadas ainda. Já me disseram que fabricam-se adaptadores na China, mas eu resolvi por aqui mesmo.

Analisando o circuito (infelizmente não tenho uma imagem da placa antes do hackeamento, sorry), vi que ele usava as pilhas grandes para acender as lâmpadas, enquanto que as grandes + as pequenas (AA) eram usadas para manter o circuito fuincionando.

Isso dava um total de 9 V para o circuito e 3 V para as lâmpadas. Pensei então: "mole: ligo uma fonte de 9V, alimento o circuito com ela e em seguida passo por um regulador 3,3 V e boa".

Ainda bem que tenho amigos mais experientes com eletrônica analógica. Ao discutir o projeto com o Euclides, ele já disse:

- Nananinanão! Vc vai é queimar o regulador, porque ele não vai suportar reduzir de 9 para 3,3 V, é muito pequenininho e nem tem jeito de por um dissipador de calor... vai rolar não.

Assim sendo, resolvi ligar um regulador de 5 V em série com um de 3,3V. Ficou assim então o circuito:


Primeiro na proto. A entrada do circuito é esse fio que parte da fita isolante. O regulador grande é o de 5 V. O fio laranja conecta a saída de um na entrada do outro, e o outro fio vermelho que sai por cima conecta o regulador de 3V3 ao Genius. Os fios azuis? "Terras", né bicho? Os verdes? Restos de outra montagem... :)


Depois, montou-se a plaquinha, soldada bymyself, com muito orguuuuulhooo, com muito...


E aqui já instalado dentro do Genius. Coloquei um plug tipo "fêmea do Arduino" para conexão externa da fonte.

Em seguida, passei a estudar como conectar o bicho.

Para as lâmpadas bastaria um fio, do lado em que o sinal mudasse. Normalmente o sinal "aterraria" quando a lãmpada é acesa, mas não foi o que aconteceu. Na verdade a tensão varia de uns 3V para pouco menos de 1. De toda forma, soldamos fios em cada lâmpada, do lado em que a tensão baixa quando a lâmpada acende.

Da mesma forma bastaria ligar um fio em cada interruptor, do lado que se altera mais. Acontece que não rolou, porque passa uma corrente grande demais pelo botão, o Arduino não dá conta de aterrá-lo. Então parti para soldar dois fios, um de cada lado dos interruptores, e conectá-los a alguma outra coisa que pudesse substituí-los.

Vale dizer que a ideia sempre foi hackear o Genius sem comprometer o seu funcionamento normal nem alterar o circuito de nenhuma forma. Uma alteração que facilitaria a vida por exemplo seria trocar as lâmpadas por LEDs, que consomem muito menos energia, mas nem isso foi feito.

Abaixo a placa com as conexões soldadas. Usamos uma fita dessas antigas de ligar HD. Ela tinha vinte fios e fizemos exatamente vinte conexões, então deu certim:

- 2 conexões por botão de jogo x 4 botões: 8 fios
- 2 conexões por botão de controle x 3 botões: 6 fios
- 1 conexão por lâmpada x 4 lâmpadas: 4 fios
- Terra e Vcc: 2 fios, total 20 fios.

A conexão de alimentação serve tanto para se alimentar o Genius quanto para, caso haja a fonte conectada ao Genius, alimentar o Arduino.



As conexões 17 e 18 acima, por exemplo, acionam um dos botões, enquanto que a 16 monitora o acendimento da lâmpada correspodente (mesma cor).

As conexões 6,8,9,10,11,12 são dos botões de controle. Por enquanto não as usaremos.

Soldados os fios, conectado o regulador, partimos para fazer os testes. De cara deu prá ver que o regulador de 5V não estava aguentando, queimei o dedo nele após poucos minutos de funcionamento.

Pensei em ligar dois em paralelo para dividir a corrente, mas antes de testar resolvi conectar uma fonte de 6V e... funcionou!

Abaixo mais 2 imagens do bicho aberto. Observem o cone de papel em torno do altofalante... bem tosco, né... e funciona!



Aqui o equipamento pronto, conectado a um Arduino Nano.


Aqui o detalhe, mostrando as conexões. Eu tive que ligar esses dois resistores aí porque a minha fonte é de 6V e pouco. De início liguei a fonte direto no Vin, para que o regulador do Arduino fizesse o serviço de rebaixá-la a 5V. Acontece que não rolou, o Vin não alimenta a placa, não sei se tem problema na minha placa...



Aí tive que ligar direto no 5V do Arduino. Para isso coloquei dois resistores em paralelo para provocar uma queda de tensão de 1V e pouco, de maneira a não estressar o Arduino.

Como chave para substituir os botões pensei em usar relés, a escolha óbvia. Resolvi testar com optoacopladores e... não é que funcionou? Usei quatro 4N25, um prá cada chave. Um pino digital do Arduino aciona o fotodiodo que conecta os dois fios do outro lado.

E, por fim, a bagaça a funcionar:



É isso. No próximo post, os softwares de teste e o programa final.

terça-feira, 15 de julho de 2014

Usando controle Nunchuck Wii com o Arduino I

Dias atrás vi um instrumento musical construído com o Arduino. Achei interessante e resolvi me dedicar a construir este e alguns outros instrumentos usando Arduino.

Comprei um controle pelo Mercado Livre por uns R$ 50,00 e me pus a hackeá-lo. A conexão é do tipo I2C, e o conector segue o padrão abaixo.


Em vez de conectar fios ao conector resolvi cortá-lo fora e soldar pinos para conexão ao Arduino. As cores dos fios variam segundo o fabricante (existem muitos clones do controle no mercado, o meu é um deles). Vendo o plug desmontado vi que as conexões são as seguintes:

3.3V  - fio azul - conexão 3V3 do Arduino
GND - fio rosa - conexão GND do Arduino
Clock - fio branco - conexão A5 do Arduino
Data  - fio amarelo - conexão A4 do Arduino

Este post continua, só publiquei para deixar registrados esses dados.