Skip to content

Instantly share code, notes, and snippets.

@hdo
Created August 15, 2017 14:22
Show Gist options
  • Save hdo/c97a4d7c866c61db902fefb7ab28a57f to your computer and use it in GitHub Desktop.
Save hdo/c97a4d7c866c61db902fefb7ab28a57f to your computer and use it in GitHub Desktop.
Arduino Soundboard Project with DFPlayer mini
#include <Arduino.h>
#define BUTTON_COUNT 36
#define KEYPAD_OUTPUT_BEGIN 2
#define KEYPAD_OUTPUT_END 7
#define KEYPAD_INPUT_BEGIN 8
#define KEYPAD_INPUT_END 13
uint8_t keypad_button_pressed[BUTTON_COUNT];
volatile uint32_t ticks;
uint32_t lastTrigger, lastTriggerFrontButton;
uint8_t index = 1;
uint8_t volume = 25;
//uint8_t cmd_01[10] = {0x7E, 0xFF, 0x06, 0x03, 0x00, 0x00, 0x01, 0xFF, 0xE6, 0xEF};
uint8_t cmd_play_num[10] = {0x7E, 0xFF, 0x06, 0x03, 0x00, 0x00, 0x01, 0xFF, 0xE6, 0xEF};
//uint8_t cmd_next[10] = {0x7E, 0xFF, 0x06, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xE6, 0xEF};
uint8_t cmd_stop[10] = {0x7E, 0xFF, 0x06, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF};
uint8_t cmd_set_vol[10] = {0x7E, 0xFF, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEF};
ISR(TIMER0_COMPA_vect, ISR_BLOCK) {
ticks++;
}
void init_systicks() {
TCCR0B = _BV(CS02) | _BV(CS00);
TCCR0A = _BV(WGM01);
TIMSK0 = _BV(OCIE0A);
// 8000000/1024/78 == 100HZ -> 10 ms
OCR0A = 77; // !!! must me set last or it will not work!
}
uint32_t math_calc_diff(uint32_t value1, uint32_t value2) {
if (value1 == value2) {
return 0;
}
if (value1 > value2) {
return (value1 - value2);
}
else {
// check for overflow
return (0xffffffff - value2 + value1);
}
}
void keypad_reset_output() {
// configure pull ups
digitalWrite(2, HIGH);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);
}
void clear_buttons() {
for(int i=0; i < BUTTON_COUNT; i++) {
keypad_button_pressed[i] = 0;
}
}
void keypad_setup() {
// initialize the digital pin as an output:
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
keypad_reset_output();
pinMode(8, INPUT);
pinMode(9, INPUT);
pinMode(10, INPUT);
pinMode(11, INPUT);
pinMode(12, INPUT);
pinMode(13, INPUT);
// configure pull ups
digitalWrite(8, HIGH);
digitalWrite(9, HIGH);
digitalWrite(10, HIGH);
digitalWrite(11, HIGH);
digitalWrite(12, HIGH);
digitalWrite(13, HIGH);
}
// the loop() method runs over and over again,
// as long as the Arduino has power
void keypad_read_buttons() {
clear_buttons();
uint8_t y=0;
for(int i=KEYPAD_OUTPUT_BEGIN; i <= KEYPAD_OUTPUT_END; i++) {
keypad_reset_output();
digitalWrite(i, LOW);
uint8_t x=0;
for(int j=KEYPAD_INPUT_BEGIN; j <= KEYPAD_INPUT_END; j++) {
if (digitalRead(j) == LOW) {
uint8_t index = x+6*y;
keypad_button_pressed[index] = 1;
}
x++;
}
y++;
}
}
uint8_t keypad_button_is_pressed() {
for (int i=0; i < BUTTON_COUNT; i++) {
if (keypad_button_pressed[i]) {
return 1;
}
}
return 0; // no button pressed
}
void send_cmd(uint8_t* cmdbuf) {
//calc checksum (1~6 byte)
uint16_t sum = 0;
for (int i=1; i<7; i++) {
sum += cmdbuf[i];
}
sum=-sum;
cmdbuf[7] = sum >> 8;
cmdbuf[8] = sum & 0xFF;
Serial.write(cmdbuf, 10);
/*
for(int i=0; i < 10;i++) {
Serial.print((char) cmd[i]);
}*/
// print(char*) will not work due to 0-termination
//Serial.print((char*) cmd);
}
void play_track(uint8_t num) {
cmd_play_num[6] = num;
send_cmd(cmd_play_num);
}
void set_volume() {
cmd_set_vol[6] = volume;
send_cmd(cmd_set_vol);
}
// The setup() method runs once, when the sketch starts
void setup() {
init_systicks();
keypad_setup();
// setup stop, vol down, vol up buttons
pinMode(A0, INPUT);
pinMode(A1, INPUT);
pinMode(A2, INPUT);
digitalWrite(A0, HIGH);
digitalWrite(A1, HIGH);
digitalWrite(A2, HIGH);
Serial.begin(9600);
}
// the loop() method runs over and over again,
// as long as the Arduino has power
void loop() {
keypad_read_buttons();
// allow button processing only every 300ms (30 systicks)
if (keypad_button_is_pressed() && (math_calc_diff(ticks, lastTrigger) > 30)) {
lastTrigger = ticks;
for(int i=0; i < BUTTON_COUNT; i++) {
if (keypad_button_pressed[i]) {
play_track(i+1);
break;
}
}
}
if (math_calc_diff(ticks, lastTriggerFrontButton) > 15) {
lastTriggerFrontButton = ticks;
// stop button
if (digitalRead(A0) == LOW) {
// send stop
send_cmd(cmd_stop);
}
if (digitalRead(A1) == LOW) {
// send vol down
if (volume > 1) {
volume--;
set_volume();
}
}
if (digitalRead(A2) == LOW) {
// send vol up
if (volume < 30) {
volume++;
set_volume();
}
}
}
delay(1);
}
int main(void) {
init();
setup();
set_volume();
while (true) {
loop();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment