From a572757f83ce7e90df1d708856325147275b1212 Mon Sep 17 00:00:00 2001 From: Astatin3 <77305074+Astatin3@users.noreply.github.com> Date: Fri, 10 May 2024 15:27:53 -0600 Subject: [PATCH] Add windows python script, Add sliders, add Serial protocol. --- .idea/oliver-keypad-thing.iml | 8 +++ keypad/keypad.ino | 63 +++++++++++------------- volume.py | 93 +++++++++++++++++++++++++++++++++++ 3 files changed, 129 insertions(+), 35 deletions(-) create mode 100644 .idea/oliver-keypad-thing.iml create mode 100755 volume.py diff --git a/.idea/oliver-keypad-thing.iml b/.idea/oliver-keypad-thing.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/oliver-keypad-thing.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/keypad/keypad.ino b/keypad/keypad.ino index 0f07583..32a9186 100644 --- a/keypad/keypad.ino +++ b/keypad/keypad.ino @@ -8,15 +8,17 @@ const int switchColPins[] = {40, 38, 36, 34, 32, 30, 28, 26, 24, 22}; // Switch const int LEDRowPins[] = {51, 49, 47, 45}; // LED Rows (Anodes) const int LEDColPins[] = {41, 39, 37, 35, 33, 31, 29, 27, 25, 23}; // LED Columns (Cathodes) -const int NUM_SLIDERS = 6; -const int analogInputs[NUM_SLIDERS] = {A2, A3, A4, A5, A7, A9}; +const int NUM_SLIDERS = 10; +const int analogInputs[NUM_SLIDERS] = {A9, A8, A7, A6, A5, A4, A3, A2, A1, A0}; const int keyLightTimeout = 100; +const int sliderUpdateTolerance = 8; #define ROWS 4 #define COLS 10 bool keyState[ROWS][COLS] = {false}; // Holds the state of each key +int analogSliderValues[NUM_SLIDERS]; // State definitions for key states @@ -46,36 +48,8 @@ void setup() { pinMode(analogInputs[i], INPUT); } - - // for(int row = 0; row < ROWS; row++){ - // for(int col = 0; col < COLS; col++){ - // if((row+col) % 2 == 0){ - // keyState[row][col] = true; - // } - // } - // } - - // for(int y = 0; y < litButtons.length; y++){ - // for(int x = 0; x < litButtons[y].length; x++){ - // litButtons - // } - // } } -// bool arrayIsFalse(bool arr[]){ -// for(bool b : arr){ -// if(!b){return false;} -// } -// return true; -// } - -// bool array2dIsFalse(bool arr[][]){ -// for(bool b[] : arr){ -// if(!arrayIsFalse(b)){return false;} -// } -// return true; -// } - void updateLights(){ for (int row = 0; row < ROWS; row++) { for (int col = 0; col < COLS; col++) { @@ -105,11 +79,27 @@ void lightsOff(){ } } +int newVal = 0; + +void updateSliderValues() { + for (int i = 0; i < NUM_SLIDERS; i++) { + newVal = analogRead(analogInputs[i]); + if(abs(analogSliderValues[i]-newVal) >= sliderUpdateTolerance){ + analogSliderValues[i] = newVal; + Serial.print("1|"); + Serial.print(i+1); + Serial.print("|"); + Serial.println(newVal); + } + } +} + unsigned long lastupdated = 0; void loop() { updateLights(); + updateSliderValues(); if(millis()-lastupdated > keyLightTimeout){ @@ -123,13 +113,16 @@ void loop() { digitalWrite(switchRowPins[row], LOW); // Activate row for (int col = 0; col < COLS; col++) { if(digitalRead(switchColPins[col]) == LOW){ + + if(keyState[row][col] == false){ + Serial.print("0|"); + Serial.print(row); + Serial.print("|"); + Serial.println(col); + } + keyState[row][col] = true; - // Serial.print(row); - // Serial.print(", "); - // Serial.print(col); - // Serial.print(" "); - // Serial.println("Pressed!"); lastupdated = millis(); } diff --git a/volume.py b/volume.py new file mode 100755 index 0000000..a45b214 --- /dev/null +++ b/volume.py @@ -0,0 +1,93 @@ +SERIAL_PORT = "COM1" + +AHK_PATH = "C:\\Program Files\\AutoHotkey\\v2\\AutoHotkey.exe" +AHK_SCRIPTS_DIR = "C:\\Users\\astatin3\\Documents\\AutoHotkey\\" + +# Button Choord starts from 0 +BUTTON_VALS = [ + { + "pos": (1,1), + "script": "test.ahk" + } +] + +# Slider ID starts from 1 +SLIDER_VALS = [ + { + "id": 1, + "program": "master" + },{ + "id": 2, + "program": "firefox.exe" + } +] + +import math +import subprocess +from serial import Serial +from comtypes import CLSCTX_ALL +from pycaw.pycaw import AudioUtilities, IAudioEndpointVolume, ISimpleAudioVolume + +sessions = AudioUtilities.GetAllSessions() + +devices = AudioUtilities.GetSpeakers() +interface = devices.Activate(IAudioEndpointVolume._iid_, CLSCTX_ALL, None) +masterVolume = interface.QueryInterface(IAudioEndpointVolume) + +def setMasterVolume(num: int): + if num < 0 or num > 100: return + masterVolume.SetMasterVolumeLevelScalar((num/100), None) + +def setProgramVolume(num: int, program: str): + if num < 0 or num > 100: return + for session in sessions: + volume = session._ctl.QueryInterface(ISimpleAudioVolume) + if session.Process and session.Process.name().lower() == program.lower(): + volume.SetMasterVolume(num/100, None) + # print(f"{session.Process.name()} volume.GetMasterVolume(): {volume.GetMasterVolume()}") + +def run_ahk_script(script:str): + subprocess.Popen([AHK_PATH, (AHK_SCRIPTS_DIR+script)]) + +def handle_button(pos:tuple): + print(f"Pressed button ({pos[0]}, {pos[1]})", end="") + for button in BUTTON_VALS: + if button["pos"] != pos: + continue + + print(f", and ran AHK Script: {AHK_SCRIPTS_DIR}{button["script"]}", end="") + run_ahk_script(button["script"]) + + print("\n", end="") + +def handle_slider(id:int, pos:int): + print(f"Slider {id} is at {pos}%", end="") + for slider in SLIDER_VALS: + if slider["id"] != id: + continue + + if slider["program"] == "master": + print(", and set master volume", end="") + setMasterVolume(pos) + else: + print(f", and set the volume of {slider["program"]}", end="") + setProgramVolume(pos, slider["program"]) + + print("\n", end="") + +def serial_ports(): + import serial.tools.list_ports + print("Open serial ports: " + str([port.name for port in serial.tools.list_ports.comports()])) + +serial_ports() + +ser = Serial('SERIAL_PORT', 9600) + +while ser.is_open: + cc=str(ser.readline()) + val = cc[2:][:-5].split('|') + match (val[0]): + case 0: # Button + pos = (int(val[1]), int(val[2])) + case 1: # Slider + level = (int(slider)/1024)*100