返回 登录
0

基于LinkNode的机器人手臂状态监视器的设计

作者:陈劼
责编:周建丁(zhoujd@csdn.net)

Linksprite最近推出了一款支持mbed编程的蓝牙开发板LinkNode,感谢Linksprite公司和CSDN的活动,本人有幸在第一时间拿到了这块蓝牙开发板,用以完成机器人手臂状态监视器的设计。

LinkNode开发板

下面先展示一下这块开发板。

图片描述

板子的包装比较简单,配件也不多,包括几条杜邦线用于与额外的模块进行连接,几颗铜柱螺丝用于安装,然后就是一块用防静电袋子装着的LinkNode。

图片描述

LinkNode的全貌如下。
图片描述

LinkNode是一款可穿戴设备原型开发板,支持BLE4.0,完全兼容mBed编程。板上集成了功能强大的器件,如nRF51822低功耗蓝牙SoC、LIS3DH超低功耗三轴线性加速度传感器、BMP180气压/温度传感器等等。同时,嵌入了一个兼容mBed下载的编程器,使得应用的开发和下载变得非常方便。

如上图所示,左边那部分就是LinkNode的主要部分,在做实际产品的时候只要用到那部分就行,而右边那部分是一个编程器,和J-LINK一样。

编程器模块

在介绍主要部分之前,先简单介绍一下那个编程器模块。编程器模块的近照如下:

图片描述

编程器模块的主控制器是ATSAM3U2C,这个是Atmel公司推出的 32-bit ARM Cortex®-M3内核的微控制器,拥有高达128KB的Flash,主频为96MHz。这个芯片最大的特点就是完全兼容ARM的mBed下载,大大简化了下载的流程。

图片描述

编程器模块的其余部分包括一个micro-USB口用于从电脑下载程序,一系列的GPIO口用于独立使用这个编程器,还有一个开关,一个复位按钮,整体设计非常简单。实际上就是一个ATSAM3U2C的最小单片机系统。

这个编程器与主要部分的连接依靠I2C总线,如果使用者有其他的编程器也可以使用。

板载硬件资源

说完编程器,下面就到主要部分的介绍。先来一张图片。

图片描述

然后介绍一下板载硬件资源,其中包括:

  • NRF51822: 蓝牙低功耗&2.4GHz 无线SoC
  • LIS3DH:超低功耗三轴加速度传感器
  • BMP180:温度气压传感器
  • 8 x GPIO pins
  • 1 x UART port
  • 1 x 双色 LED
  • 2 x 用户按键
  • 1 x 蜂鸣器

这个板的主控制器是NRF51822,先介绍一下这个芯片,这个芯片集成了如下部分:

图片描述

  1. 2.4 GHz收发器,就是蓝牙
  2. ARM® Cortex™-M0 32 bit 内核
  3. 一路 32 位 和 两路 16位 时钟、计数器
  4. 8/9/10位ADC – 8路采集通道
  5. 低功耗模式

如果对计算处理速度没有特别的要求的话,这个NRF51822可以作为传感器平台的主控制器,可以采集模拟、数字信号并进行初步处理然后通过蓝牙发送出去。至于低功耗模式,由于本项目用于工业,因此对功耗没有特殊要求,若是这个模块用于可穿戴设备则有很大意义。

项目开发

介绍完硬件以后,就开始运用这个开发板进行项目开发。

mbed编程

首先,这个开发板支持mbed编程,这里简单介绍一下mbed。mbed是一个面向ARM处理器的原型开发平台,它具体包括免费的软件库(SDK),硬件参考设计(HDK)和在线工具(Web)三部分内容。在这个平台上面,可以进行各式各样的ARM芯片的编程,只要平台支持。用户不需要下载很大的软件,也不需要去寻找各种库文件,只要专注于编程即可。
要使用ARM mbed,首先要登陆官网https://www.mbed.com/zh-cn/并注册一个账号,如下图:

图片描述

点击右上角的黄色按钮,进入如下界面:
图片描述

然后点击右上角的complier即可进入如下界面,开始编程:
图片描述

首先找到目标开发板,点击右上角开发板按钮,弹出下图,找到图示这块板:
图片描述

然后点击select platform即可选中这块板。

在正式编程之前,先运行一个简单程序,以便验证下载方法。

在编程区域加入如下代码:

#include<mbed.h> //包含头文件名,所有mbed程序里面必须有这句
DigitalOut LED_R(P0_20);  //定义引脚,P0.20作为红色LED
DigitalOut LED_B(P0_19);  //定义引脚,P0.19作为蓝色LED
int main()
{
while(1)
{
LED_R=1;   //输出1作为高电平
LED_B=1;   
wait(0.5);   //延时0.5s
LED_R=0;
LED_B=0;
wait(0.5);
}
}

解释一下上面那个程序,看下图,P0.20是控制红色LED的,P0.19是控制蓝色LED的
图片描述

然后点击编译,并下载编译好的程序:
图片描述

将该HEX文件拖入识别到的flash空间运行即可:
图片描述

运行时将会看到红蓝两个LED灯同时发光。

这样就完成一个程序的下载与运行,还是很方便的。

编写程序

接着就开始编写我们需要的程序了。首先这个项目需要用到两个传感器。一个是加速度传感器。一个是温度传感器。系统的大概框图如下:

图片描述

首先运行一个能够使用BMP180的程序。程序如下:

#include <stdio.h>
#include <mbed.h>
#include <BMP180.h>

Serial pc(P0_23,P0_25);
DigitalOut led(P0_20);
I2C i2c(P0_17, P0_18);
BMP180 bmp180(&i2c);

int main(void) {

    while(1) {
        if (bmp180.init() != 0) {
            printf("Error communicating with BMP180\n");
        } else {
            printf("Initialized BMP180\n");
            break;
        }
        wait(1);
    }

    while(1) {
        bmp180.startTemperature();
        wait_ms(5);     // Wait for conversion to complete
        float temp;
        if(bmp180.getTemperature(&temp) != 0) {
            printf("Error getting temperature\n");
            continue;
        }

        bmp180.startPressure(BMP180::ULTRA_LOW_POWER);
        wait_ms(10);    // Wait for conversion to complete
        int pressure;
        if(bmp180.getPressure(&pressure) != 0) {
            printf("Error getting pressure\n");
            continue;
        }

        printf("Pressure = %d Pa Temperature = %f C\n", pressure, temp);
        wait(1);
    }
}

将这个程序按照上面所述下载到芯片上面,就能够查看到温度了。

然后进行蓝牙通讯实验。实验的代码如下:

#include <mbed.h>
#include <ble/BLE.h>

#include <ble/services/UARTService.h>

#define NEED_CONSOLE_OUTPUT 0
#if NEED_CONSOLE_OUTPUT
#define DEBUG(...) { printf(__VA_ARGS__); }
#else
#define DEBUG(...)
#endif

BLEDevice  ble;
DigitalOut led1(LED1);

UARTService *uartServicePtr;

void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
{
    DEBUG("Disconnected!\n\r");
    DEBUG("Restarting the advertising process\n\r");
    ble.startAdvertising();
}

void onDataWritten(const GattWriteCallbackParams *params)
{
    if ((uartServicePtr != NULL) && (params->handle == uartServicePtr->getTXCharacteristicHandle())) {
        uint16_t bytesRead = params->len;
        DEBUG("received %u bytes\n\r", bytesRead);
        ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead);
    }
}

void periodicCallback(void)
{
    led1 = !led1;
}

int main(void)
{
    led1 = 1;
    Ticker ticker;
    ticker.attach(periodicCallback, 1);

    DEBUG("Initialising the nRF51822\n\r");
    ble.init();
    ble.onDisconnection(disconnectionCallback);
    ble.onDataWritten(onDataWritten);

    /* setup advertising */
    ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
    ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
    ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
                                     (const uint8_t *)"BLE UART", sizeof("BLE UART") - 1);
    ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
                                     (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));

    ble.setAdvertisingInterval(1000); /* 1000ms; in multiples of 0.625ms. */
    ble.startAdvertising();

    UARTService uartService(ble);
    uartServicePtr = &uartService;

    while (true) {
        ble.waitForEvent();
    }
}

运用这个程序可利用软件nrftoolbox与开发板进行串口信息交互。

项目目前只进行到这里,通过上述两个实验进行整合最终期望达到的目标是利用蓝牙串口发送一串指令,比如测温度的指令,芯片能通过蓝牙串口做出回应。

目前上位机的app还在开发当中,还没有结果。。。。。。

评论