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

在这部分之后,它在 read-function 中无限运行。如果有人能告诉我,我会非常感激,为什么它在树莓派上不起作用?

编辑: 找到了 uart 的解决方案:

#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;
}

在输出()中使用:

 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);
4

1 回答 1

0

如果 Java 是在您的 Raspberry Pi 上运行的选项,您可以试试这个 BLE 112 Java API

Raspberry Pi 上安装 Java sudo apt-get update && sudo apt-get install oracle-java7-jdk

于 2013-04-29T19:45:40.200 回答