sábado, 25 de fevereiro de 2017

Teclado Matricial

Teclado Matricial



O teclado matricial de membrana é um componente bastante utilizado em projeto que visam a necessidade de entrada de dados, como inserção de senhas alfanuméricas (limitando - se até a letra D) ou outros tipos de dados numéricos.
Sua membrana é formada por botões em sequência disposto em forma de matriz e divididos em linhas e colunas. A cada botão acionado faz - se acionar uma conexão entre linha e coluna correspondente informando ao microcontrolador a tecla ou sequência de teclas informada pelo usuário.

fonte: google sketchup





É bastante comum encontrar no mercado especializado de eletrônicos teclados matriciais de membrana de 4X3 e 4X4, cabendo ao usuário especificar qual o melhor modelo se adequa ao projeto.



Pinos do teclado matricial

Disponibilizado conforme a figura abaixo, as chaves do teclado matricial formam conexões entra as linhas e colunas correspondentes.

fonte: tutodonerd

Conforme o usuário necessitar, o acionamento de uma tecla faz a conexão necessária entra a linha e a coluna correspondente.


fonte: próprio autor

Integrando Arduino com teclado matricial

Circuito de ligação

Para a integração do Arduino com o teclado matricial vai ser utilizado uma membrana 4X4 e vai ser testado todas as chaves para comprovar o funcionamento correto do teclado. Com o componente em perfeito funcionamento deve ser implementado em um pequeno projeto.

O Arduino e o teclado devem ser conectados conforme demonstrado.


fonte: próprio autor

O código fonte

Feito as conexões, copie e cole o código na IDE do seu Arduino e  teste usando o monitor serial da plataforma para verificar o funcionamento das teclas.

/*
//==Codigo teste teclado matricial//
//mecatronizando@gmail.com//
*/

#include <Keypad.h>   //Biblioteca
const byte numRows=4; // linhas
const byte numCols=4; // colunas

char teclado [numRows][numCols]= // Definir as teclas
{
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'},
};

byte rowPins[numRows] = {9,8,7,6}; // Pinos digitais relacionados as linhas.
byte colPins[numCols] = {5,4,3,2}; // Pinos digitais relacionados as colunas.

Keypad meuteclado = Keypad(makeKeymap(teclado), rowPins, colPins, numRows, numCols);

void setup(){
  Serial.begin(9600);
}
void loop(){
  char keypressed = meuteclado.getKey();
  if(keypressed !=  NO_KEY)
{
Serial.println(keypressed); //Escreve na serial
  }
}







Depois de compilado, deve ser exibido no monitor serial o valor correspondente a tecla escolhida pelo usuário.



fonte: próprio autor

Senha de acesso

No projeto apresentado deve ser inserido uma combinação numérica que informa ao usuário permissão ou não de acesso a qualquer sistema.
No exemplo a senha de acesso é bem simples, a sequência 1,2,3 e 4. A tecla D (delete), limpa o visor LCD para que a senha seja corrigida ou caso seja necessária a inserção novamente .
Siga os passos de montagem conforme a figura.


fonte: próprio autor


O código fonte



No código fonte do projeto, é possível alterar a senha conforme a necessidade do usuário, está informado em combinação qual o numero de caracteres vão ser necessários para a senha e é preciso que a senha no código fonte seja inserido conforme a tabela ASCII para que o teclado possa ler, abaixo na tabela é possível ver a sequência 49, 50, 51 e 52 utilizada e está relacionada com 1, 2, 3 e 4.



fonte: internet

Copie e cole na IDE do Arduino o código abaixo e teste seu funcionamento.

/*
//==Acesso com senha teclado matricial===//
//mecatronizando@gmail.com//
Elaborado por Tony Emerson Marim
25/02/2017
*/

#include<Keypad.h>
#include <LiquidCrystal.h>

const int combinacao = 4;
int rightnumber[combinacao] = {49, 50, 51, 52};//this codes for 1,2,3,4 in ASCII. Had to use it because the library stores the input in decimal ASCII intead of a number.


int novonumero[combinacao];
char numero[combinacao];
int right = 0;
int verde = A1;
int verm = A2;
int novacomb = 0;
byte fulllcd[8] = {B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111,};
int novacombfinal = 0;
int kposicao = 0;
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'#','0','*','D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {5, 4, 3, 2}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS );
LiquidCrystal lcd(13,12,11,10,1,0);
void setup() {
  // put your setup code here, to run once:
 // Serial.begin(9600);
  pinMode(A1,OUTPUT);
  pinMode(A2,OUTPUT);
  lcd.createChar(0, fulllcd);
  lcd.begin(16,2);
  lcdstartup();
}

void loop() {
  // put your main code here, to run repeatedly:
  char k = keypad.getKey();
  if(k != 0){ //if you press something
   if(k == 68){
    kposicao = 0;
    lcdstartup();
  }
  else{
    numero[kposicao] = k; //save number in array
    kposicao++; //add to the combination digit position
    lcd.setCursor(kposicao - 1,1);
    lcd.print("*"); //writes a * each time you enter in a charcter
  delay(50);  //delay just cause i can
  if(kposicao == combinacao){ //checks if we pressed 4 numbers
   kposicao = 0;  //sets array write position to 0
   for(int g=0;g<combinacao;g++){//if each digit is right, add to the variable "right"
    if(numero[g] == rightnumber[g]){ right++;} //checks if all inputed digits are right
    }
    if(right == combinacao){
      rightaction();
      rightlcd();
      right = 0;
      }
    else{
      wrongaction();
      wronglcd();
      right = 0;
      }
   delay(100);
  }
  }
  }
}
void lcdstartup(){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Combinacao :");
}
void lcdenter(){
  lcd.clear();
  lcd.print("Inserir novo :");
}
void lcdgranted(){
 lcd.clear();
 lcd.print("*****ACESSO******");
 lcd.setCursor(0,1);
 lcd.print("****PERMITIDO*****");
}
void rightlcd(){
 lcdgranted();
 while(novacombfinal == 0){
  delay(10);
  char o = keypad.getKey();
  if(o != 0){
    if(o == 67){
      digitalWrite(verde,LOW);
      lcdenter();
      while(novacomb == 0){
      entnovocod();}
      novacomb = 0;
    }
    if(o == 68){
      novacombfinal = 1;
      digitalWrite(verde,LOW);
    }
  }
  }
  novacombfinal = 0;
 lcd.clear();
 lcdstartup();
}
void entnovocod(){
 char novak = keypad.getKey();
 if(novak != 0){
    novonumero[kposicao] = novak;
    kposicao++;
    lcd.setCursor(kposicao,1);
    lcd.print(novak);
    if(novak == 68){
    lcd.setCursor(0,1);
    lcd.print("        ");
    kposicao = 0;
    }
    if(kposicao == combinacao){
      lcd.setCursor(kposicao + 1,1);
      lcd.write(byte(0));
      delay(1000);
      kposicao = 0;
      checknovocod();
    }
 }
}
void checknovocod(){
  lcd.clear();
  lcd.print("Voce tem certeza ?");
  while(novacomb == 0){
    char novac = keypad.getKey();
    if(novac != 0){
      if(novac == 65){
        lcd.clear();
        lcd.print("Novo cod.");
        lcd.setCursor(0,1);
        lcd.print("Aceito");
        novacomb = 1;
        novacombfinal = 1;
        for(int j=0;j<combinacao;j++){
          novonumero[j] = novonumero[j];
          }
          kposicao = 0;
          delay(1500);
      }
      if(novac == 66){
        delay(10);
        lcdgranted();
        novacomb = 1;
      }
    }
  }
}
void wronglcd(){
lcd.clear();
 lcd.print("*****ACESSO******");
 lcd.setCursor(0,1);
 lcd.print("*****NEGADO*****");
 while(novacombfinal == 0){
  delay(10);
  char o = keypad.getKey();
  if(o != 0){
    if(o == 68){
      novacombfinal = 1;
    }
  }
  }
  novacombfinal = 0;
 lcd.clear();
 lcdstartup();
 digitalWrite(verm,LOW);
}

void rightaction(){
      digitalWrite(verde,HIGH);
      digitalWrite(verm,LOW);
}
void wrongaction(){
      digitalWrite(verm,HIGH);
      digitalWrite(verde,LOW);
}


No vídeo é possível ver o comportamento do projeto, montado conforme o esquema.




Gostou?


Se for necessário baixe todos os arquivos e bibliotecas AQUI!

Bons Estudos!





sábado, 18 de fevereiro de 2017

Voltímetro com Arduino

Voltímetro com Arduino

Com o intuito de disponibilizar ao usuário valores de medição de tensões o voltímetro é ma importante ferramenta de trabalho para que se arrisca no universo da eletrônica como hobista ou profissional. 
Por definição, o voltímetro é um aparelho que realiza medições de tensão elétrica em um circuito. Ele exibe essas medições, geralmente, por meio de um ponteiro móvel ou um mostrador digital, de cristal líquido (LCD) por exemplo. A unidade apresentada geralmente é o Volt (V).
Atendendo ao pedido de Miguel Angel Ramos, um seguidor do blog, estaremos realizando o projeto de um voltímetro com digital com leitura em tela LCD.
Para isso vamos começar conhecendo um pouco mais do projeto.

O projeto

Para esse projeto, vai ser elaborado um circuito que pode medir tensões de no máximo 50V em corrente contínua.
Como o conversor ADC do Arduino trabalha com tensão máxima de +5V, faz-se necessário realizar um circuito para medir tensões superiores a esse valor, então vai ser elaborado um divisor de tensão (clique no texto se quiser conhecer mais sobre esse assunto).
Com funcionamento e entendimento fácil de realizar o divisor de tensão faz-se por meio de lei de Ohm, onde a tensão de entrada é definida pela fonte, e os resistores responsáveis pela divisão da tensão determinam o valor que vai para a tensão de saída.

Analisando:
Se tiver um valor de entrada (saída da fonte) com valor de +5V, os resistores do divisor com valores de 10 Kohm cada, o valor de saída vai ficar em +2,5V.
Vsaída = Ventrada x Rdebaixo/Rdecima + Rdebaixo, calculando tem-se 2,5V.


fonte: www.feiradeciencias.com.br



fonte: próprio autor

Montagem

Para o funcionamento do circuito vai ser necessário:
1 Arduino Uno/ Mega (ou similar)
1 protoboard 
1 LCD 16 x 2
1 modulo I2C
1 resistor de 10 k
1 resistor de 100k
cabos jumpers

Todos os componente pode ser adquiridos por esse LINK!

Na proposta do nosso projeto, deve ser montado um circuito que pode medir tensões de até 50Vcc, fazendo um divisor de tensão com resistores .


fonte: próprio autor


Para outros valores que estejam acima de 50Vcc, deve ser calculado outros valores para o divisor de tensão!

O circuito

Para o correto funcionamento deve ser feito todas as ligações conforme o esquema abaixo.

fonte: próprio autor

Para o Arduino Mega, é necessário que ao invés de conectar os pinos SDA e SCL do modulo I2C nos pinos A1 e A0 conecte-se aos pinos 20 e 21 respectivamente.


fonte: próprio autor

Ao contrário dos voltímetros/ multímetros não deve-se NUNCA inverter a polaridade das pontas de prova!

Modulo I2C

Esse modulo é utilizado em projetos com Arduino para reduzir o numero de conexões junto ao LCD 16 x 2 ou 20 x 4, pois somente fazendo uso dos pinos SDA  e SCL (analógicos), formam a interface de comunicação I2C.
em sua estrutura simples, existem 4 pinos onde dois são para alimentação, dois para conectar as portas analógicas e um potênciometro ao qual pode ser controlado o ajuste de contraste do display, o jumper na extremidade oposta a dos pinos seleciona o funcionamento ou não da backlight do display.




O modulo I2C vem configurado de fábrica com endereço 0x27, em alguns casos podem vir com faixas  de endereços diferente, para descobrir utilize o programa I2CScanner e substitua no programa a linha de endereço de acordo com o resultado obtido. O resultado deve ser demonstrado no monitor serial do Arduino.

fonte: próprio autor


No meu caso está com o endereço em 0x3F.

  1. LiquidCrystal_I2C lcd(<<<0x27>>>,2,1,0,4,5,6,7,3, POSITIVE);
  1. LiquidCrystal_I2C lcd(0x3F,2,1,0,4,5,6,7,3, POSITIVE);

I2CScanner

// --------------------------------------
// i2c_scanner
//
// Version 1
//    This program (or code that looks like it)
//    can be found in many places.
//    For example on the Arduino.cc forum.
//    The original author is not know.
// Version 2, Juni 2012, Using Arduino 1.0.1
//     Adapted to be as simple as possible by Arduino.cc user Krodal
// Version 3, Feb 26  2013
//    V3 by louarnold
// Version 4, March 3, 2013, Using Arduino 1.0.3
//    by Arduino.cc user Krodal.
//    Changes by louarnold removed.
//    Scanning addresses changed from 0...127 to 1...119,
//    according to the i2c scanner by Nick Gammon
//    http://www.gammon.com.au/forum/?id=10896
// Version 5, March 28, 2013
//    As version 4, but address scans now to 127.
//    A sensor seems to use address 120.
// 
//
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.

#include <Wire.h>

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  Serial.println("\nI2C Scanner");
}

void loop()
{
  byte error, address;
  int nDevices;
  Serial.println("Scanning...");
  nDevices = 0;
  for(address = 1; address < 127; address++ ) 
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");
      nDevices++;
    }
    else if (error==4) 
    {
      Serial.print("Unknow error at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
  delay(5000);           // wait 5 seconds for next scan
}

O código fonte

Insira o código abaixo na IDE do Arduino e execute o programa, o modulo I2C utiliza a biblioteca LiquidCrystal_I2C, que pode ser baixada junto com todos os arquivos ao final da postage.

 /** Código **/
/** Baseado no original de Jhonatan Caldeira **/
// Elaborado por Tony Emerson Marim em 08/07/2016.
/** mecatronizando@gmail.com **/
/** Voltimetro **/

#include <LiquidCrystal_I2C.h>
#include "Wire.h"
LiquidCrystal_I2C lcd(0x3F,2,1,0,4,5,6,7,3, POSITIVE);

//Sensor de tensão//
int analogInput = A0;
float Vo = 0.0, Vi = 0.0;
float value_aux = 0, value = 0;

//Valores dos Resistores//
float R1 = 100000.0; //Resistência R1 (100K) 
float R2 = 10000.0; //Resistência R2 (10K) 

void setup(){
  pinMode(analogInput, INPUT);
  lcd.begin(16, 2);
  lcd.setBacklight(HIGH);
  lcd.setCursor(2,0);
  lcd.print("Voltimetro DC");
  lcd.setCursor(14,1);
  lcd.print("V");
  }

void loop(){
  
  for(int i=60;i>0;i--){
  value_aux = analogRead(analogInput);
  value += pow(value_aux,2);
}

  value = sqrt(value/60);
  Vo = (value * 5.0) / 1023.0;
  Vi = Vo / (R2/(R1+R2));
  if (Vi<0.09) {Vi=0.0;} //Filtrando medições errôneas!
  lcd.setCursor(5,1);
  lcd.print(" ");
  lcd.setCursor(5,1);
  lcd.print(Vi);
  delay(500);
}

Na eletrônica, dependendo da necessidade de precisão de medidas alguns ajustes podem ser feitos para melhorar a leitura do voltímetro, meça seus resistores que normalmente trabalham com porcentagens de até 10% de tolerância e reescreva o valor obtido no programa.


fonte: próprio autor

fonte: próprio autor

É importante ressaltar também que a fórmula citada acima está presente no programa para que o cálculo da leitura seja executada.


fonte: próprio autor

Depois de todos os ajustes e com o programa carregado fica possível obter as leituras de tensão desejadas.

No vídeo abaixo é possível ver o funcionamento do voltímetro.




Todos os arquivos do projeto se encontram nesse LINK, caso seja necessário é só baixar.

Gostou? 
Todos os componentes com ótima qualidade podem ser encontrados AQUI!



sábado, 11 de fevereiro de 2017

Controle de 2 eixos com acelerômetro

Controle de 2 eixos com acelerômetro e Arduino UNO



Nesse tutorial vamos demostrar o controle de dois eixos simulados por servo motores que vão simular o X e Y.
A novidade nessa postagem é que vamos fazer uso de um acelerômetro com giroscópio MPU - 6050, que é facilmente encontrado para compra em sites da internet e casas especializadas em eletrônicos.

MPU - 6050


Essa placa contém um conversor analógico de 16 bits por canal, estabelecendo alta precisão na captura dos eixos X, Y e Z, mesmo quando acionados ao mesmo tempo. As características de um acelerômetro e giroscópio, proporciona ao usuário trabalhar com projetos que incluem 6 eixos de liberdade (3 para acelerômetro e 3 
para giroscópio). Além do mais o sensor MPU - 6050 conta com um sensor de temperatura que variam medições em torno de -40°C até +85°C. 
fonte: https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Datasheet1.pdf 

Pinagem do MPU - 6050

De uma maneira geral, as funções dos pinos do MPU - 6050 pode ser dada conforme abaixo:

  • Vcc: Alimentação (3,3V à 5V);
  • GND: 0V;
  • SCL: I2C Serial Clock (SCL);
  • SDA (Slave_Data): I2C Serial Data (SDA);
  • XDA: I2C Master Serial Data, para conexão de sensor auxiliar;
  • XCL: I2C Master Serial Clock, para conexão de sensor auxiliar;
  • AD0: Define o endereço da I2C;
  • INT: pino para interrupção.

fonte: próprio autor

O pino ADO (endereço) define como endereço 12C do sensor como 0x68, conectando-o à tensão de 3,3v da placa o endereço é alterado para 0x69, permitindo o uso de dois módulos acelerômetro/ giroscópio MPU - 6050 em um mesmo circuito.

Servo motores

Os servos motores já foram abordados anteriormente aqui no site, pra quem ainda tem dúvidas, acesse o link e leia sobre o assunto.

Esquema de ligação

Para o projeto pode-se começar realizando a ligação do circuito conforme o esquema abaixo com os componentes:

Arduino UNO (ou similar)
Acelerômetro/giroscópio GY521 MPU - 6050
Servos motores
Protoboard (matriz de contatos)
Cabos jumpers
Fonte externa 5v 1A
fonte: próprio autor

O código fonte

Copie e cole o código fonte na IDE do seu Arduino para o funcionamento correto do seu projeto.

/* 
 /** Código **/
// Elaborado por Tony Emerson Marim em 10/02/2017.
/** mecatronizando@gmail.com **/
  /*www.mecatronizando.com.br */ 
/** Controle de eixo X e Y com acelerometro/giroscopio**/
/*Baseado no original de www.giuseppecaccavale.it
*/

#include <Wire.h>
#include <Servo.h>

const int MPU=0x68;  // I2C endereço do MPU-6050
int16_t GyX, GyY; //Variavel int a 16bit

Servo ServoMot_X;
Servo ServoMot_Y;

void setup(){
  Wire.begin();
  Wire.beginTransmission(MPU);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);
  
  ServoMot_X.attach(8);
  ServoMot_Y.attach(9);
  Serial.begin(9600);
}
void loop(){
  Wire.beginTransmission(MPU);
  Wire.write(0x3B);                // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU,14,true);  // request a total of 14 registers
  
  GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)

  int PosServo_X = map(GyX, -16000, 16000, 0, 179);
  int PosServo_Y = map(GyY, -16000, 16000, 0, 179);
  ServoMot_X.write(PosServo_X);
  ServoMot_Y.write(PosServo_Y);

  Serial.println("Giroscopio");
  Serial.print("Acelerometro X : "); Serial.println(PosServo_X);
  Serial.print("Acelerometro Y : "); Serial.println(PosServo_Y);
  Serial.println(" ");
  delay(100);
}

No vídeo abaixo é possível ver o funcionamento do circuito.


Caso seja necessário o material do tutorial pode ser baixado por meio desse LINK!
Gostou? Curta nossa FanPage!
Assine o nosso canal!

Não deixe de acompanhar a nova Seção <<<NOTAS DE AULA>>>


Bons Estudos!

quarta-feira, 8 de fevereiro de 2017

Notas de aula

Notas de Aula

Conheça a nova seção do site denominada Notas de Aula.
Nessa seção você encontrará artigos interessantes e material das aulas teóricas e práticas.
A seção de informações é dividida por matérias e temas dirigidos aos aprendizes e especialistas em Mecatrônica nos diversos níveis.
Espero que aproveitem.