Neste projeto, iremos construir um despertador utilizando um display LCD, um buzzer e um Arduino para fazer o controle do sistema.
Circuito
O objetivo é usar um buzzer ou um alto falante pra fazer a parte sonora do despertador e um display LCD 16×2 pra fazer a parte visual (configurações). Eu vou usar um shield (imagem abaixo) que possui o display e alguns botões já inclusos. Mas, caso você não possua o mesmo modelo, vou listar como fazer cada ligação separadamente.
Recomendo bastante que leia sobre o buzzer e sobre o LCD 16×2 para entender o projeto por completo.
Buzzer
Basicamente é só ligar o positivo do alto falante/buzzer em série com um resistor (pode ser 100Ω) em um pino digital do Arduino (vou ligar no 13). E o negativo vai no GND. A imagem abaixo ilustra a ligação.
Display
O display você pode ligar em qualquer pino digital, basta configurar depois na programação. A imagem abaixo mostra a ligação padrão.
Botões
Você pode ligar os botões em pinos digitais separados. A ligação adiante é só para reproduzir o comportamento do shield.
Pra reproduzir os botões que tem no shield (cima, baixo, direita, esquerda, select), basta usar 5 botões. Eles devem ser ligados, de um lado, no 5V e, do outro lado, em um pino analógico do Arduino em série com um resistor. Além disto, é preciso ligar um resistor do pino analógico para o GND. Veja a imagem abaixo para entender.
Você pode ligar todos os botões na mesma porta analógica, basta variar o valor do resistor de cada botão. Isso porque, cada botão produzirá uma tensão diferente na entrada analógica.
Assim, poderemos ler esses valores dentro do programa. Recomendo usar valores de 1kΩ, 4k7Ω, 10kΩ, 15kΩ, 22kΩ… Sempre valores que não sejam muito próximos. Com isto, você vai ter que descobrir a faixa de leitura de cada botão pra usar na programação.
Programação
Como a interface funciona
Na versão 1.0, fiz uma interface que você pode selecionar 3 opções:
- Mostrar as horas
- Direciona pra tela que mostra as horas
- Definir o alarme
- Direciona pra tela de configurar o alarme
- Definir horas
- Direciona pra tela de configurar as horas
Pra navegar pelo menu é só usar dois botões (cima e baixo) e, para acessar cada tela, basta apertar o botão select.
Na tela de configuração do alarme e das horas, os botões cima e baixo alteram os valores, os botões esquerda e direita mudam a posição do cursor e o botão select aplica as mudanças. Na tela da configuração do alarme também é possível desativar e ativar o alarme.
Já na tela de horas, o botão select volta pro menu principal.
Quando o alarme toca, o buzzer/alto falante começa a tocar e você tem que apertar select pra sair da tela. Enquanto você não apertar, o alarme não irá parar. E o alarme é constante, isto é, ele toca diariamente a partir do momento que você ligar ele na tela de alarme. Assim que você desliga o alarme (depois dele tocar), ele fica desativado até que o horário chegue no minuto seguinte e ele se ativa novamente.
Configurações
Pra usar o código, talvez seja preciso configurar algumas coisas:
- Pino do buzzer/alto falante
- Basta ir na linha 19 (#define BUZZER 13) e mudar o valor do pino.
- Música do alarme
- Na variável MUSICA, dá pra você criar sua própria música pra tocar no alarme. Veja o post sobre como tocar música com o Arduino pra entender como fazer a alteração.
- Valores analógicos dos botões
- Se você não está usando o shield que mostrei anteriormente, precisará alterar a faixa de leitura dos botões. No início do código (linhas 22-26) estão as definições das faixas de leituras dos botões, então basta alterá-las.
- Exemplo, se sua faixa do botão select foi de 50~100, é só alterar: “analogRead(A0) <= 66 && analogRead(A0) >= 66” para: “analogRead(A0) <= 100 && analogRead(A0) >= 50 “. Faça isso para todos os botões.
- Recomendo a leitura do post sobre leitura analógica com Arduino para saber como fazer a leitura da faixa de valores (leitura analógica simples).
- LCD
- O shield que utilizei usa pinos diferentes da ligação que mostrei no tópico do circuito. Se não for o seu caso mude a linha 14 no código:
- No meu caso é: LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
- Na ligação padrão fica: LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
Biblioteca
Código completo
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 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 | // PROJETO CRIADO PELO SITE MUNDO PROJETADO // Acesse: www.mundoprojetado.com.br // Versão 3.1 de um despertador criado usando um shield LCD16x2 e um buzzer // Atualizações: // Versão 3.1: verificação de mes e ano bissexto na configuração do dia da data // fornecido pelo leitor: Harrison Lucas Paula Lacerda // Versão 3.0: adição da configuração da data e pequenos ajustes no código // Versão 2.0: adição da data na tela de horas e reescrita do código de uma melhor forma // Versão 1.0: só pode configurar um despertador que fica constante a partir do momento que é ligado // ---------------------------------------------------------------------------------------------------- // ----- Bibliotecas ----- #include <TimeLib.h> #include <LiquidCrystal.h> LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // ----- Definições ----- // Pino do Buzzer #define BUZZER 13 // Condições dos botões apertados #define BOTAO_CIMA analogRead(A0) <= 43 && analogRead(A0) >= 42 #define BOTAO_BAIXO analogRead(A0) <= 57 && analogRead(A0) >= 58 #define BOTAO_SELECT analogRead(A0) <= 66 && analogRead(A0) >= 66 #define BOTAO_DIR analogRead(A0) <= 20 #define BOTAO_ESQ analogRead(A0) <= 63 && analogRead(A0) >= 62 // Delay (em milisegundos) após pressionar botões #define DELAY_BOT_SLOW 300 #define DELAY_BOT_FAST 100 // ----- Variaveis globais ----- // Simbolo da seta na configuraçao byte SIMBOLO_SETA[8] = { B00100, B00100, B01110, B10101, B00100, B00100, B00100, B00100, }; // Simbolo do relogio byte SIMBOLO_RELOGIO[8] = { B00000, B10001, B01110, B10101, B10111, B10001, B01110, B00000, }; // Musica do despertador const char* MUSICA[] = {"Re", "Mi", "Fa", "Sol", "Do", "La", "Fa", "Do", "Fim"}; const int DURACAO[] = {500, 500, 500, 500, 500, 500, 500, 500}; // Frases do menu const String titulo_menu[4] = {"Mostrar horas", "Definir alarme", "Mudar as horas", "Mudar data"}; // Estados do programa em relação aos menus enum { MENU_MAIN = 0, MENU_HORAS, MENU_ALARME, MENU_CONFIG_HORAS, MENU_CONFIG_DATA }menu_atual; // Variaveis auxiliares dos menus uint8_t d1, d2, pos = 0; uint16_t d3; // É de 16 bits, pois pode armazenar o ano da data // Variaveis para controle do alarme bool parou_alarme = false, alarme_ativado = true; // Horas e minutos do alarme unsigned char alarme[2] = {12, 01}; // ----- Prototipo das funções ----- void verificar_alarme(void); void tocar(char* mus[], int tempo[]); String get_hour(void); String get_date(void) ; void setup() { // Inicia o LCD e cria os símbolos lcd.begin(16, 2); lcd.createChar(1, SIMBOLO_SETA); lcd.createChar(2, SIMBOLO_RELOGIO); // Define hora/min/segundo - dia/mes/ano setTime(12, 00, 0, 23, 1, 2021); // Configura o pino do buzzer pinMode(BUZZER, OUTPUT); } void loop() { // Verifica em qual menu está switch (menu_atual) { // Menu principal case MENU_MAIN: // Escreve os títulos lcd.setCursor(0, 0); lcd.print(titulo_menu[pos]); lcd.setCursor(0, 1); if (pos < 3) { lcd.print(titulo_menu[pos + 1]); } // Simbolo do relogio caso o despertador esteja ativo if (!parou_alarme && alarme_ativado) { lcd.setCursor(15, 0); lcd.write(2); } // ----- Testa os botoes ----- if (BOTAO_CIMA && pos > 0) { pos--; lcd.clear(); delay(DELAY_BOT_SLOW); } else if (BOTAO_BAIXO && pos < 3) { pos++; lcd.clear(); delay(DELAY_BOT_SLOW); } else if (BOTAO_SELECT) { // Verifica em qual menu deve entrar switch (pos) { case 0: menu_atual = MENU_HORAS; break; case 1: menu_atual = MENU_ALARME; pos = 0; d1 = alarme[0]; d2 = alarme[1]; d3 = alarme_ativado; break; case 2: menu_atual = MENU_CONFIG_HORAS; pos = 0; d1 = hour(); d2 = minute(); break; case 3: menu_atual = MENU_CONFIG_DATA; pos = 0; d1 = day(); d2 = month(); d3 = year(); } lcd.clear(); delay(DELAY_BOT_SLOW); } break; // ----- MENU_MAIN ----- case MENU_HORAS: lcd.setCursor(3, 0); lcd.print(get_hour()); lcd.setCursor(3, 1); lcd.print(get_date()); // Simbolo do relogio caso o despertador esteja ativo if (!parou_alarme && alarme_ativado) { lcd.setCursor(15, 0); lcd.write(2); } if (BOTAO_SELECT) { menu_atual = MENU_MAIN; lcd.clear(); delay(DELAY_BOT_SLOW); } break; // ----- MENU_HORAS ----- case MENU_ALARME: // Escreve as horas do alarme lcd.setCursor(0, 0); if (d1 < 10) { lcd.print("0"); } lcd.print(d1); lcd.print(":"); if (d2 < 10) { lcd.print("0"); } lcd.print(d2); // Informa se está ativo ou não lcd.setCursor(7, 0); if (d3) { lcd.print("Ativado"); } else { lcd.setCursor(6, 0); lcd.print("Desativado"); } // Desenha a seta switch (pos) { case 0: lcd.setCursor(1, 1); break; case 1: lcd.setCursor(3, 1); break; case 2: lcd.setCursor(10, 1); break; } lcd.write(1); // ----- Testa os botoes ----- if (BOTAO_CIMA) { if (pos == 0 && d1 < 23) { d1 ++; } else if (pos == 1 && d2 < 59) { d2 ++; } else if (pos == 2 && d3 < 1) { d3 ++; lcd.setCursor(6, 0); lcd.print(" "); lcd.setCursor(14, 0); lcd.print(" "); } delay(DELAY_BOT_FAST); } else if (BOTAO_BAIXO) { if (pos == 0 && d1 > 0) { d1 --; } else if (pos == 1 && d2 > 0) { d2 --; } else if (pos == 2 && d3 > 0) { d3 --; } delay(DELAY_BOT_FAST); } else if (BOTAO_DIR && pos < 2) { pos++; lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(3, 1); lcd.print(" "); lcd.setCursor(10, 1); lcd.print(" "); delay(DELAY_BOT_SLOW); } else if (BOTAO_ESQ && pos > 0) { pos--; lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(3, 1); lcd.print(" "); lcd.setCursor(10, 1); lcd.print(" "); delay(DELAY_BOT_SLOW); } else if (BOTAO_SELECT) { alarme[0] = d1; alarme[1] = d2; alarme_ativado = d3; menu_atual = MENU_MAIN; pos = 0; lcd.clear(); delay(DELAY_BOT_SLOW); } break; // ----- MENU_ALARME ----- case MENU_CONFIG_HORAS: // Escreve as horas lcd.setCursor(5, 0); if (d1 < 10) { lcd.print("0"); } lcd.print(d1); lcd.print(":"); if (d2 < 10) { lcd.print("0"); } lcd.print(d2); // Desenha a seta lcd.setCursor(6 + pos*2, 1); lcd.write(1); // ----- Testa os botoes ----- if (BOTAO_CIMA) { if (pos == 0 && d1 < 23) { d1 ++; } else if (pos == 1 && d2 < 59) { d2 ++; } delay(DELAY_BOT_FAST); } else if (BOTAO_BAIXO) { if (pos == 0 && d1 > 0) { d1 --; } else if (pos == 1 && d2 > 0) { d2 --; } delay(DELAY_BOT_FAST); } else if (BOTAO_DIR && pos < 1) { pos++; lcd.setCursor(6, 1); lcd.print(" "); delay(DELAY_BOT_SLOW); } else if (BOTAO_ESQ && pos > 0) { pos--; lcd.setCursor(8, 1); lcd.print(" "); delay(DELAY_BOT_SLOW); } else if (BOTAO_SELECT) { setTime(d1, d2, 0, day(), month(), year()); menu_atual = MENU_MAIN; pos = 0; lcd.clear(); delay(DELAY_BOT_SLOW); } break; // ----- MENU_CONFIG_HORAS ----- case MENU_CONFIG_DATA: // Escreve a data lcd.setCursor(3, 0); if (d1 < 10) { lcd.print("0"); } lcd.print(d1); lcd.print("/"); if (d2 < 10) { lcd.print("0"); } lcd.print(d2); lcd.print("/"); lcd.print(d3); // Desenha a seta lcd.setCursor(4 + pos*3, 1); lcd.write(1); // ----- Testa os botoes ----- if (BOTAO_CIMA) { uint8_t aux; // Restringe o valor do dia de acordo com o mês e ano (se for bissexto) if(d2 == 1 || d2 == 3 || d2 == 5 || d2 == 7 || d2 == 8 || d2 == 10 || d2 == 12) { aux = 31; } else if(d2 == 2) { if(d3%4 == 0) { aux = 29; } else { aux = 28; } } else // Condições faltantes: mes 4, 6, 9 ou 11 { aux = 30; } if (pos == 0 && d1 < aux) { d1++; } else if (pos == 1 && d2 < 12) { d2++; } else if(pos == 2 && d3 < 9999) { d3++; } delay(DELAY_BOT_FAST); } else if (BOTAO_BAIXO) { if (pos == 0 && d1 > 1) { d1--; } else if (pos == 1 && d2 > 1) { d2--; } else if(pos == 2 && d3 > 0) { d3--; } delay(DELAY_BOT_FAST); } else if (BOTAO_DIR && pos < 2) { pos++; lcd.setCursor(4, 1); lcd.print(" "); delay(DELAY_BOT_SLOW); } else if (BOTAO_ESQ && pos > 0) { pos--; lcd.setCursor(4, 1); lcd.print(" "); delay(DELAY_BOT_SLOW); } else if (BOTAO_SELECT) { setTime(hour(), minute(), second(), d1, d2, d3); menu_atual = MENU_MAIN; pos = 0; lcd.clear(); delay(DELAY_BOT_SLOW); } break; // ----- MENU_CONFIG_HORAS ----- } // Verifica se esta na hora de despertar verificar_alarme(); } /* * Verifica se está na hora do alarme tocar */ void verificar_alarme(void) { if (hour() == alarme[0] && minute() == alarme[1] && !parou_alarme && alarme_ativado) { lcd.clear(); lcd.setCursor(1, 0); lcd.print("Segure select"); lcd.setCursor(3, 1); lcd.print("para parar"); while (!parou_alarme) { tocar(MUSICA, DURACAO); if (BOTAO_SELECT) { parou_alarme = true; } delay(200); } lcd.clear(); } // So reinicia a variável quando os segundos forem menor que 2 (próximo minuto) if (parou_alarme && second() <= 2) { parou_alarme = false; } } /* * Toca uma musica de acordo com o parâmetro */ void tocar(char* mus[], int tempo[]) { int tom = 0; for (int i = 0; mus[i] != "Fim"; i++) { if (mus[i] == "Do") tom = 262; if (mus[i] == "Re") tom = 294; if (mus[i] == "Mi") tom = 330; if (mus[i] == "Fa") tom = 349; if (mus[i] == "Sol") tom = 392; if (mus[i] == "La") tom = 440; if (mus[i] == "Si") tom = 494; if (mus[i] == "Do#") tom = 528; if (mus[i] == "Re#") tom = 622; if (mus[i] == "Fa#") tom = 370; if (mus[i] == "Sol#") tom = 415; if (mus[i] == "La#") tom = 466; if (mus[i] == "Pausa") tom = 0; tone(BUZZER, tom, tempo[i]); delay(tempo[i]); // CONDIÇAO DO DESPERTADOR - Não tem relação com essa função if (BOTAO_SELECT) { parou_alarme = true; break; } } } /* * Retorna uma string com o horário atual no formato: * HH:MM:SS */ String get_hour(void) { String horario = ""; unsigned char i, aux; for (i=0; i < 3; i++) { if(i == 0) { aux = hour(); } else if(i == 1) { aux = minute(); } else if(i == 2) { aux = second(); } if(aux < 10) { horario += "0"; } horario += aux; if(i != 2) { horario += ":"; } } return horario; } /* * Retorna uma string com a data no formato: * DD/MM/AAAA */ String get_date(void) { String data = ""; unsigned int i, aux; for (i=0; i < 3; i++) { if(i == 0) { aux = day(); } else if(i == 1) { aux = month(); } else if(i == 2) { aux = year(); } if(aux < 10) { data += "0"; } data += aux; if(i != 2) { data += "/"; } } return data; } |
Código com vários alarmes
Resolvi fazer um código à parte que é igual ao de cima com adição de diversos alarmes configuráveis via código (só um continua sendo configurado pelo display). Para alterar ou adicionar um novo alarme, altere a variável alarmes seguindo as orientações dos comentários no código (linha 86). Remova ou adicione os alarmes conforme sua necessidade.
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 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 | // PROJETO CRIADO PELO SITE MUNDO PROJETADO // Acesse: www.mundoprojetado.com.br // Versão 3.2 de um despertador criado usando um shield LCD16x2 e um buzzer // Atualizações: // Versão 3.2: verificação de mes e ano bissexto na configuração do dia da data // fornecido pelo leitor: Harrison Lucas Paula Lacerda // Versão 3.1: adição de vários alarmes configuráveis via código // Versão 3.0: adição da configuração da data e pequenos ajustes no código // Versão 2.0: adição da data na tela de horas e reescrita do código de uma melhor forma // Versão 1.0: só pode configurar um despertador que fica constante a partir do momento que é ligado // ---------------------------------------------------------------------------------------------------- // ----- Bibliotecas ----- #include <TimeLib.h> #include <LiquidCrystal.h> LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // ----- Definições ----- // Pino do Buzzer #define BUZZER 13 // Condições dos botões apertados #define BOTAO_CIMA analogRead(A0) <= 43 && analogRead(A0) >= 42 #define BOTAO_BAIXO analogRead(A0) <= 57 && analogRead(A0) >= 58 #define BOTAO_SELECT analogRead(A0) <= 66 && analogRead(A0) >= 66 #define BOTAO_DIR analogRead(A0) <= 20 #define BOTAO_ESQ analogRead(A0) <= 63 && analogRead(A0) >= 62 // Delay (em milisegundos) após pressionar botões #define DELAY_BOT_SLOW 300 #define DELAY_BOT_FAST 100 // ----- Variaveis globais ----- // Simbolo da seta na configuraçao byte SIMBOLO_SETA[8] = { B00100, B00100, B01110, B10101, B00100, B00100, B00100, B00100, }; // Simbolo do relogio byte SIMBOLO_RELOGIO[8] = { B00000, B10001, B01110, B10101, B10111, B10001, B01110, B00000, }; // Musica do despertador const char* MUSICA[] = {"Re", "Mi", "Fa", "Sol", "Do", "La", "Fa", "Do", "Fim"}; const int DURACAO[] = {500, 500, 500, 500, 500, 500, 500, 500}; // Frases do menu const String titulo_menu[4] = {"Mostrar horas", "Definir alarme", "Mudar as horas", "Mudar data"}; // Estados do programa em relação aos menus enum { MENU_MAIN = 0, MENU_HORAS, MENU_ALARME, MENU_CONFIG_HORAS, MENU_CONFIG_DATA }menu_atual; // Variaveis auxiliares dos menus uint8_t d1, d2, pos = 0; uint16_t d3; // É de 16 bits, pois pode armazenar o ano da data // Variaveis para controle do alarme bool parou_alarme = false, alarme_ativado = true; // Variavel dos alarmes // O primeiro da lista é o configurável pelo display // Adicione seu alarme mantendo o formato {XX,XX}, unsigned char alarmes[][2] = {{6, 0}, {8, 0}, {10, 0} }; // ----- Prototipo das funções ----- void verificar_alarme(void); void tocar(char* mus[], int tempo[]); String get_hour(void); String get_date(void) ; void setup() { // Inicia o LCD e cria os símbolos lcd.begin(16, 2); lcd.createChar(1, SIMBOLO_SETA); lcd.createChar(2, SIMBOLO_RELOGIO); // Define hora/min/segundo - dia/mes/ano setTime(12, 00, 0, 23, 1, 2021); // Configura o pino do buzzer pinMode(BUZZER, OUTPUT); } void loop() { // Verifica em qual menu está switch (menu_atual) { // Menu principal case MENU_MAIN: // Escreve os títulos lcd.setCursor(0, 0); lcd.print(titulo_menu[pos]); lcd.setCursor(0, 1); if (pos < 3) { lcd.print(titulo_menu[pos + 1]); } // Simbolo do relogio caso o despertador esteja ativo if (!parou_alarme && alarme_ativado) { lcd.setCursor(15, 0); lcd.write(2); } // ----- Testa os botoes ----- if (BOTAO_CIMA && pos > 0) { pos--; lcd.clear(); delay(DELAY_BOT_SLOW); } else if (BOTAO_BAIXO && pos < 3) { pos++; lcd.clear(); delay(DELAY_BOT_SLOW); } else if (BOTAO_SELECT) { // Verifica em qual menu deve entrar switch (pos) { case 0: menu_atual = MENU_HORAS; break; case 1: menu_atual = MENU_ALARME; pos = 0; d1 = alarmes[0][0]; d2 = alarmes[0][1]; d3 = alarme_ativado; break; case 2: menu_atual = MENU_CONFIG_HORAS; pos = 0; d1 = hour(); d2 = minute(); break; case 3: menu_atual = MENU_CONFIG_DATA; pos = 0; d1 = day(); d2 = month(); d3 = year(); } lcd.clear(); delay(DELAY_BOT_SLOW); } break; // ----- MENU_MAIN ----- case MENU_HORAS: lcd.setCursor(3, 0); lcd.print(get_hour()); lcd.setCursor(3, 1); lcd.print(get_date()); // Simbolo do relogio caso o despertador esteja ativo if (!parou_alarme && alarme_ativado) { lcd.setCursor(15, 0); lcd.write(2); } if (BOTAO_SELECT) { menu_atual = MENU_MAIN; lcd.clear(); delay(DELAY_BOT_SLOW); } break; // ----- MENU_HORAS ----- case MENU_ALARME: // Escreve as horas do alarme lcd.setCursor(0, 0); if (d1 < 10) { lcd.print("0"); } lcd.print(d1); lcd.print(":"); if (d2 < 10) { lcd.print("0"); } lcd.print(d2); // Informa se está ativo ou não lcd.setCursor(7, 0); if (d3) { lcd.print("Ativado"); } else { lcd.setCursor(6, 0); lcd.print("Desativado"); } // Desenha a seta switch (pos) { case 0: lcd.setCursor(1, 1); break; case 1: lcd.setCursor(3, 1); break; case 2: lcd.setCursor(10, 1); break; } lcd.write(1); // ----- Testa os botoes ----- if (BOTAO_CIMA) { if (pos == 0 && d1 < 23) { d1 ++; } else if (pos == 1 && d2 < 59) { d2 ++; } else if (pos == 2 && d3 < 1) { d3 ++; lcd.setCursor(6, 0); lcd.print(" "); lcd.setCursor(14, 0); lcd.print(" "); } delay(DELAY_BOT_FAST); } else if (BOTAO_BAIXO) { if (pos == 0 && d1 > 0) { d1 --; } else if (pos == 1 && d2 > 0) { d2 --; } else if (pos == 2 && d3 > 0) { d3 --; } delay(DELAY_BOT_FAST); } else if (BOTAO_DIR && pos < 2) { pos++; lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(3, 1); lcd.print(" "); lcd.setCursor(10, 1); lcd.print(" "); delay(DELAY_BOT_SLOW); } else if (BOTAO_ESQ && pos > 0) { pos--; lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(3, 1); lcd.print(" "); lcd.setCursor(10, 1); lcd.print(" "); delay(DELAY_BOT_SLOW); } else if (BOTAO_SELECT) { alarmes[0][0] = d1; alarmes[0][1] = d2; alarme_ativado = d3; menu_atual = MENU_MAIN; pos = 0; lcd.clear(); delay(DELAY_BOT_SLOW); } break; // ----- MENU_ALARME ----- case MENU_CONFIG_HORAS: // Escreve as horas lcd.setCursor(5, 0); if (d1 < 10) { lcd.print("0"); } lcd.print(d1); lcd.print(":"); if (d2 < 10) { lcd.print("0"); } lcd.print(d2); // Desenha a seta lcd.setCursor(6 + pos*2, 1); lcd.write(1); // ----- Testa os botoes ----- if (BOTAO_CIMA) { if (pos == 0 && d1 < 23) { d1 ++; } else if (pos == 1 && d2 < 59) { d2 ++; } delay(DELAY_BOT_FAST); } else if (BOTAO_BAIXO) { if (pos == 0 && d1 > 0) { d1 --; } else if (pos == 1 && d2 > 0) { d2 --; } delay(DELAY_BOT_FAST); } else if (BOTAO_DIR && pos < 1) { pos++; lcd.setCursor(6, 1); lcd.print(" "); delay(DELAY_BOT_SLOW); } else if (BOTAO_ESQ && pos > 0) { pos--; lcd.setCursor(8, 1); lcd.print(" "); delay(DELAY_BOT_SLOW); } else if (BOTAO_SELECT) { setTime(d1, d2, 0, day(), month(), year()); menu_atual = MENU_MAIN; pos = 0; lcd.clear(); delay(DELAY_BOT_SLOW); } break; // ----- MENU_CONFIG_HORAS ----- case MENU_CONFIG_DATA: // Escreve a data lcd.setCursor(3, 0); if (d1 < 10) { lcd.print("0"); } lcd.print(d1); lcd.print("/"); if (d2 < 10) { lcd.print("0"); } lcd.print(d2); lcd.print("/"); lcd.print(d3); // Desenha a seta lcd.setCursor(4 + pos*3, 1); lcd.write(1); // ----- Testa os botoes ----- if (BOTAO_CIMA) { uint8_t aux; // Restringe o valor do dia de acordo com o mês e ano (se for bissexto) if(d2 == 1 || d2 == 3 || d2 == 5 || d2 == 7 || d2 == 8 || d2 == 10 || d2 == 12) { aux = 31; } else if(d2 == 2) { if(d3%4 == 0) { aux = 29; } else { aux = 28; } } else // Condições faltantes: mes 4, 6, 9 ou 11 { aux = 30; } if (pos == 0 && d1 < aux) { d1++; } else if (pos == 1 && d2 < 12) { d2++; } else if(pos == 2 && d3 < 9999) { d3++; } delay(DELAY_BOT_FAST); } else if (BOTAO_BAIXO) { if (pos == 0 && d1 > 1) { d1--; } else if (pos == 1 && d2 > 1) { d2--; } else if(pos == 2 && d3 > 0) { d3--; } delay(DELAY_BOT_FAST); } else if (BOTAO_DIR && pos < 2) { pos++; lcd.setCursor(4, 1); lcd.print(" "); delay(DELAY_BOT_SLOW); } else if (BOTAO_ESQ && pos > 0) { pos--; lcd.setCursor(4, 1); lcd.print(" "); delay(DELAY_BOT_SLOW); } else if (BOTAO_SELECT) { setTime(hour(), minute(), second(), d1, d2, d3); menu_atual = MENU_MAIN; pos = 0; lcd.clear(); delay(DELAY_BOT_SLOW); } break; // ----- MENU_CONFIG_HORAS ----- } // Verifica se esta na hora de despertar verificar_alarme(); } /* * Verifica se está na hora de algum alarme tocar */ void verificar_alarme(void) { unsigned char i = 0; for(i = 0; i < sizeof(alarmes)/2; i++) { if (hour() == alarmes[i][0] && minute() == alarmes[i][1] && !parou_alarme && alarme_ativado) { lcd.clear(); lcd.setCursor(1, 0); lcd.print("Segure select"); lcd.setCursor(3, 1); lcd.print("para parar"); while (!parou_alarme) { tocar(MUSICA, DURACAO); if (BOTAO_SELECT) { parou_alarme = true; } delay(200); } lcd.clear(); } } // So reinicia a variável quando os segundos forem menor que 2 (próximo minuto) if (parou_alarme && second() <= 2) { parou_alarme = false; } } /* * Toca uma musica de acordo com o parâmetro */ void tocar(char* mus[], int tempo[]) { int tom = 0; for (int i = 0; mus[i] != "Fim"; i++) { if (mus[i] == "Do") tom = 262; if (mus[i] == "Re") tom = 294; if (mus[i] == "Mi") tom = 330; if (mus[i] == "Fa") tom = 349; if (mus[i] == "Sol") tom = 392; if (mus[i] == "La") tom = 440; if (mus[i] == "Si") tom = 494; if (mus[i] == "Do#") tom = 528; if (mus[i] == "Re#") tom = 622; if (mus[i] == "Fa#") tom = 370; if (mus[i] == "Sol#") tom = 415; if (mus[i] == "La#") tom = 466; if (mus[i] == "Pausa") tom = 0; tone(BUZZER, tom, tempo[i]); delay(tempo[i]); // CONDIÇAO DO DESPERTADOR - Não tem relação com essa função if (BOTAO_SELECT) { parou_alarme = true; break; } } } /* * Retorna uma string com o horário atual no formato: * HH:MM:SS */ String get_hour(void) { String horario = ""; unsigned char i, aux; for (i=0; i < 3; i++) { if(i == 0) { aux = hour(); } else if(i == 1) { aux = minute(); } else if(i == 2) { aux = second(); } if(aux < 10) { horario += "0"; } horario += aux; if(i != 2) { horario += ":"; } } return horario; } /* * Retorna uma string com a data no formato: * DD/MM/AAAA */ String get_date(void) { String data = ""; unsigned int i, aux; for (i=0; i < 3; i++) { if(i == 0) { aux = day(); } else if(i == 1) { aux = month(); } else if(i == 2) { aux = year(); } if(aux < 10) { data += "0"; } data += aux; if(i != 2) { data += "/"; } } return data; } |
Olá, gostei da sua idea, mas tem um porem, eu conectei todos os cabos, de acordo como vc fala, mas mesmo assim seu código continua a dar erro, poderia me ajudar?
Olá, João. Muito obrigado. Eu revisei o post e reparei que o problema vinha do plugin que eu uso para exibir códigos nos posts. Já arrumei, então pode copiar o código novamente e tentar. Qualquer, pode falar que eu te ajudo até funcionar 100%.
HOLA..Me encantó el proyecto aunque aun tengo un problema ..el codigo me compila y tambien prende la pantalla lcd mostrando la pantalla principal,pero al presionar los botones no responde….que valores de resistencias deberia poner en cada uno de los botones/pulsadores segun su codigo ?
Hola, gracias. No sé el valor de los resistores, porque estoy utilizando un shield LCD. En su caso, tu debe descubrir la escala de lectura de su circuito. Utilize ese post para te ayudar: https://mundoprojetado.com.br/lendo-valor-analogico-c-o-arduino/
Despues, tu debe trocar todas las escalas dentro del código, cambiando esa parte: “if(analogRead(A0) < 195 && analogRead(A0) > 50″ (entre 50 e 195 botton superior). Delante de cada línea yo he colocado uno comentario diciendo cuál bottón es: CIMA, BAIXO, SELECT, DIREITA, ESQUERDA. Basta presionar ctrl+f para buscar. Cualquier cosa, vuelva con los valores de su escala, que ayudo a cambiar en el codigo. Disculpa cualquier error en mi español, hace tiempo que no practico.
he leído el post que me dejaste pero sigo sin saber que resistencia poner lo unico que hallé fue en que intervalo ponerlo por cada voltio pero no logro saber que resitencia poner
Ahora yo he entendido el problema. Vea esa imagen para entender como montar los resistores: http://www.thomasclausen.net/wp-content/uploads/2017/01/IMG_0501-247×300.jpg
Puede utilizar resistores de 1kΩ. Post completo: http://www.thomasclausen.net/en/walking-through-the-1602-lcd-keypad-shield-for-arduino/
buenolo veré …gracias 🙂
Un placer. 😀
bueno lo veré …gracias 🙂
la codificacion la dejo igual o la cambio?…. ya reordene el circuito pero aun no me funciona los botones
Tu tienes que cambiar. Como he dicho, tu debes encontrar las escalas de lectura de los botones que estás utilizando. Despues cambiar los valores en la codificacion.
Olá! Estou tentando fazer esse projeto porém estou tendo dúvidas quanto a montagem ja que estou usando um shield assim como o mostrado não teria um vídeo ou alguma explicação de comer montar usando o mesmo?
Olá, Marcelo. Infelizmente no momento não tem não. Qual seria sua dúvida exatamente? Imagino que seja em relação ao buzzer, já que a shield é só encaixar ela no Arduino e pronto. Então, sobre o buzzer, o que fiz foi soldar um fio no GND e no pino digital 13. No caso, soldei o fio no shield e, pela imagem de capa do vídeo do Youtube, dá pra ver onde foram os pontos que soldei (não usei resistor). Para você entender melhor, esta imagem mostra os pontos de conexão do shield.
Olá, gostei da sua idea, mas tem um porem, eu conectei todos os cabos, de acordo como vc fala, mas mesmo assim seu código continua a dar erro, poderia me ajudar?
por exemplo o camando set time, ele esta dando erro
Olá, Cleber. Muito obrigado. Eu revisei o post e reparei que o problema vinha do plugin que eu uso para exibir códigos nos posts. Já arrumei, então pode copiar o código novamente e tentar. Qualquer, pode falar que eu te ajudo até funcionar 100%.
Tem que adicionar a biblioteca. ou seja vc tem que baixar a biblioteca..
https://github.com/PaulStoffregen/Time
baixa desse site..
Exatamente! No post eu coloquei dois links, incluindo o que você mencionou.
entonces… en la codificacion ya no la cambio?
Ola vou montar amanhã pela manhã este projeto que me chamou atenção, gostaria de saber se tem como colocar mais de um alarme.
Olá, Geraldo. Pelo código que desenvolvi, só há possibilidade de definir um único alarme.
Fabio boa tarde, sou acadêmico de tecnologia em mecatrônica industrial, estou tentando adaptar seu código para acionar um modulo rele, para acionar um motor monofásico, você poderia me ajudar?
Olá. Fizemos tudo que era necessário no código e os botões não estão funcionando. Você pode nos ajudar?
Obrigada.
Olá, posso sim! Para isso, ajudaria bastante se você me mandasse a imagem do circuito ou esquemático da montagem do seus botões. Pode mandar no email: mundoprojetado@gmail.com. Entretanto, posso fazer algumas observações que talvez ajudem: troquei a imagem do circuito dos botões para ficar mais fácil de entender. Repare que os botões estão todos ligados em paralelo, entre o 5v e o pino analógico A0. Enfim, fico no aguardo do seu email para poder ajudar melhor.
Olá, gostei do projeto e era exatamente o que eu precisava fazer, eu segui os passos fornecidos mas quando faço o upload do código na IDE não aparece nada no display já tentei ajustar o contraste pelo potenciometro e não aparece nada igual. Pode me ajudar? Se conseguir me responder as questões abaixo agradeço também.
– A biblioteca que você esta usando é LiquidCrystal.h não seria a LiquidCrystal_I2C.h? Porque estou usando o LCD 16×2 que é o que você sugere.
– No caso dos botões você informou que é necessário 5 botões, mas no vídeo esta utilizando 6, faz diferença ou não? Qual a utilidade do sexto botão?
Obrigado.
Olá. Fico feliz em saber que o projeto foi útil!
Então, o display que estou utilizando é um módulo de display lcd que é feito para você encaixar diretamente nos pinos do Arduino. E este módulo conecta em pinos diferentes aos do circuito que está mostrado no post. Portanto, a configuração dos pinos na programação ficou diferente no meu caso. A inicialização que fiz foi: “LiquidCrystal lcd(8, 9, 4, 5, 6, 7);”, sendo que, de acordo com o circuito, deveria ser: “LiquidCrystal lcd(12, 11, 5, 4, 3, 2);”. Estes números possuem a seguinte correspondência em relação aos pinos do display:
LiquidCrystal lcd(pino Rs, pino E, pino D4, pino D5, pino D6, pino D7);
Se o seu problema for em relação à conexão dos pinos, ajustar esta configuração pode resolver seu problema. Para entender melhor, sugiro o post que falo sobre o LCD 16×2.
Agora, respondendo suas duas dúvidas:
– A biblioteca “LiquidCrystal_I2C.h” serve para os displays LCD que possuem um conversor I2C. Este conversor serve para facilitar a comunicação com o Arduino, pois ele se conecta a todos os pinos do display e comunica com o Arduino utilizando apenas dois fios. E não é o caso do módulo que utilizei no post, já que ele comunica com o Arduino utilizando os 6 pinos mencionados anteriormente (RS, E, D4, D5, D6 e D7). Se você tiver interesse em aprender sobre a comunicação I2C, dê uma olha aqui.
– São necessários apenas 5 botões mesmo. Existem 6, porque o módulo LCD que utilizei já vem com os 6 botões por padrão. De qualquer forma, o 6º botão que não foi utilizado é na verdade um botão de RESET (RST), igual ao que já existe na placa do Arduino que faz ele se reiniciar. Então não dá pra utilizar ele dentro do código.
Espero ter ajudado!
tenho interesse na compra desse prototipo
Olá, Leonardo. Infelizmente, não está disponível para compra.
projeto muito legal
mas a tela fica travada no inicio “mostrar horas definir alarme ) e os botões nao interage com a tela estou usando shield preciso de ajuda
paulovbop@gmail.com
Olá, Paulo. Parece que é um problema com a leitura dos botões. Você precisa ajustar a faixa de leitura dos botões encontradas nas linhas 21 a 25. Para encontrar os valores certos, você pode usar o código deste post. Depois de anotar os valores lidos para cada botão pressionado, é só substituir no código do despertador. Qualquer dúvida no processo, é só falar.
Fabio fiz com uma protoboard, utilizando a serial para ler o valor escrito em analogRead, cada vez que apertava um botao, mas preciso de sua ajuda para modificar o projeto gostaria de determinar o tempo de parada do alarme , gotaria de acionar um modulo rele inves de um buzer, e gostaria de criar uma nova opçao no menu : “ajustar a data ” . apos isso pretendo ligar em uma eeprom para salvar os dados caso haja desligamento Pode me ajudar?
Olá, Harrison. Posso ajudar sim, mas não posso fazer o código para você. Então darei um direcionamento. Para você conseguir atingir seu objetivo por conta própria, é importante que você entenda o código (pelo menos de forma geral) e saiba fazer cada uma destas coisas que você comentou separadamente (acionar modulo relé, gravar dados na EEPROM etc). Então, sugiro a você dar uma lida no código com calma e qualquer coisa me mande por e-mail alguma dúvida específica. Sobre seus objetivos:
1 – Acionar módulo relé ao invés de buzzer -> Para isso, você pode trocar a linha 395 do código (tocar(MUSICA, DURACAO)) pelo comando de acionamento do relé. Se, por acaso, você for utilizar o relé sem módulo, aqui tem um post explicando como fazer isso.
2 – Determinar tempo de parada do alarme -> Não entendi direito o seu objetivo, a ideia seria saber por quanto tempo o alarme ficou tocando antes de alguém pará-lo?
3 – Criar opção para ajustar a data -> qualquer coisa eu te mando o código por e-mail com essa modificação.
4 – Salvar dados na EEPROM -> Recomendo ler este post para entender como utilizar a EEPROM e ter uma ideia de como você pode fazer isso.
Enfim, avalie meu comentário e qualquer dúvida futura, me mande mensagem por e-mail, que lá é mais fácil de enviar código e imagens.
A ideia é acionar um motor CA de forma autônoma por isso preciso determinar no código quanto tempo o alarme ficará ativo e depois desse tempo ele deve desarmar , ficaria muito grato se podesse me enviar o código com esse menu de data
Ah entendi agora. Beleza!
paulo você pode resolver facilmente, dentro do void setup escreva assim Serial.begin (9600) ;
depois no void loop vc escreve assim Serial.println(analogRead(A0);
dai vc vai apertar botao por botao e ver o range de valores que aparece o valor que aparecer voce poe da linha 21 a 25 o maior valor p´rimeiro e o menor por ultimo
Olá! Tira uma dúvida. Posso, ao invés de colocar um buzzer, incluir no projeto um dfplaye mini para tocar músicas quando o alarme for acionado?
Olá, Eduardo. Pode sim, sem problemas.
Aqui estou usando um Shield deu tudo certo mas os botões não funciona nem um
no display fica a mensagem do menu
o que devo fazer para funcionar
Olá, Paulo. Conforme informado no tópico “Configurações” na parte da “Programação”, você precisa ajustar à faixa de leitura dos botões para os valores do seu shield (linhas 21-25 do código). Dê uma lida no tópico para entender como fazer o ajuste.
Não funcionou no Shield.
Os botões não funcionam e com um
lcd nem nada só acende o display.
Tem como me dar um Help?
Olá, Roberto. Você precisa alterar a faixa de leitura dos botões para os valores adequados do seu shield. No tópico “Configurações”, eu explico em detalhes como isto pode ser feito (linhas 21-25 do código).
Eu estou usando o mesmo Shield que vc mas ainda os botões não respondem
criem um serial.print (A0)
mas os valores são loucos
tipo:
16:59:19.856 ->1⸮C⸮⸮
acredito que antes da seta sejam horas minutos segundos centesimos e depois da seta seja o valor desejado?
é isso?mas após apertar o select o final vira 14
e os botões para cima e para baixo tambem dão 14 tambem…
se aperto Right ou rst volta os numeros estranhos
->1⸮C⸮⸮
Serial.print(nalogRead(A0));
Por algum motivo seu comentário não foi notificado e só hoje fui reparar por conta da mensagem do Harrison. Não sei se você ainda está enfrentando este problema, mas, mesmo utilizando o mesmo shield, os valores podem variar um pouco. Estes valores ‘loucos’ normalmente aparecem por 2 motivos: você não inicializou a comunicação serial (Serial.begin) ou então escolheu uma velocidade no monitor serial diferente da velocidade configurada no código.
Esses símbolos ocorrem se o pinos estiverem conectados de forma errada, basta rever os pinos do lcd
Olá Fabio, tudo bem ?
estou com dificuldade em fazer o seu código ser executado, pois aparece uma linha de erro, sendo:
( setTime ( d1 , d2 , 0 , dia ( ) , mês ( ) , ano ( ) ) ; )
Poderia me ajudar nessa questão?
Desde já agradeço.
Olá, João. Tudo bem e você?
Você chegou a instalar a biblioteca TimeLib? Talvez esse erro tem relação com ela. Se você já tiver instalado, me mande um print do erro por e-mail, pois assim consigo entender melhor o problema: mundoprojetado@gmail.com
Olá, boa tarde!
Gostaria de saber como baixar a biblioteca para utilizar no Tinkercad.
Olá, Otávio. Infelizmente, até onde sei, não tem como instalar bibliotecas no Tinkercad. Então será necessário testar o projeto fisicamente mesmo.
Olá, poderia me ajudar? meu codigo apresenta esses erros, montei o circuito conforme as imagens e fiz as alterações necessarias como dito no post, nao estou utilizando shield. Poderia me ajudar?
C:\Users\Arthur\Documents\Arduino\sketch_jul26a\sketch_jul26a.ino: In function ‘void verificar_alarme()’:
C:\Users\Arthur\Documents\Arduino\sketch_jul26a\sketch_jul26a.ino:522:28: warning: invalid conversion from ‘const char**’ to ‘char**’ [-fpermissive]
tocar(MUSICA, DURACAO);
^
C:\Users\Arthur\Documents\Arduino\sketch_jul26a\sketch_jul26a.ino:90:6: note: initializing argument 1 of ‘void tocar(char**, int*)’
void tocar(char* mus[], int tempo[]);
^~~~~
C:\Users\Arthur\Documents\Arduino\sketch_jul26a\sketch_jul26a.ino:522:28: warning: invalid conversion from ‘const int*’ to ‘int*’ [-fpermissive]
tocar(MUSICA, DURACAO);
^
C:\Users\Arthur\Documents\Arduino\sketch_jul26a\sketch_jul26a.ino:90:6: note: initializing argument 2 of ‘void tocar(char**, int*)’
void tocar(char* mus[], int tempo[]);
^~~~~
O sketch usa 9334 bytes (28%) de espaço de armazenamento para programas. O máximo são 32256 bytes.
Variáveis globais usam 361 bytes (17%) de memória dinâmica, deixando 1687 bytes para variáveis locais. O máximo são 2048 bytes.
Olá, Arthur. Essas mensagens não são exatamente erros, são apenas avisos de que a implementação dos pontos citados não foi feita de um jeito adequado. Pela última linha que você colou, dá pra ver que a compilação foi feita com sucesso, pois mostrou a quantidade de memória ocupada pelo programa.
Ok, obrigado. Mesmo com a mensagem de “erro” o código funcionou normalmente.
Show de bola!
Parabéns pelo conteúdo Fábio, muito bem detalhado.
Estou com um projeto de TCC ao qual gostaria de fazer 4 alarmes ao longo do dia, mas todos configurados pelo display, consegue me dar um help?
Olá, Junior. Muito obrigado!
Te respondi por e-mail.
Olá, estou tentando utilizar um motor no lugar do buzzer porem o mesmo não gira, ja olhei nos codigos e não consigo achar o problema consegue me ajudar? o motor e um de 6v
Olá, Marcelo. Não é recomendado acionar um motor diretamente pelo pino do Arduino, pois o pino tem uma capacidade baixa de corrente (abaixo de 40 mA) e, normalmente, um motor puxa acima de 100 mA. Dependendo do motor, vai puxar até mais de 1 A. Ou seja, você tá correndo risco de queimar o pino do Arduino. A forma correta de acionar uma carga que puxa muita corrente é utilizando um transistor como mediador, assim como foi ensinado neste post em que o Arduino aciona um relé.
Olá Fabio, eu recentemente tentei fazer este projeto, porem apos tentar compilar o projeto, eu recebo este erro
C:\Users\IceGa\AppData\Local\Temp\.arduinoIDE-unsaved20221013-20472-1tj9c9n.ohj6\Blink\Blink.ino: In function ‘void verificar_alarme()’:
C:\Users\IceGa\AppData\Local\Temp\.arduinoIDE-unsaved20221013-20472-1tj9c9n.ohj6\Blink\Blink.ino:511:13: error: invalid conversion from ‘const char**’ to ‘char**’ [-fpermissive]
C:\Users\IceGa\AppData\Local\Temp\.arduinoIDE-unsaved20221013-20472-1tj9c9n.ohj6\Blink\Blink.ino:79:18: note: initializing argument 1 of ‘void tocar(char**, int*)’
C:\Users\IceGa\AppData\Local\Temp\.arduinoIDE-unsaved20221013-20472-1tj9c9n.ohj6\Blink\Blink.ino:511:21: error: invalid conversion from ‘const int*’ to ‘int*’ [-fpermissive]
C:\Users\IceGa\AppData\Local\Temp\.arduinoIDE-unsaved20221013-20472-1tj9c9n.ohj6\Blink\Blink.ino:79:29: note: initializing argument 2 of ‘void tocar(char**, int*)’
exit status 1
Compilation error: invalid conversion from ‘const char**’ to ‘char**’ [-fpermissive]
Eu inclusive não consigo passar o projeto para o arduino, poderia me ajudar? Desde ja agradeço.
Olá, Rogério. Estranho, parece ser algum problema na chamada da função de tocar o som do buzzer. Pra te ajudar melhor, preciso entender alguns pontos:
Por acaso esse erro que você teve foi com o código exatamente igual tá no post? Se não, me mande por e-mail o seu código para eu entender onde está o problema (mundoprojetado@gmail.com)
Outra coisa, qual é a versão da IDE do Arduino que você está usando?
Eu estou usando o codigo exatamente como esta aqui no site
a versão da IDE é 2.0.1
Te respondi no e-mail.
Boa noite.
Montei este projeto mas fins algumas alterações.
Mostra no menu inicial quando esta ligado o alarme e quando esta desligado.
Agora queria que mostrasse o dia da semana (Seg-Feira), procurei mas não encontrei nada.
Alguém pode me dar uma ajuda?
Boa noite
Montei este projeto mas fins algumas alterações.
Mostra no menu inicial quando esta ligado o alarme e quando esta desligado.
Agora queria que mostrasse o dia da semana (Seg-Feira), procurei mas não encontrei nada.
Alguém pode dar uma ajuda?
Eu liguei com lcd 20×4.
Linha 0 mostra Hora
Linha 1 mostra data (A seguir a data quero que mostre o dia da semana)
Linha 2 mostra (Escreve Alarme ativado e hora ou Alarme desativado)
Linha 3 mostra temperatura ambiente
Boa noite, João. O dia da semana pode ser obtido chamando a função weekday(). Essa função retorna um número de 1 a 7, sendo 1 correspondente ao domingo e 7 correspondente ao sábado. A partir disso, tem muitas formas diferentes de você mostrar o dia da semana na tela. Uma delas é criando um vetor com os nomes dos dias:
char * nomes_dias_semanas[7] = {“Domingo”, “Segunda”, … “Sábado”};
E então, na hora de printar o dia da semana, é só chamar:
lcd.print(nomes_dias_semanas[weekday()-1]);
Recomendo recorrer ao Chat-GPT para te ajudar nos detalhes extras que forem necessários.
Boa noite caro amigo, pela dica.
Esta a rolar na perfeição, necessita de uns ajustes.
Obrigado
A próxima etapa é ligar ao DS. Qual o DS me aconselhas?
Boa noite. Por nada! Que ótimo, fico feliz em ler isso.
Não sei dizer viu, mas o DS3231 é uma boa opção por conta do baixo consumo de corrente. Dá uma lida nos posts que tem aqui no site pra vc comparar as características do DS1302 e do DS3231.
Bom dia caro amigo e obrigado pelo VB.
Tenho um outro problema que esta me a matar a cabeça.
Programo Horas, Alarme, Data e o problema é que com a mudança do dia o alarme desparra (quando passa 00H00).
Programo Ex. hoje para no dia a seguir dar alarme as 07H30 da manha, ao passar a hora de um dia para outro (00h00) desparra o alarme.
Tenho que fazer select para parar o alarme e depois vai desparrar as 07H30.
Podias dar me uma ajuda?
Obrigado
Boa tarde caro amigo Fábio acertai com o problema do alarme referente a mudança do dia.
MENU_MAIN = 0,
MENU_HORAS,
MENU_ALARME,
MENU_CONFIG_HORAS,
MENU_CONFIG_DATA (aqui não é d3 mas sim d4)
Corri o programa em verificação e alterei d3 para d4.
Ex.
menu_atual = MENU_ALARME;
pos = 0;
d1 = alarmes[0][0];
d2 = alarmes[0][1];
//d3 = alarme_ativado;
d4 = alarme_ativado;
Bom dia, João!
Muito bom. Então isso ai corrigiu os 2 problemas que você citou?
Boa tarde.
Detetei um problema no programa, ao programar o alarme em vez de ter o símbolo escreve (Alarme Ativado e as Horas) o problema é que aparece o dia
e mês quando faço select sem programar nada.
Só mostra a hora do alarme coreto quando vou ao menu alarme e faço select volto menu principal ai sim mostra a hora do alarme coreto.
Não amigo Fábio estou testando de outra maneira.
Depois mando FB
Boa noite Fábio.
Podes me dar uma ajuda com o meu problema do alarme?
Se ou programar perto da meia meia noite(00H00)
o teu programa funciona bem, se programar Ex 15H00 do dia anterior para EX 07H00 da manha do dia seguinte dispara o alarme as (00H00).
Se o meu raciocínio estiver coreto?
MENU_MAIN = 0,
MENU_HORAS,
MENU_ALARME, = d1
MENU_CONFIG_HORAS, = d2
MENU_CONFIG_DATA= d3
Espero uma resposta.
Dodó o resto esta a trabalhar, falta ligar o (DS) mas gostava de resolver esta situação.
Agradeço a tua atenção:
Boa noite, João. Como você modificou o código, fica difícil dizer qual é o problema sem ter acesso ao programa. Então, se puder, me manda ele por email (mundoprojetado@gmail.com). Ou então manda ele pro Chat Gpt que ele também deve ser capaz de encontrar o problema.
Boa noite Fábio.
Penso que esta resolvido, eu foi ver o teu programa e reparei num erro.
Descrevo onde alterei.
// Menu principal quando entra nos menus escolher
case MENU_MAIN:
// Escreve os títulos
lcd.setCursor(0, 0);
lcd.print(titulo_menu[pos]);
lcd.write(5);
lcd.write(4);
lcd.write(6);
// Simbolo do relogio caso o despertador esteja ativo
if (!parou_alarme && alarme_ativado)//Não estava mas existe no programa original
{
lcd.setCursor(0,2);//Não estava mas existe no programa original
lcd.print(“Alarme Ativado:”);//Não estava mas existe no programa original
}
Eu testei de ontem para hoje e já não disparou o alarme , com a passagem do dia para outro.
// Menu principal quando entra nos menus escolher
case MENU_MAIN:
// Escreve os títulos
lcd.setCursor(0, 0);
lcd.print(titulo_menu[pos]);
lcd.write(5);
lcd.write(4);
lcd.write(6);
// Simbolo do relogio caso o despertador esteja ativo
if (!parou_alarme && alarme_ativado)//Não estava mas existe no programa original
{
lcd.setCursor(0,2);//Não estava mas existe no programa original
lcd.print(“Alarme Ativado:”);//Não estava mas existe no programa original
}
Vou continuar com testes, para demostrar a minha ideia final. Mandei o meu programa para o mundoprojetado.
Boa tarde, João. Entendi, que bom que você encontrou o erro. E obrigado por ter enviado o programa!
Olá, Fábio eu estou tentando fazer esse projeto mas os botões de fato não funcionam ( eu ja troquei a faixa de acordo com o que aparece quando aperto) as vezes apertando por exemplo o botão da direita por um tempo ele entra para mostrar hora e data outras vezes nada acontece, desperta e eu aperto o select as vezes ate por um tempo e nada acontece tbm, eu consegui apertando os botões por um tempo entrar no no configuração de hora mas tbm ficou parado e não mudou nem nada.
Poderia me dar uma ajuda?
Olá, Phelipe. Você está usando um modulo igual ao que usei (LCD Keypad Shield) ou é uma placa diferente?
Ola Fabio
creio que instalei as bibliotecas para o projeto
Antes de enviar o programa faço uma verificaçao no botao da IDE
Enviei o programa para o arduino
estou a utilizar um LCD KEYPAD SHIELD
VERIFIQUEI QUE TINHA 2 FIOS A SAIR DO ARDUINO E SOLDADOS NO LCD
NA tela a mensagem e a seguinte :
Mostrar horas
Definir alarmes
depois apareceu uma outra mensagem
segure a tecla select para parar….
.
“nao tenho o bezouro ligado ….”
Olá, Jose Manuel. Te respondi por email.
nesta montagem
utilizo LCD keypad Shield
nao tenho acesso aos botoes down up
nao ha comunicaçao com o programa