树莓派和BLED112(Bluegiga)

3

我有两个蓝牙设备 (来自bluegiga的bled112)。其中一个连接到了RPI,并从另一个设备接收RSSI和硬件地址。在Windows和Ubuntu上工作正常,但在树莓派上读取设备文件 (/dev/ttyACM0) 时出现问题。

我正在使用更新后的Wheezy 3.6.11版本,已安装bluez。

这是我用来读取的程序:

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>

#include "cmd_def.h"


volatile int serial_fd;

void output(uint8 len1, uint8* data1, uint16 len2, uint8* data2)
{
    int written;

    written = write(serial_fd, data1, len1);
    if(written < 0) {
        fprintf(stderr, "ERROR: Writing data. %d\n", (int)errno);
        exit(-1);
    } 
    printf("WRITE1: %d bytes ; ", written);
    written = write(serial_fd, data2, len2);
    if(written < 0) {
        fprintf(stderr, "ERROR: Writing data. %d\n", (int)errno);
        exit(-1);
    }
    printf("WRITE2: %d bytes\n", written);
}

int read_message()
{
    int rread;
    const struct ble_msg *apimsg;
    struct ble_header apihdr;
    unsigned char data[256];//enough for BLE
    //read header
    printf("\t\tread_message entered\n");
    rread = read(serial_fd, (unsigned char*)&apihdr, 4);
    if(rread < 0) {
        return errno;
    } else if(!rread) {
        return 0;
    }
    printf("READ: header %d bytes ; ", rread);
    //read rest if needed
    if(apihdr.lolen)
    {
        rread = read(serial_fd, data, apihdr.lolen);
        if(rread < 0) {
            return errno;
        }
    }
    printf("READ: data %d bytes ; ", rread);
    apimsg=ble_get_msg_hdr(apihdr);
    if(!apimsg)
    {
        fprintf(stderr, "ERROR: Message not found:%d:%d\n",(int)apihdr.cls,            (int)apihdr.command);
        return -1;
    }
    apimsg->handler(data);

    return 0;
}

int main(int argc, char *argv[] )
{
    char* portname;

    portname = "/dev/ttyACM0";

    serial_fd = open(portname, O_RDWR | O_SYNC);
    if (serial_fd < 0)
    {
        fprintf (stderr, "error %d opening %s: %s", errno, portname, strerror (errno));
        return -1;
    }

    bglib_output = output;

    //stop previous operation
    ble_cmd_gap_end_procedure();
    //get connection status,current command will be handled in response
    ble_cmd_connection_get_status(0);

    //Message loop
    while(1)
    {
        if(read_message())
        {
            fprintf(stderr, "Error reading message\n");
            break;
        }
    }

    return 0;
}

RPI的输出为:

$ sudo scanApp
WRITE1: 4 bytes ; WRITE2: 0 bytes
WRITE1: 5 bytes ; WRITE2: 0 bytes
            read_message entered

在这一部分之后,它在读取函数中无限运行。如果有人能告诉我为什么它在树莓派上不起作用,我将非常感激。
编辑:使用串口找到了解决方案。
#include <termios.h>

int serial_handle;

int uart_open(char *port){
    struct termios options;
    int i;

    serial_handle = open(port, (O_RDWR | O_NOCTTY));
    if(serial_handle < 0)
        return -1;

    tcgetattr(serial_handle, &options); //get the current options for the port...
    cfsetispeed(&options, B115200);     //set Baud rate to 115200
    cfsetospeed(&options, B115200);     //enable the receiver and set param...
    options.c_cflag &= ~(PARENB | CSTOPB | CSIZE | CRTSCTS | HUPCL);
    options.c_cflag |= (CS8 | CLOCAL | CREAD);
    options.c_lflag &= ~(ICANON | ISIG | ECHO | ECHOE | ECHOK | ECHONL | ECHOCTL | ECHOPRT | ECHOKE | IEXTEN);
    options.c_iflag &= ~(INPCK | IXON | IXOFF | IXANY | ICRNL);
    options.c_oflag &= ~(OPOST | ONLCR);
    for ( i = 0; i < sizeof(options.c_cc); i++ )
        options.c_cc[i] = _POSIX_VDISABLE;
    options.c_cc[VTIME] = 0;
    options.c_cc[VMIN] = 1;
    //set new opt for the port
    tcsetattr(serial_handle, TCSAFLUSH, &options);
    return 0;
}

int uart_close(){
        close(serial_handle);
}

//write to uart_port
 int uart_tx(int len, unsigned char *data){
     ssize_t written;
     while(len){
        written = write(serial_handle, data, len);
        if(!written)
            return -1;
        len -= written;
        data += len;
     }
  return 0;
 }

 //read from uart_port
 int uart_rx(int len, unsigned char *data, int timeout_ms){
    int l=len;
    ssize_t rread;
    struct termios options;
    tcgetattr(serial_handle, &options);
    options.c_cc[VTIME] = timeout_ms/100;
    options.c_cc[VMIN] = 0;
    tcsetattr(serial_handle, TCSANOW, &options);
    while(len){
            rread = read(serial_handle, data, len);
            if(!rread){
                 return 0;
            } else if(rread < 0) {
                return -1;
            }
            len-=rread;
            data+=len;
    }
    return l;
}


int main(){
     char* portname = "/dev/ttyACM0";
     serial_fd = uart_open(portname);
     if (serial_fd < 0){
         fprintf (stderr, "error %d opening %s: %s", errno, portname, strerror (errno));
         return -1;
     }

     bglib_output = output;
     //reset dongle
     ble_cmd_system_reset(0);
     uart_close();
     do{
         usleep(500000);
         //and start again
     }while(uart_open(portname));

     //stop previous operation
     ble_cmd_gap_end_procedure();
     //get connection status,current command will be handled in response
    ble_cmd_connection_get_status(0);

    //Message loop
    while(1){
        if(read_message()){
            fprintf(stderr, "Error reading message\n");
            break;
        }
    }

    uart_close();
    return 0;
}

在output()中使用:

 written = uart_tx(len1, data1);
 written = uart_tx(len2, data2);

在read_message()函数中:

 rread = uart_rx(sizeof(apihdr), (unsigned char*)&apihdr, 1000);
 rread = uart_rx(apihdr.lolen, data, 1000);
1个回答

0
如果您的 Raspberry Pi 上可以运行 Java,您可以尝试使用此 BLE 112 Java API
要在 Raspberry Pi 上安装 Java,请执行以下命令:sudo apt-get update && sudo apt-get install oracle-java7-jdk。详细了解安装过程

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接