触摸传感器模块可用于通过I2C向计算机发送键盘或鼠标输入。Arduino Library示例zForceKeyboardMouse中包含了如何实现这一点的示例。该示例使用官方的Arduino库<Mouse.h>和<Keyboard.h>与主机系统通信。
zForceKeyboardMouse代码
#include <Zforce.h>
#include <Keyboard.h>
#include <Mouse.h>
// IMPORTANT: change "1" to assigned GPIO digital pin for dataReady signal in your setup:
#define DATA_READY 1
long globalMillis = millis(); // global timestamp
const int keyboardBoundary = 750; // set boundary between mouse and keyboard areas on the x-axis to 75 mm.
const int holdTime = 150; // sensitivity for mouse "left-click", unit in milli-second
TouchData previousTouch;
void setup()
{
Keyboard.begin(); // initialize keyboard
Mouse.begin(); // initialize mouse
Serial.begin(115200);
Serial.println("zforce start");
zforce.Start(DATA_READY);
Message* msg = nullptr;
zforce.Enable(true);
msg = zforce.GetMessage();
do
{
msg = zforce.GetMessage();
} while (msg == nullptr);
if (msg->type == MessageType::ENABLETYPE)
{
Serial.print("Message type is: ");
Serial.println((int)msg->type);
Serial.println("Sensor is now enabled and will report touches.");
}
zforce.DestroyMessage(msg);
}
void loop()
{
Message* touch = zforce.GetMessage();
if (touch != nullptr)
{
if (touch->type == MessageType::TOUCHTYPE)
{
//Sends reported touch coordinates [x,y] and event data to mouse and keyboard function.
loopMouse(((TouchMessage*)touch)->touchData[0].x, ((TouchMessage*)touch)->touchData[0].y, ((TouchMessage*)touch)->touchData[0].event);
loopKeyboard(((TouchMessage*)touch)->touchData[0].x, ((TouchMessage*)touch)->touchData[0].y, ((TouchMessage*)touch)->touchData[0].event);
}
zforce.DestroyMessage(touch);
}
}
void loopMouse(int16_t x , int16_t y, int8_t event)
{
if (x <= keyboardBoundary) //return if the touch object is outside mouse area
{
return;
}
switch (event)
{
case 0: // DOWN event
previousTouch.x = x;
previousTouch.y = y;
globalMillis = millis();
Serial.println("Mouse Input - DOWN");
break;
case 1: // MOVE event
if ((millis() - globalMillis) >= holdTime)
{
Mouse.move((x - previousTouch.x), (y - previousTouch.y));
Serial.println("Mouse Input - Moving cursor");
}
previousTouch.x = x;
previousTouch.y = y;
break;
case 2: // UP event
Serial.print("Mouse Input - UP");
if (millis() - globalMillis < holdTime) // mouse "left click", sensitivity
{ // can be tuned by changing "holdTime"
Mouse.click(MOUSE_LEFT);
Serial.print("(Left-Click)");
}
Serial.println("");
break;
default:
break;
}
}
void loopKeyboard(int16_t x , int16_t y, int8_t event)
{
if (x > keyboardBoundary) //return if the touch object is outside keyboard area
{
return;
}
// Only act on event == DOWN, i.e. when an object has entered the touch area
if (event == 0)
{
//assign Key to the given interval
if (y < 250)
{
Keyboard.print('A'); //Print Key "A"
Serial.println("Keyboard Input - Button Press 'A'");
}
else if (y < 500)
{
Keyboard.print('B'); //Print Key "B"
Serial.println("Keyboard Input - Button Press 'B'");
}
else if (y < 750)
{
Keyboard.print('C'); //Print Key "C"
Serial.println("Keyboard Input - Button Press 'C'");
}
else if (y < 1000)
{
Keyboard.print('D'); //Print Key "D"
Serial.println("Keyboard Input - Button Press 'D'");
}
else
{
Keyboard.print('E'); //Print Key "E"
Serial.println("Keyboard Input - Button Press 'E'");
}
}
}
触摸传感器模块可以作为空气中解决方案或任何表面放置,为广泛的用户提供了大量的替代方案。传感器模块例如可以被配置为用作个性化控制面板或混合板。由于可自定义的布局和控件,它可以用于开发,也可以帮助需要自定义工作空间的人。
zForceKeyboardMouse示例展示了如何将触摸输入转换为鼠标或键盘输入。该示例使基于SAMD微型板(例如Neonode原型板)能够通过HID使用官方Arduino库<mouse.h>和<Keyboard.h>向主机系统发送按键或鼠标导航。此示例将触摸活动区域划分为一个鼠标垫和一个键盘部分,其中包含5个按钮(a-E)。鼠标部分的工作方式类似于相对鼠标垫,其中光标相对于其先前位置移动。
键盘按钮被编程为在每个相应部分中进行触摸时打印字母A-E。
我们可以通过zForce Arduino库访问传感器模块的触摸数据
int16_t x = ((TouchMessage*)touch)->touchData[0].x;
//Touch
input position x coordinate
int16_t y = ((TouchMessage*)touch)->touchData[0].y;
//Touch
input position y coordinate
int8_t event = ((TouchMessage*)touch)->touchData[0].event;
//Touch input event
state, i.e TouchUp, TouchDown...
触摸式鼠标垫
由于触摸传感器模块被识别为触摸屏数字化仪,因此需要提取触摸输入数据,以便将其转换为鼠标输入。为了将绝对位置输入坐标转换为其相对位置(移动),我们将当前触摸数据位置与先前跟踪的对象位置相减。
Mouse.move((x - previousTouch.x), (y - previousTouch.y));
//"x" and "y" arethe location of the reported touch coordinates "previousTouch.x" and "previousTouch.y" are the location of the previous reported coordinate.
在鼠标部分内“点击”或“点击”后,将执行鼠标左键单击操作。当报告的触摸具有事件数据“UP”时,会触发左键点击动作。在实践中,这意味着最终用户需要“按压”和“释放”他们的手指才能进行触摸。触摸灵敏度可以通过全局变量holdTime进行调整,它就像一个“触摸”所需时间的计时器。
为了使用鼠标垫,我们使用从传感器模块收集的触摸信息:
switch (event)
{
case 0: // DOWN event
previousTouch.x = x;
previousTouch.y = y;
globalMillis = millis();
Serial.println("Mouse Input - DOWN");
break;
case 1: // MOVE event
if ((millis() - globalMillis) >= holdTime)
{
Mouse.move((x - previousTouch.x), (y - previousTouch.y));
Serial.println("Mouse Input - Moving cursor");
}
previousTouch.x = x;
previousTouch.y = y;
break;
case 2: // UP event
Serial.print("Mouse Input - UP");
if (millis() - globalMillis < holdTime) // mouse "left click", sensitivity
{ // can be tuned by changing "holdTime"
Mouse.click(MOUSE_LEFT);
Serial.print("(Left-Click)");
}
Serial.println("");
break;
default: break;
}
对于空中解决方案,我们建议在DOWN事件而不是UP事件上预生成所有“左键点击”或“按键”。通过进行此调整,当最终用户按下手指时(而不是松开手指时)将触发左键单击。这为触摸活动区域提供了更具触觉的响应,是空中解决方案的最佳选择
要在DOWN事件上进行左键点击触发,请考虑以下调整:
switch (event)
{
case 0: // DOWN event
previousTouch.x = x;
previousTouch.y = y;
globalMillis = millis();
Mouse.click(MOUSE_LEFT);
//Left-click on DOWN-event
break;
case 1: // MOVE event
if ((millis() - globalMillis) >= holdTime)
{
Mouse.move((x - previousTouch.x), (y - previousTouch.y));
}
previousTouch.x = x;
previousTouch.y = y;
break;
case 2: // UP event
break;
default: break;
}
键盘按钮将根据触摸对象的位置发送按键。每个按钮都由可变键盘Boundary分割,然后进一步分割以区分每个键。
如果报告的带有DOWN事件的触摸位于键盘边界内,则将执行第二次查找,以评估要打印的键。
if (event == 0) { // DOWN event
//assign Key to the given interval
if (y < 250)
Keyboard.print('A'); //Print Key "A"
else if (y < 500)
Keyboard.print('B'); //Print Key "B"
else if (y < 750)
Keyboard.print('C'); //Print Key "C"
else if (y < 1000)
Keyboard.print('D'); //Print Key "D"
else
Keyboard.print('E'); //Print Key "E"
}