我目前正在使用GitHub上出色的hoverboard-firmware-hack源代码,它的确很棒。我目前正在使用UART协议,因此可以通过串行UART与Hoverboard主板进行通讯。主机慷慨地提供了一些arduino示例代码,以使用自定义固件协议发送基本命令:
SoftwareSerial mySerial(10, 11); // RX, TX
typedef struct MsgToHoverboard_t{
unsigned char SOM; // 0x02
unsigned char len; // len is len of ALL bytes to follow, including CS
unsigned char cmd; // 'W'
unsigned char code; // code of value to write
int16_t base_pwm; // absolute value ranging from -1000 to 1000 .. base_pwm plus/minus steer is the raw PWM value
int16_t steer; // absolute value ranging from -1000 to 1000 .. wether steer is added or substracted depends on the side R/L
unsigned char CS; // checksumm
};
uint16_t baseSpeed = 0;
typedef union UART_Packet_t{
MsgToHoverboard_t msgToHover;
byte UART_Packet[sizeof(MsgToHoverboard_t)];
};
void setHoverboardPWM( int16_t base_pwm, int16_t steer )
{
UART_Packet_t ups;
ups.msgToHover.SOM = 2 ; // PROTOCOL_SOM; //Start of Message;
ups.msgToHover.len = 7; // payload + SC only
ups.msgToHover.cmd = 'W'; // PROTOCOL_CMD_WRITEVAL; // Write value
ups.msgToHover.code = 0x07; // speed data from params array
ups.msgToHover.base_pwm = base_pwm;
ups.msgToHover.steer = steer;
ups.msgToHover.CS = 0;
for (int i = 0; i < ups.msgToHover.len; i++){
ups.msgToHover.CS -= ups.UART_Packet[i+1];
}
mySerial.write(ups.UART_Packet,sizeof(UART_Packet_t));
}
这非常好!我目前正在尝试在RPi上执行此操作,并且不会太遥远,因为Python可能会令人困惑,因为它的类型不是很严格,因此字节大小可能很难指定。
我尝试使用termios在C ++中做到这一点,但并没有走得太远。功能如下:
//Hover couch Serial test
#include <cstdint>
#include <iostream>
#include <stdio.h>
#include <unistd.h> //Used for UART
#include <fcntl.h> //Used for UART
#include <termios.h> //Used for UART
using namespace std;
typedef struct MsgToHoverboard_t
{
unsigned char SOM; // 0x02
unsigned char len; // len is len of ALL bytes to follow, including CS
unsigned char cmd; // 'W'
unsigned char code; // code of value to write
int16_t base_pwm; // absolute value ranging from -1000 to 1000 .. base_pwm plus/minus steer is the raw PWM value
int16_t steer; // absolute value ranging from -1000 to 1000 .. wether steer is added or substracted depends on the side R/L
unsigned char CS; // checksumm
} MsgToHoverboard_t;
uint16_t baseSpeed = 0;
typedef union UART_Packet_t {
MsgToHoverboard_t msgToHover;
uint8_t UART_Packet[sizeof(MsgToHoverboard_t)];
} UART_Packet_t;
void setHoverboardPWM(int16_t base_pwm, int16_t steer, int &handle)
{
UART_Packet_t ups;
ups.msgToHover.SOM = 2; // PROTOCOL_SOM; //Start of Message;
ups.msgToHover.len = 7; // payload + SC only
ups.msgToHover.cmd = 'W'; // PROTOCOL_CMD_WRITEVAL; // Write value
ups.msgToHover.code = 0x07; // speed data from params array
ups.msgToHover.base_pwm = base_pwm;
ups.msgToHover.steer = steer;
ups.msgToHover.CS = 0;
for (int i = 0; i < ups.msgToHover.len; i++)
{
ups.msgToHover.CS -= ups.UART_Packet[i + 1];
}
// mySerial.write(ups.UART_Packet,sizeof(UART_Packet_t));
if (handle != -1)
{
int count = write(handle, &ups.UART_Packet, sizeof(UART_Packet_t)); //Filestream, bytes to write, number of bytes to write
// cout << "count: " << count << endl;
if (count < 0)
{
printf("UART TX error\n");
}
}
}
int main()
{
//-------------------------
//----- SETUP USART 0 -----
//-------------------------
//At bootup, pins 8 and 10 are already set to UART0_TXD, UART0_RXD (ie the alt0 function) respectively
int uart0_filestream = -1;
//OPEN THE UART
//The flags (defined in fcntl.h):
// Access modes (use 1 of these):
// O_RDONLY - Open for reading only.
// O_RDWR - Open for reading and writing.
// O_WRONLY - Open for writing only.
//
// O_NDELAY / O_NONBLOCK (same function) - Enables nonblocking mode. When set read requests on the file can return immediately with a failure status
// if there is no input immediately available (instead of blocking). Likewise, write requests can also return
// immediately with a failure status if the output can't be written immediately.
//
// O_NOCTTY - When set and path identifies a terminal device, open() shall not cause the terminal device to become the controlling terminal for the process.
uart0_filestream = open("/dev/ttyAMA0", O_RDWR | O_NOCTTY | O_NDELAY); //Open in non blocking read/write mode
if (uart0_filestream == -1)
{
//ERROR - CAN'T OPEN SERIAL PORT
printf("Error - Unable to open UART. Ensure it is not in use by another application\n");
}
//CONFIGURE THE UART
//The flags (defined in /usr/include/termios.h - see http://pubs.opengroup.org/onlinepubs/007908799/xsh/termios.h.html):
// Baud rate:- B1200, B2400, B4800, B9600, B19200, B38400, B57600, B115200, B230400, B460800, B500000, B576000, B921600, B1000000, B1152000, B1500000, B2000000, B2500000, B3000000, B3500000, B4000000
// CSIZE:- CS5, CS6, CS7, CS8
// CLOCAL - Ignore modem status lines
// CREAD - Enable receiver
// IGNPAR = Ignore characters with parity errors
// ICRNL - Map CR to NL on input (Use for ASCII comms where you want to auto correct end of line characters - don't use for bianry comms!)
// PARENB - Parity enable
// PARODD - Odd parity (else even)
struct termios options;
tcgetattr(uart0_filestream, &options);
options.c_cflag = B19200 | CS8 | CLOCAL | CREAD; //<Set baud rate
options.c_iflag = IGNPAR;
options.c_oflag = 0;
options.c_lflag = 0;
tcflush(uart0_filestream, TCIFLUSH);
tcsetattr(uart0_filestream, TCSANOW, &options);
cout << "Beginning serial output\n";
while (1)
{
setHoverboardPWM(200, 0, uart0_filestream);
}
//----- CLOSE THE UART -----
close(uart0_filestream);
return 0;
}
这在很大程度上是借来的代码。我尽力使它工作。但是,我遇到了大量“ UART TX error!”(来自SetHoverBoard PWM内部)。我对UART通信协议不是非常有经验,但是我知道我的波特率是正确的,并且串行端口可以工作。我只是在打包错误?
经验丰富的人可以协助我以python方式重新生成此代码或修复当前的c ++代码吗?
我还将提供我处理过的TX示例代码,以防万一我搞砸了:
代码链接:https://raspberry-projects.com/pi/programming-in-c/uart-serial-port/using-the-uart
代码本身:
//----- TX BYTES -----
unsigned char tx_buffer[20];
unsigned char *p_tx_buffer;
p_tx_buffer = &tx_buffer[0];
*p_tx_buffer++ = 'H';
*p_tx_buffer++ = 'e';
*p_tx_buffer++ = 'l';
*p_tx_buffer++ = 'l';
*p_tx_buffer++ = 'o';
if (uart0_filestream != -1)
{
int count = write(uart0_filestream, &tx_buffer[0], (p_tx_buffer - &tx_buffer[0])); //Filestream, bytes to write, number of bytes to write
if (count < 0)
{
printf("UART TX error\n");
}
}
我假设位奇偶校验,一切都很好。似乎设置匹配。