Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fluxpad V2 #32

Closed
wants to merge 33 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
e0b1452
initial commit for fluxpad 2
TonyWu98 Jul 30, 2023
1adbeba
analog keys wip
TonyWu98 Jul 30, 2023
cecf208
usb keyboard and consumer control working
TonyWu98 Aug 1, 2023
3a99ad7
add kicad stuff
TonyWu98 Aug 5, 2023
768d0c3
more kicad files
TonyWu98 Aug 5, 2023
84b0938
code idk
TonyWu98 Aug 5, 2023
87d5b29
add leds, other stuff
TonyWu98 Aug 10, 2023
a947ae4
update pio libs, wip led changes
TonyWu98 Aug 14, 2023
0e7e24b
code updates
TonyWu98 Sep 5, 2023
bff8abe
fluxapp updates
TonyWu98 Sep 5, 2023
35f8af5
images
TonyWu98 Sep 5, 2023
fa0e326
kicad changes
TonyWu98 Sep 5, 2023
7d99a46
general updates
TonyWu98 Sep 10, 2023
c3b2aec
fix overflow bug
TonyWu98 Sep 11, 2023
d867683
more fw and fluxapp updates
TonyWu98 Sep 21, 2023
7b28490
wip adding rgb settings
TonyWu98 Sep 23, 2023
b58e43f
Update README.md
sssata Sep 23, 2023
20958bb
Merge pull request #33 from sssata/readme-update
sssata Sep 23, 2023
9ddc49b
add photos
TonyWu98 Sep 23, 2023
ab86e7a
Merge branch 'fluxpad-2' of https://github.com/sssata/fluxpad into fl…
TonyWu98 Sep 23, 2023
983d941
Update README.md
sssata Sep 23, 2023
db0ab1e
Update README.md
sssata Sep 23, 2023
a42493e
update LUT for fluxpad 2
sssata Sep 24, 2023
ca2322f
tweak LUT, add clamp to calibrated adc
sssata Sep 24, 2023
c82d1ba
Merge pull request #34 from sssata/update-LUT
sssata Sep 25, 2023
efb8714
Update main.yml
sssata Sep 25, 2023
40eb466
Merge pull request #35 from sssata/actions-disable-lfs
sssata Sep 25, 2023
c11c658
a bunch of changes
TonyWu98 Sep 25, 2023
8a8cd76
Merge pull request #36 from sssata/a-lot-of-changes
sssata Sep 25, 2023
6cea488
Update main.yml
sssata Sep 25, 2023
84e85d3
Merge pull request #37 from sssata/actions-no-lfs
sssata Sep 25, 2023
65edcc7
add calibration images
TonyWu98 Sep 25, 2023
1e23eb5
Merge pull request #38 from sssata/add-cal-images
sssata Sep 25, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@
*.SLDASM filter=lfs diff=lfs merge=lfs -text
*.STEP filter=lfs diff=lfs merge=lfs -text
*.STP filter=lfs diff=lfs merge=lfs -text
APP/images/** -filter=lfs -diff=lfs -merge=lfs -text
3 changes: 2 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ on:
pull_request:
branches:
- main
- fluxpad-2

jobs:
build-arduino:
Expand Down Expand Up @@ -41,7 +42,7 @@ jobs:
- name: Checkout with submodules
uses: actions/checkout@v3
with:
lfs: true
lfs: false
submodules: 'recursive'

- name: Create Executable
Expand Down
613 changes: 507 additions & 106 deletions APP/fluxapp.py

Large diffs are not rendered by default.

184 changes: 175 additions & 9 deletions APP/fluxpad_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,19 @@ class CommandType(enum.Enum):
READ = "r"


class LightingMode(enum.IntEnum):
Off = 0
Static = 1
Fade = 2
Flash = 3


class RGBMode(enum.IntEnum):
Off = 0
Static = 1
Rainbow = 2


class MessageKey:
COMMAND = "cmd"
TOKEN = "tkn"
Expand All @@ -46,6 +59,16 @@ class MessageKey:
CALIBRATION_DOWN = "c_d"
DATASTREAM_MODE = "dstrm"
DATASTREAM_FREQUENCY = "dstrm_freq"
LIGHTING_MODE = "l_m"
LIGHTING_FADE_BRIGHTNESS = "l_b"
LIGHTING_FLASH_DURATION = "l_d"
RGB_MODE = "rgb_m"
RGB_BRIGHTNESS = "rgb_b"
RGB_SPEED = "rgb_s"
RGB_C1 = "rgb_c1"
RGB_C2 = "rgb_c2"
RGB_C3 = "rgb_c3"
CLEAR_FLASH = "clear"


class BaseMessage:
Expand Down Expand Up @@ -197,6 +220,36 @@ def release_debounce(self, debounce_ms: int):
self._assert_uint8(debounce_ms)
self.data[MessageKey.RELEASE_DEBOUNCE] = debounce_ms

# LIGHTING MODE
@property
def mode(self):
return int(self.data[MessageKey.LIGHTING_MODE])

@mode.setter
def mode(self, mode: int):
self._assert_uint8(mode)
self.data[MessageKey.LIGHTING_MODE] = mode

# LIGHTING BRIGHTNESS
@property
def brightness(self):
return int(self.data[MessageKey.LIGHTING_FADE_BRIGHTNESS])

@brightness.setter
def brightness(self, brightness: int):
self._assert_uint8(brightness)
self.data[MessageKey.LIGHTING_FADE_BRIGHTNESS] = brightness

# LIGHTING FLASH DURATION
@property
def flash_duration(self):
return int(self.data[MessageKey.LIGHTING_FLASH_DURATION])

@flash_duration.setter
def flash_duration(self, flash_duration_us: int):
self.data[MessageKey.LIGHTING_FLASH_DURATION] = flash_duration_us


class AnalogSettingsMessage(BaseMessage):

# KEY ID
Expand All @@ -207,7 +260,6 @@ def key_id(self):
@key_id.setter
def key_id(self, key_id: int):
self._assert_uint8(key_id)
assert key_id in list(KeyType)
self.data[MessageKey.KEY_ID] = key_id

# KEYMAP
Expand All @@ -217,7 +269,7 @@ def key_code(self):

@key_code.setter
def key_code(self, key_code: int):
self._assert_uint8(key_code)
self._assert_uint16(key_code)
self.data[MessageKey.KEY_CODE] = key_code

@property
Expand Down Expand Up @@ -310,6 +362,35 @@ def rapid_trigger(self, rapid_trigger_enable: bool):
assert isinstance(rapid_trigger_enable, bool)
self.data[MessageKey.RAPID_TRIGGER] = rapid_trigger_enable

# LIGHTING MODE
@property
def mode(self):
return int(self.data[MessageKey.LIGHTING_MODE])

@mode.setter
def mode(self, mode: int):
self._assert_uint8(mode)
self.data[MessageKey.LIGHTING_MODE] = mode

# LIGHTING BRIGHTNESS
@property
def brightness(self):
return int(self.data[MessageKey.LIGHTING_FADE_BRIGHTNESS])

@brightness.setter
def brightness(self, brightness: int):
self._assert_uint8(brightness)
self.data[MessageKey.LIGHTING_FADE_BRIGHTNESS] = brightness

# LIGHTING FLASH DURATION
@property
def flash_duration(self):
return int(self.data[MessageKey.LIGHTING_FLASH_DURATION])

@flash_duration.setter
def flash_duration(self, flash_duration_us: int):
self.data[MessageKey.LIGHTING_FLASH_DURATION] = flash_duration_us


class AnalogCalibrationMessage(BaseMessage):
"""Analog key calibration message containing
Expand All @@ -323,7 +404,6 @@ def key_id(self):
@key_id.setter
def key_id(self, key_id: int):
self._assert_uint8(key_id)
assert key_id in list(KeyType)
self.data[MessageKey.KEY_ID] = key_id

# CALIBRATION
Expand Down Expand Up @@ -362,6 +442,66 @@ def calibration_down(self):
pass


class RGBSettingsMessage(BaseMessage):
"""KeyLightingMessage containing all info about a key's
per-key lighting settings"""

# RGB MODE
@property
def mode(self):
return int(self.data[MessageKey.RGB_MODE])

@mode.setter
def mode(self, mode: int):
self._assert_uint8(mode)
self.data[MessageKey.RGB_MODE] = mode

# RGB Color 1
@property
def color1(self):
return int(self.data[MessageKey.RGB_C1])

@color1.setter
def color1(self, color: int):
self.data[MessageKey.RGB_C1] = color

# RGB Color 2
@property
def color2(self):
return int(self.data[MessageKey.RGB_C2])

@color2.setter
def color2(self, color: int):
self.data[MessageKey.RGB_C2] = color

# RGB Color 3
@property
def color3(self):
return int(self.data[MessageKey.RGB_C3])

@color3.setter
def color3(self, color: int):
self.data[MessageKey.RGB_C3] = color

# RGB BRIGHTNESS
@property
def brightness(self):
return int(self.data[MessageKey.RGB_BRIGHTNESS])

@brightness.setter
def brightness(self, brightness: int):
self.data[MessageKey.RGB_BRIGHTNESS] = brightness

# RGB SPEED
@property
def speed(self):
return int(self.data[MessageKey.RGB_SPEED])

@speed.setter
def speed(self, speed: int):
self.data[MessageKey.RGB_SPEED] = speed


class AnalogReadMessage(BaseMessage):
"""Analog key read message containing """

Expand All @@ -373,7 +513,6 @@ def key_id(self):
@key_id.setter
def key_id(self, key_id: int):
self._assert_uint8(key_id)
assert key_id in list(KeyType)
self.data[MessageKey.KEY_ID] = key_id

# RAW ADC
Expand All @@ -399,7 +538,7 @@ def height_mm(self, dummy: int):
# """Composite class of all settings types"""
# pass

AnyMessage = TypeVar("AnyMessage", DigitalSettingsMessage, AnalogSettingsMessage, EncoderSettingsMessage, AnalogCalibrationMessage, AnalogReadMessage, Union[DigitalSettingsMessage, AnalogSettingsMessage, EncoderSettingsMessage, AnalogCalibrationMessage, AnalogReadMessage])
AnyMessage = TypeVar("AnyMessage", DigitalSettingsMessage, AnalogSettingsMessage, EncoderSettingsMessage, AnalogCalibrationMessage, AnalogReadMessage, RGBSettingsMessage, Union[DigitalSettingsMessage, AnalogSettingsMessage, EncoderSettingsMessage, AnalogCalibrationMessage, AnalogReadMessage, RGBSettingsMessage])


class Fluxpad:
Expand Down Expand Up @@ -578,16 +717,19 @@ def _worker(self):
class FluxpadSettings:

KEY_SETTINGS_KEY = "key_settings"
RGB_SETTINGS_KEY = "rgb_settings"

def __init__(self) -> None:
self.key_settings_list: List[Union[EncoderSettingsMessage, AnalogSettingsMessage, DigitalSettingsMessage]] = [
DigitalSettingsMessage(),
DigitalSettingsMessage(),
AnalogSettingsMessage(),
AnalogSettingsMessage(),
AnalogSettingsMessage(),
EncoderSettingsMessage(),
EncoderSettingsMessage(),
]
self.rgb_settings = RGBSettingsMessage()

def _set_key_ids(self):
key_id = 0
Expand Down Expand Up @@ -616,6 +758,18 @@ def load_from_keypad(self, fluxpad: Fluxpad):
else:
key_settings.data = response.data.copy()

try:
# Read RGB Settings
self.rgb_settings.set_zeros()
response = fluxpad.send_read_request(self.rgb_settings)

# Check all requested keys exist
assert set(response.data.keys()) == set(self.rgb_settings.data.keys()), f"Difference: {set(response.data.keys()).symmetric_difference(set(self.rgb_settings.data.keys()))}"
logging.debug("Got RGB settings")
except Exception:
logging.error(f"Failed to get RGB settings {self.rgb_settings.data}", exc_info=True)
else:
self.rgb_settings.data = response.data.copy()

def save_to_fluxpad(self, fluxpad: Fluxpad, include_calibration: bool = False):
"""Save all settings to the given connected fluxpad"""
Expand All @@ -630,22 +784,33 @@ def save_to_fluxpad(self, fluxpad: Fluxpad, include_calibration: bool = False):
logging.debug(f"Wrote settings for Key ID {key_settings.key_id}")
except Exception:
logging.error(f"Failed to write settings for Key ID {key_settings.key_id} with message {key_settings.data}", exc_info=True)

rgb_settings = self.rgb_settings
try:
response = fluxpad.send_write_request(rgb_settings)
logging.debug(f"Wrote rgb settings")
except Exception:
logging.error(f"Failed to write rgb settings with message {rgb_settings.data}", exc_info=True)

def load_from_file(self, path: pathlib.Path):
"""Load all settings from the given file"""
try:
with path.open("r") as f:
root_json = json.load(f)
except Exception:
logging.error(f"Failed to load settings from {path}", exc_info=1)
logging.error(f"Failed to load settings from {path}", exc_info=True)
return

try:
for json_object in root_json[self.KEY_SETTINGS_KEY]:
self.key_settings_list[json_object[MessageKey.KEY_ID]].data = json_object
except Exception:
logging.error(f"Failed to parse settings from {path}", exc_info=1)

logging.error(f"Failed to parse key settings from {path}", exc_info=True)

try:
self.rgb_settings.data = root_json[self.RGB_SETTINGS_KEY]
except Exception:
logging.error(f"Failed to parse rgb settings from {path}", exc_info=True)

def save_to_file(self, path: pathlib.Path):
"""Save all settings to the given file"""
Expand All @@ -658,7 +823,8 @@ def save_to_file(self, path: pathlib.Path):

# Construct master json to store all settings
root_dict = dict()
root_dict[self.KEY_SETTINGS_KEY] = [key_settings.data for key_settings in self.key_settings_list]\
root_dict[self.KEY_SETTINGS_KEY] = [key_settings.data for key_settings in self.key_settings_list]
root_dict[self.RGB_SETTINGS_KEY] = self.rgb_settings.data

with path.open("w") as f:
json.dump(root_dict, f, indent=4)
Expand Down
Binary file modified APP/images/FluxappIcon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified APP/images/cal_key1_down.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added APP/images/cal_key1_down_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified APP/images/cal_key1_up.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added APP/images/cal_key1_up_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified APP/images/cal_key2_down.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added APP/images/cal_key2_down_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified APP/images/cal_key2_up.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added APP/images/cal_key2_up_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added APP/images/cal_key3_down_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added APP/images/cal_key3_up_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions APP/ttk_slider.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def entry_defocus(self, event: tk.Event):
self.entry.tk_focusNext().focus()

def set_value(self, value):
print(f"hello {value}")
# print(f"Set slider value to {value}")
self.double_var.set(value/self.resolution)
print(f"hello {self.double_var.get()}")
print(f"Set slider value to {self.double_var.get()}")
self.on_slider_move(None)
4 changes: 3 additions & 1 deletion CAD/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@
~$*.SLDASM

# ignore OS X desktops
.DS_Store
.DS_Store

RFQs
4 changes: 2 additions & 2 deletions CAD/001_ASSEMBLY.SLDASM
Git LFS file not shown
3 changes: 3 additions & 0 deletions CAD/004_SHEET_CASE.SLDASM
Git LFS file not shown
3 changes: 3 additions & 0 deletions CAD/050_ASSEMBLY.SLDASM
Git LFS file not shown
3 changes: 3 additions & 0 deletions CAD/050_MASTER_SKETCH.SLDPRT
Git LFS file not shown
3 changes: 3 additions & 0 deletions CAD/051_PCB_ASSEMBLY.SLDASM
Git LFS file not shown
3 changes: 3 additions & 0 deletions CAD/113_SHEET_SPACER.SLDPRT
Git LFS file not shown
3 changes: 3 additions & 0 deletions CAD/114_SHEET_CASE.SLDPRT
Git LFS file not shown
3 changes: 3 additions & 0 deletions CAD/115_SHEET_BOTTOM.SLDPRT
Git LFS file not shown
3 changes: 3 additions & 0 deletions CAD/116_SHEET_DAMPER.SLDPRT
Git LFS file not shown
Binary file added CAD/150_PLATE.SLDDRW
Binary file not shown.
3 changes: 3 additions & 0 deletions CAD/150_PLATE.SLDPRT
Git LFS file not shown
Binary file added CAD/151_CASE.SLDDRW
Binary file not shown.
3 changes: 3 additions & 0 deletions CAD/151_CASE.SLDPRT
Git LFS file not shown
3 changes: 3 additions & 0 deletions CAD/152_SPACER.SLDPRT
Git LFS file not shown
Binary file added CAD/153_BOTTOM_PLATE.SLDDRW
Binary file not shown.
Loading
Loading