本应用笔记详细介绍了如何连接DS9490R、温度记录仪iButton器件和Android的USB On-the-Go(OTG)。审查每个部分之间的通信协议。我们回顾数据手册信息以及如何将其应用于终端系统。演示示例代码的示例 Android 应用程序也可供下载。
介绍
睤。智能手机无处不在。智能手机不仅仅是一部电话,而是一台功能强大的计算机,可以放在口袋里。由于智能手机中可用的计算能力和传感器不断增加,现在使用该手机作为其他设备的接口是切实可行的。本文介绍如何使用 Android 智能手机上的 USB 端口与没有计算机系统的从属设备进行通信。此处的示例使用1-Wire总线通过USB从Android到Thermochron iButton温度记录器进行通信。®®®®
系统布局
此应用程序的关键是智能手机上的USB端口。当智能手机使用USB移动(OTG)收发器时,USB主机功能可以通过其他从设备实现,例如鼠标,闪存驱动器,键盘或此处的Thermochron。最新版本的 Android 应用程序编程接口 (API) 在应用程序级别支持 USB 主机模式。此功能允许最终用户安装与 USB 外围设备“对话”的应用程序,而无需在用户的智能手机上生根或安装特殊驱动程序。
系统框图如图1所示。安卓智能手机必须使用 USB OTG 收发器。通常,手机连接到计算机并充当USB从站,但USB OTG收发器允许将手机转换为USB主站。这种角色转换需要一根特殊的OTG电缆来提供USB A型端口,并发出USB从站连接到智能手机的信号。
此应用程序是一个主从系统,以Android智能手机为主,Thermochron数据记录器作为从机。系统使用USB转1线/iButton(DS9490R)适配器将智能手机与数据记录器桥接。使用网络电缆/插座DS1402D-DR8作为1-Wire总线,只需要一条数据线。数据记录器是iButton温度记录器(DS1921G)。
图1.系统框图使用DS9490R 1-Wire适配器作为智能手机和应用器件之间的接口;DS1402D-DR8总线电缆连接到应用器件,此处为DS1921G温度时线iButton。
1-Wire总线的重要作用
1-Wire总线是单主系统与多从系统之间的接口。1-Wire输出为漏极开路,采用类似于I2C. 一些1-Wire从机可以由1-Wire总线寄生供电,当不发生通信时,该总线为从器件中的内部电容器充电。每个1-Wire从器件还具有一个工厂光刻的、唯一的64位注册号,因此每个从器件都可以在总线上轻松识别和监控。
1-Wire交易序列(图2)由复位脉冲(trst) 发送给奴隶。复位脉冲通过按住1-Wire总线预定的时间段,使所有从机进入已知状态。接下来,从机通过存在检测脉冲(tPD),在主站释放总线后将其拉下。
图2.1线时序图。
复位后,从设备可以接受针对每个从设备的各种ROM命令,这些命令由其注册号标识。匹配ROM的命令仅激活具有正确标识注册的单个从设备。搜索ROM用于发现总线上所有从站的注册号。因此,尽管我们在这里只显示一个从器件,但该应用可以有多个1-Wire兼容的从器件。
一旦选择了特定的ROM命令,那么设备特定的命令就可以由主节点发出,在我们的例子中是Android。使用像Thermochron这样的温度记录器作为从站,主机的命令可能涉及写入或读取其暂存器或存储器,或转换温度。
1-Wire接口没有时钟线,因此通信被分成多个时隙(t槽),每个都携带一点信息。在时隙开始时,主站会短暂地拉下总线以指示位的开始。传输零点时,主站或从站继续保持总线低电平。传输一个时,主站或从站释放总线。主站或从站按规定的时间读取总线(t样本) 之后,母版指示时隙的开始。
与1线适配器的USB通信
DS9490R是1线转USB适配器,具有四个USB端点:控制、中断、批量输入()和批量输出()。通常,控制端点用于向1-Wire适配器发送命令并设置传输类型。批量输入/输出用于数据传输,中断终结点用于接收状态寄存器和返回消息等时间敏感信息。epINepOUT
使用安卓作为 USB 主机
这里提出的设计是有先例的。Android API 从版本 3.1 开始,支持 USB 主机模式。曼努埃尔·迪·塞尔博1通过USB将Arduino微控制器板与Android手机连接。我们的应用修改了DiCerbo的工作,将基本概念扩展到DS9490R USB转1-Wire适配器,并将1-Wire适配器与Thermochron配合使用,而不是微控制器。
DiCerbo示例代码是该项目的基础。该代码首先请求用户允许访问连接到Android智能手机的USB设备。然后,程序搜索供应商和设备 ID,并设置 USB 终结点以进行通信。该代码提供 ,用于执行批量和控制传输的 USB 设备连接;它为批量输入和 .这与所有系统用于初始化USB并将低级USB命令写入从站的基本设置相同。
现在我们将演示如何使用Android在温度上执行温度转换并读取温度结果。每个事务步骤(表 1)都以 开头,后跟选择从设备,然后是最终特定于设备的命令。
表 1.1-Wire主机对温度数据记录器执行的命令
1线复位 | 匹配光盘 | 转换温度 |
1线复位 | 匹配光盘 | 读存储器/寄存器 |
1-Wire复位通过USB控制传输执行,Android API的控制传递函数原型如下所示。
// Performs a control transaction on endpoint zero for this device. int controlTransfer(int requestType, int request, int value, int index, byte[] buffer, int length, int timeout)
控制传输用于启动 、 或 。参数在数据手册中描述。稍后,我们将说明如何使用此函数。
批量传输用于读/写内存。这里的端点将是 或 ,取决于我们是读取数据还是写入数据。终结点缓冲区存储要发送的数据,或者为空以存储接收的数据。长度是接收或发送的字节数。超时是以毫秒为单位的 USB 超时设置。
// Performs a bulk transaction on the given endpoint. int bulkTransfer(UsbEndpoint endpoint, byte[] buffer, int length, int timeout)
此处显示了将转换温度命令 (0x44) 发送到温度时线的代码。如前所述,第一行1-Wire复位通过控制传输发送(表1)。这是 、 ,它转换温度序列。
// 1-Wire Reset 1 conn.controlTransfer(0x40, 0x01, 0x0C4B, 0x0001, null, 0x0000, 0); // Match ROM, where romid is the iButton's registration number 2 romid = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 3 conn.bulkTransfer(epOUT, romid, 8, 0); 4 conn.controlTransfer(0x40, 0x01, 0x0065, 0x55, null, 0, 0); // Convert Temperature for DS1921G 5 data = new byte[]{0x44}; 6 conn.bulkTransfer(epOUT, data, data.length, 0); 7 conn.controlTransfer(0x40, 0x01, 0x1075, data.length, null, 0, 0);
在上面的第4行中,匹配访问控制传输在0-Wire总线上发送一个、55x1、匹配访问ROM命令,后跟所需从站的ROM注册号。1-Wire Reset2索引参数设置为 0x55。match 访问命令要求用户将注册号预加载到 ,如代码的第 2 行和第 3 行所示。功能参数在DS2490数据资料中描述。
温度小时管的数据表将0x44标识为开始温度转换的代码。(表2)。转换温度命令通过使用块 I/O 操作写入0x44来执行。对于块 I/O 操作,将输出数据写入,如上面的第 6 行所示。然后,第 7 行中的控制传输执行块 I/O 命令。epOUT
表 2.温度存储器和控制命令(使用批量 I/O)
内存/控制命令 | 命令代码 | 描述 |
---|---|---|
读内存 | 0xF0 | 从内部寄存器读取数据。按照寄存器地址的命令进行操作,首先使用 LSb。继续为每个字节读取0xff虚拟数据。 |
转换温度 | 0x44 | 开始温度转换。 |
下面的代码显示了通过USB批量I/O传输读取温度寄存器数据的顺序。温度时线的读取存储器命令代码0xF0(请参阅表 2)。接下来是 0x0211 的目标寄存器地址 (TA),该地址具有只读访问权限,并分为两个字节(第 8 行)。在1-Wire总线上写入和发送的数据全部环回主机,因为总线仅由一根线组成。然后,主站需要将虚拟数据(0xff)写入总线。从机响应并覆盖0xff数据,因为如前所述,1-Wire是一条漏极开路总线。净效应是数据与0xff的 AND。
这一系列命令被放到1-Wire总线(第9行和第10行)上,控制传输通过发送命令来执行命令。回读数据位于 USB 终结点 中。这是在第 12 行的批量传输命令复制到的。然后将生成的原始温度代码转换为第 13 行的相应温度值。epOUTepINtempdata
// 1-Wire Reset and Match ROM // (omitted) ... // Read Temperature Register/Memory Command // Read Memory, TA2, TA1, dummy data 8 command = new byte[] {(byte)0xf0, 0x11, 0x02, (byte)0xff, (byte)0xff}; 9 conn.bulkTransfer(epOUT, command, command.length, 0); 10 conn.controlTransfer(0x40, 0x01, 0x1075, command.length, null, 0, 0); // Return Data from input endpoint 11 byte[] tempdata = new byte[5]; 12 conn.bulkTransfer(epIN, tempdata, 5, 0); // Temperature calculation 13 temperature = (int)(tempdata[4] & 0xff)/2.0 – 40;
我们的安卓应用程序示例
示例 Android 应用程序如图 3 所示。当用户运行程序并按“枚举”按钮时,将显示一个屏幕,询问访问 USB 设备的权限。用户点击确定后,应用程序将执行搜索并在下拉菜单中列出所有从站的64位注册号。当用户选择特定的注册号时,应用程序将执行上述例程,并显示来自温度时线的实时温度。枚举按钮和注册号的选择连接到生成一个 .这些任务是完成请求的操作并在完成后更新用户界面 (UI) 的线程。这些任务不会在 UI 线程中执行,以防止它在等待 iButton 响应时冻结。
在最终应用中,代码被抽象为一般的1-Wire操作,如、、、、和。此外,这些命令一起可以进一步抽象为 iButton 函数,例如 和 。这允许调用正确的函数。
图3.Android 应用程序,USB 权限(左)。特定温度时线iButton的温度测量由其注册号(右)标识。
示例应用包含用于将用户交互(如按下按钮)链接到1-Wire从机执行命令的UI代码。除DS1921G温度时线外,该应用还支持iButton温度记录仪(DS1922L/DS1922T)和iButton湿度记录器(DS1923)。如图3所示,每个器件的注册号分为三个字段:家族代码、序列号和循环冗余校验(CRC)。可以从每个注册号读取家族代码,以确定确切的设备型号。
结论
此示例应用程序的代码是使用 Eclipse 编程的,可供下载。访问整个项目文件后,可以轻松浏览和修改源代码。项目代码使用抽象函数间接使用低级 USB 命令。本文末尾的一般参考资料有助于理解Android USB API和1-Wire命令。这些资源广泛用于开发此示例应用程序。可能的修改可能会改变应用,使其可与其他5V 1-Wire从器件(如存储器)配合使用,或启用其他iButton功能。可定制的选项很多,最终结果取决于设计人员的系统要求。
审核编辑:郭婷
-
智能手机
+关注
关注
66文章
18474浏览量
180070 -
usb
+关注
关注
60文章
7927浏览量
264403 -
适配器
+关注
关注
8文章
1948浏览量
67990
发布评论请先 登录
相关推荐
评论