quinta-feira, 25 de março de 2010

Novas placas e novos kits

Pessoal,

Acabamos de receber novas placas e kits de eletrônica que podem interessar a vocês:


1. Tomad@ - É uma placa que comporta dois relês, com transistor, diodo, fusível e led de funcionamento, ou seja, é uma placa já pronta para você trabalhar com tomadas, motores de alta corrente e tudo mais que necessita de um relê. Por enquanto temos apenas a placa sem componentes e em breve teremos o kit completo para você soldar na sua casa.

2. Protoshield Arduino - Esta é uma placa para você criar seus próprios shields para Arduino e encaixar por cima. É extremamente útil pois com ela você pode poupar sua protoboard e deixar componentes que você utiliza normalmente já soldados em um shield.


3. Elétron kit 1 - Este kit de eletrônica contém uma série de componentes que utilizamos no dia-a-dia:
- 1 caixa plástica com divisórias,
- 1 Protoboard
- 3 leds vermelho
- 3 leds verde
- 3 leds amarelo
- 1 led RGB
- 1 piezo
- 1 potenciômetro
- 1 motor DC
- 1 Chave microswitch
- 1 Chave táctil (botão)
- 1 Sensor de Luz LDR
- 1 Sensor de temperatura
- 1 regulador de voltagem 7805
- 1 relê 12v
- 1 microcontrolador ATMega8
- 1 Clock cristal 16 mhz
- 5 diodos in4007
- 8 jumpers
- 2 capacitores eletrolíticos 100uf 25v
- 2 capacitores eletrolíticos 10uf 50v
- 8 capacitores cerâmicos 104
- 2 capacitores cerâmicos 22
- 4 transistores TIP122
- 10 resistores 1k
- 10 resistores 10k
- 10 resistores 330r
- 10 resistores 220r
- 1 resistor 1mega
- 1 Barra pinos simples
- 1 barra pinos dupla
- 30 CM flat cable 8 vias
- pedaço de termocontrátil

Com este kit você pode desenvolver diferentes tipos de projetos:
- Controle de motor com potenciômetro
- Soluções diversas com sensor de temperatura e luz
- EXCLUSIVO: o conteúdo deste kit permite você um Arduino em Protoboard

4. Geek Tools kit: nesta pequena caixa de ferramentas você tem tudo que precisa para soldar e colocar a mão na massa:

- Caixa de ferramentas plástica
- Ferro de solda 30watts
- 1 Sugador de Solda
- 1 Suporte de ferro de solda com esponja
- 1 alicate bico reto
- 1 alicate corte
- 1 pasta de soldagem
- 1 suporte para placa
- 1 tubo de estanho




Vamos agora aos preços:

1. Placa de relê dupla sem componentes - R$ 12,00
2. Protoshield Arduino - R$ 15,00
3. Elétron Kit - R$ 130,00
4. Geek Tools - R$ 150,00
5. Protoboard importada - R$ 29,00
6. Multímetro ICEL IK1250 - R$ 45,00
7. Program-ME completo com caixa e ATMega 328 - R$ 199,00
8. Program-ME completo com caixa e ATMega 168 - R$ 179,00
9. Program-ME placa virgem - R$ 20,00


Se você quer entrar no mundo da eletrônica e Arduino temos um pacotes especial:

Program-ME + Elétron Kit + Geek Tools por R$ 439,00 e você ganha uma placa de relês de graça.

Vinicius Senger
http://twitter.com/vsenger

terça-feira, 9 de março de 2010

Bússola Digital com sensor de temperatura e umidade utilizando o Program-Me da Globalcode.


Neste post descrevo como é simples conectar sensores tipo bússola, temperatura e umidade ao Program-ME utilizando a interface I2C, e construir uma interessante bússola digital com display LCD gráfico.

O chip ATMEGA utilizado em todos os Arduinos possui uma interface muito interessante chamada I2C . Essa interface permite a conexão de diversos sensores, memórias EEPROM e inclusive outros Arduinos utilizando apenas dois fios além do terra (GND). Essa interface funciona como um barramento onde cada dispositivo tem um endereço e o dispositivo mestre, neste caso o ATMEGA, controla o acesso aos demais dispositivos denominados escravos.

Para aprender mais sobre esta interface recomendo os links abaixo:

http://www.arduino.cc/playground/Learning/I2C

http://www.nxp.com/acrobat_download2/literature/9398/39340011.pdf (especificação da interface)

Neste projeto utilizei dois sensores, um magnético que utiliza o chip HMC6352 da Honeywell e um sensor de temperatura e umidade que utiliza o chip SHT-15 da Sensirion, sendo que ambos são compatíveis com a interface I2C, apesar de que o SHT-15 não é endereçável por esta interface, porém pode conviver com os outros dispositivos no barramento I2C desde que isso seja gerenciado pelo software.




Para exibir as informações dos sensores foi utilizado um display LCD gráfico de 128x64 pixels em conjunto com a biblioteca KS0108.

O interessante da biblioteca KS0108, é que podemos transferir imagens para o display com apenas uma linha de comando. Para isso, a imagem .BMP deve ser convertida por um sketch de Processing chamado glcdBitmap em um arquivo hexadecimal que será utilizado pela biblioteca para identificar quais são os pixels do display que devem ou não ser ativados.
Aí é só incluir o arquivo gerado no seu programa e utilizar quando necessário.

Existe um programa muito simples chamado FASTLCD que ajuda muito na construção das telas gráficas. Na figura abaixo temos o layout da tela deste projeto sendo construída no FASTLCD.



Após construir a tela no FASTLCD devemos salvar o arquivo .BMP no diretório “..\hardware\libraries\ks0108\Processing\glcdBitmap\data” que fica dentro do diretório da IDE do Arduino.

Com o arquivo BMP salvo no diretório acima, abrimos na IDE de Processing o arquivo “..\hardware\libraries\ks0108\Processing\glcdBitmap\glcdBitmap.pde”



Então é só editar a linha abaixo colocando o nome do seu arquivo .BMP no lugar de “ArduinoIcon.bmp”

String sourceImage = "ArduinoIcon.bmp"; // mude esta linha para o nome do seu BMP

Ao executar este Processing, será gerado um arquivo nomedoseuBMP.h no diretório “..\hardware\libraries\ks0108\Processing\glcdBitmap” correspondente a imagem.

Então basta no início do seu programa incluir a figura com o comando do exemplo abaixo:

#include "Layout_bussola.h"

E depois para exibir a figura no display basta dar o seguinte comando:

GLCD.DrawBitmap(Layout_bussola, 0,0, BLACK); //desenha layout básico do display para bússola.

IMPORTANTE: Caso apresente falha na compilação do seu programa, será necessário copiar o arquivo .h do diretório “..\hardware\libraries\ks0108\Processing\glcdBitmap” para o diretório “..\hardware\libraries\ks0108”

O método GLCD.DrawBitmap permite especificar a partir de qual pixel será carregada a imagem, então para alterar as direções da bússola, criei 8 bitmaps diferentes (figuras abaixo) com resolução 64x64, ou seja, somente a metade direita do display e carrego elas a partir do pixel (64,0) conforme o valor recebido do sensor magnético HMC6352.




Com isso o trecho do programa que atualiza a indicação da bússola no display fica bem simples como pode ser observado na listagem do programa.



// Bussola com medidor de temperatura e humidade utilizando PROGRAM-ME

#include
#include // biblioteca para display ITM12864
#include "SystemFont5x7.h" // definicao de fontes pequenas (5x7)Arial
#include "Layout_bussola.h" // bitmap de layout inicial do display
#include "N.h" // bitmap bussola Norte
#include "NE.h" // bitmap bussola Nordeste
#include "L.h" // bitmap bussola Leste
#include "SU.h" // bitmap bussola Sudeste
#include "S.h" // bitmap bussola Sul
#include "SO.h" // bitmap bussola Sudoeste
#include "O.h" // bitmap bussola Oeste
#include "NO.h" // bitmap bussola Noroeste
#include "logo_globalcode.h" // bitmap logo Globalcode

int EnderecoBussola = 0x42 >> 1; // datasheet informa 0x42, biblioteca wire só utiliza 7 bits fazemos um shift para ficar com MSB
int angulo = 0; //variavel para armazenamento do angulo medido
int temperatureCommand = B00000011; // comando para leitura de temperatura
int humidityCommand = B00000101; // comando para leitura de umidade
int clockPin = 13; // porta usada para clock da interface com sensor de Temperaruta e umidade
int dataPin = 12; // porta usada para dados da interface com sensor de Temperaruta e umidade
int ack; // acknowledgment para erros
long val;
float temperature; //variavel para armazenamento da leitura de temperatura
float humidity; //variavel para armazenamento da leitura de umidade

void setup() {
Wire.begin();
Serial.begin(9600); // configura serial em 9600
GLCD.Init(NON_INVERTED); // inicializa a library no modo "non inverted" de escrita de pixels
GLCD.ClearScreen(); // limpa a tela do display
GLCD.DrawBitmap(logo_globalcode, 0,0, BLACK); //desenha logo da Globalcode no display
delay (4000); //mantem logo globalcode no display por 4 segundos
GLCD.ClearScreen(); // limpa a tela do display
GLCD.DrawBitmap(Layout_bussola, 0,0, BLACK); //desenha layout básico do display para bussola
}

void loop() {
// Bussola
Wire.beginTransmission(EnderecoBussola); //inicia comunicação I2C com a bussola
Wire.send('A'); // envia comando para bussola executar mediçao do angulo
Wire.endTransmission();
delay(10); // aguardar pelo menos 6 milisegundos antes de efetuar leitura do angulo
Wire.requestFrom(EnderecoBussola, 2); // executa leitura do angulo com 2 bytes
if(2 <= Wire.available()) { // se já estiverem disponiveis os 2 bytes
angulo = Wire.receive(); // recebe o byte mais significativo
angulo = angulo << 8; // desloca o byte mais significativo para sua posicao (MSB)
angulo += Wire.receive(); // recebe o byte menos significativo adicionando ao byte anterior
angulo = int ((double)angulo / 10); // divide por dez para converter de decimos de grau para graus
Serial.println(angulo); // mostra o valor no serial monitor
GLCD.FillRect(16,55,19,7, WHITE); //apaga valor de angulo anterior para evitar sobreposicao
GLCD.SelectFont(System5x7); // seleciona fontes 5x7
GLCD.GotoXY(16,63); // posiciona o cursor na cord x=16, y=63 para escrever o valor do angulo obtido da bussola
GLCD.PrintNumber(angulo); // escreve o valor do angulo no display
if (angulo >= 68 and angulo <= 112) {
GLCD.DrawBitmap(L, 64,0, BLACK); //desenha bussola na posicao LESTE
}
if (angulo >= 113 and angulo <= 157) {
GLCD.DrawBitmap(SU, 64,0, BLACK); //desenha bussola na posicao SUDESTE
}
if (angulo >= 158 and angulo <= 202) {
GLCD.DrawBitmap(S, 64,0, BLACK); //desenha bussola na posicao SUL
}
if (angulo >= 203 and angulo <= 247) {
GLCD.DrawBitmap(SO, 64,0, BLACK); //desenha bussola na posicao SUDOESTE
}
if (angulo >= 248 and angulo <= 292) {
GLCD.DrawBitmap(O, 64,0, BLACK); //desenha bussola na posicao OESTE
}
if (angulo >= 293 and angulo <= 337) {
GLCD.DrawBitmap(NO, 64,0, BLACK); //desenha bussola na posicao NOROESTE
}
if ((angulo >= 338 and angulo <= 360) or (angulo >= 0 and angulo <= 22)) {
GLCD.DrawBitmap(N, 64,0, BLACK); //desenha bussola na posicao NORTE
}
if (angulo >= 23 and angulo <= 67) {
GLCD.DrawBitmap(NE, 64,0, BLACK); //desenha bussola na posicao NORDESTE
}
}

// Temperatura e umidade

// le valor da temperatura e converte para graus centigrados
sendCommandSHT(temperatureCommand, dataPin, clockPin);//chama rotina de leitura solicitando temperatura
waitForResultSHT(dataPin);// aguarda resultado das leituras
val = getData16SHT(dataPin, clockPin);//lê os dois bytes correspondentes a temperatura
skipCrcSHT(dataPin, clockPin);// ignora os dados de CRC
temperature = (float) (-40.1 + 0.01 * val);//calcula a temperatura
Serial.print("temperature: ");
Serial.print(temperature,DEC);//envia valor da temperatura para o serial monitor
GLCD.FillRect(16,9,18,13, WHITE);//limpa campo da umidade no display antes de atualizar
GLCD.SelectFont(System5x7); // seleciona fonte 5x7
GLCD.GotoXY(16,11); // posiciona o cursor na cord x=16, y=11 para escrever o valor da temperatura
GLCD.PrintNumber(temperature); // escreve o valor da temperatura no display

// le valor da umidade
sendCommandSHT(humidityCommand, dataPin, clockPin);//chama rotina de leitura solicitando umidade
waitForResultSHT(dataPin);// aguarda resultado das leituras
val = getData16SHT(dataPin, clockPin);//lê os dois bytes correspondentes a umidade
skipCrcSHT(dataPin, clockPin);// ignora os dados de CRC
humidity = -4.0 + 0.0405 * val + -0.0000028 * val * val;//calcula a umidade
Serial.print("humidity: ");
Serial.print((long)humidity, DEC);//envia valor da umidade para o serial monitor
GLCD.FillRect(16,33,10,7, WHITE);//limpa campo da umidade antes de atualizar
GLCD.SelectFont(System5x7); // seleciona fonte 5x7
GLCD.GotoXY(16,33); // posiciona o cursor na cord x=13, y=39 para escrever o valor da umidade
GLCD.PrintNumber(humidity); // escreve o valor da umidade no display

delay(100); // aguarda 100 ms antes de executar nova leitura
}


// rotina para deslocar bits das leituras do sensor SHT15
int shiftIn(int dataPin, int clockPin, int numBits) {
int ret = 0;
for (int i=0; i< numBits; ++i) {
digitalWrite(clockPin, HIGH);
//delay(10); not needed :)
ret = ret*2 + digitalRead(dataPin);
digitalWrite(clockPin, LOW);
}
return(ret);
}

// rotina para envio de comandos ao sensor SHT15
void sendCommandSHT(int command, int dataPin, int clockPin) {
int ack;
// inicia transmissao
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
digitalWrite(dataPin, HIGH);
digitalWrite(clockPin, HIGH);
digitalWrite(dataPin, LOW);
digitalWrite(clockPin, LOW);
digitalWrite(clockPin, HIGH);
digitalWrite(dataPin, HIGH);
digitalWrite(clockPin, LOW);

// envia comando (os 3 bits mais significativos sao o endereco que deve ser 000 os 5 bits menos significativos sao o comando)
shiftOut(dataPin, clockPin, MSBFIRST, command);

// verifica se foi recebido ack
digitalWrite(clockPin, HIGH);
pinMode(dataPin, INPUT);
ack = digitalRead(dataPin);
if (ack != LOW)
Serial.println("ACK error 0");
digitalWrite(clockPin, LOW);
ack = digitalRead(dataPin);
if (ack != HIGH)
Serial.println("ACK error 1");
}

// rotina para aguardar resultado da leitura solicitada ao SHT15
void waitForResultSHT(int dataPin) {
int ack;
pinMode(dataPin, INPUT);
for(int i=0; i<100; ++i) {
delay(10);
ack = digitalRead(dataPin);
if (ack == LOW)
break;
}
if (ack == HIGH)
Serial.println("ACK error 2");
}

// rotina que obtem dados da leitura executada pelo SHT15
long getData16SHT(int dataPin, int clockPin) {
long val;
//obtem byte mais significativo
pinMode(dataPin, INPUT);
pinMode(clockPin, OUTPUT);
val = shiftIn(dataPin, clockPin, 8);
Serial.println(val);
val *= 256; // this is equivalent to val << 8;
Serial.println(val);

// envia sinal ACK para sensor SHT15
pinMode(dataPin, OUTPUT);
digitalWrite(dataPin, HIGH);
digitalWrite(dataPin, LOW);
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);

// obtem byte menos significativo
pinMode(dataPin, INPUT);
val |= shiftIn(dataPin, clockPin, 8);
return val;
}

// rotina para ignorar dados de CRC vindos do sensor SHT15
void skipCrcSHT(int dataPin, int clockPin) {
pinMode(dataPin, OUTPUT);
pinMode(clockPin, OUTPUT);
digitalWrite(dataPin, HIGH);
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}






Na foto abaixo temos todo o conjunto montado em um protoboard e mais abaixo temos dois vídeos demonstrando o funcionamento do circuito.



Obs: As bússolas apontam sempre para o Norte, porém neste projeto configurei de forma que seja indicado pela seta o rumo que estamos seguindo e o NORTE fica fixo à frente. Para operar no modo padrão, bastaria criar as imagens com o norte acompanhando a ponta da seta e rotacionar tudo no sentido oposto ao que está sendo feito. É possível também conectar uma chave em uma das portas do Program-ME e com isso seria possível selecionar dois modos de operação da bússola.

O próximo desafio é adaptar a biblioteca KS0108 para trabalhar com display serial, assim não ocuparemos tantas portas do Program-Me só para o display.


Ache outros vídeos como este em Globalcode Program-ME



Ache outros vídeos como este em Globalcode Program-ME