Еще одна клавиатура. Аж до 32 кнопок.
Кнопки организованы в матрицу 8 на 4. Чтобы всё это хозяйство сканировать, нужно 8 выходов, а у COM-порта их только три. Поэтому поступим так. Средствами hal свернем сканирующий код в двоичный, а потом раскодируем его обратно аппаратным дешифратором.
В качестве дешифратора возьмем мультиплексор CD4051 (наш аналог - КР1561КП2). Эта микросхема удобна следующим:
- во-первых, коммутируемые сигналы проходят непосредственно со входа на выход и обратно через аналоговые КМОП-ключи. Это позволяет использовать микросхему не только как цифровой и аналоговый мультиплексор 8 сигналов на один выход, но и как дешифратор 3-битного двоичного кода в код "один из восьми".
- во-вторых, напряжение питания этой серии и амплитуда входных/выходных может достигать 20 вольт, что позволяет непосредственно работать с уровнями сигналов RS232 (-10..+10В).
- в третьих, ток потребления очень мал, что дает возможность организовать питание от сигналов порта. Цепь питания организована состоит из диодов D1..D6, конденсаторов С1 и C2, а также стабилитронов D7 и D8, ограничивающих напряжение до 18В. Токоограничивающих резисторов нет, поскольку они полагаются передатчикам порта по стандарту RS232.
Код: Выделить всё
loadrt threads name1=base-thread period1=30000 fp1=0 name2=servo-thread period2=1000000
loadusr -Wn comkbd32 pyvcp -c comkbd32 comkbd32.xml
loadrt serport io=0x3f8
addf serport.0.read base-thread
addf serport.0.write base-thread
loadrt matrix_kb config=8x4s
addf matrix_kb.0 servo-thread
setp matrix_kb.0.negative-logic 0
loadrt logic count=3 personality=0x204,0x204,0x204
addf logic.0 base-thread
addf logic.1 base-thread
addf logic.2 base-thread
net col0 serport.0.pin-9-in => matrix_kb.0.col-00-in
net col1 serport.0.pin-8-in => matrix_kb.0.col-01-in
net col2 serport.0.pin-6-in => matrix_kb.0.col-02-in
net col3 serport.0.pin-1-in => matrix_kb.0.col-03-in
net row0 matrix_kb.0.row-00-out
net row1 matrix_kb.0.row-01-out => logic.0.in-00
net row2 matrix_kb.0.row-02-out => logic.1.in-00
net row3 matrix_kb.0.row-03-out => logic.0.in-01 logic.1.in-01
net row4 matrix_kb.0.row-04-out => logic.2.in-00
net row5 matrix_kb.0.row-05-out => logic.0.in-02 logic.2.in-01
net row6 matrix_kb.0.row-06-out => logic.1.in-02 logic.2.in-02
net row7 matrix_kb.0.row-07-out => logic.0.in-03 logic.1.in-03 logic.2.in-03
net code-row1 logic.0.or => serport.0.pin-4-out
net code-row2 logic.1.or => serport.0.pin-3-out
net code-row4 logic.2.or => serport.0.pin-7-out
net led0 matrix_kb.0.key.r0c0 => comkbd32.led0
net led1 matrix_kb.0.key.r1c0 => comkbd32.led1
net led2 matrix_kb.0.key.r2c0 => comkbd32.led2
net led3 matrix_kb.0.key.r3c0 => comkbd32.led3
net led4 matrix_kb.0.key.r4c0 => comkbd32.led4
net led5 matrix_kb.0.key.r5c0 => comkbd32.led5
net led6 matrix_kb.0.key.r6c0 => comkbd32.led6
net led7 matrix_kb.0.key.r7c0 => comkbd32.led7
net led8 matrix_kb.0.key.r0c1 => comkbd32.led8
net led9 matrix_kb.0.key.r1c1 => comkbd32.led9
net led10 matrix_kb.0.key.r2c1 => comkbd32.led10
net led11 matrix_kb.0.key.r3c1 => comkbd32.led11
net led12 matrix_kb.0.key.r4c1 => comkbd32.led12
net led13 matrix_kb.0.key.r5c1 => comkbd32.led13
net led14 matrix_kb.0.key.r6c1 => comkbd32.led14
net led15 matrix_kb.0.key.r7c1 => comkbd32.led15
net led16 matrix_kb.0.key.r0c2 => comkbd32.led16
net led17 matrix_kb.0.key.r1c2 => comkbd32.led17
net led18 matrix_kb.0.key.r2c2 => comkbd32.led18
net led19 matrix_kb.0.key.r3c2 => comkbd32.led19
net led20 matrix_kb.0.key.r4c2 => comkbd32.led20
net led21 matrix_kb.0.key.r5c2 => comkbd32.led21
net led22 matrix_kb.0.key.r6c2 => comkbd32.led22
net led23 matrix_kb.0.key.r7c2 => comkbd32.led23
net led24 matrix_kb.0.key.r0c3 => comkbd32.led24
net led25 matrix_kb.0.key.r1c3 => comkbd32.led25
net led26 matrix_kb.0.key.r2c3 => comkbd32.led26
net led27 matrix_kb.0.key.r3c3 => comkbd32.led27
net led28 matrix_kb.0.key.r4c3 => comkbd32.led28
net led29 matrix_kb.0.key.r5c3 => comkbd32.led29
net led30 matrix_kb.0.key.r6c3 => comkbd32.led30
net led31 matrix_kb.0.key.r7c3 => comkbd32.led31
start
Шифратор "8-в-3" организован на трех 4-входовых элементах ИЛИ. В качестве таковых используются универсальные компоненты logic
http://www.linuxcnc.org/docs/html/man/man9/logic.9.html
в режиме OR.
Чтобы убедиться в работоспособности, собрал на макетке.

Код: Выделить всё
<!-- Test panel for the serial port simple keyboard -->
<pyvcp>
<hbox>
<relief>RIDGE</relief>
<bd>2</bd>
<label>
<text>" 0"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led0"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>" 1"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led1"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>" 2"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led2"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>" 3"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led3"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>" 4"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led4"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>" 5"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led5"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>" 6"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led6"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>" 7"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led7"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
</hbox>
<hbox>
<relief>RIDGE</relief>
<bd>2</bd>
<label>
<text>" 8"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led8"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>" 9"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led9"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>"10"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led10"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>"11"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led11"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>"12"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led12"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>"13"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led13"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>"14"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led14"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>"15"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led15"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
</hbox>
<hbox>
<relief>RIDGE</relief>
<bd>2</bd>
<label>
<text>"16"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led16"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>"17"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led17"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>"18"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led18"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>"19"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led19"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>"20"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led20"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>"21"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led21"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>"22"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led22"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>"23"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led23"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
</hbox>
<hbox>
<relief>RIDGE</relief>
<bd>2</bd>
<label>
<text>"24"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led24"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>"25"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led25"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>"26"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led26"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>"27"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led27"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>"28"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led28"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>"29"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led29"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>"30"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led30"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
<label>
<text>"31"</text>
<font>("Courier",20)</font>
</label>
<led>
<halpin>"led31"</halpin>
<size>25</size>
<on_color>"red"</on_color>
<off_color>"black"</off_color>
</led>
</hbox>
</pyvcp>

Если нужно использовать какие-то входы или выходы порта для других целей, количество кнопок придется сократить. Так, для пульта со штурвалом два входа порта "монопольно" отводим под энкодер, и количество кнопок сократится до 8 * 2 = 16. Что, в общем-то, тоже неплохо

Ну и напомню, чтобы допустимое количество одновременно замкнутых контактов было больше двух, придется последовательно с каждым из них включить по диоду, как на предыдущих схемах.