Go Down

Topic: Será que aqui alguém me ajuda ?!!! (Read 6170 times) previous topic - next topic

   Bom pessoal , já tentei em 2 foruns e nada de nenhuma resposta , vou tentar aqui , espero que alguém me ajude.

   Bom  com a biblioteca keypad.h usando exemplo para teclado 4x3 , ta tudo funcionando no circuito, só que eu queria desenvolver um programa que abra um menu para salvar uma senha e armazene na EEPROM , depois entrar com a senha para acionar um relé , led e etc , se a mesma estiver correta logico , senão , senha incorreta , e tb que tivesse a possibilidade de excluir a senha atual e incluir uma nova.

  Não estou pedindo que façam pra mim e sim , que me deem uma luz de como fazer , dica , link a respeito , ou até um exemplo ou esboço de programa de voces mesmo , principalmente em relação ao como que digita a senha e a mesma seja armazena diretamente na EEPROM , uma senha de 6 digitos

  Qualquer ajuda é bem vinda , obg.

#1
Jan 08, 2013, 02:35 pm Last Edit: Jan 08, 2013, 02:38 pm by bubulindo Reason: 1
Escrever na EEPROM é fácil, dá uma vista aqui:

http://arduino.cc/en/Reference/EEPROMWrite

Para o resto, se calhar encontrar uma biblioteca para fazeres os menus do LCD seja o mais simples. Senão, fazer uma máquina de estados para o menu será a melhor maneira de conseguir o que pretendes.

Tens exemplos de máquinas de estados no fórum ou então aqui:

http://playground.arduino.cc/code/FiniteStateMachine

Vai fazendo código e metendo aqui as dúvidas e vamos ajudando. :)
Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

  Obg amigo pela resposta , mais a ideia seria um controle de acesso pelo teclado , é questão principal é como fazer uma rotina onde os numeros digitados no teclado 4x3 fiquem armazenados na EEPROM , usando a biblioteca keypad.h , como fazer isso , é o que eu não sei por isso naum da nem pra eu comerçar a fazer o cod porque a questão principal seria isso , e teoricamente é simples , um menu pra digitar e salvar a senha ,
outro pra ativar alguma porta se a senha estiver correta , e outro pra excluir a senha e incluir outra , e a principio seria pela serial mesmo , mostrando no monitor

  Até pq a EEPROM armazena valores até 255 , como fazer uma rotina pra cadastrar uma senha de 6 digitos sendo digitadas pelo teclado 4x3 e salvar esse favor na EEPROM ?? , sabendo dessa rotina o resto eu desenvolvo , que essa seria a rotina principal , se voce ou alguém souber eu agradeço.

HugoPT

Sei que nao te responde a tudo mas
Quote
Até pq a EEPROM armazena valores até 255 ,

Correcto, por esse motivo armazenas cada digito numa posiçao da eeprom.Como perguntas tu?
Bom eu faria um array de char ( unsigned char secureCode[5];// 4 elementos + o caracter terminador '\0)   com o numero de elementos que desejas + um para o caracter terminador.
Depois armazenas cada elemento desse array na eeprom.
Quando o arduino renicia metes uma funçao que te reconstrua a string com o codigo indo ler na eeprom a cada posiçao e carrega-lo para cada elemento do array char.No fim disso colocas o caracter terminador e depois tens a tua string montada pronta para fazer strcmp ou muitas outras funçoes para poderes tomares decisoes no programa.
Debian,Mint,Ubuntu
Arduino Mega 2560
Arduino Nano
Arduino Duemilanove
MAC OS Montain Lion
Raspberry PI Model B

O problema aqui é que não precisas duma rotina... precisas de várias...

Uma para escrever o código na eeprom, outra para ler o código, uma para receber os valores do teclado...
O segredo da programacão é dividir o problema grande em problemas pequenos. Então este é o meu conselho. Faz estas funcões primeiro e testa individualmente.
A mäquina de estados serve para ligar todas estas funcões dependendo do estado em que o sistema se encontra.

Funcão para escrever:
Code: [Select]

#include <avr/eeprom.h>

void escreveCodigo(char * code, unsigned char length) {

for (i = 0; i <= length; i++) {
   eeprom_write_byte(i, code[i]]);
}
}


Funcão para ler
Code: [Select]


void leCodigo(char * code, unsigned char length) {

for (i = 0; i <= length; i++) {
    *(code + i) = eeprom_read_byte(i);
}
}


Para testar isto, escreves um sketch com a primeira funcão e gravas algo na EEPROM. Depois escreves um sketch com a segunda funcão (e sem a primeira) e corres de novo. O que vais ler da eeprom deve ser igual ao que escreveste.
Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

   Obrigado pelas respostas , fiz esse cod tirando uns exemplos de outros e acrescentando algo mais  no meu.
   A questão que neste tem uma senha já definida e na verdade eu gostaria de criar uma senha e que a mesma seja armazenada na flash mesmo pra não complicar mais ainda, do que na EEPROM , assim toda vez que resetasse possibilitaria o cadastro de outra senha , já que a mesma não está salva na EEPROM, uma nova senha , seria a mesma logica do programa abaixo , só que com as questões a cima citadas.

Code: [Select]

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

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {8, 7, 6}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
LiquidCrystal lcd(53, 51, 49, 47, 45, 43);
int contador = 0;
int fechadura = 30;
char senha [] = {'2','5','4','3','\0'};
char teste[] = {'0','0','0','0','\0'};

void setup()
{
  lcd.begin(16, 2);
  pinMode(fechadura,OUTPUT);
  digitalWrite(fechadura,LOW); 
  lcd.print("Digite a Senha");
}
void loop()
{
  char key = keypad.getKey();
   if(key == '*')
   {
    limpaLinha(1);
    contador=0;
    }
  else if(key)
  {
    lcd.setCursor(0,0);
    lcd.print("Digite a Senha");
    lcd.setCursor(contador,1);
    lcd.print('*');
    delay(500);
    teste[contador] = key;
    contador++;
  }
   
    if (contador == 4)
    {
      teste[contador] = '\0';
      if ((teste[1]== senha[1]) && (teste[2]== senha[2]) && (teste[3]== senha[3])&& (teste[4]== senha[4]))
        {
        lcd.clear();
        lcd.print("Senha correta");
        delay(2000);
        contador = 0;
        lcd.clear();
        lcd.print("Digite a Senha: ");
        digitalWrite(fechadura, HIGH);
        delay(2000);
        digitalWrite(fechadura, LOW);
      }       
       else
      {
        lcd.clear();
        lcd.print("Senha incorreta");
        delay(2000);
        contador = 0;
        lcd.clear();
        lcd.print("Digite a Senha: ");
        digitalWrite(fechadura, LOW);
      }
   }
 

void limpaLinha(byte linha)
{
  lcd.setCursor(0, linha);
  lcd.print("                ");
}



Agradeço desde já a qualquer amigo que possa me ajudar , valeu.

Importas-te de explicar o que pretendes de novo?

A senha para ficar armazenada na flash tem de ser definida no programa e não pode ser gravada quando o programa está em execução.

Para criar uma nova senha, tens de criar uma combinação de teclas ou condição para que o programa entre nesse modo e o utilizador possa meter a senha e gravá-la.

Em todo o caso, isso deverá ter de ser feito após colocar a senha correctamente.

Mais uma vez, se pensares no programa como uma máquina de estados isso será muito mais simples de fazer.
Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

   Ok, Amigo , é que no 8051 tenho um programa que consigo armazenar na flash e toda vez que resetava ou desligava , era possível cadastrava uma nova senha e quando tentava entrar no menu por ex: fazia a mesma rotina do programa que citei , só que a unica diferença é que eu não definia a senha antes , pensava que fosse possível para os micros do arduino, mas não vou aprofundar nessa questão.

  Eu até entendo a maquina de estado , em relação a logica , só que não vai adiantar nada pra mim se eu primeiro não resolve essa questão principal ,  saber como fazer a rotina , para cadastrar uma senha e senão é possível que fique na flash sem ser definida que seja na EEPROM mesmo , de preferencia com mais de 6 digitos , é só isso mesmo , não faço ideia de como fazer isso.

  1. Cadastrar uma senha e armazena-la na EEPROM , preferencia 6 digitos , digitando com um teclado matricial usando a biblioteca keypad.
 
  2. Como seria a rotina para comparar a senha digitada quando fosse acessar o "menu" , com a senha armazenada na EEPROM , acredito que sabendo a questão 1 , a questão 2 ficaria mais "fácil" , falo isso porque nunca fiz uma rotina fazendo uma comparação com alguma variável armazenada na EEPROM , por isso possa ser que tenha um pouco de dificuldade.

3.Sabendo a questão 1 principalmente, depois  faria rotinas para apagar a senha armazenada e incluir outra quando necessário , e etc.

  Quem souber a questão 1 ou algum link ou exemplo de como faze-la usando a biblioteca keypad.h resolveria o meu problema , pois trata-se de um controle de acesso e essa questão da senha é a principal.

   Obrigado  pela atenção , e aguardo alguma luz ai de algum amigo , espero que tenham entendido , o que realmente quero.

Então vamos por partes...

Já tens um pedaço de código em que alguém digita a senha para entrar na porta, certo? Então, podes usar esse mesmo pedaço de código para a pessoa digitar o código a ser guardado.

1. Depois de teres esse código, guardas os caracteres com a função que escrevi em cima para a EEPROM.

2. O código que postaste já faz isso... já compara uma senha digitada com uma senha guardada. Não comparas nada que esteja na EEPROM... aliás, pensa na EEPROM como um back-up. O programa inicia, vai buscar o código para RAM e depois não usa mais a EEPROM até ser resetado ou programado de novo.

Olha aqui... metes isto antes da setup (o include vai para o inicio do ficheiro).

Code: [Select]
#include <avr/eeprom.h>

void leCodigo(char * code, unsigned char length) {

for (i = 0; i <= length; i++) {
    *(code + i) = eeprom_read_byte(i);
}
}

void escreveCodigo(char * code, unsigned char length) {

for (i = 0; i <= length; i++) {
   eeprom_write_byte(i, code[i]]);
}
}


Depois alteras a função setup para fazer isto.

Code: [Select]


void setup()
{
  //Isto assume que a senha já foi previamente guardada na EEPROM da posição 0 a 4.
  leCodigo(senha, 5); 


  lcd.begin(16, 2);
  pinMode(fechadura,OUTPUT);
  digitalWrite(fechadura,LOW); 
  lcd.print("Digite a Senha");
}



Então, para testares isto, primeiro tens de gravar a EEPROM com algo.

Faz um sketch com isto:

Code: [Select]

#include <avr/eeprom.h>
#include <string.h>

void leCodigo(char * code, unsigned char length) {

for (i = 0; i <= length; i++) {
    *(code + i) = eeprom_read_byte(i);
}
}

void escreveCodigo(char * code, unsigned char length) {

for (i = 0; i <= length; i++) {
   eeprom_write_byte(i, code[i]]);
}
}

char senha [] = {'2','5','4','3','\0'};
char teste [6];
void setup(){
   Serial.begin(19200);
   escreveCodigo(senha,5);
   leCodigo(teste, 5);

   if (strcmp(teste, senha) == 0) {
      Serial.println("SEnha gravada com sucesso");
   } else {
      Serial.println ("erro...");
   }

}

void loop(){}



Isto vai gravar o código na EEPROM. Depois gravas o outro programa que vai ler o código (podes ver como o fazer neste último programa também) para a RAM e prossegue.

Mais uma vez, a máquina de estados serve para tu dividires se a pessoa vai colocar o código para abrir a porta ou para fazer setup da senha.
Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

   Ok Amigo , obg pela atenção , consegui fazer tudo o que eu queria com essas rotinas que você me passou , vejo que você ajuda muitos companheiros aqui no forum , com o seu conhecimento , quando surgir alguma outra dúvida que com certeza irá aparecer já sei onde procurar a resposta , hehehe , valeu Bubulindo.


quando surgir alguma outra dúvida que com certeza irá aparecer já sei onde procurar a resposta , hehehe , valeu Bubulindo.


No fórum...
Mensagem pessoal não resulta. :P
Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

HugoPT

Ola Bubulindo ja agora uma questao.Hoje tentei usar a eeprom com a lib do avr nativa e deparei me com o seguinte
A funçao   eeprom_write_byte ( uint8_t *  __p,uint8_t  __value) recebe estes dois parametros, até aqui tudo bem tenho de lhe passar o endereço que quero gravar e o valor a escrever nessse endereço, a minha questao e que apenas a consegui usar fazendo um cast para me aceitar o valor e nao dar erro no compilador.
Para ser mais preciso:
Code: [Select]
void writeCodeToMemory(char *code ,int length)
{
 for(uint8_t i=0; i<=length ; i++)
 {
 eeprom_write_byte((uint8_t *)i,*code++);
 }
}


O codigo esta a funcionar mas com o cast, sem o cast com eu estava à espera nao da usando eeprom_write_byte(i,*code++);
Fiz o cast porque o erro que ele dá é o seguinte:

Code: [Select]
invalid conversion from 'uint8_t' to 'uint8_t*'
Porque é que a funçao espera um ponteiro do valor?
Apesar de estar a dar tanto a ler como a escrever gostava de perceber melhor o que esta aqui a acontecer
Debian,Mint,Ubuntu
Arduino Mega 2560
Arduino Nano
Arduino Duemilanove
MAC OS Montain Lion
Raspberry PI Model B

#12
Jan 25, 2013, 10:45 am Last Edit: Jan 25, 2013, 10:54 am by bubulindo Reason: 1
Já verificaste a EEPROM a ver se realmente ela está a escrever no sítio correcto e a escrever o que pretendes correctamente?

Eu fiz este sketch de teste:

Code: [Select]

#include <avr/eeprom.h>

void writeCodeToMemory(char *code ,int length)
{
 for(uint8_t i=0; i<=length ; i++)
 {
 eeprom_write_byte(&i,*code++);//(uint8_t *)
 }
}

void setup(){

char nome[] = "myName";

writeCodeToMemory(nome, 6);
}
void loop(){}


O erro estava a dizer-te que o código queria um apontador e não um valor. Isso resolve-se colocando o & (sinal de endereço) na chamada da função.
Sinceramente, não te consigo dizer porque é que definiram estas funções com ponteiros para memória... uma possível explicação pode ser por causa disto:

Quote
For Xmega the EEPROM start address is 0, like other architectures. The reading functions add the 0x2000 value to use EEPROM mapping into data space.


Mas mesmo assim não me convence. Algo que nunca tinha reparado são as funções de update e o facto destas funções da EEPROM serem busy-wait. Isto é um bom começo para o colega Boeira iniciar a sua colecção de bibliotecas. eh eh eh

Outra coisa que me confundiu (e eu não sou de todo um mestre de apontadores) foi isto:

Code: [Select]
*code++

Isto incrementa o valor apontado por *code, certo?
Não quererias antes algo deste género:

Code: [Select]

*(code++)

?

Eu nestes casos normalmente sou mais picuinhas e opto por fazer algo assim:

Code: [Select]

void writeCodeToMemory(char *code ,int length)
{
 for(uint8_t i=0; i<=length ; i++)
 {
 eeprom_write_byte((uint8_t *)i,*(code+i));
 }
}

Como disse, não sou propriamente um mestre de apontadores, mas isto funciona.

Ahh, também podes fazer assim:

Code: [Select]

void writeCodeToMemory(char *code ,int length)
{
  for(uint8_t i=0; i<=length ; i++)
  {
  eeprom_write_byte(&i,code[i]);//(uint8_t *)
  }
}
Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

HugoPT

Obrigado , so agora é que tive tempo para poder responder.
Quote
Já verificaste a EEPROM a ver se realmente ela está a escrever no sítio correcto e a escrever o que pretendes correctamente?

Sim esta.
Quote
Outra coisa que me confundiu (e eu não sou de todo um mestre de apontadores) foi isto:
*code++
Isto incrementa o valor apontado por *code, certo?
Não quererias antes algo deste género:
Code:
*(code++)

?

Aqui esta uma questao pertinente:) Atrevo me a dizer que *code++ e *(code++) sao a mesma coisa em C.Podes la colocar o parenthesis mas o compilador nao necessita dele pois quando ele passar por a variavel vai ter o mesmo comportamento
Vejamos o que acontece nestas atribuições:
Quando temos o ++ depois da variavel primeiro o valor é usado e so depois incrementado sempre!
Ou seja no meu *code++ primeiro e avaliado o conteudo do apontado por code usado e depois incrementado, que é o que eu quero.
Aqui esta a prova disto:
x=5;
y= x++;
No final desta atribuiçao os valores sao: x=6 e y =5 (primeiro avalia e so depois incrementa)
Se fosse:
x=5
y=++x;
No final desta os valores seriam x = 6 e y = 6

É desnecessario usar *(code++) porque resulta no mesmo pela natureza do ++ estar à frente da variavel code.










Debian,Mint,Ubuntu
Arduino Mega 2560
Arduino Nano
Arduino Duemilanove
MAC OS Montain Lion
Raspberry PI Model B

Mas a minha questão era, com os parêntesis tu incrementas o endereço, sem parêntesis tu incrementas o apontado por esse endereço.

Neste caso, se code for um vector que queres gravar, quererias gravar o próximo valor do array ( incrementando o endereço) e não o valor inicial incrementado, certo?
Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

Go Up