Countdown Voice Timer and Fire Starter
1 524 Medium

Introduction
 

This project is about a programmable countdown timer that can speak countdown numbers through an enclosed speaker ! User can set any countdown value between 0 to 100, thus device can countdown up to 100 seconds.

Voice countdown allows user to be "eyes-free" (kind of like hands-free), there is no need to look at the display during countdown.

The idea is to move to a safe distance while the timer is counting down. Then let something happen when the timer reaches zero.

 

 

Application

 

This device can be used to do relatively dangerous experiments/activities like:

Igniting Fireworks

Launching hobby Rockets

Mixing dangerous Chemicals

Doing hazardous Physics experiments

Short Circuiting Electronics

Starting a Fire

There are 3 GPIO pins available to interface with external devices to carry out trigger signal and do something stupid !

 

 

Disclaimer: This device is for 'harmless' mad-scientists and pyromaniacs, should not be used to harm others !

 

 

Hardware Build

 

Following hardware are used to make this project:

 

DF Beetle: Very small size Arduino Leonardo compatible board based on Atmega32UA4 microcontroller.

 

DF Voice Rec/Playback Module: A complete voice recording solution with microcontroller, flash storage, microphone and speaker driver. It can hold about 40 minutes of MP3 files (in 48kbps quality) on the 16MB storage. A maximum of 1000 Audio files can be recorded or played. The board can be used independently with Rec/Play buttons or from a microcontroller over serial commands.

 

1306 OLED 128x32 display: I2C based display for showing user interface.

 

Enclosed Speaker: Small size 8 Ohms 3 Watt speaker for loud voice

 

projectImage
HARDWARE LIST
1 DFRobot Beetle - The Smallest Arduino
1 DFRobot Monochrome 0.91”128x32 I2C OLED Display with Chip Pad
1 DFRobot DF Voice Rec/Playback Module
1 DFRobot Enclosed Speaker
3 DFRobot Mini Push Buttons
1 DFRobot USB A to C Cable

You will also need a protoboard for soldering all the modules together, few push buttons for input, some small cable ties,

To interface with the I2C OLED, you need to connect to I2C pads, which are placed in an inconvenient location on Beetle board. Bend odd number pins on a 6 pin male header as shown in the the image below and solder to access I2C and Serial pads. This way, 10 I/Os + Vcc + Gnd can be accessed.

 

 

 

You will also need a protoboard for soldering all the modules together, few push buttons for input, some small cable ties,

To interface with the I2C OLED, you need to connect to I2C pads, which are placed in an inconvenient location on Beetle board. Bend odd number pins on a 6 pin male header as shown in the the image below and solder to access I2C and Serial pads. This way, 10 I/Os + Vcc + Gnd can be accessed.

 

 

 

Solder all the modules and components according to the schematic:-

projectImage

Use some cable ties to fasten the speaker with the protoboard in 90 degree position like this :-

projectImage
projectImage

You will also need a protoboard for soldering all the modules together, few push buttons for input, some small cable ties,

To interface with the I2C OLED, you need to connect to I2C pads, which are placed in an inconvenient location on Beetle board. Bend odd number pins on a 6 pin male header as shown in the the image below and solder to access I2C and Serial pads. This way, 10 I/Os + Vcc + Gnd can be accessed.

 

 

 

Fire starter circuit

 

This is a very simple DIY fire starter circuit made of very low resistance coil (anything between 0.5 to 2 ohms) wrapped around a safety match stick. Power the coil through any relay or MOSFET. The coil will heat up and match stick will flash. Nichrome or Kanthal coils (for vape devices) will provide best results. Even through hole resistor (half watt) or fuse wire will also work.

 

 

projectImage

Preparing Voice Audio Files

 

Step1: I used this text-to-speech service to make the audios.

Use some cable ties to fasten the speaker with the protoboard in 90 degree position like this :-

projectImage

Step 2: While the speech was playing, the sound was recoded with Audacity . Select Windows WASPAPI and Source as Headphone/Speaker, then click the Record icon to capture audio playback in your computer.

 

Recording with Audacity:-

 

projectImage

Step 3: After recording, the audios are segmented into multiple mp3 files. To separate each segment of the audio (sound for every number), select that part with mouse, then use shortcut Ctrl+C (copy), Ctrl+N (new), Ctrl+V (paste) that audio segment. Repeat this step for each audio voice segment.

 

Converting to MP3 files

 

 

Step 2: While the speech was playing, the sound was recoded with Audacity . Select Windows WASPAPI and Source as Headphone/Speaker, then click the Record icon to capture audio playback in your computer.

 

Recording with Audacity:-

 

projectImage
projectImage

Step 4: Go to Files > Export as MP3, select 48 kbps quality and rename as FILE0000.MP3, FILE0001.MP3, FILE0002.MP3 up to FILE0100.MP3

(all the audio files are attached below, you can skip step 1-4, just download and copy the files according to step 5)

Step 5: Voice module is connected to computer with a USB C cable, 16 MB Flash Drive appeared. It will require formatting (FAT) when using for the first time. Next, all the mp3 files are copied to a DF_REC directory inside the voice module's flash drive.

Each filename corresponds to the voice of that number. For example, FILE0007.MP3 holds the sound for "Seven"

You can put maximum of 1000 MP3 files with total audio length of 40 minutes @ 48kbps. Higher sampling frequency song/audio voice will work but the audio length will be less due to larger file size

Alternatively, you can record your own voice directly on the module by pressing the Rec button (see reference section for details)

 

 

 

Programming

 

Before diving into Arduino IDE, let's review the Beetle pins and associated functions:-

projectImage

For some reason, I couldn't manage to use the hardware serial (pin 0 & 1) to control the voice module from Beetle.

 

Pin 10 and 11 will be used to control the voice module

Pin 2 & 3 are I2C pins to interface 1306 OLED

Pin A0, 1 and A2 are connected to 3 push buttons

Pin 0, A1 and 9 are available for interfacing external hardware

______________________________________________________

You will need to add couple of libraries and select the correct board profile for this project.

 

Step 1: As, Beetle is Arduino Leonardo, Open Arduino IDE and select Tools > Board > Arduino Leonardo

 

Selecting board for Beetle

 

projectImage

Step2: Download the Voice module library in zip file and add the library to Arduino from Sketch > Include Library > Add zip Library and select the downloaded zip file (DFRobot_DF1101S-master)

projectImage
projectImage

Step3: Next, add the 1306 OLED library from Tools > Library Manager > type 'u8g' and install the U8G library (by Oliver)

Step 4: Connect Beetle board to computer with micro USB cable, copy and paste the attached code below. Then compile and upload the firmware.

Done !

 

 

 

References

DF Robot Voice Recorder Wiki

Audacity Tutorial

 

 

 

Conclusion

This project can have extended functionalities with some change in firmware. As the voice module can hold up to 1000 mp3 files, you can synthesize syntax (sentences in any human language) from multiple words : like - "Relay Activated" or "Low Battery" or "I am a Robot".

It is possible to speak up any number with some clever coding. For example: if you want to speak 575, you need 3 audio files playing the words "Five", " Hundred" and "Seventy-Five" in a sequence. All you need some mp3 files with sound from "Zero" to "Ninety-Nine" + "Hundred", "Thousand" "Million" "Billion" and "Trillion" to speak any number

Projects like voice warning systems, talking weather station, voice interactive UI can also be designed with the same hardware setup.

CODE
#include "U8glib.h"
#include <DFRobot_DF1101S.h>
#include <SoftwareSerial.h>

SoftwareSerial df1101sSerial(10, 11);          // RX = 10  TX = 11
U8GLIB_SSD1306_128X32 u8g(U8G_I2C_OPT_NONE);   // SCL = 2  SDA = 3

DFRobot_DF1101S df1101s;

#define BUTTON_DEC    A2
#define BUTTON_INC     1
#define BUTTON_SEL    A0

#define OUTPUT_PIN1   0
#define OUTPUT_PIN2   A1
#define OUTPUT_PIN3   9

#define BLUE_LED      13

/////////////////////////
// FILE0999.MP3 says "FIRE"
#define FIRE      999
#define THOUSAND  103
#define MILLION   106
#define BILLION   109
#define tRILLION  112

// record more mp3 and add more defines like this
// if device needs to say something through speaker

//////////////////////////////////////////////////


int number_index = 3;
int volume = 10;
long last_millis;

void setup(void)
{
 
 u8g.setRot90();        // change oled display orientation

 // set GPIOs for buttons and LED
 
 pinMode(BUTTON_DEC, INPUT_PULLUP);
 pinMode(BUTTON_INC, INPUT_PULLUP);
 pinMode(BUTTON_SEL, INPUT_PULLUP);
 pinMode(BLUE_LED, OUTPUT);

 //  Output pins for controlling something
 pinMode(OUTPUT_PIN1, OUTPUT); digitalWrite(OUTPUT_PIN1,LOW);
 pinMode(OUTPUT_PIN2, OUTPUT); digitalWrite(OUTPUT_PIN2,LOW);
 
 // welcome message  
 update_display_message_0();
 delay(500);

 // init soft serial to communicate with voice playback moduel
 
  df1101sSerial.begin(115200);
  delay(100);
  while(!df1101s.begin(df1101sSerial))
  {
  update_display_message_1();  
  df1101s.setPrompt(false);  
  }
  
  //Set initial volume to 10
  df1101s.setVol(volume);

  // set playback mode
  df1101s.switchFunction(df1101s.MUSIC);

  // fast blink LED on pin 13
  for(int i = 0; i<10; i++)
  {debounce_blinky();}

 
 
 // adjust volume with buttons
 // BUTTON_SEL for selecting shown value
 // BUTTON_INC for increasing shown value
 // BUTTON_DEC for decreasing shown value
 
  while(digitalRead(BUTTON_SEL))
  {
    if(!digitalRead(BUTTON_DEC))
    {
      volume--;
      debounce_blinky();
    }
    if(!digitalRead(BUTTON_INC))
    {
      volume++;
      debounce_blinky();
    }
    if (volume<10)   {volume = 10;}
    if (volume>30)   {volume = 30;}
    
    df1101s.setVol(volume);     // set volume for Spk
    update_display_message_2(); // update OLED
  }

for(int i = 0; i<10; i++)
{debounce_blinky();}

// set mp3 playback as single cycle
df1101s.setPlayMode(df1101s.SINGLECYCLE);  
 
}

void loop()
{

set_count_down_timer();    

while(number_index>=0)
{
df1101s.playSpecFile(number_index);
update_display_message_4();  
last_millis =millis();
while(millis()<last_millis+1000)
{}
number_index--;
}

// control fire starter circuit
trigger_event();

 
} // end of loop

///////////////////////////////////
///control and display functions///
///////////////////////////////////

void update_display_message_0(void)
{    
  u8g.firstPage();  
  do {
     u8g.setFont(u8g_font_6x12); 
     u8g.drawStr( 0, 10, "This");
     u8g.drawStr( 0, 25, "is a");
     u8g.drawStr( 0, 40, "voice");
     u8g.drawStr( 0, 55, "count");
     u8g.drawStr( 0, 70, "down");
     u8g.drawStr( 0, 85, "Timer");
     
  } while( u8g.nextPage() );
}



void update_display_message_1(void)
{    
  u8g.firstPage();  
  do {
     u8g.setFont(u8g_font_6x12); 
     u8g.drawStr( 0, 10, "Please");
     u8g.drawStr( 0, 25, "check");
     u8g.drawStr( 0, 40, "if Ckt");
     u8g.drawStr( 0, 55, "Wiring");
     u8g.drawStr( 0, 70, "is OK !");
     u8g.drawStr( 0, 85, "or Not");
  } while( u8g.nextPage() );
}

void update_display_message_2(void)
{    
  
  u8g.firstPage();  
  do {
   u8g.setFont(u8g_font_7x13);  
   u8g.drawStr( 4, 40, "Adj");
   u8g.drawStr( 4, 55, "VOL:");   
   u8g.drawStr( 4, 110, "-  +");
   u8g.setFont(u8g_font_10x20);  
   u8g.setPrintPos(8, 90);u8g.print(volume);
 
  } while( u8g.nextPage() );



}


void update_display_message_3(void)
{
    u8g.firstPage();  
  do {
    u8g.setFont(u8g_font_7x13); 
    u8g.drawStr( 0, 10, "Set ");
    u8g.drawStr( 0, 25, "Count");
    u8g.drawStr( 0, 40, "Down");
    u8g.drawStr( 0, 55, "Timer");
    u8g.drawStr( 4, 110, "-  +");
    u8g.setFont(u8g_font_10x20); 
    u8g.setPrintPos(8,90 );u8g.print(number_index);
     
  } while( u8g.nextPage() );
delay(10);

}

void update_display_message_4(void)
{
    u8g.firstPage();  
  do {
    u8g.setFont(u8g_font_7x13); 
    u8g.drawStr( 0, 10, "Count");
    u8g.drawStr( 0, 25, "Down");
    u8g.drawStr( 0, 40, "Time");
    u8g.drawStr( 0, 55, "Left");
    
    u8g.setFont(u8g_font_10x20); 
    u8g.setPrintPos(5,90 );u8g.print(number_index);
     
  } while( u8g.nextPage() );
delay(10);

}

void update_display_message_5(void)
{
    u8g.firstPage();  
  do {
    u8g.setFont(u8g_font_6x12); 
    u8g.drawStr( 0, 10, "Trigg");
    u8g.drawStr( 0, 25, "Active");
    u8g.drawStr( 0, 40, "NOW!!");
    u8g.setFont(u8g_font_7x13); 
    u8g.drawStr( 0, 80, "&&&&");    
    u8g.drawStr( 0, 95, "FIRE");
    u8g.drawStr( 0, 105, "FIRE");
     
  } while( u8g.nextPage() );
delay(10);

}


void debounce_blinky(void)
{
  digitalWrite(BLUE_LED,HIGH);
  delay(25);  
  digitalWrite(BLUE_LED,LOW);
  delay(25);

}



void set_count_down_timer(void)
{
  while(digitalRead(BUTTON_SEL))
  {
    if(!digitalRead(BUTTON_DEC))
    {
      number_index--;
      debounce_blinky();
    }
    if(!digitalRead(BUTTON_INC))
    {
      number_index++;
      debounce_blinky();
    }
    if (number_index<0)   {number_index = 0;}
    if (number_index>100) {number_index = 100;}
    
    update_display_message_3();
  }
  
}

void trigger_event (void)
{
  digitalWrite(OUTPUT_PIN1,HIGH);
  delay(300);
  update_display_message_5();
  df1101s.playSpecFile(FIRE);
  digitalWrite(OUTPUT_PIN1,LOW);
  delay(2000);
  digitalWrite(OUTPUT_PIN2,HIGH);
  delay(300);
  digitalWrite(OUTPUT_PIN2,LOW);
  delay(200);
}
License
All Rights
Reserved
licensBg
1