Relógio Falante





















Para demonstrar a utilização da placa standalone MBZ Pro Mega, vamos realizar uma das montagens clássicas com Arduino: um relógio digital. 
Mas para incrementar um pouco, vamos fazer esse relógio FALAR as horas.






Para tornar a montagem mais fácil, não será necessário nenhum módulo especial para reproduzir o áudio, para tanto vamos utilizar a biblioteca TMRpcm, que toca arquivos PCM/WAV direto de um cartão SD, através de uma porta PWM do Arduino.


Apesar desse artigo mostrar a montagem usando uma placa MBZ Standalone, ela não é imprescindível para a conclusão da montagem. 


Cartão SD

Para ler o cartão SD pode ser utilizado um módulo padrão para Arduino. A principal vantagem desse módulo é que ele já pode trabalhar diretamente com 5V, tanto na alimentação quanto nos pinos de sinal:

Mas se você não tem um módulo SD, pode usar um simples adaptador de cartão SD com uma barra de pinos soldada nos seus terminais:


  

A alimentação do cartão SD deve ser 3.3V e os pinos de sinal devem trabalhar também com 3.3V, para isso pode-se usar um divisor de tensão com resistores (como no módulo SD) ou usar um chip CD74HC4050, que faz a conversão do nível de sinal de 5V para 3.3V.
Lembrando que a utilização desse chip torna a leitura muito mais rápida que nos módulos SD normais, que usam divisores de tensão com resistores. O único módulo SD no mercado que se compara é o da Adafruit, que também usa o chip 4050.
Como a MBZ Pro Mega tem um chip desses, vamos utilizá-lo do projeto.

Clique aqui para ver o data sheet do CD74HC4050

Faça o download dos arquivos de voz WAV e descompacte o arquivo ZIP na raiz do cartão SD. Use um cartão SD de no máximo 2GB.

Clique aqui para fazer o download do arquivo com os áudios WAV

Se você quiser criar seus próprios arquivos WAV, eles devem estar configurados com os seguintes parâmetros: WAV, mono, 16Khz, 8 bit.
Você pode gerar novos arquivos de áudio a partir de TTS (Texto to Speech) no site Voice RSS.


Amplificador

Os arquivos WAV são lidos e as informações são traduzidas em pulsos PWM na porta digital 9 do Arduino. Se você ligar um fone de ouvido já pode ouvir o arquivo sendo tocado.
Como a potência na saída não é suficiente para um alto-falante, esse áudio passa por um amplificador feito com o C.I. TDA7052.
O chip TDA7052 é um amplificador mono de 1W, bem simples de usar e fácil de ser encontrado.

Clique aqui para ver o data sheet do TDA7052

Esse amplificador poderia ser feito com outros chips como, por exemplo, o LM386, ou mesmo com um módulo de amplificador como o PAM8403.

O transistor BC548 está sendo utilizado como um interruptor para ligar a alimentação no TDA7052 apenas quando for necessário.



O Circuito

A figura abaixo mostra a montagem do circuito usando um Arduino Nano em uma breadboard:

Abaixo está o diagrama esquemático do circuito:



Usando a MBZ Pro Mega

A MBZ Standalone permite fazer a montagem do Relógio Falante em uma única placa. Ela tem uma área para montar um Arduino (que já tem header para o RTC), uma área no centro equivalente à uma mini-breadboard (onde você pode soldar os componentes do circuito) e uma área para colocar um ESP8266 para acesso WIFI. Neste projeto não será utilizado WIFI, portanto não vamos usar esse módulo, mas vamos aproveitar o chip CD74HC4050 que faz a conversão dos sinais digitais de 5V para 3.3V:


A foto acima mostra o circuito do amplificador TDA7052 soldado na placa e dois headers, um para o OLED e outro para o cartão SD.



Agora basta encaixar o RTC, o cartão SD, o display OLED, ligar uma fonte de alimentação, fazer o upload do sketch e o relógio está pronto para funcionar.




Segue abaixo o código fonte (sketch) que deve ser colocado no Arduino. Faça as modificações que quiser, para adaptá-lo às suas necessidades: 

#include <RtcDS3231.h>
#include <TMRpcm.h>
#include <Wire.h>
#include <SD.h>
#include <U8glib.h>

#define SD_ChipSelect_Pin 10
#define Amp_Enable_Pin 8
#define Tmc_Pin 9
#define btn_Pin A0

U8GLIB_SH1106_128X64 u8g(4, 5, 6, 7);  //software SPI: SCK=4, MOSI=5, CS=7, A0=7

RtcDS3231 Rtc;
RtcDateTime now;

bool dispTime = true;

TMRpcm tmrpcm;

void setup ()
{
  Serial.begin(9600);

  // inicializa o SD
  if (!SD.begin(SD_ChipSelect_Pin)) {
    Serial.println("Erro SD");
    return;
  }

  // inicializa o TmrPCM
  tmrpcm.speakerPin = Tmc_Pin;
  tmrpcm.quality(1);
  tmrpcm.setVolume(5);

  // inicializa o pino que liga o amplificador
  pinMode(Amp_Enable_Pin, OUTPUT);
  digitalWrite(Amp_Enable_Pin, LOW);

  // inicializa o RTC
  Rtc.Begin();
  RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
  if (!Rtc.IsDateTimeValid())
  {
    Rtc.SetDateTime(compiled);
  }
  if (!Rtc.GetIsRunning()) {
    Serial.println("Inicializando o RTC");
    Rtc.SetIsRunning(true);
  }
  RtcDateTime now = Rtc.GetDateTime();
  if (now < compiled)
  {
    Rtc.SetDateTime(compiled);
  }

  // gira o display OLED
  u8g.setRot180();

  // inicializa o push-button
  pinMode(btn_Pin, INPUT);
  digitalWrite(btn_Pin, LOW);
  pinMode(13, OUTPUT);
}

void displayTime(void) {
  int hour = now.Hour();
  int minute = now.Minute();
  int day = now.Day();
  int month = now.Month();
  int year = now.Year();
  char st[10];

  sprintf(st, "%02d:%02d", hour, minute);

  u8g.setFont(u8g_font_fub35n);
  u8g.drawStr( 0, 36, st);

  sprintf(st, "%02d/%02d/%04d", day, month, year);
  u8g.setFont(u8g_font_9x15);
  u8g.drawStr( 20, 60, st);
}

void loop ()
{
  now = Rtc.GetDateTime();

  if (dispTime) {
    Serial.println(now.Second());
    // exibe a hora no oled
    u8g.firstPage();
    do {
      displayTime();
    } while ( u8g.nextPage() );
  }

  if (now.Second() == 0) {
    dispTime = true;
  } else {
    dispTime = false;
  }

  if (Rtc.IsDateTimeValid()) {
    now = Rtc.GetDateTime();
  }

  if (digitalRead(btn_Pin) == HIGH) {
    talkTime(now.Hour(), now.Minute());
    delay(500);
  }
}

void talkTime(int hour, int minute) {
  char fileHour[12];
  char fileMinute[12];

  if (hour > 12) {
    hour = hour - 12;
  }

  sprintf(fileHour, "%02dH.wav", hour);
  Serial.println(fileHour);

  turnAmpOn();
  tmrpcm.play(fileHour);
  waitPlay();

  if (minute > 0) {
    sprintf(fileMinute, "%02dM.wav", minute);
    Serial.println(fileMinute);
    tmrpcm.play(fileMinute);
    waitPlay();
  }

  turnAmpOff();
}

void waitPlay() {
  bool b = false;

  while (tmrpcm.isPlaying()) {
    delay(10);
  }
}

void turnAmpOn() {
  digitalWrite(Amp_Enable_Pin, HIGH);
}

void turnAmpOff() {
  digitalWrite(Amp_Enable_Pin, LOW);
}


Após a compilação será exibida uma mensagem de pouca memória disponível, mas o programa funcionará normalmente. Essa mensagem é devido ao uso da biblioteca U8GLIB que consome muita memória para as fontes que serão exibidas no display OLED. Também a biblioteca SD consome muita memória.

10 comentários :

  1. Bonito trabalho e didática, Parabens.

    ResponderExcluir
  2. Show! Parabéns, Marcelo!
    Como vc fez para salvar os arquivos WAV no site Voice RSS ?
    Obrigado!

    ResponderExcluir
    Respostas
    1. Você tem que se cadastrar no site para conseguir uma API key. Depois na área de teste da API você pode configurar uma URL com os parâmetros de formato de arquivo. Ao chamar a URL, é feito o download do arquivo para seu computador.

      Excluir
  3. Muito legal. eu fiz um e funcionou direitinho.

    ResponderExcluir
  4. Posso usar um CD4050 no lugar do 74HC4050?

    ResponderExcluir
    Respostas
    1. Sim, é o mesmo circuito integrado. Dependendo do fabricante o código muda.

      Excluir
  5. Gostaria de dar saudacao tipo shopping na entrada do condomínio utilizando arduino

    Teria que utilizar horário para selecionar bom dia, boa tarde ou Boa noite

    Poderia me ajudar nesta questão

    ResponderExcluir