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.