#KMK with demux/decoder
1 messages · Page 1 of 1 (latest)
I'm new to KMK, but I believe that you need a custom Scanner to handle the decoder. Unless you can find a community contribution that does so, I think you'll have to write it yourself.
But the supplied digitalio Scanner (http://kmkfw.io/docs/scanners#digitalio-scanners) is close to what you need. Its source is kmk/scanners/digitalio in the KMK download.
It's a good idea to read over this source to get an idea of how it's working if you were able to pass in 15 pins for the columns. Basically the class initializer sets up each row and column pin as a digitalio and sets a bunch of variables for use in scan_for_changes. Each time scans_for_changes is called, it sets each output (column in this case) pin in turn, checks each input (row) pin in turn for a change, and reports any changes.
The essential change is that that output pins (your CLD* pins) are used to select the column. Talking about changes here, I'll try to stick to minimal changes to the digitialio.py code, but feel free to special-case it as much as makes sense.
First, you need a new variable that represents the actual number of columns you're using, say col_count. You can add self.col_count = 15 to the class initializer, or pass it in as an argument and assign it to self.col_count.
Then, in scan_for_changes, the first two lines of the outer (output) loop currently look like
for oidx, opin in enumerate(self.outputs):
opin.value = self.pull is not digitalio.Pull.UP
(These are at line 187 in my download from yesterday).
Instead you need something like:
for oidx in range(self.col_count):
# set the decoder pins to select the column
for i in range(len_cols):
if oidx & (1 << i):
cols[i].value = self.pull if not digitalio.Pull.UP
else
cols[i].value = self.pull if digitalio.Pull.UP
I just saw you're online now. With me so far?
okay i think i understand
now i would need to translate based on the truth table, right?
The other changes are mostly that the code assumes that self.len_cols is the number of columns. In the initializer, it uses it calculate self._key_count. In scan_for_changes, it uses it to calculate new_oidx (around line 127). You'll need to change those to use self.col_count.
oh so it’s literally just a translation
That's what the inner loop in the change I suggested is doing -- setting the output pins to represent the number oidx (output, or column, index).
yep, okay i see now
what would you recommend for the LE and E pins?
that’s another area i wasn’t sure what to do with
I'll have to look at the 74HC4515 data sheet again to remind myself what those are used for.
"When LE is HIGH, the selected output is determined by the data on An. When LE goes LOW, the last data present at An are stored in the latches and the outputs remain stable. When E is LOW, the selected output, determined by the contents of the latch, is LOW. When E is HIGH, all outputs are HIGH. The enable input E does not affect the state of the latch. When the device is used as a demultiplexer, E is the data input and A0 to A3 are the address inputs."
You could probably get by with holding LE HIGH and E LOW. But before that encoding loop, it might be best to set E HIGH, make the changes to the address pins, then set it LOW.
Given the way this works (setting the active column output pin LOW), your pull should be UP
okay sounds good, anything else i should take into consideration