Linknode开发板评测

一、开箱与三个sensortag对比

拿到LinkNode,看了看包装,Mbed BLE sensors Tag,那咱也当他是一个sensortag吧,正好手头还有两颗Ti的sensortag,一起比较以下哦。先看看三个小家伙的包装对比,咱们的LinkNode是最小的。

然后是板子对比,也是linknode最小,而且已经自带了下载器,还是mbed的哦。而Ti的还是需要另找调试器的,关键调试器接口还是1.27间距的,相当的难弄。不过Linknode用的是2.0mm间距的口子,所以附送了2.0转2.54的杜邦线,以及2.0mm的排针,也算细心了。可是调试口明明只用了4个,为啥要来6孔2.0mm呢,变成4孔2.54mm的不是挺好?

LinkNode尺寸的减小,主要是两个方面造成的,首先,Ti全部使用PCB天线,而LinkNode使用了陶瓷天线,就是照片上那颗蓝色的,这个差别很大。另外,T1使用的传感器众多(在后面表格中有比较),而LinkNode只是板载了加速度和大气压,还是比较简单的。不过LinkNode比较有特色的是板载了一颗buzzer,就是蜂鸣器了,非常适合来做一个随身的提醒功能,多了一样用户交互方式。
最后是三个家伙的比对,可以看到nRF51822的性能功耗在三者中处于中档的样子。

二、开发环境与第一个mbed程序

概要:按照官方wiki做就行,注意事项:开发板自带的flash盘的链接添加的是nRF51-DK,用这个是不行的,必须用nRF51822,原因未知。具体过程如下。

将开发板插入电脑后,会看到一个名字叫JLINK的flash盘,里面有4个文件,从readme的文档中可以知道,这个就是用来更新目标板程序用的flash盘,只要把hex文件拖进去,就可以完成程序的下载。

在浏览器中打开其中的MBED.HTM,则会自动连接到mbed网站,并将对应的开发板加入到自己账户名下,很是方便。同时也说明了我们的开发板其实对应的就是Nordic nRF51-DK,至少在编程器部分是相同的。

写到这里发现忽然有点问题,就是官方的wiki上说选用的是Nordic nRF51822,到底应该用哪个?还得后续试用才知道。

所以就让我们从点亮LED开始吧,原理图显示,低电平点亮,R连P020,蓝色P019

mbed的代码组织和开发过程倒是和常见的IDE相似,原始界面如下图,workshop下面就是自己的各个program了。可以新建,也可以导入,最右边是帮助。

点新建可以出来界面,我们来一个LinkNode_blink

然后增加一个main.cpp文件,并在里面添加官网代码

  1. #include<mbed.h>

  2. DigitalOut LED_R(P0_20);

  3. DigitalOut LED_B(P0_19);

  4. int main()

  5. {

  6. while(1)

  7. {

  8. LED_R=0;

  9. LED_B=1;

  10. wait(0.5);

  11. LED_R=1;

  12. LED_B=0;

  13. wait(0.5);

  14. }

  15. }

复制代码

如果忘记导入mbed库,会有错误提示,

点击fix it可以自动跳出lib的搜寻结果,找到合适添加一下就好了,添加完以后会自动重新编译(也可以编译前手动导入)。

编译成功就可以下载hex文件到本地啦,不过不能直接下载到那个jlink盘里面,要下载到本地,然后再拖进去。复制进去以后会自动重启,可是,并没有看到什么blink!!试了很多次还是这样,最后忽然想到,要不换一块板?从nRF51DK换成nRF51822,成功闪烁!!看来有时盘里的东西也不一定靠谱啊,还是看官网的说明比较靠谱。

三、mbed之用户交互-串口

LinkNode上的用户交互主要有按键、LED、buzzer,但是更重要的是uart,一般mbed除了虚拟U盘(MSD programmer) 外,还有两个设备,分别是CMSIS-DAP Debug和虚拟串口。

不过虚拟串口和debug这两个不能默认使用,必须先装驱动。串口界面在此,可是并不能装
https://developer.mbed.org/handbook/Windows-serial-configuration
只好求助于nordic的官网。可惜是51822mDK是一个discontinued的产品,也没找到合适的驱动。论坛求助以后给了一个新的固件,可能目前并不是标准的mbed?不过考虑到后面要退回的,暂时也不影响评测,那就先对付着用着吧。串口就先使用另外引出的P023和P025。

so,我们先通过串口来采集一下bmp180的大气压和温度。mbed的一个优势是有大量共享的库可以用,比如这个bmp180在mbed上就能搜到,我们直接使用lib方式就好了。会有很多,选一个介绍比较全面一点的

比如上面这个,里面有class reference

还有具体使用示例,节省空间,帖个部分

只要复制这个代码就行,唯一需要修改的就是I2C的具体管脚(sda,scl),

  1. I2C i2c(P0_17, P0_18);

复制代码

并增加一个串口界面,示例中直接使用了printf,应该是打印到了默认的串口上了吧。如果删除下面这行,编译没有问题,但是串口上就没有任何东西啦。

  1. Serial pc(P0_23,P0_25);

复制代码

剩下就没有剩下了,编译下载,顺利看到现象。

顺便总结下bmp180的使用过程(以温度为例):

  1. bmp180.init();  //返回0表示成功

  2. bmp180.startTemperature();

  3. wait_ms(5);

  4. bmp180.getTemperature(&temp);//返回0表示成功

复制代码

四、BLE双向数据传输

mbed上有不少关于ble的例子,用BLE搜索到的项目有43页,其中很多都是针对nRF51822的,可以直接拿来用。

那我们就先选用那个simplechat好了,看说明应该是配合某个app来实现双向数据传输的,BLE的显示终端是串口,而手机的显示终端就是某个app。

不过这个app上的uart和LinkNode的定义是不一样的,因此我们需要来做一下改造。在OOP下,这个也很容易,只要把main里面的//Serial pc(USBTX, USBRX);改为Serial pc(P0_23,P0_25);就可以了。初始打印串口上有些问题,主要体现在计数值的输出上,会出现乱码,其实主要是在调用串口的putc方法的问题,本来应该显示对应数值的ascii码,结果实际将byte值直接输出了。

所以只要将putc直接用printf的%d代替就可以了,修改前代码

  1. pc.printf("Length: ");

  2. pc.putc(bytesRead);

  3. pc.printf("\r\n");

复制代码

修改后代码

  1. pc.printf("Length: %d\r\n",bytesRead);

复制代码

这样就可以完美实现LinkNode和手机通过BLE的双向数据传输了。没有安装例子上说的app,直接用了一个通用的调试工具,lightblue。具体效果看视频。需要注意的是,LinkNode串口收到数据后,会把\r\n都算成字符数目,所以看到的是6,而实际可见字符只有4个。
flash视频请点击阅读原文。

另外有一个隐藏的问题,就是长UUID和短UUID的问题,前面用长uuid有问题,

  1. static const uint8_t uart_tx_uuid[]   = {0x71, 0x3D, 0, 3, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};

复制代码

换了短的UUID就行。

  1. #define BLE_UUID_TX_CHARACTERISTIC       0x0002

复制代码

但是这个问题没法复现,对应一个char的问题,研究一下另开贴讨论。

五、LinkNode玩呼吸灯

这个其实就是利用PWM的占空比来控制LED的亮度,对于单片机来说是很普通的功能,但在mbed下会发现更加无法想象的简单。在没有看官方例子前,总觉得该配置点定时器什么的,然后再得到PWM。结果并非如此。因为已经定义了PwmOut这个类了!!官方例子是控制蜂鸣器演奏一首歌曲,那我们就改造成呼吸灯吧。不够在pwm的duty-cycle设置中有个小坑,跟大家分享一下。

编程环境,mbed,添加mbed库即可。在库中可以找到pwm类的说明,还是比较简单的。下图所示的方法用用就够了

另外write和read可以简单的用实例=和=实例来完成。废话少说,先来试试这个duty-cycle到底是数字大亮还是数字小亮。既然是百分比,那么肯定在0-1.0之间取值。我们给两盏LED都点上

  1. #include <mbed.h>

  2. PwmOut L_red(P0_20);

  3. PwmOut L_blue(P0_19);

  4. int main(void){

  5. L_red=0.1;

  6. L_blue=0.9;

  7. while(1){

  8. }

  9. }

复制代码

实验结果:红灯很亮,蓝灯比较暗。但是因为IO口接的是LED灯的阴极,所以这个duty-cycle数字表示的是高电平的比例。然后就是咱们的呼吸灯了,定时改变占空比咯。蓝色比较优雅,就选它了。不过很奇怪 ,现象并不乐观,首先使用这段代码,预期是灯从最暗变到最亮,然后再回到最暗。

  1. #include <mbed.h>

  2. PwmOut L_blue(P0_19);

  3. int main(void){

  4. L_blue=1.0;

  5. while(1){

  6. wait(1);

  7. L_blue=L_blue-0.2;

  8. if (L_blue==0) {

  9. L_blue=1.0;

  10. }

  11. }

  12. }

复制代码

结果实际情况是:从暗变到最亮,然后就停在最亮状态不变了!!开始以为是0值比较问题,可是把第三行变成L_blue<0也没戏。参考了下mbed的PWM例程。也是失败。

但是while(1)中,使用这段代码可以。

  1. wait(1);

  2. L_blue=1.0;

  3. wait(1);

  4. L_blue=0.8;

  5. wait(1);

  6. L_blue=0.6;

  7. wait(1);

  8. L_blue=0.4;

  9. wait(1);

  10. L_blue=0.2;

  11. wait(1);

  12. L_blue=0.0;

复制代码

想了半天,最后使用了一个中间变量dc,严格保证给到L_blue的值一定在0和1之间。于是就成功了。最终完整代码如下:

  1. #include <mbed.h>

  2. PwmOut L_blue(P0_19);

  3. int main(void){

  4. float dc=0.0;

  5. L_blue=dc;

  6. L_blue.period_us(10);

  7. while(1){

  8. wait(1);

  9. dc=dc+0.2;

  10. if (dc>1.1) {

  11. dc=0.0;

  12. }

  13. L_blue=dc;

  14. }

  15. }

复制代码

看来mbed也是有坑的啊,官方例程也靠不住。当然也许在底层实现中,有些mcu会自动检查duty-cycle的范围,有些就没有?如果误写入了不合理的数值,可能就引起单片机的奇怪状态了。库的源文件并不可见,所以也不追究了。

六、并不成功的LinkNode的三轴加速度计

概要:按照官方代码,读不到正常数据。初步估计原因可能有以下几个:1、SPI驱动有问题。可是呢IO口没有引出,没法测试。2、主芯片和LIS3DH之间的连接有问题,导致不能正常通信。看了看引脚太小,没法测试。具体过程描述如下。

LinkNode上有一个LIS3DH,可是官方手册上并没有给出参考代码。就连SPI的参考代码都没有。不过linksprite的wiki上有,可以在以下网址找到(http://linksprite.com/wiki/index ... IS3DH_accelerometer)。
本来想利用mbed的库从头建个工程看看,但是搜索了以下,发现LIS3DH的库和项目都只有2个,而且都是i2c接口的。虽然芯片CS拉高就是i2c模式,但是看原理图,并没有看到有接i2c上拉电阻,所以还是乖乖用SPI,参考官方代码来写吧。有时间再转换一下i2c驱动到SPI吧。

官方代码比较简单,就是写了一个SPI的初始化,读写寄存区的子函数,然后调用。结果烧写以后满屏的“device err”。这又是什么鬼??!!

看了下代码,每次读数都会查看下芯片的ID,如果是0x33,表示有芯片,如果不是,则显示上图的出错信息。
打印了一下收到的who am i,发现都是255。这说明MI上全是高电平啊。

绕过who am I检测,强制读取三轴的值就是这么个死相

改造下显示代码,其实是以下这么回事,也就是说,读到的全是1。和读who am I的结果一致。真是醉了

可怜的SPI引脚也没有引出,无法测试。有没有人可以跑动这个例程的呢?

七、BLE light

尝试使用手机控制两个LED灯的亮度。本次是在nRF51822_SimpleControls基础上修改的。因为redbear的app只能控制一个LED,所以手机上配合通用的BLE调试工具完成。不求功能复杂,只要控制亮度就行,玩转整个流程。
删除servo.cpp和servo.h
service只留下一个可写的LIGHT_CHAR

  1. #define BLE_UUID_LIGHT_SERVICE            0x0000 /**< The UUID of the Nordic UART Service. */

  2. #define BLE_UUID_LIGHT_CHARACTERISTIC       0x0002 /**< The UUID of the TX Characteristic. */

复制代码

控制单元只留下两个灯,都是PwmOut

  1. PwmOut          LEDR(LIGHT_R);

  2. PwmOut          LEDB(LIGHT_B);

复制代码

修改串口Pin,显示调试信息。

  1. Serial pc(P0_23,P0_25);

复制代码

注释掉所有的长UUID,测试只用短的UUID是否可行。
手机发送控制命令2个字节,第一字节指定控制哪个LED,1 for LEDR,2 forLEDB。第二个字节表示灯的亮度,0是熄灭,0xff是最亮。对应的代码也要修改,因为PWM接的是LED的阴极。

  1. float value = 1.0-(buf[1]/255.0);

  2. LEDR = value;

复制代码

效果看视频。控制命令格式如上所述,测试结果,短UUID是可以的。用通用app控制还是有点慢啊,其他七七八八修改的东西都是细节,一并附在附件里面吧。

未完,待续……

(0)

相关推荐