-
-
Save nathandarnell/abaae0caf96efc16973dbdb3c1bdb615 to your computer and use it in GitHub Desktop.
Arduino Soundboard Project with DFPlayer mini
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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