Validar números de CPF utilizando um Arduino UNO.
O algoritmo de validação de números de CPF é interessante para trabalharmos o aprendizado em lógica de programação.
Vamos trabalhar essa lógica no Arduino UNO, montando um validador com display LCD e um teclado numérico.
O CPF é composto por 9 números e mais 2 dígitos verificadores que são indicados após uma barra. Totalizando 11 números.
A partir dos 9 primeiros números calculamos quais serão os 2 dígitos verificadores e, dessa forma, podemos identificar se é um valor de CPF válido ou não.
Vamos tratar cada dígito da seguinte forma: ABCDEFGHI-JK. Onde após a barra estão J e K, representando os dígitos verificadores.
Para calcularmos o primeiro dígito verificador (J), devemos multiplicar cada número pelo valor respectivo na tabela abaixo e somar os resultados.
A |
B |
C |
D |
E |
F |
G |
H |
I |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
(A x 10) + (B x 9) + (C x 8) + (D x 7) + (E x 6) + (F x 5) + (G x 4) + (H x 3) + (I x 2)
Como exemplo, vamos utilizar os números 5 1 8 1 3 3 7 2 5 - J K
(5x10) + (1x9) + (8x8) + (1x7) + (3x6) + (3x5) + (7x4) + (2x3) + (5x2) = 207
O resultado obtido deverá ser dividido por 11, considerando apenas o valor inteiro do resto da divisão.
207 divido por 11 temos como quociente o valor 18 e como resto o valor 9.
O valor do primeiro dígito (J) é: caso o valor do resto da divisão seja 0 ou 1, devemos considerar o valor 0. Caso contrario, subtrai-se o valor obtido de 11. No nosso exemplo, será 11 - 9 = 2.
O nosso exemplo agora é 5 1 8 1 3 3 7 2 5 - 2 K
Para calcularmos o segundo dígito verificador (K), devemos multiplicar cada número pelo valor respectivo na tabela abaixo e somar os resultados. Como fizemos para o primeiro dígito, porém agora temos um número a mais incluído na tabela, o primeiro dígito verificador (J).
A |
B |
C |
D |
E |
F |
G |
H |
I |
J |
11 |
10 |
9 |
8 |
7 |
6 |
5 |
4 |
3 |
2 |
(5x11) + (1x10) + (8x9) + (1x8) + (3x7) + (3x6) + (7x5) + (2x4) + (5x3) + (2x2) = 246
Devemos seguir as mesmas regras do primeiro dígito.
246 divido por 11 temos como quociente o valor 22 e como resto o valor 4.
O valor do segundo dígito (K) é: caso o valor do resto da
divisão seja 0 ou 1, devemos considerar o valor 0. Caso contrario,
subtrai-se o valor obtido de 11. No nosso exemplo, será 11 - 4 = 7.
Agora temos os dois dígitos verificadores do nosso exemplo: 5 1 8 1 3 3 7 2 5 - 2 7
Outra regra da validação do CPF: os números não podem ser todos iguais.
No projeto foi utilizado um Arduino UNO, um display LCD com módulo I2C e um teclado matricial.
Segue o esquema elétrico e o código fonte:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | /*--------------------------------------------------------- Programa : VALIDADOR DE CPF Autor : Fellipe Couto [ http://www.efeitonerd.com.br ] Data : 01/03/2021 ---------------------------------------------------------*/ #include <LiquidCrystal_I2C.h> //LCD I2C [ https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library ] LiquidCrystal_I2C lcd(0x3F, 16, 2); //LCD 16x2 no endereço 0x3F String cpf = ""; //Variável para receber o CPF digitado /*--- SETUP ---*/ void setup() { //Inicializa o lcd lcd.begin(); lcdBegin(); } /*--- LOOP PRINCIPAL ---*/ void loop() { String k = keypad(); //Retorna o valor da tecla pressionada na variável k if (k != "" && k != "*" && k != "#") { lcd.print(k); cpf += k; if (cpf.length() == 11) { delay(500); lcd.setCursor(0, 1); if (checkCPF(cpf)) { lcd.print(">>>> VALIDO!"); } else { lcd.print(">>>> INVALIDO"); } delay(3000); cpf = ""; lcdBegin(); } } } /*--- MENSAGEM PRINCIPAL NO LCD ---*/ void lcdBegin(){ lcd.clear(); lcd.setCursor(0, 0); lcd.print("CPF: "); } /*--- VALIDA O CPF ---*/ bool checkCPF(String cpf) { if (cpf.length() != 11) return false; int n1 = 0; int n2 = 0; bool equalNum = true; for (int i = 1; i <= 9; i++) { n1 += cpf.substring(i - 1, i).toInt() * (11 - i) ; n2 += cpf.substring(i - 1, i).toInt() * (12 - i) ; if (cpf.substring(i - 1, i).toInt() != cpf.substring(i, i + 1).toInt()) equalNum = false; } if (equalNum) return false; n1 = 11 - (n1 % 11); if (n1 > 9) n1 = 0; n2 += n1 * 2; n2 = 11 - (n2 % 11); if (n2 > 9) n2 = 0; if (cpf != cpf.substring(0, 9) + String(n1) + String(n2)) return false; return true; } /*--- RETORNA A TECLA PRESSIONADA NO TECLADO ---*/ String keypad() { const int totalLines = 4; //Total de linhas do teclado const int totalColumns = 3; //Total de colunas do teclado const int lines[totalLines] = {2, 3, 4, 5}; //Portas de conexão das linhas const int columns[totalColumns] = {6, 7, 8}; //Portas de conexão das colunas const String keyBoard[totalLines][totalColumns] = { //Disposição das teclas {"1", "2", "3"}, {"4", "5", "6"}, {"7", "8", "9"}, {"*", "0", "#"} }; const String keyPressed = ""; for (int i = 0; i < totalLines; i++) { //Configura os pinos das linhas como saída pinMode(lines[i], OUTPUT); } for (int i = 0; i < totalColumns; i++) { //Configura os pinos das colunas como entrada com pull-up pinMode(columns[i], INPUT_PULLUP); } for (int w = 0; w < totalLines; w++) { //Varre as linhas for (int i = 0; i < totalLines; i++) { digitalWrite(lines[i], HIGH); } digitalWrite(lines[w], LOW); //Uma linha LOW por vez for (int c = 0; c < totalColumns; c++) { //Varre as colunas while (digitalRead(columns[c]) == LOW) { keyPressed = keyBoard[w][c]; } } } delay(50); return keyPressed; } |
Muito bom!
ResponderExcluir