Talking clock



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.

0 comentários :

Post a Comment