Um dos momentos mais importantes da história da Eletron Livre aconteceu no dia 06 de Outubro de 2011. O projeto JHome, foi selecionado entre os vencedores do Duke's Choice Award 2011 a fazer uma demo no Community Keynote do JavaOne.
Depois de 10 anos de participação no JavaOne do Vinicius e 8 participações minhas aconteceu o que parecia impossível. Participar de um keynote. E não foi só isto, o Bruno Souza, fundador do SouJava também foi convidado e teve uma participação genial representando o SouJava e a comunidade Brasileira junto com outros líderes de JUGs!
O vídeo do Keynote está disponível na íntegra e muitas outras palestras podem ser assistidas no Parleys.com
O Keynote é muito organizado e planejado, e participamos do ensaio do Keynote na noite anterior onde tive o prazer de conhecer a principal responsável pelo JavaOne: Alvina O'Neal.
Pela primeira vez recebemos o Keynote Early Access Pass e pudemos entender um pouco mais sobre a realização de um keynote em um dos maiores eventos do mundo. Foi demais.
Estaremos com um pequeno stand no pavilhão de exposição esperando você para aproveitarmos um dos melhores eventos para quem realmente gosta e trabalha com Java!
jHome é uma plataforma open-source para automação residencial baseada em Java EE 6 e Glassfish desenvolvida pela Globalcode através da iniciativa Elétron Livre. Na verdade é uma consolidação de diversos projetos e demos realizadas pelos colaboradores da iniciativa Elétron Livre. Utilizando componentes JavaEE, como EJB, Servlet, WebService Endpoint e Timer Service, você pode controlar tomadas e muitos eletro-eletrônicos na sua casa. Desta forma você pode aprender Java EE de forma muito mais divertida.
Você pode injetar uma cafeteira no EJB usando CDI, brincou Vinicius Senger
Uma das coisas mais importantes que aprendemos com este projeto foi a confirmação da frase: : Quem não arrisca não petisca!
O Vinicius submeteu o projeto sem muita pretensão e o projeto foi selecionado! Depois de 10 anos participando ativamente da comunidade Java veio o primeiro prêmio da nossa história, um dos momentos mais sonhados por todo participante do JavaOne: um Duke's Choice Award.
Esta edição do TechEd Brasil foi muito especial para as pessoas que curtem Software e Hardware livre. A Microsoft abriu as portas para nos receber com a palestra Arduino + Java + .NET numa trilha focada em interoperabilidade.
O evento foi sensacional, mais de 3000 pessoas participando, com uma área de alimentação enorme para servir almoço para todos, infra-estrutura inpecável! Muito networking!
Java + Arduino + .NET
Open Source Hardware é um tema que está ganhando cada vez mais visibilidade, desde a publicação no Wall Stret Journal, meio artistico, universidades e agora os principais eventos de tecnologia! Vinicius Senger apresentou este conceito e também as principais conceitos sobre Arduino.
E para encerrar... cade o .NET ? Uma super arquitetura conceitual Java EE foi utilizada para criação de uma API para autoamção residêncial chamada JHome, que tem várias interfaces: JavaME, JavaFX e agora uma nova interface com .NET apresentada e discutida durante a palestra.
Mas, para aqueles que querem continuar escrevendo em .net, utilizando Visual Studio o Vinicius apresentou o .NET Microframework. E encerramos a palestra com várias perguntas e muita animação!
Esquenta TechEd Brasil na Globalcode
No dia 28 de agosto, véspera do maior evento da Microsoft na América Latina fizemos um encontro organizado pelo Vinicius Senger, Elemar Jr, Leandro Daniel, Emerson Gomes Brandão e Giovanni Bassi! Além da galera nota 10 da comunidade .NET recebemos também os amigos Felipe Oliveira (SoaExpert) e Alexandre Porcelli.(noSQL:br).
O clima esquentou mesmo, e teve muita discussão sobre a "morte ou não do silverlight", várias demos de WindowsPhone, uma prévia da apresentação de Java + Arduino + .NET, tudo isto com pizza e vinho.
Está sendo sensacional a interoperabilidade das comunidades: pessoal de Java conversando com a comunidade .NET, com a comunidade Python, Ruby, Arduino, etc, etc. Nada de cada um na sua panelinha. Developers são devolopers!
Agradeço aos amigos da comunidade .NET, em especial ao Giovanni Bassi que coordenou a primeira trilha .NET no The Developer's Conference 2011, bem como Fernando Figueira pela abertura e pelo espaço que tem nos ofercido, sem contar o apoio e participação no TDC!
É isso, ficamos super honrados e felizes com a participação no TechEd Brasil, esperamos que seja o primeiro de muitos!
Quer saber mais sobre a comundiade .NET ? Sobre o Esquenta Tech Ed Brasil ? Sobre interoperabilidade de comunidades ? Você não pode perder o podcast produzido pelos amigos @elemarjr @leandronet e @vquaiato VOID PODCAST Vazio e sem retorno de valor !
Gostaria de compartilhar mais um projeto bacana desenvolvido pelo nosso Professor Pardal Vinicius Senger, uma forma de aprender e experimentar com as coisas da vida real.
Veleiro + Android + Arduino
Tudo começou com um piloto automático quebrado. O piloto automático de um veleiro é uma peça que controla a Cana de Leme mantendo o barco numa determinada direção da bussola, por exemplo 30 graus.
Com o piloto automático trabalhando (companheiro carinhosamente apelidado de Mané) o Capitão Senger consegue fazer outras coisas enquanto navegamos para uma determinada direção, e de tempos em tempos ajusta-se novamente a orientação do piloto automático.
A bussola do piloto automático quebrou, e por isto o Capitão Senger (ou outro alguém) precisa ficar 100% do tempo mantendo a Cana de Leme na direção correta, caso contrário o barco fica girando ao redor do próprio eixo com influência do vento e do movimento das águas.
Embora fosse totalmente possível reproduzir a interface original o Vinicius preferiu utilizar os mesmos conceitos de controle e comunicação com Bluetooth do Robô BR1 e o acelerômetro do Android foi escolhido como interface para indicação da direção do barco, ou seja, o capitão inclina o celular para direita ou para esquerda indicando a direção da navegação.
Vale a pena assistir ao vídeo que eu mesma editei para entender o funcionamento do projeto:
Em tempos de conectividade os antigos Diários de bordo já não são tão precisamente utilizados e há sempre a vontade de "logar" todos os passeios e viagens com o barco por isto um módulo de GPS foi adicionado ao projeto que cria a rota do barco no Google Earth.
Evidentemente este ainda é um projeto experimental, e sem dúvida um dia pode ser transformado num projeto real, mas o fruto mais importante já foi colhido: conhecimento prático!
Lançamos hoje oficialmente o nosso framework Arduino para gerenciar nossos projetos mais complexos que trabalham com múltiplos modos de operação.
O Arduino apesar de simples, pode tomar uma proporção maior em projetos de média complexidade em diante, por isso criamos o Electron Kernel que é um gerenciador de modos, tarefas e eventos para Arduino.
Com ele você consegue programar múltiplos sketches que podem ser alternados via Serial, via botão / interrupção ou de formas customizadas, por exemplo, robôs que mudam de comportamento quando estão em um determinada inclinação.
Usando de conceitos de inversão de controle, principios de orientação a objetos com C++ e muito ponteiro de função, conseguimos abstrair as principais complexidades gerando uma biblioteca simples de usar e com alto poder.
Open Hardware está ganhando cada vez mais espaço na mídia convencional , saindo das redes sociais, blogs e YouTube e ganhando as páginas de jornal e televisão enquanto o Arduino está saíndo das "Garagens" dos hobbistas e ganhando cada vez mais a confiança de grandes instituições, escolas e universidades.
Vale a pena conferir esta reportagem realizada com o Vinicius Senger (@vsenger) e Lucas Fragomeni (@lucasfragomeni) no Correio Braziliense.
Carolina Vicentin
Cada vez mais pessoas usam hardwares livres para desenvolver soluções tecnológicas ou melhorar produtos já existentes no mercado
A Globalcode, nesta quinta edição do The Developer’s Conference, repetindo o formato inovador do ano passado - com várias trilhas de temas específicos, conta com o apoio e organização da Elétron Livre.
A coordenação da trilha de Arduino, que acontecerá no domingo, dia 10, está sob o comando do Vinicius Senger e do José Luiz Sanchez Lorenzo, ou seja, está imperdível! Domingo geek = Tecnologia + Futuro + Hacking + Arte + Diversão
Vamos abordar palestras sobre o incrível mundo de invenções open source que unem hardware e software para solucionar problemas do mundo real, tornando a computação muito mais divertida.
Através de palestras, demonstrações e discussões, vamos mostrar parte do infinito mundo de possibilidades que temos acesso.
Empolgados com o lançamento das novas placas Program-ME resolvemos reestruturar todo site, veja só como ficou:
Direto na home você verá as últimas notícias dos produtos, das inovações, participações e parcerias.
A loja virtual também mudou: Na página dos Program-MEs, por exemplo, você terá acesso à descrição detalhada das novas placas e download gratuito do manual e esquemático.
A compra e o pagamento continua vinculado ao PagSeguro, uma solução para pagamentos online que garante a segurança de quem compra, além da facilidade e ótimas formas de parcelamento.
O site foi desenvolvido utilizando a arquitetura Java EE 6, uma solução simples que demanda produtividade aliada à confiabilidade das tecnologias nativas como EJB, JMS e JSF. #2 Híbrido com OSGi.
Falando um pouco dos Program-MEs v2
As novas placas já vem com mais de 12 funções:
Sensor de luz
Sensor de temperatura
4 Transistores: para ligar relés, motor de passo, motor DC, leds de alto brilho, etc.
Ponte H L293D: controle motores DC com inversão de polaridade (frente / ré) ou motor de passo bipolar
2 entradas para servo-motor
Speaker;
Botão / chave tátil;
2 entradas analógias
2 entradas para interrupções
1 entrada I2C
1 entrada para bluetooth
5 leds
Os componentes são exatamente os mesmos em ambos formatos e recomendamos a placa redonda para robôs e quadrada para projetos estacionados.
A Google anunciou hoje no evento Google I/O algo que incrível para a plataforma Android em termos de hardware: um kit que permite o usuário desenvolver seu próprio acessório / dispositivo para seu telefone, e além de tudo utilizando a plataforma Arduino que é totalmente aberta e com forte participação da comunidade.
A placa é baseada no microcontrolador Atmega2560, ou seja, é semelhante a um Arduino Mega! Com isso podemos contar com os seguintes recursos:
40 Portas digitais
14 Portas digitais PWM
16 portas analógicas
Clock 16 MHz
Flash Memory 256 KB
SRAM 8 KB
EEPROM 4 KB
USB Host baseado no shield da SparkFun com MAX3421EEHJ
Desta forma encontramos na placa dois conectores USB:
Conector para transferir programas do PC para o Arduino (via FT232RL)
Conector para ligar o celular Android na placa (via MAX3421)
O modelo de programação é o seguinte:
Você desenvolve um aplicativo Arduino utilizando uma biblioteca de USB host da Google que vem no kit de desenvolvimento;
Transfere o programa (sketch) para o Arduino.
Você desenvolve um aplicativo para o Android e transfere da forma que preferir para o telefone
Conecta o Arduino no telefone pela serial do MAX3421
Boa!
Além da placa com USB Host publicaram também um modelo de uma placa shield que embarca alguns componentes onboard para facilitar a vida de quem quer brincar sem protoboard (qualquer semelhança com Program-ME é mera coincidência!!):
3 Leds RGB
3 Entradas para servo-motor
2 relés
Entrada para joystick (vou desvendar melhor esse CI!)
1 microswitch
3 leds
Pelo pouco que vi o shield fala com a placa por I2C, mas isso confirmo depois...
Vejam aqui imagens do arquivo cad desta placa:
Estamos muito felizes com isso porque nosso projeto Program-ME tem características semelhantes como uma development board e a ligação da nossa placa com o Android é até mais requintada pois é feita com Bluetooth, mas de qualquer forma isso nos mostra que estamos no caminho certo, tanto em investimentos no Arduino quanto tecnicamente nos nossos projetos de development board.
Além disso, temos um exemplo claro do poder que o open-source de um lado pode ter com dinheiro e muito carisma, ou com carisma e muito dinheiro (Android) e como de outro lado pode ter algo academico que também toma proporções épicas apenas pelo efeito da comunidade (Arduino). E a soma dessas duas energias resultará em centenas de milhares de oportunidades de negócio, para todos nós!
Podem esperar: seremos os primeiros no mundo a ter um curso disso, aguardem!
O projeto Ubatubino é uma pequena parte de uma grande história que merece ser contada.
Um dia, monitorando as atividades do GES, nosso sistema de gestão detectei uma solicitação de proposta da prefeitura municipal de Ubatuba, de um curso Introdução a Eletrônica de um professor que estava tendo o primeiro contato com a Globalcode.
Recebemos o aceite da proposta e o curso foi ministrado algumas semanas depois pelo instrutor José Luiz. Ficamos sabendo um pouco mais sobre o projeto de construção de um Satélite na escola. Neste projeto seria necessário criar, soldar e programar as placas do satélite.
O Vinicius, no auge da sua empolgação com a criação de placas caseiras (com o sucesso da placa Program-me e da Placa Tomada), ofereceu um segundo curso gratuitamente para ensiná-los a criar placas manualmente e apresentar o Arduino.
Para este curso era necessário criar uma placa, mas qual placa? Criar 20 placas inúteis não parecia uma solução, criar placas tomada talvez...
Foi então que o Vinicius teve a ideia de criar uma simplificação do Arduino, uma placa de baixo custo e baixa complexidade que os professores e crianças pudessem usar depois para outros projetos, valorizando ainda mais o investimento em peças e o conhecimento adquirido.
Foi assim que nasceu o Ubatubino.
Depois dos cursos, o Vinicius ajudou-os a montar um laboratório na escola, ajudando a desvendar os "segredos da Santa Efigênia", bem como ofereceu suporte quando os professores, criaram as placas, e acreditem: ensinaram várias turmas de quinto ano, isto mesmo... quase 120 alunos a imprimir, correr, corrigir, furar, soldar as placas Ubatubino!
Veja as imagens na matéria realizada sobre o Projeto maior da escola, a construção de um Satélite!
Este projeto tem tido uma excelente repercussão na mídia, principalmente depois do apoio recebido do meu avô Sérgio Mascarenhas, que abriu diversas portas com a publicação da história no Blog do Chico (que tem a história muito interessante dos primeiros passos do Professor Candido) , depois a publicação na Revista Fapesp, originando tantas solicitações da imprensa.
Desta forma agradeço imensamente ao meu avô Sérgio Mascarenhas e também ao Vinicius Senger que vem dedicando dezenas de horas voluntariamente a este projeto, e claro, a toda equipe de professores da Escola Municipal Tancredo Neves, em Ubatuba.
Quais os próximos passos com o Projeto Ubatubino ? A criação de um robô voador com balões de hélio! Veja o vídeo do protótipo:
Aconteceu na FATEC de São José do Rio Preto-SP entre 26 e 27 de Fevereiro de 2011 o Arduino Hacking Day, com o apoio da comunidade Java Noroeste e dos professores e técnicos da FATEC.
No início de 2011, a lista do Java Noroeste foi bem movimentada com o assunto Arduino, que surpreendeu a muitos pela alta procura que proporcionou a 50 pessoas divididas em dois grupos passarem horas conversando e trocando ideias com o Vinicius Senger que com maestria e muita habilidade conduziu a todos numa viagem de possibilidades para futuros projetos.
Enfatizamos todo o agradecimento a FATEC que proporcionou instalações para o Arduino Hacking Day fosse um sucesso e a DESTAQUE do nosso colega Thiago Vespa pela realização de mais este evento. Esperamos agora novas oportunidades para um novo Arduino Hacking Day, já que muitas pessoas não puderam fazer.
Fica ai o registro e atenção para o próximo Arduino Hacking Day.
Neste post falaremos sobre a teoria do funcionamento do dimmer digital com Arduino desenvolvido pelo Vinicius Senger e como implementar um controle de intensidade preciso utilizando um sensor de distância IR.
A rede elétrica que temos disponível na maioria das residências no Brasil é senoidal com 127 volts, sendo que a freqüência de oscilação é de 60 Hz (sessenta ciclos por segundo). Isso significa que temos um ciclo a cada 16,66 ms.
Para implementar o controle de luminosidade de uma lâmpada em AC, normalmente utilizamos um componente chamado TRIAC.
TRIAC ou Triode for Alternating Current é um componente eletrônico equivalente a dois retificadores controlados de silício (SCR ou tiristores) ligados em antiparalelo e com os terminais de disparo “gate“ ligados juntos.
Este tipo de ligação resulta em uma chave eletrônica bidirecional que pode conduzir a corrente elétrica nos dois sentidos. O TRIAC faz parte da família de tiristores.
Um TRIAC pode ser disparado tanto por uma corrente positiva quanto negativa aplicada no terminal de disparo (gate). Uma vez disparado, o dispositivo continua a conduzir até que a corrente elétrica caia abaixo do valor de corte.
Isto torna o TRIAC ideal para o controle de circuitos de corrente alternada, permitindo acionar grandes potências com circuitos acionados por correntes da ordem de miliamperes.
Podemos controlar o início da condução do dispositivo, aplicando um pulso em um ponto pré-determinado do ciclo de corrente alternada, o que permite controlar a percentagem do ciclo que estará alimentando a carga (também chamado de controle de fase).
Quando usado com cargas indutivas, como motores elétricos, é necessário que se assegure que o TRIAC seja desligado corretamente no final de cada semi-ciclo.
Para circuitos de maior potência, podemos utilizar dois SCRs ligados em antiparalelo, o que garante que cada SCR estará controlando um semi-ciclo independente, não importando a natureza da carga.
Para que seja possível disparar o TRIAC no momento correto, precisamos sincronizar esse disparo com a forma de onda da rede elétrica, para isso utilizamos um circuito detector de passagem por zero volts, no nosso projeto esse circuito é formado pelos componentes R1 a R4 , OK1 (4N35) e R5 (ver diagrama elétrico) .
A cada passagem da onda por zero volts, é gerada uma interrupção (INT0) no ATMEGA, ou seja , temos uma interrupção a cada 8,33 ms. Devemos então gerar um pulso no gate do TRIAC dentro de um intervalo entre 150 microsegundos até 8 milisegundos após a interrupção, assim ele conduzirá corrente elétrica em parte do semi-ciclo atual, seja ele positivo ou negativo.
Quanto mais antecipado for o disparo do TRIAC maior será a intensidade da lâmpada.
obs: não devemos disparar o TRIAC exatamente após a interrupção, pois a tensão ainda estará baixa e não haverá corrente suficiente para manter o TRIAC conduzindo, por isso demos uma margem de 150 microsegundos.
Neste projeto o circuito responsável pelo acionamento do TRIAC é formado pelos componentes OK2 (MOC3021), R7 e TRIAC-1.
Lembrando que tanto OK1 como OK2 tem também as funções de isolar o circuito AC do circuito DC.
Para controlarmos o instante de disparo do TRIAC, quando o ATMEGA recebe uma interrupção externa (INT0), iniciamos o TIMER1 com um valor em us (microsegundos) que é inversamente proporcional a ultima leitura válida do sensor de distância, sendo que transcorrido esse período será gerada uma interrupção indicando o momento do disparo do TRIAC.
O momento do disparo definirá a intensidade luminosa da lâmpada.
A implementação da interrupção utilizando o TIMER1 é feita utilizando a biblioteca TIMER1.
Com a utilização do TIMER1 da forma descrita acima, liberamos o ATMEGA para executar outras funções durante o período entre a detecção de passagem por zero e o momento do disparo do TRIAC, ou seja , ganhamos até 8 ms por semi-ciclo. Esse tempo é aproveitado por exemplo para fazer a multiplexação dos displays de 7 segmentos que indicam a % da potência aplicada à lâmpada (método Loop), evitando assim a necessidade de mais componentes para controlar esses displays.
A figura abaixo mostra as formas de onda da rede AC, da saída do detector de passagem pelo zero volts, do momento de disparo do gate do TRIAC e da forma de onda aplicada na lâmpada com 3 níveis diferentes de intensidade (100%, 50% e 10%).
Vejam que quanto mais cedo for disparado o TRIAC, maior será a área do ciclo aplicado a lâmpada (em vermelho) , e consequentemente maior será a intensidade luminosa.
Para definir o momento de leitura do sensor de distância, utilizamos a biblioteca MS_Timer2 de forma que seja gerada uma interrupção a cada 200ms. No tratamento dessa interrupção efetuamos a leitura do sensor de distância e definimos os dígitos de cada display 7 segmentos de acordo com a leitura efetuada.
Como pode ser observado no código disponibilizado , o método loop( ) deste projeto, fica o tempo todo atualizando a informação nos displays de 7 segmentos, e todas as demais funções são tratadas a partir de interrupções externa (INT0 “zerocross detection”) e internas(Timer1 “disparo do TRIAC” / TIMER2 “leitura do sensor distância IR”).
O resultado dessa implementação é um dimmer preciso e com indicação visual da potência aplicada na lâmpada.
Nas figuras abaixo temos o diagrama elétrico completo e a arte final em formato de shield.
Lista de Componentes:
R1 a R4 : resistores de 47K
R5 : resistor de 10K
R6 e R7 : resistores de 330ohm
OK1: fotoacoplador 4N35
OK2: MOC3021
TRIAC-1: BTA16
Display de 7 segmentos com 3 digitos (anodo comum).
Protoshield
sensor de distância analógico (IR)
O protótipo foi montado em uma protoshield que atendeu muito bem, possibilitando a montagem de todos os componentes com bastante facilidade. (foto abaixo)
abaixo temos o código completo do dimmer:
#include <TimerOne.h> // inclui biblioteca Timer1
#include <MsTimer2.h> // Inclui biblioteca MsTimer2
//define portas associadas ao display 7seg
//int displaySeg[] = {a, b, c, d, e, f, g, pd};
int displaySeg[] = {6, 1, 17, 15, 14, 5, 18, 12};
//int displayPorts[] = {Anodo1, Anodo2, Anodo3};
int displayPort[] = {7, 4, 3};
// define padroes do display 7SEG, de 0 - 9 e apagado
// 1 = segmento apagado, 0 = segmento aceso
byte seven_seg_digits[11][8] = {
{ 0,0,0,0,0,0,1,1 }, // = 0
{ 1,0,0,1,1,1,1,1 }, // = 1
{ 0,0,1,0,0,1,0,1 }, // = 2
{ 0,0,0,0,1,1,0,1 }, // = 3
{ 1,0,0,1,1,0,0,1 }, // = 4
{ 0,1,0,0,1,0,0,1 }, // = 5
{ 0,1,0,0,0,0,0,1 }, // = 6
{ 0,0,0,1,1,1,1,1 }, // = 7
{ 0,0,0,0,0,0,0,1 }, // = 8
{ 0,0,0,1,1,0,0,1 }, // = 9
{ 1,1,1,1,1,1,1,1 } // = blank
};
int sensorDistancia = 2; // porta associada ao sensor distancia IR
int triacGatePin = 10 ; // porta associada ao gate do TRIAC
int distancia = 0 ; // variavel para armazenar distancia
int power= 0 ; //inicializa variavel que controla potencia na lampada com 0 (lampada apagada)
int centena = 10 ; // armazena informacao a ser apresentada no display de centena (inicializa com 10 = apagado)
int dezena = 10 ; // armazena informacao a ser apresentada no display de dezena (inicializa com 10 = apagado)
int unidade = 10 ; // armazena informacao a ser apresentada no display de unidade (inicializa com 10 = apagado)
void setup() {
//Serial.begin(9600);
pinMode(triacGatePin, OUTPUT);
for (int i=0 ; i<=3 ; i++) {
pinMode(displayPort[i], OUTPUT);
}
for (int j=0 ; j<=7 ; j++) {
pinMode(displaySeg[j], OUTPUT);
}
attachInterrupt(0, zeroCrossInterrupt, CHANGE); //associa interrupcao INT0 com funcao "zeroCrossInterrupt"
MsTimer2::set(200, leSensor); // inicializa Timer2 com 200 milisegundos (tempo entre leituras do sensor de dintancia)
MsTimer2::start(); // start do timer2
}
void loop() {
atualizaDisplay(unidade, dezena, centena); // atualiza informacoes nos displays de 7 segmentos
}
void atualizaDisplay(int uni, int dez, int cen) {
for (int k = 0; k < 8; ++k) {
digitalWrite(displaySeg[k], seven_seg_digits[uni][k]);
}
digitalWrite(displayPort[2], HIGH);
delay (1);
digitalWrite(displayPort[2], LOW);
for (int k = 0; k < 8; ++k) {
digitalWrite(displaySeg[k], seven_seg_digits[dez][k]);
}
digitalWrite(displayPort[1], HIGH);
delay (1);
digitalWrite(displayPort[1], LOW);
for (int k = 0; k < 8; ++k) {
digitalWrite(displaySeg[k], seven_seg_digits[cen][k]);
}
digitalWrite(displayPort[0], HIGH);
delay (1);
digitalWrite(displayPort[0], LOW);
}
void zeroCrossInterrupt(){ // trata interrupcao INT0
if(power > 0) {
long dimtime = int(map(power,0,100,8000,150)); // calcula o tempo de delay para o disparo do TRIAC
Timer1.initialize (dimtime); // inicializa o TIMER1 com o delay calculado
Timer1.attachInterrupt(gateTRIAC); //associa a funcao gateTRIAC com Interrupcao do TIMER1
Timer1.start(); // inicia contagem TIMER1
} else {
digitalWrite(triacGatePin, LOW); // mantem gate do TRIAC desativado.
Timer1.stop();
}
}
void gateTRIAC () { // trata interrupcao do TIMER1 gerando pulso no gate do TRIAC
digitalWrite(triacGatePin, HIGH); // dispara o Triac
delayMicroseconds(15); // aguarda 15 microsegundos para garantir disparo do TRIAC
digitalWrite(triacGatePin, LOW); // desabibilta gate do TRIAC
Timer1.stop();
}
void leSensor() {
distancia = analogRead(sensorDistancia); // le sensor de distancia
//Serial.println(distancia);
distancia = map(distancia,70,600,120,0); // mapeia distancia lida para uma faixa de potencia entre 0 e 120
if (distancia < 0) {
distancia = 0;
}
if (distancia >=0 && distancia <= 100) { // se distancia <= a 100 atualiza potencia
power=distancia;
}
centena = int(power / 100); // atualiza variaveis que contem informacoes dos displays
dezena = int((power - (centena*100)) / 10);
unidade = int(power - (centena*100)-(dezena*10));
if (centena == 0 && dezena == 0){
centena = 10;
dezena = 10;
}
if (centena == 0){
centena = 10;
}
}
Segue um vídeo demonstrando o funcionamento do dimmer.
Neste post demonstrarei como utilizar uma tela touchscreen resistiva implementando o jogo SIMON (Genius da Estrela) no Arduino.
Primeiro vamos ver como é o funcionamento da tela touchscreen resistiva.
Basicamente essas telas são compostas de dois filmes resistivos "resistive Coating". Entre eles existem espaçadores "spacers" que evitam falsos toques. Existe também uma base de vidro "Bottom Glass" que dá resistência mecânica e mantém firme o resistive Coating da parte inferior.
Esse tipo de tela possui 4 pontos de conexão, sendo dois deles associados aos extremos do resistive Coating (on top film) e os outros dois associados aos extremos do resistive Coating (on bottom glass).
Ao pressionarmos um ponto da tela, o Resistive Coating superior entra em contato com o inferior criando uma resistência entre os pontos de conexão do resistive Coating superior e do resistive Coating inferior.
Na prática o que temos é que a tela touchscreen resistiva se comporta como dois potênciometros, um associado ao eixo X e outro ao eixo Y.
Obtendo as coordenadas do ponto pressionado
Para obtermos a cordenada X, aplicamos (GND) em um dos terminais associados ao barramento lateral da tela e 5 volts no terminal associado ao outro barramento lateral da tela, então efetuamos uma leitura analógica no terminal associado ao barramento superior ou inferior da tela.
A figura ao lado mostra como efetuar a leitura da cordenada X:
Para obtermos a cordenada Y, aplicamos (GND) no terminal associado ao barramento inferior da tela e 5 volts no terminal associado ao barramento superior da tela, então efetuamos uma leitura analógica no terminal associado a qualquer um dos barramentos laterais da tela.
A figura ao lado mostra como efetuar a leitura da cordenada Y:
Com relação a calibragem da tela, foi necessário apenas ajustar no código o posicionamento na tela de acordo com os valores analógicos máximos e mínimos obtidos das cordenadas X e Y.
As linhas principais do código para obter o ponto pressionado na tela ficaram da seguinte forma:
int x=analogRead(yLow); x=map(x,90,850,0,127);
onde valores mínimo e máximo de X (90 e 850) foram mapeados para os pixels do display (0 ~ 127)
int y=analogRead(xLow); y=map(y,80,820,0,63);
onde valores mínimo e máximo de Y (80 e 820) foram mapeados para os pixels do display (0 ~ 63)
Bem agora que já sabemos o funcionamento básico do touchscreen resistivo, vamos ao projeto.
Para implementar o SIMON touchscreen com Arduino, utilizei uma placa Brasileirino da Globalcode, um display LCD gráfico ITM-12864 (128x64 pixels), uma tela touchscreen resistiva de Nintendo DS e um Nintendo DS Touch Screen Connector Breakout (este para conexão do flat cable da tela touch). Obs: Recomendo a utilização do Nintendo DS Touch Screen Connector Breakout, pois a conexão da tela sem ele se torna muito delicada.
A tela foi dividida em 4 quadrantes, onde cada um representa um botão do jogo. Vide foto abaixo:
Essa biblioteca facilita bastante a interface com o display LCD, visto que podemos carregar imagens bimap no display com apenas um comando. Mais detalhes sobre a utilização dessa biblioteca podem ser vistos no meu post sobre bússola digital ou na página oficial da biblioteca. Um detalhe importante na utilização dessa biblioteca é configurar corretamente o arquivo ks0108_Arduino.h. Nesse arquivo indicamos onde está conectado cada terminal do display no Arduino.
Para este projeto o trecho inicial do arquivo ficou da seguinte forma:
/*
/*********************************************************/ /* Configuration for assigning LCD bits to Arduino Pins */ /*********************************************************/ /* Arduino pins used for Commands * default assignment uses the first five analog pins */
#define CSEL1 2 // CS1 Bit // swap pin assignments with CSEL2 if left/right image is reversed #define CSEL2 3 // CS2 Bit
#define R_W 13 // R/W Bit #define D_I 12 // D/I Bit #define EN 19 // EN Bit //#define RES 19 // Reset Bit // uncomment this to contol LCD reset on this pin
/* option: uncomment the next line if all command pins are on the same port for slight speed & code size improvement */ #define LCD_CMD_PORT PORTB // Command Output Register for pins 14-19
/* Arduino pins used for LCD Data * un-comment ONE of the following pin options that corresponds to the wiring of data bits 0-3 */ #define dataPins8to11 // bits 0-3 assigned to arduino pins 8-11, bits 4-7 assigned to arduino pins 4-7 //#define dataPins14to17 //bits 0-3 assigned to arduino pins 14-17, bits 4-7 assigned to arduino pins 4-7. (note command pins must be changed) //#define dataPins0to3 // bits 0-3 assigned to arduino pins 0-3 , bits 4-7 assigned to arduino pins 4-7, this is marginally the fastest option but its only available on runtime board without hardware rs232.
/* NOTE: all above options assume LCD data bits 4-7 are connected to arduino pins 4-7 */
/*******************************************************/ /* end of Arduino configuration */ /*******************************************************/
A maioria dos displays LCD necessitam de uma tensão negativa para acionamento do display, muitos deles possuem um circuito interno para gerar essa tensão. Como o ITM-12864 não possui esse circuito e afim de evitar a utilização de duas fontes de alimentação externas, montei no protoboard localizado em baixo do display, um conversor de +12volts para -9 volts utilizando um CI 555.
Nas figuras abaixo temos o diagrama elétrico do conversor e a montagem dele no protoboard. Na protoboard foram adicionados também o speaker, o potenciômetro de controle de contraste do display e os resistores que ligam os terminais da tela touch ao terra.
Nas imagens abaixo temos o detalhe da conexão do flat cable da tela touch utilizando a Nintendo DS touch Screen Connector Breakout. Também é possível ver a colagem da tela touch no display onde utilizei tiras de fita dupla face.
Além de ser conectada nas portas analógicas 0 a 3, a tela touch necessita resistores para o terra (GND) conforme diagrama abaixo: Esses resistores foram montados na protoboard em baixo do display e eles tornam o processo de calibração da tela desnecessário.
O programa deste projeto foi baseado no código apresentado pelo Spock em seu post sobre "DOJO de programação com Program-Me", sendo que aproveitei toda a parte funcional do código original e fiz apenas as adaptações necessárias para substituir os botões e Leds pela touchscreen e pelo display, além de implementar sons diferentes para cada botão.
Segue abaixo o código final do projeto.
#include <ks0108.h> // inclui biblioteca KS0108 #include "bloco1_ON.h" // bitmap botao 1 ativado #include "bloco2_ON.h" // bitmap botao 2 ativado #include "bloco3_ON.h" // bitmap botao 3 ativado #include "bloco4_ON.h" // bitmap botao 4 ativado #include "blocos_OFF.h" // bitmap todos os botoes desativados #include "principal.h" // bitmap logo SIMONDUINO #include "logo_Globalcode.h" // bitmap logo Globalcode #include "level1.h" // bitmap nivel 1 #include "level2.h" // bitmap nivel 2 #include "level3.h" // bitmap nivel 3 #include "level4.h" // bitmap nivel 4 #include "gameOver.h" // bitmap game over #include "parabens.h" // parabens voce venceu
#define xLow 15 //define porta associada ao xLow (X2) #define xHigh 17 //define porta associada ao xHigh (X1) #define yLow 16 //define porta associada ao yLow (Y2) #define yHigh 14 //define porta associada ao yHigh (Y1)
int bip = 18; char state = 'S'; // S = Start, P = Play, B = Read button, ... int sequencia[] = {0,0,0,0,0,0,0,0,0}; int currentRound = 0; // armazena round atual int level = 1; //define nivel 1 como inicial int tamanhoSequencia = 8; //define o tamnanho de cada sequencia boolean fimJogo = true; // indica fim de jogo
void setup() { pinMode(bip, OUTPUT); // configura porta speaker como saida Serial.begin(9600); GLCD.Init(NON_INVERTED); // inicializa a biblioteca GLCD GLCD.ClearScreen(); // limpa tela do display GLCD.DrawBitmap(principal,0,0,BLACK); //desenha na tela o bitmap do SIMONDUINO delay(3000); GLCD.DrawBitmap(logo_Globalcode,0,0,BLACK); //desenha na tela o logo da Globalcode delay(3000); GLCD.DrawBitmap(level1,0,0,BLACK); //desenha na tela o bitmap do nivel 1 delay(2000); }
void loop() { if (state == 'S') { inicio(); //inicializa jogo fimJogo = false; currentRound = 0; state = 'P'; } if (state == 'P') { acendeluzesdarodada(); //reproduz seguencia da rodada no display e no speaker state = 'B'; } if (state == 'B') { for (int i = 0; i <= currentRound; i++){ int botao = leBotao(); //chama funcao que le os botoes (touchscreen) if (sequencia[i] != botao || botao==-1) { state = 'S'; fimJogo = true; GLCD.DrawBitmap(gameOver,0,0,BLACK); //desenha na tela o bitmap de gameover beep(); delay(2000); GLCD.DrawBitmap(level1,0,0,BLACK); //draw the bitmap at the given x,y position level = 1; break; } } if (!fimJogo) { currentRound++; if (currentRound == tamanhoSequencia) { //verifica se round foi concluido level++ ; switch (level) { //caso concluido desenha bitmap do proximo nivel case 2: GLCD.DrawBitmap(level2,0,0,BLACK); //draw the bitmap at the given x,y position break; case 3: GLCD.DrawBitmap(level3,0,0,BLACK); //draw the bitmap at the given x,y position break; case 4: GLCD.DrawBitmap(level4,0,0,BLACK); //draw the bitmap at the given x,y position break; case 5: GLCD.DrawBitmap(parabens,0,0,BLACK); //draw the bitmap at the given x,y position delay(5000); GLCD.DrawBitmap(level1,0,0,BLACK); //desenha na tela o bitmap do nivel 1 delay(2000); state = 'S'; level = 1 ; break; } state = 'S';}else{ state = 'P'; } } } delay(2000); }
void acendeluzesdarodada() { for (int i = 0; i <= currentRound;i++){ alteraBotoes(sequencia[i]); ton(sequencia[i]); delay(500 - (level*50)); noTone(bip); alteraBotoes(-1); delay(250 - (level*25)); } }
int leBotao() { int timeout = 0; int botao = -1; while (botao == -1 && timeout <= (35 - (level*5))) { botao = leScreen(); //le touchscreen if(botao != -1) { break; } delay(100); timeout++; } alteraBotoes (botao); while (leScreen( ) != -1){ ton(botao); } noTone(bip); GLCD.DrawBitmap(blocos_OFF,0,0, BLACK); //desenha todos os botoes desativados return botao; }
void beep() { // emite som de fim de jogo tone(bip,100); delay(2000); noTone(bip); }
void ton(int freq) { //emite sond de cada botao tone(bip,freq*1000); }
void inicio() { GLCD.ClearScreen(); GLCD.DrawBitmap(blocos_OFF,0,0,BLACK); //desenha todos os botoes desativados randomSeed(analogRead(4)); // inicializa numeros randomicos for (int i = 0; i < tamanhoSequencia; i++) { sequencia[i] = (int) random(1, 5); // gera sequencia aleatoria do round } }
int leScreen() { pinMode(xLow,OUTPUT); // prepara sinais da tela touch para leitura da coordenada X pinMode(xHigh,OUTPUT); digitalWrite(xLow,LOW); digitalWrite(xHigh,HIGH); digitalWrite(yLow,LOW); digitalWrite(yHigh,LOW); pinMode(yLow,INPUT); pinMode(yHigh,INPUT); delay(10); //xLow has analog port -14 !! int x=analogRead(yLow -14); // le coordenada X x=map(x,90,850,0,127); // ajusta coordenada X de acordo com resolucao do display
pinMode(yLow,OUTPUT); // prepara sinais da tela touch para leitura da coordenada Y pinMode(yHigh,OUTPUT); digitalWrite(yLow,LOW); digitalWrite(yHigh,HIGH); digitalWrite(xLow,LOW); digitalWrite(xHigh,LOW); pinMode(xLow,INPUT); pinMode(xHigh,INPUT); delay(10); //xLow has analog port -14 !! int y=analogRead(xLow - 14); // le coordenada Y y=map(y,80,820,0,63); // ajusta coordenada Y de acordo com resolucao do display
// Serial.print(x,DEC); //imprime cordenadas no serial monitor (descomentar para debug) // Serial.print(","); // Serial.println(y,DEC);
delay(200);
if ((x >= 0 && x < 64) && y > 32) { // verifica em qual quadrante da tela foi efetuado o toque de acordo com as coordenadas X e Y return 1; } if ((x >= 64 && x < 128) && y > 32) { return 2; }
if ((x >= 0 && x < 64) && (y >= 0 && y < 32)) { return 3; } if ((x >= 64 && x < 128) && (y >= 0 && y < 32)) { return 4; } return -1; }
Abaixo temos um video demonstrando o funcionamento do SIMONDUINO Touchscreen, sendo que apenas reduzi o tamanho das combinações de cada nível de 8 para 3 afim de encurtar o vídeo. A cada nível que se avança as sequências são apresentadas com maior velocidade e o jogador tem menos tempo para reproduzi-las.
Custo dos componentes principais:
Display LCD gráfico ITM-12864 R$ 50,00 Tela touchscreen Nintendo DS US$ 9,95 Breakout board para conexão da tela US$ 3,95
Bem é isso pessoal, espero que gostem do projeto. Me diverti bastante fazendo ele.