Cleaned up code and added features

This commit is contained in:
Arne van Iterson 2020-05-29 16:16:58 +02:00
parent ed1bc1fdb4
commit 51b45c2ca7
4 changed files with 262 additions and 158 deletions

3
res/data.json Normal file
View File

@ -0,0 +1,3 @@
{
"device-id": "1A86:7523"
}

View File

@ -5,10 +5,16 @@
#include <Button.h> #include <Button.h>
#include <Encoder.h> #include <Encoder.h>
Adafruit_PCD8544 display = Adafruit_PCD8544(14, 15, 16, 17, 18); #include "logo.h"
Button button(4); // SCLK, DIN, D/C, SCE, RST
Encoder encoder(3, 2); // 10k, 10k, 10k, 1k, 10k
Adafruit_PCD8544 display = Adafruit_PCD8544(8, 9, 19, 17, 18);
Button button1(4);
Button button2(6);
Button button3(7);
Encoder encoder(2, 3);
// General vars // General vars
unsigned long time; unsigned long time;
@ -23,27 +29,31 @@ long position = 0;
// Serial related vars // Serial related vars
const byte numChars = 32; const byte numChars = 32;
char receivedChars[numChars]; char receivedChars[numChars];
char tempChars[numChars]; char tempChars[numChars];
char command[numChars] = {0}; char command[numChars] = {0};
boolean newData = false; boolean newData = false;
// Screen related vars
int light = 128;
int contrast = 60;
int lightTimeout = 10;
// Set backlight void setBacklight(int value)
boolean light = 0; {
int timeout = 10000; analogWrite(5, value);
if (value != 0)
void toggleBacklight(int value = 128) { {
if (light) { light = value;
analogWrite(5, 0);
light = 0;
} else {
analogWrite(5, value);
light = 1;
} }
} }
void setContrast(int value)
{
display.setContrast(value);
contrast = value;
}
// Set variables for menu // Set variables for menu
int programLenght; int programLenght;
int currentProgram = 0; int currentProgram = 0;
@ -52,7 +62,8 @@ boolean menuUpdate = true;
float volume = -1; float volume = -1;
// Draw screen // Draw screen
void drawMenu() { void drawMenu()
{
display.clearDisplay(); display.clearDisplay();
display.setFont(&Picopixel); display.setFont(&Picopixel);
@ -71,33 +82,40 @@ void drawMenu() {
display.setFont(NULL); display.setFont(NULL);
// Check for connection // Check for connection
if (connected && dataReady) { if (connected && dataReady)
{
// Program name // Program name
drawName(); drawName();
// Volume Bar // Volume Bar
drawBar(); drawBar();
} else { }
else
{
// Blink connection message if not connected // Blink connection message if not connected
if (time % 500 == 0) if (time % 500 == 0)
{ {
blink = (!blink) ? true : false; blink = (!blink) ? true : false;
} }
display.drawBitmap(0, 7, logo, 84, 16, 1);
display.setFont(&Picopixel);
if (!blink) if (!blink)
{ {
display.setCursor(9, 10);
display.print("Waiting for");
if (!connected) if (!connected)
{ {
display.setCursor(12, 18); display.setCursor(4, 28);
display.print("Connection"); display.print("Waiting for connection");
} else if (!dataReady) }
else if (!dataReady)
{ {
display.setCursor(30, 18); display.setCursor(15, 28);
display.print("Data"); display.print("Waiting for data");
} }
} }
display.setFont(NULL);
} }
// Bottom Bar // Bottom Bar
@ -108,7 +126,9 @@ void drawMenu() {
if (editing) if (editing)
{ {
display.print(" - OK + "); display.print(" - OK + ");
} else { }
else
{
display.print(" < OK > "); display.print(" < OK > ");
} }
} }
@ -117,10 +137,11 @@ void drawMenu() {
} }
// Bar position // Bar position
const int pos[2] = { 4, 26 }; const int pos[2] = {4, 26};
// Draw volume bar and text // Draw volume bar and text
void drawBar() { void drawBar()
{
// Set fonts and size // Set fonts and size
display.setFont(&Picopixel); display.setFont(&Picopixel);
display.setCursor(4, pos[1] - 2); display.setCursor(4, pos[1] - 2);
@ -133,11 +154,16 @@ void drawBar() {
} }
// Center percentage // Center percentage
if (volume == 0) { if (volume == 0)
{
display.setCursor(39, pos[1] - 2); display.setCursor(39, pos[1] - 2);
} else if (volume == 100) { }
else if (volume == 100)
{
display.setCursor(36, pos[1] - 2); display.setCursor(36, pos[1] - 2);
} else { }
else
{
display.setCursor(37, pos[1] - 2); display.setCursor(37, pos[1] - 2);
} }
@ -159,7 +185,8 @@ void drawBar() {
} }
// Draw program name in the middle of the display or scroll it // Draw program name in the middle of the display or scroll it
void drawName() { void drawName()
{
int width = 0; int width = 0;
for (size_t i = 0; i < sizeof(programName); i++) for (size_t i = 0; i < sizeof(programName); i++)
{ {
@ -172,163 +199,204 @@ void drawName() {
if (width > 84) if (width > 84)
{ {
// TODO: Make the text scroll if the name is too long // TODO: Make the text scroll if the name is too long
} else { }
else
{
int x = (84 / 2) - (width / 2); int x = (84 / 2) - (width / 2);
display.setCursor(x, 10); display.setCursor(x, 10);
} }
display.print(programName); display.print(programName);
} }
void processData() { void processData()
if (newData == true) { {
strcpy(tempChars, receivedChars); if (newData == true)
{
char * strtokIndx; strcpy(tempChars, receivedChars);
strtokIndx = strtok(tempChars,","); char *strtokIndx;
strcpy(command, strtokIndx);
strtokIndx = strtok(NULL, ",");
if (strcmp("HELLO", command) == 0) strtokIndx = strtok(tempChars, ",");
{ strcpy(command, strtokIndx);
connected = true;
Serial.println("<OK>");
Serial.println("<COUNT>");
Serial.println("<SWITCH," + (String)currentProgram + ">");
}
else if (strcmp("COUNT", command) == 0)
{
programLenght = atoi(strtokIndx);
Serial.println("<OK>");
}
else if (strcmp("CURRENT", command) == 0)
{
currentProgram = atoi(strtokIndx);
Serial.println("<OK>");
}
else if (strcmp("NAME", command) == 0)
{
strcpy(programName, strtokIndx);
Serial.println("<OK>");
}
else if (strcmp("GETVOL", command) == 0)
{
volume = atoi(strtokIndx);
Serial.println("<OK>");
}
newData = false; strtokIndx = strtok(NULL, ",");
dataReady = true;
if (strcmp("HELLO", command) == 0)
{
connected = true;
Serial.println("<OK>");
Serial.println("<COUNT>");
Serial.println("<SWITCH," + (String)currentProgram + ">");
} }
else if (strcmp("COUNT", command) == 0)
{
programLenght = atoi(strtokIndx);
Serial.println("<OK>");
}
else if (strcmp("CURRENT", command) == 0)
{
currentProgram = atoi(strtokIndx);
Serial.println("<OK>");
}
else if (strcmp("NAME", command) == 0)
{
strcpy(programName, strtokIndx);
Serial.println("<OK>");
}
else if (strcmp("GETVOL", command) == 0)
{
volume = atoi(strtokIndx);
Serial.println("<OK>");
}
newData = false;
dataReady = true;
}
} }
void checkSerial() { void checkSerial()
static boolean recvInProgress = false; {
static byte ndx = 0; static boolean recvInProgress = false;
char startMarker = '<'; static byte ndx = 0;
char endMarker = '>'; char startMarker = '<';
char rc; char endMarker = '>';
char rc;
while (Serial.available() > 0 && newData == false) { while (Serial.available() > 0 && newData == false)
rc = Serial.read(); {
rc = Serial.read();
if (recvInProgress == true) { if (recvInProgress == true)
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
processData();
}
// Check for button input
// TODO: Improve encoder input
void checkInput(unsigned long time) {
long newPosition = encoder.read();
if (newPosition != position) {
menuUpdate = true;
if (newPosition < position - 3) // Rotating anti-clockwise
{ {
if (!editing) if (rc != endMarker)
{ {
if (currentProgram == 0) receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars)
{ {
currentProgram = programLenght - 1; ndx = numChars - 1;
} else {
currentProgram--;
}
Serial.println("<SWITCH," + (String)currentProgram + ">");
} else {
if (volume != 0)
{
Serial.println("<SETVOL," + (String)(volume - 1) + ">");
} }
} }
position = newPosition; else
}
if (newPosition > position + 3) // Rotating clockwise
{
if (!editing)
{ {
if (currentProgram == programLenght - 1) receivedChars[ndx] = '\0'; // terminate the string
{ recvInProgress = false;
currentProgram = 0; ndx = 0;
} else { newData = true;
currentProgram++;
}
Serial.println("<SWITCH," + (String)currentProgram + ">");
} else {
if (volume != 100)
{
Serial.println("<SETVOL," + (String)(volume + 1) + ">");
}
} }
position = newPosition; }
else if (rc == startMarker)
{
recvInProgress = true;
} }
} }
if (button.pressed()) processData();
}
boolean input = false;
// Check for button input
void checkInput(unsigned long time)
{
input = false;
int value = 0;
long newPosition = encoder.read();
// Encoder button
if (button1.pressed())
{ {
input = true;
editing = (editing) ? 0 : 1; editing = (editing) ? 0 : 1;
} }
if (newPosition != position)
{
if (newPosition < position - 3) // Rotating anti-clockwise
{
value = -1;
}
else if (newPosition > position + 3)
{ // Rotating clockwise
value = 1;
}
if (value != 0)
{
position = newPosition;
menuUpdate = true;
input = true;
if (button2.read() == Button::PRESSED)
{
// Change backlight
if (!(light + value < 0) && !(light + value > 254))
{
setBacklight(light + value);
}
} else if (button3.read() == Button::PRESSED)
{
// Change contrast
if (!(contrast + value < 0) && !(contrast + value > 100))
{
setContrast(contrast + value);
}
}
else if (!editing)
{
// Change program
if (currentProgram + value < 0)
{
currentProgram = programLenght - 1;
}
else if (currentProgram + value > programLenght - 1)
{
currentProgram = 0;
}
else
{
currentProgram = currentProgram + value;
}
Serial.println("<SWITCH," + (String)(currentProgram) + ">");
}
else
{
// Change volume
if (!(volume + value < 0) && !(volume + value > 100))
{
Serial.println("<SETVOL," + (String)(volume + value) + ">");
}
}
}
}
} }
// Init arduino // Init arduino
void setup() { void setup()
{
// Start serial connection // Start serial connection
Serial.begin(115200); Serial.begin(115200);
// Init button // Init button
button.begin(); button1.begin();
button2.begin();
button3.begin();
// Init display // Init display
display.begin(); display.begin();
display.setContrast(50);
toggleBacklight(); setContrast(contrast);
setBacklight(light);
display.clearDisplay(); display.clearDisplay();
display.display(); display.display();
// TODO: Remove testing variables
currentProgram = 0;
} }
void loop() { void loop()
{
// Check time // Check time
time = millis(); time = millis();
menuUpdate = (time % 1000 == 0) ? true : false; menuUpdate = (time % 1000 == 0) ? true : false;
@ -342,8 +410,24 @@ void loop() {
{ {
blink = false; blink = false;
} }
if (input || newData)
{
lightTimeout = 10;
setBacklight(light);
}
if (lightTimeout <= 0)
{
setBacklight(0);
}
else
{
if (time % 1000 == 0)
{
lightTimeout--;
}
}
// Check for serial data or commands // Check for serial data or commands
checkSerial(); checkSerial();
@ -352,15 +436,17 @@ void loop() {
if (connected && dataReady) if (connected && dataReady)
{ {
// Draw menu every second or every 0.1 second when editing // Draw menu every second or every 0.1 second when editing
if (menuUpdate || (editing && time % 100 == 0)) { if (menuUpdate || (editing && time % 100 == 0))
{
menuUpdate = false; menuUpdate = false;
drawMenu(); drawMenu();
} }
// Check input // Check input
checkInput(time); checkInput(time);
}
} else { else
{
if (menuUpdate) if (menuUpdate)
{ {
// Draw menu with "Waiting for connection", name and volume are ignored bij drawMenu() // Draw menu with "Waiting for connection", name and volume are ignored bij drawMenu()

14
src/arduino/logo.h Normal file
View File

@ -0,0 +1,14 @@
// 'AudioMixer', 84x16px
const unsigned char logo [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x30, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x33, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x31, 0xfc, 0x00,
0x05, 0x00, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x33, 0x30, 0x04, 0x00, 0x04, 0x00, 0x20, 0x40, 0x00,
0x00, 0x00, 0x33, 0x78, 0x04, 0x00, 0x04, 0x00, 0x22, 0x40, 0x00, 0x00, 0x00, 0x33, 0x79, 0xfd,
0x05, 0xfd, 0x3f, 0xa2, 0x49, 0x0b, 0xfb, 0xe0, 0x33, 0x31, 0x05, 0x05, 0x01, 0x20, 0xa2, 0x48,
0x92, 0x0a, 0x00, 0x33, 0x31, 0x05, 0x05, 0x01, 0x20, 0xa2, 0x48, 0x62, 0xf2, 0x00, 0x33, 0x31,
0x05, 0x05, 0x01, 0x20, 0xa2, 0x48, 0x92, 0x02, 0x00, 0x33, 0x31, 0x05, 0xfd, 0xfd, 0x3f, 0xa2,
0x49, 0x0b, 0xfa, 0x00, 0x37, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37,
0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x30, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

View File

@ -11,7 +11,7 @@ def main():
sessions = AudioUtilities.GetAllSessions() sessions = AudioUtilities.GetAllSessions()
print (str(len(sessions)) + " audio sessions found:") print (str(len(sessions)) + " audio sessions found:")
for session in sessions: for session in sessions:
print (" " + str(session)) print (" " + str(session.DisplayName) + ": " + str(session.Process and session.Process.name()))
# Init serial connection # Init serial connection
ports = serial.tools.list_ports.comports() ports = serial.tools.list_ports.comports()
@ -70,13 +70,14 @@ def main():
if program.DisplayName == "@%SystemRoot%\System32\AudioSrv.Dll,-202": if program.DisplayName == "@%SystemRoot%\System32\AudioSrv.Dll,-202":
name = "Systeem" name = "Systeem"
# TODO: This line is being overwritten somehow elif str(program.Process and program.Process.name()) == "firefox.exe":
elif session.Process and session.Process.name() == "firefox.exe":
name = "Firefox" name = "Firefox"
elif str(program.Process and program.Process.name()) == "Discord.exe":
name = "Discord"
elif program.DisplayName != "": elif program.DisplayName != "":
name = str(program.DisplayName) name = str(program.DisplayName)
else: else:
name = str(session.Process and session.Process.name()) name = str(program.Process and program.Process.name())
board.write(("<NAME," + name + ">").encode()) board.write(("<NAME," + name + ">").encode())
board.write(("<GETVOL," + str(round(volume * 100)) + ">").encode()) board.write(("<GETVOL," + str(round(volume * 100)) + ">").encode())