quinta-feira, 26 de junho de 2014

Código Morse na placa Intel® Galileo via porta serial

Este será um teste simples da porta serial da Galileo com o envio de caracteres que serão transformados em código morse e apresentados na placa Galileo pelo led.

O código abaixo foi baseado neste código fonte, com algumas modificações:
//Define the LED Pin
#define PIN_OUT        13
//Define unit length in ms
#define UNIT_LENGTH    250

String incomingWord = "";
int menu = 0;    
char message[25];

//Build a struct with the morse code mapping
static const struct {const char letter, *code;} MorseMap[] =
{
 { 'A', ".-" },
 { 'B', "-..." },
 { 'C', "-.-." },
 { 'D', "-.." },
 { 'E', "." },
 { 'F', "..-." },
 { 'G', "--." },
 { 'H', "...." },
 { 'I', ".." },
 { 'J', ".---" },
 { 'K', ".-.-" },
 { 'L', ".-.." },
 { 'M', "--" },
 { 'N', "-." },
 { 'O', "---" },
 { 'P', ".--." },
 { 'Q', "--.-" },
 { 'R', ".-." },
 { 'S', "..." },
 { 'T', "-" },
 { 'U', "..-" },
 { 'V', "...-" },
 { 'W', ".--" },
 { 'X', "-..-" },
 { 'Y', "-.--" },
 { 'Z', "--.." },
 { ' ', "     " }, //Gap between word, seven units 
  
 { '1', ".----" },
 { '2', "..---" },
 { '3', "...--" },
 { '4', "....-" },
 { '5', "....." },
 { '6', "-...." },
 { '7', "--..." },
 { '8', "---.." },
 { '9', "----." },
 { '0', "-----" },
  
 { '.', "·–·–·–" },
 { ',', "--..--" },
 { '?', "..--.." },
 { '!', "-.-.--" },
 { ':', "---..." },
 { ';', "-.-.-." },
 { '(', "-.--." },
 { ')', "-.--.-" },
 { '"', ".-..-." },
 { '@', ".--.-." },
 { '&', ".-..." },
};

void setup()
{
  pinMode( PIN_OUT, OUTPUT );
  digitalWrite( PIN_OUT, LOW );
  Serial.begin(9600);
    
}

void loop(){
  
  if (Serial.available() && menu == 0) {
    
    Serial.println("-- Decodificador de string para codigo Morse -- ");
    Serial.println("Pronto para enviar uma mensagem.");
    menu = 1;
  
  }
  
  if (Serial.available() && menu == 1) {
    incomingWord = Serial.readStringUntil('\n');
  
    
    Serial.println("Eu recebi: ");
    Serial.println(incomingWord);
    
    incomingWord.toCharArray(message,incomingWord.length());
  
    String morseWord = encode( message );
    
    for(int i=0; i<=morseWord.length(); i++){
      switch( morseWord[i] ){
        case '.': //dit
          digitalWrite( PIN_OUT, HIGH );
          delay( UNIT_LENGTH );
          digitalWrite( PIN_OUT, LOW );
          delay( UNIT_LENGTH );
            
          break;
   
        case '-': //dah
          digitalWrite( PIN_OUT, HIGH );
          delay( UNIT_LENGTH*3 );
          digitalWrite( PIN_OUT, LOW );
          delay( UNIT_LENGTH );
            
          break;
   
        case ' ': //gap
          delay( UNIT_LENGTH );
      }
    }
  }
}
String encode(const char *string)
{
  size_t i, j;
  String morseWord = "";
  
  for( i = 0; string[i]; ++i )
  {
    for( j = 0; j < sizeof MorseMap / sizeof *MorseMap; ++j )
    {
      if( toupper(string[i]) == MorseMap[j].letter )
      {
        morseWord += MorseMap[j].code;
        break;
      }
    }
    morseWord += " "; //Add tailing space to seperate the chars
  }
 
  return morseWord;  
}
 
String decode2(String morse)
{
  String msg = "";
  
  int lastPos = 0;
  int pos = morse.indexOf(' ');
  while( lastPos <= morse.lastIndexOf(' ') )
  {    
    for( int i = 0; i < sizeof MorseMap / sizeof *MorseMap; ++i )
    {
      if( morse.substring(lastPos, pos) == MorseMap[i].code )
      {
        msg += MorseMap[i].letter;
      }
    }
 
    lastPos = pos+1;
    pos = morse.indexOf(' ', lastPos);
    
    // Handle white-spaces between words (7 spaces)
    while( morse[lastPos] == ' ' && morse[pos+1] == ' ' )
    {
      pos ++;
    }
  }
 
  return msg;
}

O código acima fica em loop esperando até que uma mensagem seja enviada pela porta serial, quando esta mensagem é recebida o programa decodifica cada letra com seu respectivo significado em morse ( a funcção estática no inicio do programa possui todas as relações letra - sinal) em "ponto" e "traço".

Faça upload deste código para a placa Galileo e abra o terminal serial em Tools...Serial Monitor para enviar as mensagens via porta serial.

Acesso ao terminal serial
Terminal serial acima da IDE arduino
Faça os testes enviando uma palavra de cada vez e verifique o led da placa acender em código morse.


Primeiro teste da Intel® Galileo: 'blink'

Este tutorial inicial tem como objetivo a familiarização básica com a placa de desenvolvimento Galileo e sua IDE, portanto apenas a placa de desenvolvimento será necessária para executá-lo.

Inicialmente deve-se baixar os drivers necessários e a IDE para desenvolvimento neste site, e selecione a versão compatível com o seu sistema operacional.

A IDE utilizada neste tutorial é a Arduino de versão 1.5.3. Descompacte o arquivo baixado pelo link disponibilizado anteriormente e instale os drivers referentes ao seu sistema.

Antes de tudo, atente-se a dicas deste post. Prestar atenção especial aos seguintes cuidados:

  • Ligar a placa Galileo na fonte, antes de ligar na porta usb;
  • Após ligar a porta usb da Galileo no computador, verifique que ela foi corretamente identificada pelo sistema operacional (no Windows pode-se ver pelo gerenciador de dispositivos, em alguma porta COM).

Ao abrir a interface arduino, a seguinte janela será apresentada:

IDE para programar na Galileo

Clicando em Tools...Serial Port, verifique novamente se a Galileo está conectada em uma porta serial do seu computador. Para Windows, ela estará em alguma porta COM.

Na aba File, vá até Examples...Basics...Blink.

Com o código carregado na tela, clique no botão upload.


Verifique se o led está piscando na placa, na posição indicada abaixo:



No próximo post, testarei um código de um blink modificado com comunicação serial.

sexta-feira, 9 de agosto de 2013

Configurações 3D utilizando Blender

    O objetivo do post é expôr a minha solução para sobrepor duas cenas diferentes em uma aplicação 3D no Blender. Neste caso a camada inferior é um vídeo já em 3d (lado a lado) e a camada superior é um game que deveria ser adaptado em 3D, para que houvesse um casamento entre os efeitos.

Imagem 1: Vídeo 3D lado a lado e game sobreposto

    Após alguns testes com a aplicação direta do plugin do desenvolvedor noeol, sendo este código sendo usado juntamente com o controle add overlay scene do blender obtive um certo sucesso com a cena do game ficando 3d juntamente com o video. No entando, neste game o cursor colorido atira o projétil para "dentro" da tela, e este efeito estava completamente errado na aplicação que fiz.


Imagem 2: Controles para sobrepor a cena 'game' na cena principal
    A solução do problema foi alcançada com a aplicação de viewports, que dividem a cena verticalmente (ou horizontalmente) de modo que cada câmera que filma o game seja exibida em exatamente metade da tela.

Imagem 3: Blocos lógicos para o viewport


    Para o vídeo usado o viewport foi aplicado com uma divisão vertical, e deste modo, o efeito 3D do game foi alcaçado pois cada visão do game foi colocada em cima da metade do vídeo, de modo que quando uma tv compatível fizer a composição das imagens o game também ficará em 3D.



Imagem 4: Cursores duplicados, compatíveis com o vídeo
 
    O código utilizado para configurar os viewports foi obtido aqui, referente a este vídeo.