Design Files
Group Assignment
My original plan was to replicate the functions of the Bare Conductive Touchboard and use an SD card reader, amplifier and speaker to play MP3 files when the capacitive sensor is touched. During research, I discovered another way to play audio, using low-bitrate (8KHz) audio files. The benefit of this, is that the only hardware needed is a speaker attached to an Arduino, so would reduce costs.
I got the example code to work and updated the audio clip to me saying 'elephant'. I followed the guide at http://highlowtech.org/?p=1963:
However with more understanding of the system, it doesn't seem to be possible to add multiple audio clips because it is stored in the Arduino's Flash memory which is a lot smaller than using RAM. According to http://highlowtech.org/?p=1963 the arduino will be able to store approx. 4 seconds of audio. Also the program has been designed to be done with an Arduino Uno chip, and doesn't work with the ATMega32U4 because it only has 1x 8 bit timer whereas the code needs two.
So I moved away from the low-bitrate audio and researched how to play mp3 files on an Arduino. I kept coming across ways to do it with a shield, but for this assignment, I needed it to be more DIY and for the talking puzzle I need to keep within the grant budget. During my research, I discovered the DFPlayer Mini module and learnt the basics from the video below. I used the circuit layout from the video which is easier to see at http://educ8s.tv/arduino-mp3-player/ and found out more information about the module at https://www.dfrobot.com/blog-445.html
Continuous Audio
Result: Played audio files very quietly. When one audio clip ends, another one begins. Need to work out how to link a different track to each button and for it to play once and then stop.
Play Specific TracksDFMiniMp3 mp3(Serial1);
to turn the line into a comment and uncomment the lines SoftwareSerial secondarySerial(10, 11);
DFMiniMp3 mp3(secondarySerial);
mp3.playMp3FolderTrack(1);
Buttons
if(buttonstate4 == HIGH)
to == LOW
for each button. This is because the internal pull up resistor inverts the logic, so off = 1 (high) and on = 0 (low).This is the code I used to play specific tracks on the press of a button, with digital pullup resistors.
// it expects the sd card to contain these three mp3 files
// but doesn't care whats in them
//
// sd:/mp3/0001.mp3
// sd:/mp3/0002.mp3
// sd:/mp3/0003.mp3
const int buttonPin2 = 2; // the number of the pushbutton pin
const int buttonPin3 = 3; // the number of the pushbutton pin
const int buttonPin4 = 4; // the number of the pushbutton pin
const int ledPin = 13; // the number of the LED pin
int buttonState2 = 0; // variable for reading the pushbutton status
int buttonState3 = 0; // variable for reading the pushbutton status
int buttonState4 = 0; // variable for reading the pushbutton status
#include <SoftwareSerial.h>
#include <DFMiniMp3.h>
// implement a notification class,
// its member methods will get called
//
class Mp3Notify
{
public:
static void OnError(uint16_t errorCode)
{
// see DfMp3_Error for code meaning
Serial.println();
Serial.print("Com Error ");
Serial.println(errorCode);
}
static void OnPlayFinished(uint16_t globalTrack)
{
Serial.println();
Serial.print("Play finished for #");
Serial.println(globalTrack);
}
static void OnCardOnline(uint16_t code)
{
Serial.println();
Serial.print("Card online ");
Serial.println(code);
}
static void OnCardInserted(uint16_t code)
{
Serial.println();
Serial.print("Card inserted ");
Serial.println(code);
}
static void OnCardRemoved(uint16_t code)
{
Serial.println();
Serial.print("Card removed ");
Serial.println(code);
}
};
// instance a DFMiniMp3 object,
// defined with the above notification class and the hardware serial class
//
//DFMiniMp3<HardwareSerial, Mp3Notify> mp3(Serial1);
// Some arduino boards only have one hardware serial port, so a software serial port is needed instead.
// comment out the above definition and uncomment these lines
SoftwareSerial secondarySerial(10, 12); // RX, TX
DFMiniMp3<SoftwareSerial, Mp3Notify> mp3(secondarySerial);
void setup()
{
// initialize the LED pin as an output:
pinMode(ledPin, OUTPUT);
// initialize the pushbutton pin as an input:
pinMode(buttonPin2, INPUT_PULLUP);
pinMode(buttonPin3, INPUT_PULLUP);
pinMode(buttonPin4, INPUT_PULLUP);
Serial.begin(9600);
Serial.println("initializing...");
mp3.begin();
}
void loop() {
//read the pushbutton value into a variable
int sensorVal = digitalRead(2);
//print out the value of the pushbutton
Serial.println(sensorVal);
// read the state of the pushbutton value:
buttonState2 = digitalRead(buttonPin2);
buttonState3 = digitalRead(buttonPin3);
buttonState4 = digitalRead(buttonPin4);
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (buttonState2 == LOW) {
// turn LED on:
digitalWrite(ledPin, HIGH);
// play track 1:
Serial.println("track 1");
mp3.playMp3FolderTrack(1); // sd:/mp3/0001.mp3
} else {
// turn LED off:
digitalWrite(ledPin, LOW);
}
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (buttonState3 == LOW) {
// turn LED on:
digitalWrite(ledPin, HIGH);
// play track 2:
Serial.println("track 2");
mp3.playMp3FolderTrack(2); // sd:/mp3/0002.mp3
} else {
// turn LED off:
digitalWrite(ledPin, LOW);
}
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (buttonState4 == LOW) {
// turn LED on:
digitalWrite(ledPin, HIGH);
// play track 3:
Serial.println("track 3");
mp3.playMp3FolderTrack(3); // sd:/mp3/0003.mp3
} else {
// turn LED off:
digitalWrite(ledPin, LOW);
}
}
Move components over to Leonardo
I tested the DFPLayer with an Arduino Uno, because it makes it easier to troubleshoot by using the same board as the example I'm following. However the board I made in Inputs week has the same microcontroller as an Arduino Leonardo, so I moved the components over to a Leonardo and luckily the code worked using the same pins as the Uno.
Adding components to my milled boardUsing the ATMega32U4 pinout diagram, the Eagle Schematic of my board and the current circuit layout of the button/mp3 setup on the Arduino Leonardo, I mapped out a circuit diagram to add the DFPlayer to my board.
The current set up on the Arduino Leonardo uses digital pin 11 to connect to the RX pin on the DFPlayer module, but my board has no copper trace coming out of digital pin 11, so I tried changing it to pin 12 which is accessible and it worked. It just required a change in the code from
SoftwareSerial secondarySerial(10, 11);
to SoftwareSerial secondarySerial(10, 12);
This section is part of my final project here.