#include <SPI.h>
#include "Adafruit_GFX.h" // Core graphics library
#include "Adafruit_HX8357.h"
#include "Adafruit_SPITFT.h" // Hardware-specific library
#include <Fonts/FreeSansBold12pt7b.h>
#include <Bounce.h>
#include <Audio.h>
#include <Wire.h>
#include <SD.h>
#include <SerialFlash.h>
Bounce button1 = Bounce(24, 15); //Pin number, debounce time.
Bounce button2 = Bounce(25, 15); //15 = 15 ms debounce time
Bounce button3 = Bounce(27, 15);
Bounce button4 = Bounce(28, 15);
Bounce button5 = Bounce(29, 15);
Bounce button6 = Bounce(30, 15);
Bounce button7 = Bounce(31, 15);
Bounce button8 = Bounce(32, 15);
// GUItool: begin automatically generated code
AudioPlaySdWav playSdWav1; //xy=138,160
AudioPlaySdWav playSdWav2; //xy=146,263
AudioInputI2S i2s2; //xy=148,353
AudioMixer4 mixer1; //xy=366,207
AudioMixer4 mixer2; //xy=366,296
AudioOutputI2S i2s1; //xy=563,257
AudioConnection patchCord1(playSdWav1, 0, mixer1, 0);
AudioConnection patchCord2(playSdWav1, 1, mixer2, 0);
AudioConnection patchCord3(playSdWav2, 0, mixer1, 1);
AudioConnection patchCord4(playSdWav2, 1, mixer2, 1);
AudioConnection patchCord5(i2s2, 0, mixer1, 2);
AudioConnection patchCord6(i2s2, 1, mixer2, 2);
AudioConnection patchCord7(mixer1, 0, i2s1, 0);
AudioConnection patchCord8(mixer2, 0, i2s1, 1);
AudioControlSGTL5000 sgtl5000_1; //xy=362,444
// GUItool: end automatically generated code
//46, 45, 44 SCK, MISO, MOSI
//These are 'flexible' lines that can be changed
#define TFT_CS 43 //ALTERNATE (Default 10)
#define TFT_DC 54 //ALTERNATE (Default 9)
#define TFT_RST -1 // RST can be set to -1 if you tie it to Arduino's reset (Was set to 8)
#define WHITE 0xFFFF
#define BLACK 0x0000
// Use these with the Teensy Audio Shield
#define SDCARD_CS_PIN 10
#define SDCARD_MOSI_PIN 7
#define SDCARD_SCK_PIN 14
// 0x4B is the default i2c address
#define MAX9744_I2CADDR 0x4B
int thevol = 31;
int mgain = 18;
int brtness = 25;
int YGridPos = 2;
int XGridPos = 2;
int YGridPosPrev = 2;
int XGridPosPrev = 2;
int stringnum = 1;
int TextHeight = 23;
int CatHeight = 25;
int Row1Height = 98;
int Row2Height = 97;
const char* cellstrings[]={
"-", //Null Row 1, 0
"-", //Null Row 1, 1
"-", //Null Row 1, 2
"-", //Null Row 1, 3
"-", //Null Row 1, 4
"-", //Null Row 2, 5
"Cell1", //File 1 - Row 2, Col 2, #6
"Cell2", //File 2 - Row 2, Col 3, #7
"Cell3", //File 3 - Row 2, Col 4, #8
"-", //Null Row 2
"-", //Null Row 3
"Cell4", //File 4 - Row 3, Col 2, #11
"Cell5", //File 5 - Row 3, Col 3, #12
"Cell6", //File 6 - Row 3, Col 4, #13
"-", //Null Row 3
"-", //Null Row 4
"Cell7", //File 17 - Row 4, Col 2, #16
"Cell8", //File 18 - Row 4, Col 3, #17
"Cell9", //File 19 - Row 4, Col 4, #18
"-", //Null Row 4
"-", //Null Row 5
"-", //Null Row 5
"-", //Null Row 5
"-", //Null Row 5
"-", //Null Row 5
};
const char* CatStrings[]={
"-",
"Cat1",
"Cat2",
"Cat3",
"-",
};
// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
//Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC, TFT_RST);
// SoftSPI - note that on some processors this might be *faster* than hardware SPI!
//Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC, MOSI, SCK, TFT_RST, MISO);
Adafruit_HX8357 tft = Adafruit_HX8357(TFT_CS, TFT_DC, 44, 46, TFT_RST, 45);
//SPISettings TFTSPI(1000000, MSBFIRST, SPI_MODE0); // 1Mhz? Mode 0, 1, 2 or 3?
void setup() {
Serial.begin(9600);
Serial.println("Begin");
Wire.begin();
sgtl5000_1.enable();
sgtl5000_1.volume(0.8);
sgtl5000_1.inputSelect(AUDIO_INPUT_MIC); //Select mic source for audio shield
sgtl5000_1.micGain(mgain); //Set initial gain. Range 0-63dB.
//Turn off ADC high pass filter to reduce noise level
sgtl5000_1.adcHighPassFilterDisable();
pinMode(35, OUTPUT); //PWM Output
pinMode(24, INPUT_PULLUP); //PUSH-TO-TALK Button
pinMode(25, INPUT_PULLUP); //STOP
pinMode(27, INPUT_PULLUP); //PLAY
pinMode(28, INPUT_PULLUP); //PRESS 5-Way Switch - Settings Screen
pinMode(29, INPUT_PULLUP); //RIGHT Nav Screen
pinMode(30, INPUT_PULLUP); //LEFT Nav Screen
pinMode(31, INPUT_PULLUP); //DOWN Nav Screen
pinMode(32, INPUT_PULLUP); //UP Nav Screen
// TFT Screen Setup
tft.begin(HX8357D);
tft.setRotation(3);
tft.setFont(&FreeSansBold12pt7b);
tft.setTextColor(WHITE);
tft.setTextSize(1);
tft.fillScreen(BLACK);
tft.drawFastVLine(159, 0, 319, WHITE);
tft.drawFastVLine(320, 0, 319, WHITE);
tft.drawFastHLine(0, (CatHeight), 479, WHITE);
tft.drawFastHLine(0, (CatHeight+Row1Height+1), 479, WHITE);
tft.drawFastHLine(0, (CatHeight+Row1Height+Row2Height+2), 479, WHITE);
SPI.setMOSI(SDCARD_MOSI_PIN);
SPI.setSCK(SDCARD_SCK_PIN);
if (!(SD.begin(SDCARD_CS_PIN))) {
// stop here, but print a message repetitively
while (1) {
Serial.println("Unable to access the SD card");
delay(500);
}
}
//Manually define TFT SPI settings?
//SPI2.setMOSI(44);
//SPI2.setMISO(45);
//SPI2.setSCK(46);
//SPI2.begin();
//delayMicroseconds(100000);
tft.setCursor(0, (TextHeight));
tft.println("PLACEHOLDER");
}
void loop() {
button1.update(); //Read bounced buttons
button2.update();
button3.update();
button4.update();
button5.update();
button6.update();
button7.update();
button8.update();
if (button8.fallingEdge()) { //UP
Serial.println("UP");
if ((YGridPos = 1)) {} //Do nothing if YPos is already min (1)
else {
YGridPos = YGridPos - 1;
}
}
if (button7.fallingEdge()) { //DOWN
Serial.println("DOWN");
if ((YGridPos = 3)) {} //Do nothing if YPos is already max (3)
else {
YGridPos = YGridPos + 1;
}
}
if (button6.fallingEdge()) { //LEFT
Serial.println("LEFT");
if ((XGridPos = 1)) {} //Do nothing if XPos is already min (1)
else {
XGridPos = XGridPos - 1;
}
}
if (button5.fallingEdge()) { //RIGHT
Serial.println("RIGHT");
if ((XGridPos = 3)) {} //Do nothing if XPos is already max (3)
else {
XGridPos = XGridPos + 1;
}
}
if (button4.fallingEdge()) { //PRESS
Serial.println("PRESS");
settingsMenu();
YGridPosPrev = 0; //Fake change to force screen re-draw
XGridPosPrev = 0;
}
if (button3.fallingEdge()) {
Serial.println("PLAY");
if (playSdWav1.isPlaying() == 1) {
if (playSdWav2.isPlaying() == 1) {}
else {
playFile1("TEST1.WAV"); // filenames are always uppercase 8.3 format
Serial.println("TEST1.WAV");
}
}
else {
playFile2("TEST2.WAV");
Serial.println("TEST2.WAV");
}
}
if (button2.fallingEdge()) {
Serial.println("STOP");
if (playSdWav2.isPlaying() == 1) { //If Wav2 is playing...
playSdWav2.stop();
Serial.println("STOP2");
}
else if (playSdWav1.isPlaying() == 1) {
playSdWav1.stop();
Serial.println("STOP1");
}
}
//if (digitalRead(26) == LOW) {
// Serial.println("MIC ACTIVATE");
// MicPTT();
// mixer1.gain(0, 0.5);
// mixer1.gain(1, 0.5);
// mixer1.gain(2, 0);
// mixer2.gain(0, 0.5);
// mixer2.gain(1, 0.5);
// mixer2.gain(2, 0);
//}
if ((YGridPos == YGridPosPrev) & (XGridPos == XGridPosPrev)){
Serial.println("No change X or Y");
}
//Increment "no change" counter? Display YoRHa bitmap? bmpDraw(bmpfilename, x, y); (24-bit BMP)
else {
Serial.println("Refresh screen");
//tft.fillScreen(BLACK);
tft.fillRect(0, 0, 480, 320, BLACK);
tft.drawFastVLine(159, 0, 319, WHITE);
tft.drawFastVLine(320, 0, 319, WHITE);
Serial.println("CatHeight");
Serial.println(CatHeight);
Serial.println("RowHeight1");
Serial.println(Row1Height);
Serial.println("RowHeight2");
Serial.println(Row2Height);
tft.drawFastHLine(0, (CatHeight), 479, WHITE);
tft.drawFastHLine(0, (CatHeight+Row1Height+1), 479, WHITE);
tft.drawFastHLine(0, (CatHeight+Row1Height+Row2Height+2), 479, WHITE);
if ((XGridPos == XGridPosPrev)){}
else {
//tft.fillRect(0, 0, 158, (CatHeight-1), BLACK);
//tft.fillRect(160, 0, 319, (CatHeight-1), BLACK);
//tft.fillRect(321, 0, 479, (CatHeight-1), BLACK);
tft.setCursor(0, (TextHeight));
tft.println(CatStrings[(XGridPos-1)]);
Serial.println("CatStrings X-1: ");
Serial.println(CatStrings[(XGridPos-1)]);
tft.setCursor(160, (TextHeight));
tft.println(CatStrings[(XGridPos)]);
tft.setCursor(321, (TextHeight));
tft.println(CatStrings[(XGridPos+1)]);
}
stringnum = ((YGridPos * 5) + XGridPos);
//tft.fillRect(0,(CatHeight+1), 158,(CatHeight+Row1Height), BLACK);
//tft.fillRect(0,(CatHeight+Row1Height+2), 158,(CatHeight+Row1Height+Row2Height+1), BLACK);
//tft.fillRect(0,(CatHeight+Row1Height+Row2Height+3), 158, 319, BLACK);
//tft.fillRect(160, (CatHeight+1), 319, (CatHeight+Row1Height), BLACK);
//tft.fillRect(160, (CatHeight+Row1Height+2), 319, (CatHeight+Row1Height+Row2Height+1), BLACK);
//tft.fillRect(160, (CatHeight+Row1Height+Row2Height+3), 319, 319, BLACK);
//tft.fillRect(321, (CatHeight+1), 479, (CatHeight+Row1Height), BLACK);
//tft.fillRect(321, (CatHeight+Row1Height+2), 479, (CatHeight+Row1Height+Row2Height+1), BLACK);
//tft.fillRect(321, (CatHeight+Row1Height+Row2Height+3), 479, 319, BLACK);
tft.setCursor(0, (CatHeight+TextHeight+1));
tft.println(cellstrings[(stringnum - 6)]);
tft.setCursor(160, (CatHeight+TextHeight+1));
tft.println(cellstrings[(stringnum - 5)]);
tft.setCursor(321, (CatHeight+TextHeight+1));
tft.println(cellstrings[(stringnum - 4)]);
tft.setCursor(0, (CatHeight+Row1Height+TextHeight+2));
tft.println(cellstrings[(stringnum - 1)]);
tft.setCursor(160, (CatHeight+Row1Height+TextHeight+2));
tft.println(cellstrings[(stringnum)]);
tft.setCursor(321, (CatHeight+Row1Height+TextHeight+2));
tft.println(cellstrings[(stringnum + 1)]);
tft.setCursor(0, (CatHeight+Row1Height+Row2Height+TextHeight+3));
tft.println(cellstrings[(stringnum + 4)]);
tft.setCursor(160, (CatHeight+Row1Height+Row2Height+TextHeight+3));
tft.println(cellstrings[(stringnum + 5)]);
tft.setCursor(321, (CatHeight+Row1Height+Row2Height+TextHeight+3));
tft.println(cellstrings[(stringnum + 6)]);
}
//Serial.println("X, Y, Prevs");
//Serial.println(XGridPos);
//Serial.println(YGridPos);
//Serial.println(XGridPosPrev);
//Serial.println(YGridPosPrev);
YGridPosPrev = YGridPos;
XGridPosPrev = XGridPos;
//Serial.println("X, Y, Prevs");
//Serial.println(XGridPos);
//Serial.println(YGridPos);
//Serial.println(XGridPosPrev);
//Serial.println(YGridPosPrev);
delay(500);
}
void settingsMenu() {
Serial.println("SettingsMenu");
tft.fillScreen(BLACK);
//Set Text Size?
//Print Settings Labels
tft.setCursor(45, 154);
tft.println("VOL 0-63");
tft.setCursor(183, 154);
tft.println("BRT 25-255");
tft.setCursor(345, 154);
tft.println("MIC 0-63");
//Print current settings values
tft.setCursor(77, 194);
tft.println(thevol);
tft.setCursor(227, 194);
tft.println(brtness);
tft.setCursor(377, 194);
tft.println(mgain);
//Draw Triangle vol up/down indicators. x0,y0 = left, x1,y1 = top/bottom point, x2,y2 = right corner.
//void drawTriangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
//void fillTriangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
tft.fillTriangle(29, 99, 89, 19, 149, 99, WHITE); //Up and down arrows (6 total, white with black fill)
tft.fillTriangle(179, 99, 239, 19, 299, 99, WHITE);
tft.fillTriangle(329, 99, 389, 19, 449, 99, WHITE);
tft.fillTriangle(29, 219, 89, 299, 149, 219, WHITE);
tft.fillTriangle(179, 219, 239, 299, 299, 219, WHITE);
tft.fillTriangle(329, 219, 389, 299, 449, 219, WHITE);
tft.fillTriangle(32, 97, 89, 22, 146, 97, BLACK); //Black fill in white triangles
tft.fillTriangle(182, 97, 239, 22, 296, 97, BLACK);
tft.fillTriangle(332, 97, 389, 22, 446, 97, BLACK);
tft.fillTriangle(32, 221, 89, 296, 146, 221, BLACK);
tft.fillTriangle(182, 221, 239, 296, 296, 221, BLACK);
tft.fillTriangle(332, 221, 389, 296, 446, 221, BLACK);
int settingsSelect = 2;
//Draw initial box around middle option
tft.drawRect(179, 119, 120, 80, WHITE);
while (digitalRead(28) == HIGH) {
Serial.println("WHILE LOOP");
delay(500);
button4.update();
button5.update();
button6.update();
button7.update();
button8.update();
if (settingsSelect > 3) { //Keep value in bounds in case of craziness
settingsSelect = 3;
}
if (settingsSelect < 1) {
settingsSelect = 1;
}
if (button8.fallingEdge()) { //UP
Serial.println("UP");
if (settingsSelect == 1) {
if (thevol == 63) {}
else {
thevol = thevol + 1;
setvolume(thevol);
tft.fillRect(75, 159, 50, 37, BLACK);
tft.setCursor(77, 194);
tft.println(thevol);
}
}
else if (settingsSelect == 2) {
if (brtness == 255) {} //0-255 PWM
else {
brtness = brtness + 5;
analogWrite(35, brtness);
tft.fillRect(225, 159, 50, 37, BLACK);
tft.setCursor(227, 194);
tft.println(brtness);
}
}
else if (settingsSelect == 3) {
if (mgain == 63) {}
else {
mgain = mgain + 1;
sgtl5000_1.micGain(mgain);
tft.fillRect(375, 159, 50, 37, BLACK);
tft.setCursor(377, 194);
tft.println(mgain);
}
}
}
if (button7.fallingEdge()) { //DOWN
Serial.println("DOWN");
if (settingsSelect == 1) {
if (thevol == 0) {}
else {
thevol = thevol - 1;
setvolume(thevol);
tft.fillRect(75, 159, 50, 37, BLACK);
tft.setCursor(77, 194);
tft.println(thevol);
}
}
else if (settingsSelect == 2) {
if (brtness == 25) {} //25 is about ~10% brightness (0-255)
else {
brtness = brtness - 5;
analogWrite(35, brtness);
tft.fillRect(225, 159, 50, 37, BLACK);
tft.setCursor(227, 194);
tft.println(brtness);
}
}
else if (settingsSelect == 3) {
if (mgain == 0) {}
else {
mgain = mgain - 1;
sgtl5000_1.micGain(mgain);
tft.fillRect(375, 159, 50, 37, BLACK);
tft.setCursor(377, 194);
tft.println(mgain);
}
}
}
if (button6.fallingEdge()) { //LEFT
Serial.println("LEFT");
if (settingsSelect == 1) {} //Do nothing if farthest left (Vol)
else {
Serial.println("CLEAR/REDRAW RECT");
if (settingsSelect == 2) {
tft.fillRect(179, 119, 120, 80, BLACK);
tft.setCursor(183, 154);
tft.println("BRT 25-255");
tft.setCursor(227, 194);
tft.println(brtness);
tft.drawRect(29, 119, 120, 80, WHITE);
settingsSelect = settingsSelect - 1;
}
else {
tft.fillRect(329, 119, 120, 80, BLACK);
tft.setCursor(345, 154);
tft.println("MIC 0-63");
tft.setCursor(377, 194);
tft.println(mgain);
tft.drawRect(179, 119, 120, 80, WHITE);
settingsSelect = settingsSelect - 1;
}
//tft.drawRect((29 + (150 * settingsSelect)), 119, 120, 80, BLACK); //Black-out current box
//settingsSelect = settingsSelect - 1;
//tft.drawRect((29 + (150 * settingsSelect)), 119, 120, 80, WHITE); //Draw new box
}
}
if (button5.fallingEdge()) { //RIGHT
Serial.println("RIGHT");
if (settingsSelect == 3) {} //Do nothing if farthest right (Mic Gain)
else {
Serial.println("CLEAR/REDRAW RECT");
if (settingsSelect == 1) {
tft.fillRect(29, 119, 120, 80, BLACK);
tft.setCursor(45, 154);
tft.println("VOL 0-63");
tft.setCursor(77, 194);
tft.println(thevol);
tft.drawRect(179, 119, 120, 80, WHITE);
settingsSelect = settingsSelect + 1;
}
else {
tft.fillRect(179, 119, 120, 80, BLACK);
tft.setCursor(183, 154);
tft.println("BRT 25-255");
tft.setCursor(227, 194);
tft.println(brtness);
tft.drawRect(329, 119, 120, 80, WHITE);
settingsSelect = settingsSelect + 1;
}
//tft.drawRect((29 + (150 * settingsSelect)), 119, 120, 80, BLACK); //Black-out current box
//settingsSelect = settingsSelect + 1;
//tft.drawRect((29 + (150 * settingsSelect)), 119, 120, 80, WHITE); //Draw new box
}
}
}
//Reset Text Size?
}
boolean setvolume(int v) {
// cant be higher than 63 or lower than 0
if (v > 63) v = 63;
if (v < 0) v = 0;
Serial.print("Setting volume to ");
Serial.println(v);
Wire.beginTransmission(MAX9744_I2CADDR);
Wire.write(v);
if (Wire.endTransmission() == 0)
return true;
else
return false;
}
void playFile1(const char *filename)
{
Serial.print("Playing file: ");
Serial.println(filename);
// Start playing the file. This sketch continues to
// run while the file plays.
playSdWav1.play(filename);
delay(5);
}
void playFile2(const char *filename)
{
Serial.print("Playing file: ");
Serial.println(filename);
playSdWav2.play(filename);
delay(5);
}
void MicPTT() {
while (digitalRead(24) == LOW) {
mixer1.gain(0, 0.33);
mixer1.gain(1, 0.33);
mixer1.gain(2, 0.33);
mixer2.gain(0, 0.33);
mixer2.gain(1, 0.33);
mixer2.gain(2, 0.33);
Serial.println("MIC ON");
delay(500);
}
}