Add multiplexing switch
This commit is contained in:
parent
3b3e4d9f34
commit
156b904bfd
2 changed files with 91 additions and 0 deletions
79
cd4052.py
Normal file
79
cd4052.py
Normal file
|
@ -0,0 +1,79 @@
|
|||
"""MicroPython CD4052B Analog Multiplexer driver
|
||||
|
||||
Driver for the 8-channel analog multiplexer with logic-level conversion from
|
||||
Texas Instruments. (https://www.ti.com/lit/ds/symlink/cd4051b.pdf)
|
||||
|
||||
The CD4052B switches up to four pairs of inputs or outputs, numbered 0 through
|
||||
3, mapping them to the two common pins.
|
||||
|
||||
Copyright 2023 Correl Roush
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the “Software”), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
from machine import Pin
|
||||
|
||||
|
||||
class CD4052:
|
||||
def __init__(self, channel_select_a: int, channel_select_b: int, inh: int):
|
||||
self._channel_select_a = Pin(channel_select_a, Pin.OUT)
|
||||
self._channel_select_b = Pin(channel_select_b, Pin.OUT)
|
||||
self._inh = Pin(inh, Pin.OUT)
|
||||
|
||||
def select(self, channel: int) -> None:
|
||||
"""Select a channel pair between 0 and 3.
|
||||
|
||||
The device will be muted during the switch. Mute will be re-enabled once
|
||||
the switch is complete if the device wasn't already muted.
|
||||
|
||||
"""
|
||||
a = channel & 0b01
|
||||
b = (channel & 0b10) >> 1
|
||||
print(f"CD4052: Selecting Channel {channel} ({a}, {b})")
|
||||
mute = self._inh()
|
||||
self._inh.on()
|
||||
self._channel_select_a(a)
|
||||
self._channel_select_b(b)
|
||||
self._inh(mute)
|
||||
|
||||
def channel(self) -> int:
|
||||
"""Retrieve the currently selected channel pair."""
|
||||
return self._channel_select_a() | (self._channel_select_b() << 1)
|
||||
|
||||
def muted(self) -> bool:
|
||||
"""Return the mute status."""
|
||||
return bool(self._inh())
|
||||
|
||||
def mute(self, value: bool = True) -> None:
|
||||
"""Mute the device."""
|
||||
self._inh(value)
|
||||
|
||||
def unmute(self) -> None:
|
||||
"""Unmute the device."""
|
||||
self._inh(False)
|
||||
|
||||
def toggle_mute(self) -> None:
|
||||
"""Togggle mute."""
|
||||
self._inh(not self._inh())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
switch = CD4052(18, 19, 23)
|
||||
switch.select(0)
|
12
main.py
12
main.py
|
@ -8,6 +8,7 @@ import utime
|
|||
|
||||
from umqtt.simple import MQTTClient
|
||||
|
||||
import cd4052
|
||||
import ssd1306
|
||||
import mcp4
|
||||
from rotary_irq_esp import RotaryIRQ
|
||||
|
@ -25,7 +26,9 @@ state = StateTree(
|
|||
"volume": {
|
||||
"left": 0,
|
||||
"right": 0,
|
||||
"muted": False,
|
||||
},
|
||||
"channel": 0,
|
||||
}
|
||||
)
|
||||
last_update = 0
|
||||
|
@ -49,6 +52,9 @@ except Exception as e:
|
|||
print("WARNING: OLED unavailable:", e)
|
||||
oled = None
|
||||
|
||||
switch = cd4052.CD4052(18, 19, 23)
|
||||
switch.select(state["channel"])
|
||||
|
||||
sta_if = network.WLAN(network.STA_IF)
|
||||
|
||||
spi = SPI(1)
|
||||
|
@ -75,6 +81,10 @@ def on_message(topic, msg):
|
|||
pot.write(0, volume["left"])
|
||||
if isinstance(volume.get("right"), int):
|
||||
pot.write(1, volume["right"])
|
||||
if isinstance(volume.get("muted"), bool):
|
||||
switch.mute(volume["muted"])
|
||||
if isinstance(msg.get("channel"), int):
|
||||
switch.select(msg["channel"])
|
||||
|
||||
|
||||
def loop():
|
||||
|
@ -82,6 +92,8 @@ def loop():
|
|||
|
||||
state["volume"]["left"] = pot.read(0)
|
||||
state["volume"]["right"] = pot.read(1)
|
||||
state["volume"]["muted"] = switch.muted()
|
||||
state["channel"] = switch.channel()
|
||||
|
||||
if state.changed:
|
||||
# Volume changed externally
|
||||
|
|
Loading…
Reference in a new issue