Mostrando postagens com marcador robótica. Mostrar todas as postagens
Mostrando postagens com marcador robótica. Mostrar todas as postagens

segunda-feira, 9 de junho de 2014

Bagunça Organizada II - Oficina / Laboratório em Casa, versão 2014

Há cerca de um ano, num dos primeiros posts neste blog, mostrei como eu organizava minhas coisas de brincar com arduino. Basicamente, cabia tudo em um único gaveteiro.

De lá para cá, acumulei um bocado de tralha e as coisas tomaram conta de todo um cômodo da minha casa, que a gente chamava de escritório, mas agora é quase um hackerspace particular.

Como de lá para cá eu também peguei gosto pelos vídeos, gravei um para vocês conhecerem o meu espaço e terem ideias de como organizar um cantinho para seus hobbies também na casa de vocês.


Ver direto no YouTube: http://youtu.be/p9fdkQGMRUk?list=UUgP9UJRSxYe687HhHYsBwYA

Para ver mais dicas como esta, clique no marcador "organização", logo abaixo.

Um abraço!
Otávio


sexta-feira, 31 de janeiro de 2014

Olho de LCD com Arduino e Nokia 5110 - #sucesso

E... voilá!!


Consegui fazer o Olho de LCD usando um display Nokia 5110 e o Arduino!!!


De início eu havia pensado em gerar um arquivo bitmap (BMP) e convertê-lo depois em código usando uma ferramenta automatizada. Ou pelo menos foi o que eu escrevi que ia fazer no meu último post...

Acabei fazendo uma coisa bem diferente... Foi um trabalho mais braçal, mas deu certo.

Primeiro, marquei com uma canetinha vermelha as divisas das linhas do display, a cada 8 quadradinhos. O display recebe os dados a exibir na forma de bytes. Cada byte contém oito bits, então os dados chegam ao display na forma de linhas com oito bits de espessura. Foram essas linhas que marquei.

Para cada uma das 6 linhas, montei uma sequência de bytes. Para ficar bem claro no código, escrevi os bytes usando o sistema binário, assim:

0b00000000 //uma linha em branco
0b11111111 //uma linha preta

O "0b" no início diz ao Arduino que estou usando o sistema binário, ou seja, só zeros e uns.
Tive que escrever o correspondente de 0 ou 1 para cada quadradinho da grade que forma o display. Ou seja, 84 x 48 = 4032. Claro que usei um bocado de Ctrl + C, Ctrl + V e escrevi em linhas de 8 bits, então foram apenas 504 linhas de código para descrever o desenho... ;)
O código inteiro está aí embaixo, usem à vontade!


Se fizerem melhorias para ele olhar para os lados, piscar, etc, por favor compartilhem! Eu quero fazer isso também, mas se forem mais rápidos que eu, vai me poupar um bocado de trabalho!

Abraços!


//Olho de LCD - v1
//Controlador de Display LCD Nokia 5110 (84x48 pixels)
//em 31 de janeiro de 2014
//Mais informacoes: umcarneiro.blogspot.com
//Licenca: MIT (use como quiser!)

//Pinos utilizados no arduino
#define PIN_SCE   7  //pino 2 do display
#define PIN_RESET 6  //pino 1 do display
#define PIN_DC    5  //pino 3 do display
#define PIN_SDIN  4  //pino 4 do display
#define PIN_SCLK  3  //pino 5 do display

//Tamanho do LCD em pixels:
#define LCD_X     84
#define LCD_Y     48

byte linhaUm[84] = {
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //5
      0b00000000,
      0b00000001,
      0b00000010,
      0b00000100,
      0b00000100,  //10
      0b00001000,
      0b00001000,
      0b00010000,
      0b00100000,
      0b00100000,  //15
      0b00100000,
      0b01000000,
      0b01000000,
      0b01000000,
      0b01000000,  //20
      0b01000000,
      0b10000000,
      0b10000000,
      0b10000000,
      0b10000000,  //25
      0b10000000,
      0b10000000,
      0b10000000,
      0b10000000,
      0b10000000,  //30
      0b10000000,
      0b10000000,
      0b10000000,
      0b10000000,
      0b10000000,  //35
      0b10000000,
      0b10000000,
      0b10000000,
      0b10000000,
      0b10000000,  //40
      0b10000000,
      0b10000000,
      0b10000000,
      0b10000000,
      0b10000000,  //45
      0b10000000,
      0b10000000,
      0b10000000,
      0b10000000,
      0b10000000,  //50
      0b10000000,
      0b10000000,
      0b10000000,
      0b10000000,
      0b10000000,  //55
      0b10000000,
      0b10000000,
      0b10000000,
      0b10000000,
      0b10000000,  //60
      0b10000000,
      0b10000000,
      0b10000000,
      0b10000000,
      0b01000000,  //65
      0b01000000,
      0b00100000,
      0b00100000,
      0b00010000,
      0b00010000,  //70
      0b00001000,
      0b00001000,
      0b00000100,
      0b00000010,
      0b00000010,  //75
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //80
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000
};

byte linhaDois[84] = {
      0b00000000,
      0b00000011,
      0b00001100,
      0b00110000,
      0b01000000,  //5
      0b10000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //10
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //15
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //20
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //25
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //30
      0b00000000,
      0b00000000,
      0b00000001,
      0b00000011,
      0b00000111,  //35
      0b00000111,
      0b00001111,
      0b00001111,
      0b00001110,
      0b00011110,  //40
      0b00011111,
      0b00011111,
      0b00011111,
      0b00011111,
      0b00011111,  //45
      0b00011111,
      0b00011111,
      0b00011111,
      0b00011111,
      0b00011111,  //50
      0b00011111,
      0b00011111,
      0b00011111,
      0b00011111,
      0b00011111,  //55
      0b00011111,
      0b00011111,
      0b00011111,
      0b00001111,
      0b00001111,  //60
      0b00001111,
      0b00001111,
      0b00001111,
      0b00001111,
      0b00000111,  //65
      0b00000111,
      0b00000011,
      0b00000001,
      0b00000000,
      0b00000000,  //70
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //75
      0b00000000,
      0b10000000,
      0b01000000,
      0b00100000,
      0b00010000,  //80
      0b00001000,
      0b00000110,
      0b00000001,
      0b00000000
};

byte linhaTres[84] = {
      0b11111111,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //5
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //10
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //15
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //20
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //25
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00001111,  //30
      0b00111111,
      0b11111111,
      0b11111111,
      0b11111111,
      0b11111111,  //35
      0b10001111,
      0b00000111,
      0b00000111,
      0b00000011,
      0b00000011,  //40
      0b00000011,
      0b00000111,
      0b00001111,
      0b11111111,
      0b11111111,  //45
      0b11111111,
      0b11111111,
      0b11111111,
      0b11111111,
      0b11111111,  //50
      0b11111111,
      0b11111111,
      0b11111111,
      0b11111111,
      0b11111111,  //55
      0b11111111,
      0b11111111,
      0b11111111,
      0b11111111,
      0b11111111,  //60
      0b11111111,
      0b11111111,
      0b11111111,
      0b11111111,
      0b11111111,  //65
      0b11111111,
      0b11111111,
      0b11111111,
      0b11111111,
      0b00111111,  //70
      0b00001111,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //75
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //80
      0b00000000,
      0b00000000,
      0b10000000,
      0b01111111
};

byte linhaQuatro[84] = {
      0b11111000,
      0b00000110,
      0b00000001,
      0b00000000,
      0b00000000,  //5
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //10
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //15
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //20
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //25
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b11100000,  //30
      0b11111000,
      0b11111100,
      0b11111111,
      0b11111111,
      0b11111111,  //35
      0b11111111,
      0b11111111,
      0b11111111,
      0b11111111,
      0b11111111,  //40
      0b11111111,
      0b11111111,
      0b11111111,
      0b11111111,
      0b11111111,  //45
      0b11111111,
      0b11111111,
      0b11111111,
      0b11111111,
      0b11111111,  //50
      0b11111111,
      0b11111111,
      0b11111111,
      0b11111111,
      0b11111111,  //55
      0b11111111,
      0b11111111,
      0b11111111,
      0b11111111,
      0b11111111,  //60
      0b11111111,
      0b11111111,
      0b11111111,
      0b11111001,
      0b11111001,  //65
      0b11111111,
      0b11111111,
      0b11111111,
      0b11111111,
      0b11111110,  //70
      0111111000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //75
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //80
      0b00000000,
      0b00000000,
      0b00001111,
      0b11110000
};

byte linhaCinco[84] = {
      0b00000000,
      0b00000000,
      0b00000000,
      0b11000000,
      0b00110000,  //5
      0b00001100,
      0b00000010,
      0b00000001,
      0b00000000,
      0b00000000,  //10
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //15
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //20
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //25
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //30
      0b00000000,
      0b00000000,
      0b00000000,
      0b10000000,
      0b11000000,  //35
      0b11000000,
      0b11100000,
      0b11100000,
      0b11110000,
      0b11110000,  //40
      0b11110000,
      0b11111000,
      0b11111000,
      0b11111000,
      0b11111000,  //45
      0b11111000,
      0b11111000,
      0b11111000,
      0b11111000,
      0b11111000,  //50
      0b11111000,
      0b11111000,
      0b11111000,
      0b11111000,
      0b11111000,  //55
      0b11111000,
      0b11111000,
      0b11111000,
      0b11111000,
      0b11111000,  //60
      0b11110000,
      0b11110000,
      0b11110000,
      0b11110000,
      0b11100000,  //65
      0b11100000,
      0b11000000,
      0b11000000,
      0b10000000,
      0b00000000,  //70      
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //75
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000011,
      0b00000100,  //80
      0b00011000,
      0b01100000,
      0b10000000,
      0b00000000
};

byte linhaSeis[84] = {
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000,  //5
      0b00000000,
      0b00000000,
      0b00000000,
      0b10000000,
      0b01000000,  //10
      0b00100000,
      0b00010000,
      0b00010000,
      0b00001000,
      0b00001000,  //15
      0b00001000,
      0b00000100,
      0b00000100,
      0b00000100,
      0b00000010,  //20
      0b00000010,
      0b00000010,
      0b00000010,
      0b00000010,
      0b00000001,  //25
      0b00000001,
      0b00000001,
      0b00000001,
      0b00000001,
      0b00000001,  //30
      0b00000001,
      0b00000001,
      0b00000001,
      0b00000001,
      0b00000001,  //35
      0b00000001,
      0b00000001,
      0b00000001,
      0b00000001,
      0b00000001,  //40
      0b00000001,
      0b00000001,
      0b00000001,
      0b00000001,
      0b00000001,  //45
      0b00000001,
      0b00000001,
      0b00000001,
      0b00000001,
      0b00000001,  //50
      0b00000001,
      0b00000001,
      0b00000001,
      0b00000001,
      0b00000001,  //55
      0b00000001,
      0b00000001,
      0b00000001,
      0b00000001,
      0b00000001,  //60
      0b00000001,
      0b00000001,
      0b00000001,
      0b00000010,
      0b00000010,  //65
      0b00000010,
      0b00000010,
      0b00000010,
      0b00000010,
      0b00000100,  //70
      0b00000100,
      0b00000100,
      0b00001000,
      0b00010000,
      0b00100000,  //75
      0b00100000,
      0b01000000,
      0b10000000,
      0b00000000,
      0b00000000,  //80
      0b00000000,
      0b00000000,
      0b00000000,
      0b00000000
};

void setup(void)
{
  pinMode(PIN_SCE, OUTPUT);   // Inicializa os pinos...
  pinMode(PIN_RESET, OUTPUT);
  pinMode(PIN_DC, OUTPUT);
  pinMode(PIN_SDIN, OUTPUT);
  pinMode(PIN_SCLK, OUTPUT);
  digitalWrite(PIN_RESET, LOW); //RESET no controlador
  digitalWrite(PIN_RESET, HIGH);
  LcdWrite(LOW, 0x21 );  // Function set: PD=0 (On); V=0 (Horizontal); H=1 (Extended instruction set)
  LcdWrite(LOW, 0xBA );  // Define o LCD Vop (Contraste). //XXXXXXXXXXXXXXX
  LcdWrite(LOW, 0x04 );  // Define o coeficiente de temperatura (??)
  LcdWrite(LOW, 0x14 );  // LCD bias mode 1:48  (??)
  LcdWrite(LOW, 0x20 );  // Function set: PD=0 (On); V=0 (Horizontal); H=0 (Basic instruction set)
  LcdWrite(LOW, 0x0C );  // Display control = 10 (Normal)
  
  limpaTela();
  
  desenhaLinha(linhaSeis);
  desenhaLinha(linhaCinco);
  desenhaLinha(linhaQuatro);
  desenhaLinha(linhaTres);
  desenhaLinha(linhaDois);
  desenhaLinha(linhaUm);   
}
  
void limpaTela(void) {
  //Percorre todas as posicoes
  for (int index = 0; index < LCD_X * LCD_Y / 8; index++)
  {
    LcdWrite(HIGH, 0);
  }
}

void desenhaLinha(byte linha[]) {
  //Percorre as colunas
  for (int coluna = 0; coluna < LCD_X; coluna++)
  {
    LcdWrite(HIGH, linha[coluna]);
  }
}


//Cuida da burocracia: envia o comando ou dado seguindo o protocolo do chip
void LcdWrite(byte dc, byte data)
{
  digitalWrite(PIN_DC, dc); //define se vai mandar dado ou comando
  digitalWrite(PIN_SCE, LOW); //ativa o chip para receber dados
  shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data); //envia um bit de cada vez, comecando pela esquerda
  digitalWrite(PIN_SCE, HIGH); //desativa o envio de dados
}

void loop(void)
{  
  //nada
}


Você pode ver todas as etapas deste projeto usando este link, ou clicando no marcador "olho_de_lcd", abaixo.

quinta-feira, 16 de janeiro de 2014

LCD Nokia 5110 com Arduino #sucesso

No meu post anterior eu falei que comprei um display LCD Nokia 5110 no MercadoLivre e, inicialmente não consegui fazê-lo funcionar... Depois eu atualizei o post dizendo que ele funcionou e fiquei de dar mais detalhes depois. Bom, aqui estão os detalhes!

Display Nokia 5110 sobre datasheet Philips PCD8544

Apesar de todo mundo se referir ao display como Nokia 5110, a parte importante para conhecer é o controlador que ele tem dentro, que na verdade é feito pela Philips! O controlador/driver é um Philips PCD8544.

O datasheet dele é bem extenso (32 páginas), mas você não precisa se preocupar, está numa linguagem bem acessível e tem até um exemplo de como desenhar uma palavra na tela, mostrando o que você deve enviar, bit a bit (página 22).


Para tentar entender o funcionamento do módulo, imprimi as páginas 14 e 22 e ainda montei uma "cola" para anotar o que cada byte representava em bits.


O problema que eu estava tendo com este módulo parecia estar na definição do contraste, então criei o código abaixo para vocês testarem o módulo de vocês. O que ele faz é desenhar uma barra que vai crescendo a medida que o contraste vai aumentando.

Este gif animado dá uma ideia do resultado. O contraste ideal é aquele em que a barra fica bem escura sobre um fundo claro. Se o fundo do seu LCD escurecer, é porque você passou da conta e deve diminuir um pouquinho.


//Controlador de Display LCD Nokia 5110 (84x48 pixels)
//em 13 de janeiro de 2014
//Mais informacoes: umcarneiro.blogspot.com
//Licenca: MIT (use como quiser!)

//Pinos utilizados no arduino
#define PIN_SCE   7  //pino 2 do display
#define PIN_RESET 6  //pino 1 do display
#define PIN_DC    5  //pino 3 do display
#define PIN_SDIN  4  //pino 4 do display
#define PIN_SCLK  3  //pino 5 do display

//Tamanho do LCD em pixels:
#define LCD_X     84
#define LCD_Y     48

//Estas variaveis restringem o menor e o maior contraste a ser testado
//Se sua tela estiver muito escura desde o inicio do teste, diminua este valor
const int MIN_CONTRAST = 175; //tem que ser maior que 128
//Se sua tela estiver muito clara no fim do teste, aumente este valor
const int MAX_CONTRAST = 200; //tem que ser menor que 255


void setup(void)
{
  pinMode(PIN_SCE, OUTPUT);   // Inicializa os pinos...
  pinMode(PIN_RESET, OUTPUT);
  pinMode(PIN_DC, OUTPUT);
  pinMode(PIN_SDIN, OUTPUT);
  pinMode(PIN_SCLK, OUTPUT);
  digitalWrite(PIN_RESET, LOW); //RESET no controlador
  digitalWrite(PIN_RESET, HIGH);
  LcdWrite(LOW, 0x21 );  // Function set: PD=0 (On); V=0 (Horizontal); H=1 (Extended instruction set)
  LcdWrite(LOW, 0xBA );  // Define o LCD Vop (Contraste). //XXXXXXXXXXXXXXX
  LcdWrite(LOW, 0x04 );  // Define o coeficiente de temperatura (??)
  LcdWrite(LOW, 0x14 );  // LCD bias mode 1:48  (??)
  LcdWrite(LOW, 0x20 );  // Function set: PD=0 (On); V=0 (Horizontal); H=0 (Basic instruction set)
  LcdWrite(LOW, 0x0C );  // Display control = 10 (Normal)
  
  //Clear - apaga todas as posicoes
  for (int index = 0; index < LCD_X * LCD_Y / 8; index++)
  {
    LcdWrite(HIGH, 0x00); //bit 0 em todo mundo!
  }

}

//Cuida da burocracia: envia o comando ou dado seguindo o protocolo do chip
void LcdWrite(byte dc, byte data)
{
  digitalWrite(PIN_DC, dc); //define se vai mandar dado ou comando
  digitalWrite(PIN_SCE, LOW); //ativa o chip para receber dados
  shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data); //envia um bit de cada vez, comecando pela esquerda
  digitalWrite(PIN_SCE, HIGH); //desativa o envio de dados
}

//desenha uma barra repetindo o byte informado
void desenhaBarra(int largura, byte caracter)  
{
  //Coloca o cursor no local correto
  LcdWrite( 0, 0x80 | 0);  // Coluna 0
  LcdWrite( 0, 0x40 | 2);  // Linha 2

  //barra horizontal
  for (int index = 0; index < largura; index++)
  {
    LcdWrite(HIGH, caracter);
  }
}

void loop(void)
{  
  //dentro dos limites que estabelecemos, define o contraste a mostrar
  for (int contrast = MIN_CONTRAST; contrast < MAX_CONTRAST; contrast++)
  {  
    LcdWrite(LOW, 0x21 );  // Function set: PD=0 (On); V=0 (Horizontal); H=1 (Extended instruction set)
    LcdWrite(LOW, contrast );  // Define o contraste (VOP)
    
    //define a largura da barra proporcional ao contraste
    int largura = map(contrast, MIN_CONTRAST, MAX_CONTRAST, 0, LCD_X); 

    LcdWrite(LOW, 0x20 );  // Function set: PD=0 (On); V=0 (Horizontal); H=0 (Basic instruction set)
    LcdWrite(LOW, 0x0C );  // Display control = 10
  
    //desenha a barra horizontal na largura que definimos
    desenhaBarra(largura, 0x7f);
    delay(350); //dah um tempo para podermos ver o resultado
  }
  
  //desenha uma barra invisivel da largura da tela
  desenhaBarra(LCD_X, 0x00); //ou seja, apaga a barra!
}


Juro que este foi o código mais simples que eu consegui fazer! Enchi de comentários para ver se conseguia torná-lo inteligível. Defini o contraste usando números decimais de propósito, para facilitar a leitura.  Tem um ótimo conversor de números entre binário, decimal e hexa nesta página. Eu usei um bocado para tentar entender o que estava acontecendo.

O circuito ficou assim:



Pino LCDResistorArduinoCor
1-RST10kPino 6Vermelho
2-CE10kPino 7Azul
3-DC10kPino 5Amarelo
4-DIN10kPino 4Verde
5-CLK10kPino 3Azul
6-VCC-3.3vVermelho
7-LIGHT330RGNDAzul
8-GND-GNDPreto

O código que eu tinha usado da outra vez usava, obrigatoriamente os pinos 11 e 13, mas este é mais simples e não tem essa exigência.

Repare também que o backlight (pino 7 do LCD) foi para o GND. Confesso que não entendi bem a lógica disso, já que o backlight se acende quando colocamos +3V direto no pino 7 e GND no pino 8.


O desenho do módulo de LCD no Fritzing eu fiz por conta própria. Se quiser o arquivo ou aprender a fazer você mesmo, leia este outro post.

Espero que vocês consigam colocar as suas telinhas para funcionar!

Quem sabe em um próximo post a minha já terá virado um olho de brinquedo?

Aguardem!

UPDATE: Desenhei o olho para colocar no LCD. Vejam neste outro post.

Você pode ver todas as etapas deste projeto usando este link, ou clicando no marcador "olho_de_lcd", abaixo.

terça-feira, 7 de janeiro de 2014

Olho de LCD com Arduino e Nokia 5110 - #fail

Minha filha tem um brinquedo com olhos muito expressivos feitos de LCD, vejam:


Eu fiquei tão fascinado por estes olhos que quis reproduzí-los com o Arduino, então comprei um display LCD Nokia 5110.

Para este projeto, contei com a colaboração da dona do brinquedo:


ATENÇÃO: Se você é fã dos 2Carneiros e esperava encontrar aqui um vídeo nosso montando o projeto, você não precisa ler mais nada. Vá direto aos comentários e peça um vídeo, aqui eu só postei esse gif animado. Se isso não resolver, se inscreva no blog e no canal do YouTube, peça pelo Facebook, me aborde na rua ou xingue muito no Twitter. O resto deste post é para as pessoas interessadas em Arduino e afins.

 O display que comprei vem em um mini kit feito de uma tela de LCD com uma moldura que o fixa em uma placa de circuito (breakout board). Esta placa tem furos identificados de 1 a 8 na frente e por suas funções, no verso. Nestes furos você pode soldar uma barra de pinos (fornecida no kit).



Para soldar os pinos na placa eu usei um conector jacaré para segurá-los no lugar e uma terceira mão para manter uma altura confortável. Depois de soldar os pinos no lugar, você já pode encaixar o seu display na breadboard.

Como as indicações das funções dos pinos ficam no verso, recomendo você anotar em um papel para deixar à mão. Isso vai te poupar de ficar virando o display de um lado para o outro enquanto monta o circuito.

Existem muitas referências na internet de como utilizar esse display de LCD. Eu utilizei as orientações da página da Sparkfun.

Se for utilizar a mesma referência, você deve ficar atento para a localização dos pinos. O produto que você comprou pode ter pinos em locais diferentes do que os do produto da Sparkfun.

No meu caso, fazendo as devidas substituições, ficou assim:




Pino LCDResistorArduinoCor
1-RST10kPino 6Vermelho
2-CE1kPino 7Azul
3-DC10kPino 5Amarelo
4-DIN10kPino 11Verde
5-CLK10kPino 13Azul
6-VCC-3.3vVermelho
7-LIGHT330Pino 9Amarelo
8-GND-GNDPreto

Indiquei as cores só para facilitar o entendimento da foto e do esquema que desenhei no Fritzing. Se for fazer em casa, use a cor que quiser.



Baixei o código sugerido na página da Sparkfun, compilei, subi para o arduino e... nada!

Mentira, o backlight acendeu. E para minha surpresa, ele era azul! Não sei por que, mas achei que seria branco.

O display de LCD deveria ter mostrado várias animações bacanas e até uma chargezinha, mas não vi nada disso.

E aí, desisto?

Ainda não, estou conversando sobre garantia com o fornecedor da peça. Se eu conseguir uma reposição, posto aqui o resultado. Se não, vou recorrer aos chineses...

Aguardem cenas do próximo episódio!

UPDATE (em 10/01/2014): O fornecedor do display (EletroKits, no MercadoLivre) foi muito atencioso e me mandou uma foto do circuito que ele fez para testar a peça e até um código de teste personalizado, que me permitiu fazer a peça funcionar. Vejam:


UPDATE (em 16/01/2014) Documentei melhor para mostrar para vocês neste post.

UPDATE (em 27/01/2014): Desenhei o olho para colocar no LCD. Vejam neste outro post.

Você pode ver todas as etapas deste projeto usando este link, ou clicando no marcador "olho_de_lcd", abaixo.

sábado, 10 de agosto de 2013

Quem são os Dois Carneiros (2Carneiros)?


O Só Mais Um Carneiro é um blog sobre qualquer coisa. Quando comecei, eu queria chamá-lo de "O Carneiro" para ser o blog do Otávio Carneiro (O. Carneiro) e ficar com cara de nome de jornal, com um artigo definido e um substantivo (ex: O Dia, A Tarde). O login "ocarneiro" estava tomado, no entanto, e eu fiquei com o "umcarneiro". No fim eu achei bom, achei que dava mais a cara de "um blog qualquer" e aí completei a ideia chamando-o de "Só mais um Carneiro".

 O blog tem uma tag chamada "paternidade", que não deixa nenhuma dúvida de que ser pai é uma parte importante da minha personalidade. Eu curto isso demais e minha filha, com apenas 5 anos, acha legal ter um pai blogueiro e tenta participar sempre que pode. E foi assim que ela se tornou mais um Carneiro nesse blog. Ela ainda não sabe escrever, então a primeira aparição dela foi em um vídeo que eu fiz sobre como criar um bristlebot (um robô-escova).


Eu nunca cheguei a escrever nada aqui sobre como fazer o tal robô escova, mas se estiverem interessados, deixem comentários que eu explico melhor. Ele é basicamente uma escova qualquer com um motor de vibração (ou motor desbalanceado) em cima. O motor precisa de uma fonte de energia, claro, então você adiciona pilhas e, opcionalmente, um interruptor. Se houver demanda, escrevo mais sobre isso.

Hoje eu abri meu presente de Dia dos Pais (uma Dremel que comprei no Palácio das Ferramentas) e resolvi fazer um segundo vídeo dos "2Carneiros". Nós falamos um pouco sobre segurança, equipamentos de proteção individual e etc., mas a graça está mesmo está na espontaneidade infantil, que eu espero não ter cortado demais editando o vídeo.

Espero que curtam! E tenham um Feliz Dia dos Pais!

Abraços,

Otávio e Júlia (2Carneiros)


 

UPDATE:


sábado, 20 de julho de 2013

Bagunça Organizada

Meu amigo Jerônimo, do Blog do Je, compartilhou um artigo da Revista Wired sobre o espaço de trabalho de Casey Neistat e eu fiquei babando...

Claro que pouca gente tem o espaço e a quantidade de bugigangas que esse cara tem, mas muita gente que brinca com arduínos e outros hobbies se preocupa em como organizar tudo isso para evitar conflitos em casa com a patroa...

Assim, resolvi mostrar aqui como eu organizo meu modesto carrinho onde cabem todas as minhas brincadeiras. Fiquem à vontade para comentar e fazer sugestões, cada dia a bagunça aumenta e estou sempre pensando em como rearranjá-la.

Abs.,
Otávio

Visão Geral

Comprei esse gaveteiro em um hipermercado (não lembro se Walmart ou Extra). Ele é de plástico e tem rodinhas, o que quer dizer que é bem fácil de carregar para onde eu quiser trabalhar (com mais luz, menos calor, na frente da TV, perto do computador, etc).



Nível Superior - Solda e Terceira Mão

Em cima do carrinho eu deixo o ferro de solda e esse suportezinho chamado de terceira mão. Eles são pesados e desajeitados e ficam melhor aí. Na terceira mão, nesta foto, tem um eixo com engrenagens, que eu estava usando para prototipar um projeto. Essa terceira mão tem uma lupa, que eu coloquei de lado para este projeto. Não liguem para esse carretel de fio, ele vai sair daí.

Primeira Gaveta - Componentes

Essa gaveta tem, basicamente, caixas organizadoras. O tema aqui é "componentes", então cada caixa tem um tipo. Vou mostrá-las abaixo.






Resistores

Eu não queria me embananar com os resistores e ter que ficar consultando o que é mesmo cada cor em outro lugar quando precisasse, então comprei essa caixinha em uma loja de 1,99 (foi 5 reais, mas beleza) e escrevi a resistência de cada grupo no papel que vem neles. Os que não tinham papel ganharam uma fita crepe dobrada para identificar.


Kit Arduino

Essa caixa é basicamente o Kit para iniciantes em Arduino que eu comprei da Robocore. Deve ter mais alguns LED's e umas garras jacaré, mas é basicamente o kit.


Transistores

Quando comprei minha estação de solda na MRE Ferramentas, vi essa caixinha de plástico antiestática e comprei também. Guardo ali os transistores e circuitos integrados, que costumo comprar na Huinfinito. 


Motores

Nessa caixinha ficam meus motores. O de passo e os desbalanceados são sucata. Os servos vieram do Mercado Livre. O DC eu comprei no e-bay.


Baterias e Pilhas

Minhas pilhas AA eu compro em hipermercado mesmo. As baterias de 9V e as de relógio eu comprei na Solda Fria, junto com esses cabinhos manga flexíveis.


Segunda Gaveta - Ferramentas





Terceira Gaveta - Projetos em andamento








Para ver mais dicas como esta, clique no marcador "organização", logo abaixo.


terça-feira, 7 de maio de 2013

Como se faz um robô

Você sabe o que é uma protoboard? Pois é, até uns dez dias atrás, eu também não sabia. Quando descobri, achei que era algo tão legal que quis arrumar um jeito de fazê-la andar... Esse post explica como eu consegui.

Uma protoboard é uma plaquinha de plástico, cheia de furinhos. O que a torna importante é o que ela tem por dentro. Filosófico, não?

Dentro da protoboard, há ligações elétricas entre os buraquinhos do meio, na vertical, e entre os buraquinhos das extremidades, na horizontal, como nesse desenho:

Protoboard e suas conexões verticais e horizontais
A vantagem disso é que, quando você quer fazer testes com componentes eletrônicos ("protótipos"), você não precisa ficar soldando ou enroscando um fio no outro, basta plugá-los na sua placa ("board").

Ficou claro, então, que a protoboard, sozinha, não faz nada. Você precisa ter um monte de componentes eletrônicos para fazer coisas interessantes, como isso aqui:
Robô feito com protoboard, arduino e servo motores

Neste meu robozinho, eu usei:

  1. Uma protoboard;
  2. Um Arduino Uno (uma plaquinha programável);
  3. Quatro (4) servo motores de 9g;
  4. Dois suportes para duas pilhas AA;
  5. Três pilhas AA;
  6. Vários jumpers (fios com conectores) coloridos;
  7. Vários pedaços de fio flexível;
  8. Fita isolante;
  9. Fita crepe.

Se vocês quiserem ver o robô em movimento, aqui está um vídeo:


Para fazer isso tudo funcionar, vocês precisam conectar todos os componentes de forma que o controlador do Arduino consiga dizer a todos os motores como e quando se mexer. Eu usei servo motores, que são motores muito usados em aeromodelismo. Em um motor comum, enquanto houver energia, haverá movimento. Um servo motor pode ser controlado para se mover de forma mais específica. Você pode dizer em que posição ele deve ficar. No caso do meu robô, eu digo para cada perna ficar 90° em relação ao chão e depois vou dizendo para cada uma delas ficar paralela ao chão e depois perpendicular de novo, movimentando o robô.

Os servo motores que eu usei, no entanto, só giram 180°. Ou seja, cada perna não pode dar uma volta completa, então cada perna tem que ir e voltar. Para o robô não ficar indo e voltando sem sair do lugar, eu tive que fazer um pé para ele. Cortei uma embalagem de plástico e dobrei para ficar como um joelho. Ela dobra para trás para sair do caminho, mas fica firme na frente para dar propulsão ao robô quando o motor desce. Prendi essa pecinha com um arame que acabou ajudando mais ainda na propulsão. É como se o robô estivesse de salto alto, tocando o salto primeiro no chão. As analogias que eu tinha em mente eram muito mais másculas. Pensei num elefante, ficou uma galinha. Funcionou melhor, na verdade.

Eu pluguei os servos de trás nos pinos 9 (esquerda) e 10 (direita) e os da frente nos pinos 6 (esquerda) e 5 (direita). Estes pinos transmitem um sinal modularizado. Eu ainda não sei bem o que é isso, mas o fato é que esse sinal não é suficiente para energizar os motores. O arduino tem saídas de 5V e 3,3V que até poderiam energizar os motores, mas são só duas. Além disso, os motores usam muito energia e, ligados nessas portas, fazem o arduino que ficar desligando por falta de força. Então tive que colocar uma fonte extra de energia.

Arduino com servos conectados aos pinos 10, 9, 6 e 5
Eu tinha aqui 3 pilhas novas e dois suportes para 2 pilhas AA cada. Até pensei em sair para comprar mais pilhas, mas resolvi usar só as três mesmo. Se até 3,3V já movem o motor, 4,5V devia funcionar, pensei. E funcionou. Um dos suportes ficou capenga, com uma pilha só, então enrolei um fio no negativo dessa filha pilha única e liguei direto na protoboard.

De forma bem esquemática, as ligações ficaram assim:
Ligações dos servos e pilhas ao Arduino

O Fritzing, programa que usei para desenhar, não tem um desenhinho de suporte de pilha capenga, mas você pode usar três ou quatro pilhas.

Uma coisa importante a se notar é que, mesmo não usando o Arduino como fonte de energia, você precisa conectar o negativo das suas pilhas ao negativo dele, pois só assim a corrente elétrica pode sair dele e chegar até os motores.

Espero ter conseguido explicar em linhas gerais como conectar múltiplos servo motores ao Arduino. Se tiverem mais dúvidas, deixem nos comentários que eu vou tentando explicar.

Quem leu até aqui pode se interessar em saber que não precisava ter lido nada, pois eu fiz um segundo vídeo explicando essas mesmas coisas...

E quem resolver tentar fazer em casa, vai precisar do código para rodar no Arduino, então vou colá-lo aqui embaixo. Fiquem à vontade para usar o código, os desenhos, os vídeos e as fotos desse post como quiserem, só não me responsabilizem pelo que vier a dar errado.

Abraços,

Otávio

// Walking Breadboard / Protoboard Ambulante
// by Otavio Carneiro dos Santos <http://umcarneiro.blogspot.com>
// based on Sweep, by BARRAGAN (example in Arduino)
// This code is in the public domain.

#include <Servo.h> 
 
Servo pataEsquerdaTras;
Servo pataEsquerdaFrente;
Servo pataDireitaTras;
Servo pataDireitaFrente;

int pos = 0;    //variavel temporaria
                //guarda a posicao atual do servo
 
void setup() 
{ 
  pataEsquerdaTras.attach(9);
  pataDireitaTras.attach(10);
  pataEsquerdaFrente.attach(6);
  pataDireitaFrente.attach(5);
} 
 
 
void loop() 
{ 
  movePataEsquerdaParaFrente(pataEsquerdaTras);
  movePataEsquerdaParaTras(pataEsquerdaTras);
  delay(1000);
  movePataDireitaParaFrente(pataDireitaFrente);
  movePataDireitaParaTras(pataDireitaFrente);
  delay(1000);
  movePataEsquerdaParaFrente(pataEsquerdaFrente);
  movePataEsquerdaParaTras(pataEsquerdaFrente);
  delay(1000);
  movePataDireitaParaFrente(pataDireitaTras);
  movePataDireitaParaTras(pataDireitaTras);
  delay(1000);
} 

//move o servo esquerdo informado para frente
//nota: os servos do lado esquerdo ficam espelhados em relacao
//      aos do lado direito, por isso ha metodos distintos
//      para cada lado.
void movePataEsquerdaParaTras(Servo servoToMove)
{
  int posInicial = 1;
  int posFinal = 90;
  
  for(pos = posInicial; pos < posFinal; pos += 1) 
  {                                  
    servoToMove.write(pos);          
    delay(15);
  } 
}

void movePataEsquerdaParaFrente(Servo servoToMove)
{
  int posInicial = 1;
  int posFinal = 90;
  
  for(pos = posFinal; pos>=posInicial; pos-=1) 
  {                                
    servoToMove.write(pos);
    delay(15);
  } 
}

void movePataDireitaParaTras(Servo servoToMove)
{
  int posInicial = 90;
  int posFinal = 180;
  
  for(pos = posFinal; pos>=posInicial; pos-=1)
  {                                
    servoToMove.write(pos);
    delay(15);
  } 
}

void movePataDireitaParaFrente(Servo servoToMove)
{
  int posInicial = 90;
  int posFinal = 180;
  
  for(pos = posInicial; pos < posFinal; pos += 1)
  {                                  
    servoToMove.write(pos);
    delay(15);
  } 
}