Neonode触摸传感器模块之I2C鼠标和键盘

引言

触摸传感器模块可用于通过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 1long 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-secondTouchData previousTouch;void setup()
{Keyboard.begin();           // initialize keyboardMouse.begin();              // initialize mouseSerial.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 eventpreviousTouch.x =  x;previousTouch.y =  y;globalMillis = millis();Serial.println("Mouse Input - DOWN");break;case 1: // MOVE eventif ((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 eventSerial.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 areaif (event == 0){//assign Key to the given intervalif (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'");}}
}

触摸传感器模块可以作为空气中解决方案或任何表面放置,为广泛的用户提供了大量的替代方案。传感器模块例如可以被配置为用作个性化控制面板或混合板。由于可自定义的布局和控件,它可以用于开发,也可以帮助需要自定义工作空间的人。

1说明

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"
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/619770.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VR转接器:打破界限,畅享虚拟现实

你是否曾梦想过踏入另一个世界&#xff0c;体验那种仿佛置身其中的感觉&#xff1f;随着科技的飞速发展&#xff0c;虚拟现实&#xff08;VR&#xff09;已经成为了现实。而VR转接器&#xff0c;正是让你畅享虚拟现实的关键所在。 添加图片注释&#xff0c;不超过 140 字&…

猫头虎分享:探索TypeScript的世界 — TS基础入门 ‍

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通Golang》…

Web前端 ---- 【Vue3】vue3中的组件传值(props、自定义事件、全局事件总线)

目录 前言 props 自定义事件 全局事件总线 安装第三方库mitt 封装event-bus.js文件 使用全局事件总线 清除全局事件绑定 前言 本文介绍在vue3中的组件传值&#xff0c;props、自定义事件以及全局事件总线。相较于vue2中&#xff0c;略有变化。关于vue2中的组件传值看这篇…

vscode运行Python的两种方法,及无法运行的原因

vscode运行Python代码 下面介绍的vscode运行Python代码的方法基于的一个前提条件是&#xff1a;当前的计算机已经安装好了Python&#xff0c;且已经配置好了相关的环境变量。如果要查看是否已经都安装好了&#xff0c;可以打开Windows系统的命令行工具Windows PowerShell&…

鸿蒙(HarmonyOS)应用开发指南

1. 概述 1.1 简介 鸿蒙&#xff08;即 HarmonyOS &#xff0c;开发代号 Ark&#xff0c;正式名称为华为终端鸿蒙智能设备操作系统软件&#xff09;是华为公司自 2012 年以来开发的一款可支持鸿蒙原生应用和兼容 AOSP 应用的分布式操作系统。该系统利用“分布式”技术将手机、电…

vue、element-ui使用el-tooltip判断文本是否溢出

1.需求&#xff1a;需要实现文本单行显示&#xff0c;超出时&#xff0c;使用省略号&#xff0c;划过该文本时使用tooltip显示全部文本。需要考虑数据是由接口动态获取&#xff0c;只有溢出文本鼠标滑过时显示全部文本&#xff0c;没有溢出的则不需要。 2.实现&#xff1a; 第…

img标签的奇怪问题

本来只是为实现一个轮播图&#xff0c;img的url地址是从后端接口获取的&#xff0c;但不巧的是url地址的图片都过期了。 因为懒得重新到网上找图&#xff0c;就想直接用一下本地的图片&#xff0c;简单的想法遇到一堆问题。 问题一&#xff1a; 因为是springboot项目&#xf…

windows11通过虚拟机安装Ubuntu20.04

VMware 分为 VMware Workstation Pro 和 VMware Workstation Player, Pro体验期后收费&#xff0c;Player则免费。player 早期不能创建虚拟机&#xff0c;只能Pro创建好后给Player运行&#xff0c;而现在player早已加入创建虚拟机功能&#xff0c;所以使用体验上两者相差不大&a…

物联网协议Coap之Core和NetWork简介

目录 前言 一、Coap的Core包 1、Coap对象 2、Message对象 3、Request对象 4、Response对象 二、Coap的NetWork调试 1、UDP运行模式 2、Network消息接收 3、Sender线程发送数据 三、总结 前言 在之前的博文中&#xff0c;对Californium中Coap的实现进行了简要的介绍&a…

swing快速入门(四十)JList、JComboBox实现列表框

注释很详细&#xff0c;直接上代码 上一篇 新增内容 &#x1f9e7;1.列表的属性设置与选项监听器 &#x1f9e7;2.下拉框的属性设置与选项监听器 &#x1f9e7;3.Box中组件填充情况不符合预期的处理方法 &#x1f9e7;4.LIst向Vector的转化方法 源码&#xff1a; package swing…

OpenCV 基于C++图像读取及存储API函数

OpenCV可以从存储介质中读入图像&#xff0c;也可以将摄像头(Camera)抓取的图像载入内存&#xff0c;然后进行处理。而存储图像就是将内存中的图像数据写入存储介质中&#xff0c;如写入硬盘、优盘等。 OpenCV要读入图像、操作图像。首先要用到Mat类&#xff0c;并且需创建Mat对…

mysql 获取距离某点最近的数据

方式一 算法&#xff1a;st_distance (POINT ( latitude, longitude ),POINT ( 106.695823, 26.574557 )) * 111195 SELECT*,st_distance (POINT ( latitude, longitude ),POINT ( 106.695823, 26.574557 )) * 111195 AS distance FROMtest_distance ORDER BYdistance DESC…

理想汽车迎来新算力平台负责人,内部化名为张一粟;王者荣耀在抖音直播全面开放;陈楚生等人现身央视春晚彩排

今日精选 • 理想汽车迎来新算力平台负责人,内部化名为张一粟。目前理想内部暂未公布其内部职级• 王者荣耀在抖音直播全面开放• 陈楚生等人现身央视春晚彩排 投融资 • 2023年12月份&#xff0c;中国社会融资规模增量为1.94万亿元• OpenAI 支持的人形机器人公司 1X 完成 …

mybatis之动态sql、if\choose\when\otherwise\trim\where\set\foreach\bind有案例

mybatis之动态sql 动态SQLif元素choose 、when 、otherwise 元素trim 、where 、set 元素foreach 元素bind 元素 动态SQL 定义&#xff1a;根据不同条件拼接SQLy语句&#xff0c;实现对数据库更准的操作。 实现方式&#xff1a;映射器配置文件或者注解 常用动态SQL元素&…

oracle-事务一系列理解

一个事务开始后&#xff0c;会被分配一个唯一的id号&#xff0c;xid&#xff0c;xid不仅是一个编号也是一个地址。 事务表 存在undo表空间的某一个段的段头块&#xff0c;最多存放47个事务&#xff0c;事务开始的时候&#xff0c;先将信息写入这个表&#xff0c;所以一个undo段…

css宽度适应内容

废话不多说,看如下demo,我需要将下面这个盒子的宽度变成内容自适应 方法有很多,如下 父元素设置display:flex 实现子元素宽度适应内容 如下给父元素设置flex能实现宽度自适应内容 <!DOCTYPE html><html lang"en"><head><meta charset"U…

我开源了一个 Go 学习仓库

前言 大家好&#xff0c;这里是白泽&#xff0c;我是21年8月接触的 Go 语言&#xff0c;学习 Go 也正好两年半&#xff0c;我决定重启我之前未完成的计划&#xff0c;继续阅读《The Go Programing Language》&#xff0c;一年多前我更新至第五章讲解的时候&#xff0c;工作的忙…

K8S--daemonset小结

1、简介 1、daemonset中的pod会自动设置node.kubernetes.io/unschedulable污点的容忍度&#xff0c;所以即使一台机器被设置成无法调度&#xff0c;daemonset所控制的pod也会调度到该节点上。2、当有一个节点注册到K8S集群上的时候&#xff0c;daemonset控制器将会在该节点上运…

基于springboot+vue2的灾区物资管理系统(Java毕业设计)

大家好&#xff0c;我是DeBug&#xff0c;很高兴你能来阅读&#xff01;作为一名热爱编程的程序员&#xff0c;我希望通过这些教学笔记与大家分享我的编程经验和知识。在这里&#xff0c;我将会结合实际项目经验&#xff0c;分享编程技巧、最佳实践以及解决问题的方法。无论你是…

力扣第 379 场周赛VP

目录 一1.思路2.代码 二1.思路2.代码 三1.思路2.代码 四1.思路2.代码 链接:https://leetcode.cn/contest/weekly-contest-379/ 一 1.思路 找最长对角线&#xff0c;很显然直接比较a^2 b ^ 2就行 注意更新时考虑对角线长度相等时候去面积最大 2.代码 class Solution { publ…