FLProg + RemoteXY = Беспроводная клавиатура для компьютера на Вашем телефоне
У меня дома сложилась интересная ситуация. Телевизор в спальне подключен к компьютеру расположенному в другой комнате, и для того что бы жена могла посмотреть очередную серию сериала (хотя у меня есть андроидная приставка, которая стоит рядом с телевизором, она предпочитает смотреть с компа), приходится приложить достаточно много усилий. В виду присутствия детей, беспроводные мыши и клавиатуры у нас не приживаются. Я давно с интересом присматривался к возможности Arduino Leonardo прикидываться мышкой и клавиатурой, и когда эта плата пришла ко мне, реализовал данную возможность в программе FLProg версии 2.2. В паре с возможностями проекта RevoteXY получилась очень интересная штука. Для начала видео работы получившегося устройства.
В первую очередь создаётся проект на сайте RemoteXY. Особенность этого проекта в том что созданный Вами интерфейс не надо грузить на телефон. Достаточно иметь на телефоне саму программу RemoteXY, а все созданные интерфейсы хранятся в прошивке Arduino. При соединении с ней, описание интерфейса передаётся на телефон, и открывается в программе.
Сейчас на сайте RemoteXY появилась возможность делится своими проектами, и вот ссылка на мой проект для рассматриваемого в этом уроке устройства. Проект состоит из четырёх экранов.
Первый экран — управление мышью.
Для управления перемещением мыши служит джойстик. Управление с помощью него очень напоминает управление с помощью той штуки, которая торчала посередине клавиатуры на известном «ThinkPad T41».
У меня достаточно долго такой был, так что опыт есть. Разработчики проекта RemoteXY обещали сделать новый элемент — «Сенсорная панель», с помощью которой можно будет полностью имитировать тачпад ноутбука. Когда это произойдёт в данном проекте я заменю джойстик на него. Слайдер в правой части экрана имитирует колесо прокрутки. Чем сильнее его сдвиг от центра, тем быстрее будет крутиться колесо виртуальной мышки.
Три столбца кнопок в левой части экрана имитируют разные нажатия на кнопки виртуальной мыши. Каждый столбец отвечает за свою кнопку — левую, среднюю, и правую соответственно. Верхний ряд кнопок (с символом «P») имитирует обычное нажатие. То есть при нажатии на эту кнопку, будет нажата соответствующая кнопка виртуальной мыши, при отпускании — отпущена. Второй ряд (с символом «PF») — имитирует нажатие с фиксацией. При первом нажатии на эту кнопку, кнопка виртуальной мыши будет нажата, при втором — отпущена. Это удобно при перетаскивании окон например. Навели мышь на заголовок окна, нажали кнопку «PF» (закрепили окно к мышке), перетащили окно, ещё раз нажали «PF» (отпустили окно). Ну, а третий ряд (с символом «C») — клик по соответствующей кнопке виртуальной мыши.
Второй экран — английская клавиатура.
Тут объяснять особенно нечего. Кнопочка «Caps» включает ввод прописных символов, кнопка «Shft«включает прописные символы на один символ. После ввода одного символа она сбрасывается.
Тут то же все понятно. Клавиши «Caps» и «Shift» работают так же как и на предыдущем экране.
Тут есть небольшая тонкость. В онлайн редакторе RemoteXY обнаружилась небольшая бага. Если в надписи на кнопке использовать символ »\» то проект не сохраняется и не обрабатывается. Поэтому для кнопки этого символа я использовал надпись «not/». Ну не придумал я ничего лучше.
После создания проекта на сайте RemoteXY необходимо получить код для загрузки в блок «RemoteXY» в проекте FLProg. Для этого в свойствах проекта RemoteXY выбираем среду программирования — FLProg.
REMOTEXY_MODE__SOFTSERIAL
REMOTEXY_SERIAL_RX 8
REMOTEXY_SERIAL_TX 9
REMOTEXY_SERIAL_SPEED 9600
[128,5,144,5,6,8,4,5,32,41
,11,47,47,7,1,4,48,92,11,7
,50,7,1,1,1,1,18,12,12,7
,1,80,0,1,1,14,18,12,12,7
,1,80,0,1,1,27,18,12,12,7
,1,80,0,1,1,1,32,12,12,7
,1,80,70,0,1,1,14,32,12,12
,7,1,80,70,0,1,1,27,32,12
,12,7,1,80,70,0,1,1,1,47
,12,12,7,1,67,0,1,1,14,47
,12,12,7,1,67,0,1,1,27,47
,12,12,7,1,67,0,1,1,1,22
,8,8,6,2,81,0,1,1,10,22
,8,8,6,2,87,0,1,1,19,22
,8,8,6,2,69,0,1,1,28,22
,8,8,6,2,82,0,1,1,37,22
,8,8,6,2,84,0,1,1,46,22
,8,8,6,2,89,0,1,1,55,22
,8,8,6,2,85,0,1,1,64,22
,8,8,6,2,73,0,1,1,73,22
,8,8,6,2,79,0,1,1,82,22
,8,8,6,2,80,0,1,1,1,31
,8,8,6,2,65,0,1,1,10,31
,8,8,6,2,83,0,1,1,19,31
,8,8,6,2,68,0,1,1,28,31
,8,8,6,2,70,0,1,1,37,31
,8,8,6,2,71,0,1,1,46,31
,8,8,6,2,72,0,1,1,55,31
,8,8,6,2,74,0,1,1,64,31
,8,8,6,2,75,0,1,1,1,40
,8,8,6,2,90,0,1,1,10,40
,8,8,6,2,88,0,1,1,19,40
,8,8,6,2,67,0,1,1,28,40
,8,8,6,2,86,0,1,1,37,40
,8,8,6,2,66,0,1,1,46,40
,8,8,6,2,78,0,1,1,55,40
,8,8,6,2,77,0,1,1,1,49
,98,13,6,2,0,1,1,73,31,8
,8,6,2,76,0,1,1,91,22,8
,8,6,2,60,0,1,1,82,31,17
,17,6,2,69,110,116,101,114,0,1
,1,64,40,8,8,6,2,44,0,1
,1,73,40,8,8,6,2,46,0,1
,1,1,16,17,5,6,2,83,104,105
,102,116,0,1,1,7,10,11,5,6
,2,67,97,112,115,0,1,1,1,25
,7,7,0,3,208,153,0,1,1,8
,25,7,7,0,3,208,166,0,1,1
,15,25,7,7,0,3,208,163,0,1
,1,22,25,7,7,0,3,208,154,0
,1,1,29,25,7,7,0,3,208,149
,0,1,1,43,25,7,7,0,3,208
,147,0,1,1,57,25,7,7,0,3
,208,169,0,1,1,78,25,7,7,0
,3,208,170,0,1,1,36,25,7,7
,0,3,208,157,0,1,1,64,25,7
,7,0,3,208,151,0,1,1,71,25
,7,7,0,3,208,165,0,1,1,50
,25,7,7,0,3,208,168,0,1,1
,86,25,13,7,0,3,60,0,1,1
,1,49,98,13,0,3,0,1,1,1
,41,7,7,0,3,208,175,0,1,1
,9,41,7,7,0,3,208,167,0,1
,1,17,41,7,7,0,3,208,161,0
,1,1,25,41,7,7,0,3,208,156
,0,1,1,33,41,7,7,0,3,208
,152,0,1,1,41,41,7,7,0,3
,208,162,0,1,1,49,41,7,7,0
,3,208,172,0,1,1,57,41,7,7
,0,3,208,145,0,1,1,65,41,7
,7,0,3,208,174,0,1,1,1,33
,7,7,0,3,208,164,0,1,1,9
,33,7,7,0,3,208,171,0,1,1
,17,33,7,7,0,3,208,146,0,1
,1,25,33,7,7,0,3,208,144,0
,1,1,33,33,7,7,0,3,208,159
,0,1,1,41,33,7,7,0,3,208
,160,0,1,1,49,33,7,7,0,3
,208,158,0,1,1,57,33,7,7,0
,3,208,155,0,1,1,65,33,7,7
,0,3,208,148,0,1,1,73,33,7
,7,0,3,208,150,0,1,1,81,33
,7,7,0,3,208,173,0,1,1,73
,41,7,7,0,3,44,0,1,1,81
,41,7,7,0,3,46,0,1,1,89
,33,10,15,0,3,69,110,116,101,114
,0,1,1,7,13,11,5,0,3,67
,97,112,115,0,1,1,1,19,17,5
,0,3,83,104,105,102,116,0,1,1
,1,13,9,8,5,4,49,0,1,1
,11,13,9,8,5,4,50,0,1,1
,21,13,9,8,5,4,51,0,1,1
,41,13,9,8,5,4,53,0,1,1
,51,13,9,8,5,4,54,0,1,1
,61,13,9,8,5,4,55,0,1,1
,91,13,9,8,5,4,48,0,1,1
,81,13,9,8,5,4,57,0,1,1
,71,13,9,8,5,4,56,0,1,1
,31,13,9,8,5,4,52,0,1,1
,32,49,68,13,5,4,0,1,1,51
,40,9,8,5,4,60,0,1,1,61
,40,9,8,5,4,39,0,1,1,71
,40,9,8,5,4,34,0,1,1,1
,31,9,8,5,4,95,0,1,1,91
,22,9,8,5,4,60,60,0,1,1
,41,40,9,8,5,4,62,0,1,1
,31,40,9,8,5,4,125,0,1,1
,21,40,9,8,5,4,123,0,1,1
,11,40,9,8,5,4,93,0,1,1
,1,40,9,8,5,4,91,0,1,1
,51,22,9,8,5,4,38,0,1,1
,61,31,9,8,5,4,124,0,1,1
,51,31,9,8,5,4,110,111,116,47
,0,1,1,41,31,9,8,5,4,47
,0,1,1,31,31,9,8,5,4,61
,0,1,1,21,31,9,8,5,4,45
,0,1,1,11,31,9,8,5,4,43
,0,1,1,71,31,9,8,5,4,63
,0,1,1,1,22,9,8,5,4,33
,0,1,1,11,22,9,8,5,4,64
,0,1,1,21,22,9,8,5,4,35
,0,1,1,31,22,9,8,5,4,36
,0,1,1,41,22,9,8,5,4,94
,0,1,1,61,22,9,8,5,4,42
,0,1,1,71,22,9,8,5,4,40
,0,1,1,81,22,9,8,5,4,41
,0,1,1,81,40,9,8,5,4,44
,0,1,1,91,40,9,8,5,4,46
,0,1,1,91,31,9,8,5,4,69
,110,116,101,114,0,1,1,81,31,9
,8,5,4,37,0,1,1,1,49,9
,8,5,4,58,0,1,1,11,49,9
,8,5,4,59,0,1,1,21,49,9
,8,5,4,126,0,65,10,1,10,5
,5,2,2,65,10,1,13,5,5,2
,3,65,9,1,1,5,5,2,2,65
,9,1,1,5,5,2,3,65,9,1
,1,5,5,2,4,131,1,82,1,17
,6,7,1,77,111,117,115,101,0,131
,0,64,1,17,6,6,2,69,110,0
,131,0,46,1,17,6,0,3,208,160
,209,131,209,129,0,131,0,28,1,17
,6,5,4,49,46,46,57,0];
input signed char joystick_1_x; /* =-100…100 координата x положения джойстика */
input signed char joystick_1_y; /* =-100…100 координата y положения джойстика */
input signed char slider_1; /* =-100…100 положение слайдера */
input unsigned char pressL; /* =1 если кнопка нажата, иначе =0 */
input unsigned char PressM; /* =1 если кнопка нажата, иначе =0 */
input unsigned char PressR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char pressLF; /* =1 если кнопка нажата, иначе =0 */
input unsigned char pressMF; /* =1 если кнопка нажата, иначе =0 */
input unsigned char pressRF; /* =1 если кнопка нажата, иначе =0 */
input unsigned char ClickL; /* =1 если кнопка нажата, иначе =0 */
input unsigned char ClickM; /* =1 если кнопка нажата, иначе =0 */
input unsigned char ClickR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bQ; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bW; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bE; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bT; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bY; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bU; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bI; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bO; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bP; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bA; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bS; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bD; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bF; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bG; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bH; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bJ; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bK; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bZ; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bX; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bC; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bV; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bB; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bN; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bM; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSpace; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bL; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bBacspace; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bEnter; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bZap; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bTochka; /* =1 если кнопка нажата, иначе =0 */
input unsigned char ShiftEn; /* =1 если кнопка нажата, иначе =0 */
input unsigned char CapsEn; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bQR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bWR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bER; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bRR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bTR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bUR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bOR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bTverdR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bYR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bPR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bXXR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bIR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bBacspaceR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSpaceR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bZR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bXR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bCR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bVR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bBR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bNR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bMR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bRusBR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bRusUR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bAR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bDR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bFR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bGR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bHR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bJR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bKR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bLR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bRusGR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bRusER; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bZapR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bTochkaR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bEnterR; /* =1 если кнопка нажата, иначе =0 */
input unsigned char CapsRus; /* =1 если кнопка нажата, иначе =0 */
input unsigned char ShiftRus; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bNum1; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bNum2; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bNum3; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bNum5; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bNum6; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bNum7; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bNum0; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bNum9; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bNum8; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bNum4; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSpaceSim; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim24; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim25; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim26; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim10; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bBacspaceSim; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim23; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim22; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim21; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim20; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim19; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim6; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim16; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim15; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim14; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim13; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim12; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim11; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim17; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim1; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim2; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim3; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim4; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim5; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim7; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim8; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim9; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim27; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim28; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bEnterSim; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim18; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim29; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim30; /* =1 если кнопка нажата, иначе =0 */
input unsigned char bSim31; /* =1 если кнопка нажата, иначе =0 */
output unsigned char IsShiftEn_g; /* =0…255 яркость зеленого цвета индикатора */
output unsigned char IsShiftRus_g; /* =0…255 яркость зеленого цвета индикатора */
output unsigned char hasEngSim_b; /* =0…255 яркость синего цвета индикатора */
output unsigned char hasRusSim_b; /* =0…255 яркость синего цвета индикатора */
output unsigned char hasSpecSim_b; /* =0…255 яркость синего цвета индикатора */
С сайтом RemoteXY мы закончили. Переходим к проекту на FLProg.
Прикидываться стандартной (то есть не требующей специальных драйверов) мышью и клавиатурой могут контроллеры Arduino Leonardo (проверено), Arduino DUE (поддержка данного контролера появилась с версии 2.3 — проверено), и Arduino Micro (теоритически, ещё не пришла, жду что бы проверить).
Проект FLProg для данного урока можно скачать здесь. В качестве устройтва связи с телефоном используется модуль блютуз HC-05. Подключён он в соответствии с таблицей.
Здесь присутствует очень большой блок «RemoteXY» который обеспечивает связь с телефоном. Для его настройки необходимо загрузить в него код полученный с сайта проекта RemoteXY. Процесс загрузки подробно описан в информации к блоку (свойства блока → закладка «Информация»), поэтому не будем здесь её дублировать. Отмечу только для тех, кто работает в версии FLProg 2.3 и младше. В этих версиях есть небольшая бага. Если при создании проекта на сайте RemoteXY в настройках выбрать порт который отсутствует или занят в проекте в который будет производится загрузка описания, то при загрузке произойдёт падение программы. Что бы этого избежать, необходимо СНАЧАЛА выбрать в настройках блока свободный порт, а ЗАТЕМ загружать описание. В более поздних версиях программы FLProg эта ошибка исправлена.
Блоки CD (шифратор) служат для определения номера нажатой кнопки. Они выдают на своём выходе номер входа на котором появилась логическая 1. В случае отсутствия лог. 1 на всех входах, на выходе этого блока 0.
Здесь мы из данных полученных с телефона детектируем направление перемещения мыши и колеса. Зону нечувствительности я выбрал 5 едениц (при максимальном изменении сигнала от джойстика и слайдера 0–100 в каждую сторону). В принципе для улучшения работы с мышкой этой величиной можно поиграться. Так же здесь определяется величина шага (скорость перемещения мыши или прокрутки). Параметрами блоков «Scale» так же можно поиграть для более комфортного управления мышью.
Здесь мы непосредственно отправляем команды на перемещение виртуальной мыши. Для этого используем новый блок «Mouse move». Каждый из блоков отправляет команду на перемещение мыши в определённом направлении каждые 10 мс (задаётся в настройках блока), на шаг, рассчитанный в предыдущей плате при наличии высокого уровня на входе «Send».
Здесь так же используется новый блок «Mouse wheel». Тот блок отправляет команду на поворот колеса прокрутки виртуальной мыши. Здесь для достижения эффекта плавности используется другой (отличный от перемещения мыши) принцип. При наличии высокого уровня на входе «Send» блок передает на виртуальную мышь команду на поворот колеса прокрутки на один шаг, но с периодичностью рассчитанной на плате 2. Эта периодичность зависит от положения слайдера на телефоне и меняется от 200 миллисекунд до 5 миллисекунд при изменении значения получаемого со слайдера от 5 (зона нечувствительности) до 100 (крайнее положение).
Здесь используется блок «MousePressKey». При высоком уровне на входе «Send» он держит нажатой выбранную в настройках кнопку виртуальной мыши, при низком — отпускает её. Для реализации эффекта нажатия с фиксацией используются триггеры ТТ (счётные триггеры). По первому переднему фронту на своём входе они переводят свой выход в состояние лог. 1, а при втором сбрасывают его в 0. И так по кругу.
Здесь используется блок «MouseClickKey», который по переднему фронту на входе «Send» производит короткий клик на выбранную в настройках блока кнопку виртуальной мыши.
Здесь используются блоки «KeyboardStatus» и «MouseStatus» которые при высоком уровне на входе «Status» включают виртуальные клавиатуру и мышь соответственно, а при низком уровне — выключают их. В данной схеме для управления включением и отключением служит сигнал наличия соединения телефона с ардуинкой. Он формируется на выходе «CS» блока «RemoteXY» (плата 1). Кроме этого при наличии соединения мы зажигаем встроенный в плату ардуино светодиод (пин 13).
Здесь определяется факт нажатия кнопки на одной из клавиатур в приложении на телефоне, и на какой конкретно клавиатуре была нажата кнопка — русской или английской. Кроме того формируются сигналы для зажигания светодиода расположенного правом верхнем углу каждой из клавиатур приложения на телефоне. Этот светодиод показывает, что сигнал о нажатии кнопки дошёл до контроллера. Я использовал его при наладке, но решил оставить его и в финальной версии приложения.
Здесь определяется необходимость ввода прописного символа. Передний фронт нажатия кнопки «Shift» в приложении на телефоне устанавливает SR тригер в состояние лог.1. После окончания ввода символа (задний фронт сигнала наличия нажатого символа) тригер сбрасывается в 0.
Каждое нажатие кнопки «Caps» в приложении на телефоне инвертирует работу кнопки «Shift». То есть в начальном положении основное состояние ввода — строчные символы, а при нажатии кнопки «Shift» вводится один прописной символ, то после однократого нажатия кнопки «Caps» режим меняется. Основными становятся прописные буквы, а при нажатии кнопки «Shift» вводится один строчный символ. При повторном нажатии кнопки «Caps» ввод переводится в основной режим. Кроме того здесь формируется сигнал для зажигания индикатора «Shift» в приложении на телефоне.
Здесь из номера нажатой на клавиатуре в приложении на телефоне кнопки формируется код символа этой кнопки. Это делается с помощью блока «Code table«этот блок выдаёт на выходе «Q» код, номер которого в загруженной в блоке таблице соответствует значению на входе «I».
Обратите внимание, что и для русских символов и для английских символов используется одна таблица кодов. Дело в том, что библиотека Keybord понимает только однобайтовые коды, и реально нажимает кнопку виртуальной клавиатуры на которой написан символ с переданным ей кодом. Для ввода русских символов метод ввода на компьютере принудительно переключается на русский при их вводе. Как это сделано рассмотрим на следующей плате.
Здесь используются два блока «SequenceKeybord». Эти блоки по переднему фронту на входе «Send» выполняют сценарий действий с клавиатурой, который был сконфигурирован при настройке блока. Именно с помощью этого блока мы можем настроить ввод русских или английских символов, а так же переключение строчных или прописных символов. Но для этого так же требуется некоторая настройка компьютера к которому подключено наше устройство. Надо настроить сочетание клавиш для включения русских и ангдийских раскладок. Это делается в панели управления компьютера.
Для данного устройства я настроил включение английского языка с помощью клафиш CTRL+1, а русского CTRL+0. Именно эти комбинации и используются блоках сценария.
Рассмотрим сценарий верхнего блока.
Сценарий выполняется по шагам сверху вниз по переднему фронту на входе «Send» (Когда появился сигнал наличия нажатого символа на клавиатуре приложения в телефоне). На первом шаге на виртуальной клавиатуре нажимается и удерживается кнопка CTRL. На втором шаге производится короткое нажатие на кнопку, код который подан на вход «Code Step 2». В случае если нажатие было на русской клавиатуре это будет 48 (код символа 1), а если на английской — 49 (код символа 0). На третьем шаге отпускается кнопка CTRL. Таким образом, мы переключили язык ввода на нужный нам для ввода данного символа.
Выполнение следующего шага зависит от наличия высокого уровня на входе «Activity Step 4». Он возникает при активном режиме ввода прописных символов. В этом случае шаг 4 выполняется, и нажимается и удерживается кнопка «Shift» на виртуальной клавиатуре. Таким образом производится ввод прописных символов.
Ну и на последнем шаге нажимается и удерживается кнопка виртуальной клавиатуры, код который приходит на вход «Code Step 5» (код нажатой нами кнопки на клавиатуре в приложении на телефоне).
При пропадании сигнала наличия нажатой кнопки на клавиатуре в приложении на телефоне, за счет инверсии на входе нижнего блока сценария, происходит выполнение сконфигурированного в нём сценария.
Сначала мы отпускаем ранее нажатую кнопку символа, а затем отпускаем кнопку «Shift»
Здесь аналогично плате 10 формируем сигнал о наличии нажатой кнопке на клавиатуре спецсимволов и цифр в приложении на телефоне, и код этой кнопки.
При появлении сигнала наличия нажатой клавише на клавиатуре спецсимволов в приложении на телефоне выполняется сценарий, сконфигурированный в блоке «SequenceKeyboard». В нём мы сначала переводим способ ввода на английский (нажатие клавиши «CTRL» → нажатие клавиши »1» → отпускание клавиши «CTRL»), а затем нажимаем необходимую символную клавишу. При пропадании сигнала наличия нажатой кнопки, выполняется блок однократного воздействия на клавиатуру «OneKeyboard» который выполняет одно запрограммированное в настройках действие. В данном случае отпускает ранее нажатую клавишу специального символа.
После компиляции данный проект занимает чуть более половины памяти контроллера Arduino Leonardo что позволяет произвести ещё различные доработки данного проекта.
Удачного Вам творчества.