commit bd6c7237c5c950e30c1532aba649973d706834ab Author: Arne van Iterson Date: Mon Sep 6 20:43:06 2021 +0200 Putting this on Gitea so I don't lose it diff --git a/README.md b/README.md new file mode 100644 index 0000000..177faa2 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# TI-84_DFPlayer +TI-84 Plus with inbuilt MP3 player using an ATtiny85 as a communication bridge. + +## Usage +- Put the `.ino` file on your MCU of choice, I used an ATtiny 85. +- Connect the DFPlayer to the MCU using the Serial port, use pins 0 (RX) and 1 (TX) on the ATtiny 85 +- Connect the calculator to the MCU using its serial connection, use pins 4 (TIP) and 3 (RING) on the ATtiny 85 +- Power the MCU using an external battery or steal power from the calculators batteries, you will need an external power switch and make a voltage devider +- Put music on the DFPlayers SD card +- Put DFPlayer.8xp on your calculator to control the DFPlayer +- Enjoy! \ No newline at end of file diff --git a/TI-84_DFPlayer.ino b/TI-84_DFPlayer.ino new file mode 100644 index 0000000..0687a60 --- /dev/null +++ b/TI-84_DFPlayer.ino @@ -0,0 +1,91 @@ +#include +#include +#include "CBL2.h" +#include "TIVar.h" + +CBL2 cbl; +SoftwareSerial SoftSerial(0, 1); // RX, TX +DFRobotDFPlayerMini DFPlayer; + +#define MAXDATALEN 32 +uint8_t header[16]; +uint8_t data[MAXDATALEN]; + +int onSendAsCBL2(uint8_t type, enum Endpoint model, int *headerlen, int *datalen, data_callback *data_callback); +int onGetAsCBL2(uint8_t type, enum Endpoint model, int datalen); + +void setup() +{ + SoftSerial.begin(9600); + DFPlayer.begin(SoftSerial); + DFPlayer.play(2); + + cbl.setLines(4, 3); + cbl.resetLines(); + cbl.setupCallbacks(header, data, MAXDATALEN, onGetAsCBL2, onSendAsCBL2); +} + +void loop() +{ + int rval; + rval = cbl.eventLoopTick(); + if (rval && rval != ERR_READ_TIMEOUT) + { + SoftSerial.print("eventLoopTick: error code "); + SoftSerial.println(rval); + } +} + +void sendtoDFP(short command, short parameter) +{ + switch (command) + { + case 1: + DFPlayer.next(); break; + + case 2: + DFPlayer.previous(); break; + + case 3: + DFPlayer.play(parameter); break; + + case 4: + DFPlayer.volumeUp(); break; + + case 5: + DFPlayer.volumeDown(); break; + + case 6: + DFPlayer.volume(parameter); break; + + case 8: + DFPlayer.randomAll(); break; + + case 13: + DFPlayer.start(); break; + + case 14: + DFPlayer.pause(); break; + + case 17: + DFPlayer.stop(); break; + } +} + +int onGetAsCBL2(uint8_t type, enum Endpoint model, int datalen) +{ + uint16_t list_len = TIVar::sizeWordToInt(&(data[0])); // Convert 2-byte size word to int + int size_of_real = TIVar::sizeOfReal(model); + + short cmd = TIVar::realToLong8x(&data[size_of_real * 0 + 2], model); // First list element starts after 2-byte size word + short parameter = TIVar::realToLong8x(&data[size_of_real * 1 + 2], model); + + sendtoDFP(cmd, parameter); + + return 0; +} + +int onSendAsCBL2(uint8_t type, enum Endpoint model, int *headerlen, int *datalen, data_callback *data_callback) +{ + return 0; +} diff --git a/TI/DFPlayer.8xp b/TI/DFPlayer.8xp new file mode 100644 index 0000000..652d0b3 Binary files /dev/null and b/TI/DFPlayer.8xp differ diff --git a/TI/DFPlayer.txt b/TI/DFPlayer.txt new file mode 100644 index 0000000..429d40a --- /dev/null +++ b/TI/DFPlayer.txt @@ -0,0 +1,60 @@ +0→N +0→L + +Lbl MM +WisHome +Menu("DFPlayer Mini","Play",PL,"Pause",PA,"Playback",PB,"Volume",V,"Quit",Q) + +Lbl PL +Send({13}) +Goto MM + +Lbl PA +Send({14}) +Goto MM + +Lbl PB +WisHome +Menu("Playback","Next",NE,"Previous",PR,"Stop",ST,"Shuffle",SH,"Select",SE,"Back",MM) + +Lbl NE +Send({1}) +Goto PB + +Lbl PR +Send({2}) +Goto PB + +Lbl ST +Send({17}) +Goto PB + +Lbl SH +Send({8}) +Goto PB + +Lbl SE +Input "Select song: ",N +Send({3,N}) +Goto PB + + +Lbl V +WisHome +Menu("Volume","Volume Up",VU,"Volume Down",VD,"Set",VS,"Back",MM) + +Lbl VU +Send({4}) +Goto V + +Lbl VD +Send({5}) +Goto V + +Lbl VS +Input "Set volume 1-30: ",L +Send({6,L}) +Goto V + +Lbl Q +Stop \ No newline at end of file