px4_add_module(
MODULE modules__rw_uart
MAIN rw_uart
COMPILE_FLAGS
-Os
SRCS
rw_uart.c
DEPENDS
platforms__common
)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
__EXPORT int rw_uart_main(int argc, char *argv[]);
int set_uart_baudrate(const int fd, unsigned int baud);
int set_uart_baudrate(const int fd, unsigned int baud)
{
int speed;
switch (baud) {
case 9600: speed = B9600; break;
case 19200: speed = B19200; break;
case 38400: speed = B38400; break;
case 57600: speed = B57600; break;
case 115200: speed = B115200; break;
default:
warnx("ERR: baudrate: %d\n", baud);
return -EINVAL;
}
struct termios uart_config;
int termios_state;
/* fill the struct for the new configuration */
tcgetattr(fd, &uart_config);
/* clear ONLCR flag (which appends a CR for every LF) */
uart_config.c_oflag &= ~ONLCR;
/* no parity, one stop bit */
uart_config.c_cflag &= ~(CSTOPB | PARENB);
/* set baud rate */
if ((termios_state = cfsetispeed(&uart_config, speed)) < 0) {
warnx("ERR: %d (cfsetispeed)\n", termios_state);
return false;
}
if ((termios_state = cfsetospeed(&uart_config, speed)) < 0) {
warnx("ERR: %d (cfsetospeed)\n", termios_state);
return false;
}
if ((termios_state = tcsetattr(fd, TCSANOW, &uart_config)) < 0) {
warnx("ERR: %d (tcsetattr)\n", termios_state);
return false;
}
return true;
}
int rw_uart_main(int argc, char *argv[])
{
char data = '0';
char buffer[4] = "";
int uart_read = open("/dev/ttyS2", O_RDWR | O_NOCTTY);//打开串口设备
if (uart_read < 0) {
err(1, "failed to open port: %s", "/dev/ttyS2");
return -1;
}
if(false == set_uart_baudrate(uart_read,9600)){
printf("[YCM]set_uart_baudrate is failed\n");
return -1;
}
printf("[YCM]uart init is successful\n");
while(true){
read(uart_read,&data,1);
if(data == 'R'){
for(int i = 0;i <4;++i){
read(uart_read,&data,1);//读取串口数据
buffer[i] = data;
data = '0';
}
printf("%s\n",buffer);
}
}
return 0;
}
modules/rw_uart
make clean
make px4fmu-v2_default
char[4] datastr0
uint8 data
rw_uart_raspberry_topic.msg
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
static bool thread_should_exit = false;
static bool thread_running = false;
static int daemon_task;
__EXPORT int rw_uart_main(int argc, char *argv[]);
int rw_uart_thread_main(int argc, char *argv[]);
static void usage(const char *reason);
static int uart_init(char * uart_name);
static int set_uart_baudrate(const int fd, unsigned int baud);
static void usage(const char *reason)
{
if (reason) {
fprintf(stderr, "%s\n", reason);
}
fprintf(stderr, "usage: position_estimator_inav {start|stop|status} [param]\n\n");
exit(1);
}
int set_uart_baudrate(const int fd, unsigned int baud)
{
int speed;
switch (baud) {
case 9600: speed = B9600; break;
case 19200: speed = B19200; break;
case 38400: speed = B38400; break;
case 57600: speed = B57600; break;
case 115200: speed = B115200; break;
default:
warnx("ERR: baudrate: %d\n", baud);
return -EINVAL;
}
struct termios uart_config;
int termios_state;
/* fill the struct for the new configuration */
tcgetattr(fd, &uart_config);
/* clear ONLCR flag (which appends a CR for every LF) */
uart_config.c_oflag &= ~ONLCR;
/* no parity, one stop bit */
uart_config.c_cflag &= ~(CSTOPB | PARENB);
/* set baud rate */
if ((termios_state = cfsetispeed(&uart_config, speed)) < 0) {
warnx("ERR: %d (cfsetispeed)\n", termios_state);
return false;
}
if ((termios_state = cfsetospeed(&uart_config, speed)) < 0) {
warnx("ERR: %d (cfsetospeed)\n", termios_state);
return false;
}
if ((termios_state = tcsetattr(fd, TCSANOW, &uart_config)) < 0) {
warnx("ERR: %d (tcsetattr)\n", termios_state);
return false;
}
return true;
}
int uart_init(char * uart_name)
{
int serial_fd = open(uart_name, O_RDWR | O_NOCTTY);
if (serial_fd < 0) {
err(1, "failed to open port: %s", uart_name);
return false;
}
return serial_fd;
}
int rw_uart_main(int argc, char *argv[])
{
if (argc < 2) {
usage("[YCM]missing command");
}
if (!strcmp(argv[1], "start")) {
if (thread_running) {
warnx("[YCM]already running\n");
return 0;
}
thread_should_exit = false;
daemon_task = px4_task_spawn_cmd("rw_uart",
SCHED_DEFAULT,
SCHED_PRIORITY_DEFAULT,
2000,
rw_uart_thread_main,
(argv) ? (char * const *)&argv[2] : (char * const *)NULL);
return 0;
}
if (!strcmp(argv[1], "stop")) {
thread_should_exit = true;
return 0;
}
if (!strcmp(argv[1], "status")) {
if (thread_running) {
warnx("[YCM]running");
} else {
warnx("[YCM]stopped");
}
return 0;
}
usage("unrecognized command");
return 1;
}
int rw_uart_thread_main(int argc, char *argv[])
{
warnx("[daemon] starting\n");
thread_running = true;
char data = '0';
char buffer[4] = "";
/*
* TELEM1 : /dev/ttyS1
* TELEM2 : /dev/ttyS2
* GPS : /dev/ttyS3
* NSH : /dev/ttyS5
* SERIAL4: /dev/ttyS6
* N/A : /dev/ttyS4
* IO DEBUG (RX only):/dev/ttyS0
*/
int uart_read = uart_init("/dev/ttyS2");
if(false == uart_read)return -1;
if(false == set_uart_baudrate(uart_read,9600)){
printf("[YCM]set_uart_baudrate is failed\n");
return -1;
}
printf("[YCM]uart init is successful\n");
struct rw_uart_raspberry_topic_s test_data; //定义类型为rw_uart_raspberry_topic_s的结构体变量rd
orb_advert_t rw_uart_raspberry_topic_pub = orb_advertise(ORB_ID(rw_uart_raspberry_topic), &test_data);
while(!thread_should_exit){
read(uart_read,&data,1);
if(data == 'R'){
for(int i = 0;i <4;++i){
read(uart_read,&data,1); //读取串口设备数据1个字节,放到data中
buffer[i] = data;
data = '0';}
write(uart_read,&buffer,4);
char * s;
strncpy(test_data.datastr0,buffer,4);
test_data.data = strtol(test_data.datastr0,&s,10);
orb_publish(ORB_ID(rw_uart_raspberry_topic), rw_uart_raspberry_topic_pub, &test_data);
int b=strtol(test_data.datastr0,&s,10);
printf("\t%s\t%d\t%d\n",test_data.datastr0,test_data.data,b);
}
}
warnx("[YCM]exiting");
thread_running = false;
close(uart_read);
fflush(stdout);
return 0;
}
rw_uart start
make clean
make px4fmu-v2_default
make px4fmu-v2_default_upload
# -*- coding: utf-8 -*-
import serial
import time
def port_send(send_date):
if (serial.isOpen()):
serial.write(send_date.encode('utf-8'))
time.sleep(0.5)
else:
print("send failed")
if __name__ == "__main__":
serial = serial.Serial('/dev/ttyS2', 9600, timeout=0.5) # /dev/ttyUSB0
if serial.isOpen():
print("open success")
else:
print("open failed")
while True:
port_send("R1100")
在编译的过程中碰到了很多问题,但是大部分都是可以百度谷歌到的。我主要将不能搜索到的问题摆出来,供大家在开发过程时参考。
#include
Pixhawk与树莓派3的串口通信
Pixhawk—通过串口方式添加一个自定义传感器(超声波为例)
pixhawk串口读取传感器数据
Python 串口读写实现