尝试通过串行通讯驾驶直升机 [英] Trying to pilot an helicopter via serial communication
问题描述
晚上好,
我有一个无线电指令的四轴飞行器 [ ] ^ ]
可以通过PC使用串行通信协议进行控制.
协议格式是一个18字节的字符串,如下所示:
1)startstring 1:> (十六进制为0x3e)
2)startstring 2:*(0x2A)
3)startstring 3:> (十六进制为0x3e)
4)packet descripotr->始终为0x17
5)数据包长度-低字节
6)数据包长度-高字节
7)pitch-低字节
8)pitch-高字节
9)滚动-低字节
10)roll-高字节
11)推力-低字节
12)推力-高字节
13)偏航-低字节
14)偏航-高字节
15)标志-低字节--->>该位的每一位都启用串行端口与直升机零件之间的通信(尤其是从左数第三位的第8位为1英寸,如1000 0100(十六进制为0x84),则通过串行接口启用通讯,并通过以下方式启用推力控制:串行接口.
16)标志-高位字节->数据包的发送速率
17)crc16-高
18)crc16-低
使用我制作的VC ++控制台程序(在Windows 7 x32上使用MS Visual C ++ express 2010),我可以发送正确的数据包,因为我从直升机收到一个0x19的字节,作为收到的数据包写在指南中描述符.
问题是我无法移动"它,并且我将推力设置为正值,将标志设置为0x84.
我还有一个由Asctec提供的测试软件,该软件可以运行,可以启动发动机并增加推力.我有一个使用串行监视器的.avi,一个软件和一个代码,如果有人看一看,它们会以megaupload的形式上传到此处:
有效的测试软件
[url] http://www.megaupload.com/?d=2SZ4Z4HQ [ http://www.megaupload.com/?d=K8R9IIHX [
Good evening,
I have a radio commanded quadcopter []http://www.asctec.de/downloads/researchpilot_manual.pdf[^]
which could be controlled via PC using a serial communication protocol.
The protocol format is a 18 byte string built as follow:
1)startstring 1: > (0x3e in hex)
2)startstring 2: * ( 0x2A)
3)startstring 3: > (0x3e in hex)
4)packet descripotr -> always 0x17
5)length of packet - lowbyte
6)length of packet - highbyte
7)pitch - low byte
8)pitch - high byte
9)roll -low byte
10)roll - high byte
11)thrust - low byte
12)thrust - high byte
13)yaw - low byte
14)yaw - high byte
15)flags -low byte --->> every single bit of this one enable the communication between serial port and a parts of my copter (epecially, an 1 in in 8th the third position from left , as 1000 0100 (0x84 in hex) enable comm via serial interface and enable thrust control through serial interface.
16)flags - high byte --> sendrate of packet
17)crc16 - high
18)crc16- low
Using a VC++ console program I made (with MS visual C++ express 2010 on windows 7 x32), I can send a correct packet, as I''m receiving a byte from the copter that is 0x19, written in the guide as the received packet descriptor.
The problem is that I can''t "move" it, and I''m putting positive values for thrust and a 0x84 for flags.
I''ve also a testsoftware provided from Asctec that works, can start engine and increase thrust. I''ve a pair of .avi using a serial monitor, one of this software and one of my code, If someone would take a look they are uploaded in megaupload here:
testsoftware that works
[url]http://www.megaupload.com/?d=2SZ4Z4HQ[^][/url]
my code, not working
[url]http://www.megaupload.com/?d=K8R9IIHX[^][/url]
I think that my problem should be some rigidities in write and read methods, I''m just sending the same packet in a while cycle.
If someone could address me to some notions. It would be a great favour!!
Thanks a lot, my program is the following:
// sendPacket.cpp : file di progetto principale.
namespace sendPacket {
#include "stdafx.h"
#include <conio.h>
#include <cstdio>
#include <stdlib.h>
#include <string>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <stdexcept>
#include <valarray>
using namespace System;
using namespace std;
using namespace System::IO;
using namespace System::IO::Ports;
using namespace System::Threading;
//initialize flags structure (:1 means 1 bit register dimension, using bitfields)
struct FLAGS
{
unsigned char pitch:1;
unsigned char roll:2;
unsigned char thrust:3;
unsigned char yaw:4;
unsigned char acc:5;
unsigned char height:6;
unsigned char acc_height:7;
unsigned char trigger:8;
unsigned char freq;
};
//initialize command data structure to send
struct SCIENTIFIC_COMMANDDATA
{
//always 0x17
unsigned char packetdescriptor;
//pitch, roll, thrust, yaw commands. 0..4095 2048=middle
unsigned short pitch;
unsigned short roll;
unsigned short thrust;
unsigned short yaw;
//flags
//Bit 0(0x01): Pitch control through serial interfacae enabled
//Bit 1(0x02): Roll control through serial interface enabled
//Bit 2(0x04): Thrust control through serial interface enabled
//Bit 3(0x08): Yaw control through serial interface enabled
//Bit 4(0x10): ACC-Mode on/off
//Bit 5(0x20): Height control - on/off (only with ACC)
//Bit 6(0x40): overwrite ACC/Height mode control
//(0=mode selected by RC 1=mode selected by Bit 4 and 5)
//Bit 7(0x17): Trigger Scientific status packet (triggers a response
//with the actual scientific state)
//Bit 8..15: sendrate of the scientific packet in 5Hz
//(0=off;1=5Hz, 20=100Hz, 200=1kHz)
//Scientific packet is send for three seconds max.
//after the last command_data packet
FLAGS flags; //insert a FLAG structure in a SCIENTIFIC_COMMANDDATA structure
};
//send-data methods
void sendData_String(array<unsigned char> ^ send_data)
{
StringComparer^ stringComparer = StringComparer::OrdinalIgnoreCase;
// Create a new SerialPort object with default settings.
SerialPort^ _serialPort = gcnew SerialPort("COM3");
// Allow the user to set the appropriate properties.
_serialPort->BaudRate = 9600 ;
_serialPort->Parity = Parity::None;
_serialPort->DataBits = 8;
_serialPort->StopBits = StopBits::One;
_serialPort->Handshake =Handshake::None;
//variables
array<unsigned char> ^ received_data =gcnew array<unsigned char>(50);
//open-send-close port
_serialPort->Open();
while(!_kbhit())
{
printf("\nsending data...\n");
for(int ii=0;ii<=send_data->Length;ii++)
{
Thread::Sleep(50);
_serialPort->Write(send_data,ii,1);
printf("%d", send_data[ii]);
Thread::Sleep(50);
}
printf("\nreceiving data...\n");
for (int ii=0;ii<=received_data->Length; ii++)
{
_serialPort->Read(received_data,ii,1);
printf("%d", received_data[ii]);
}
}
_serialPort->Close();
}
//crc methods
unsigned short crc_update(unsigned short crc, unsigned char data)
{
data ^= (crc & 0xff);
data ^= data << 4;
return ((((unsigned short )data << 8) | ((crc>>8)&0xff))
^ (unsigned char )(data >> 4) ^ ((unsigned short )data << 3));
}
unsigned short crc16(void *data, unsigned short cnt)
{
unsigned short crc=0xff;
unsigned char *ptr=(unsigned char *) data;
int i;
for (i=0;i<cnt;i++)
{
crc=crc_update(crc,*ptr);
ptr++;
}
return crc;
}
//MAIN
int main(array<System::String ^> ^args)
{
//initialize structs and variables
FLAGS flags;
SCIENTIFIC_COMMANDDATA scientific_commanddata;
//int data;
unsigned short crc;
unsigned char *ptr = &(scientific_commanddata.packetdescriptor);
//set startstring and crc low byte and high byte var
array<unsigned char> ^ startString={''>'',''*'',''>''};
//length calc
unsigned short length = 0xb; //fix it becouse the struct is too long
//length = sizeof(scientific_commanddata);
unsigned char length_high =length>>8;
unsigned char length_low =length&0xFF;
//other SCIENTIFIC_COMMANDATA variables manually set
scientific_commanddata.packetdescriptor = 0x17;
scientific_commanddata.pitch= 0x04;
scientific_commanddata.roll=0x00;
scientific_commanddata.thrust=0x00; //fixed at 50
scientific_commanddata.yaw=0x04;
//flags manually set 0x8C
scientific_commanddata.flags.pitch=0;
scientific_commanddata.flags.roll=0;
scientific_commanddata.flags.thrust=1; //enable motors
scientific_commanddata.flags.yaw=1;
scientific_commanddata.flags.acc=0;
scientific_commanddata.flags.height=0;
scientific_commanddata.flags.acc_height=0;
scientific_commanddata.flags.trigger=1;
scientific_commanddata.flags.freq= 4; //20 hz??
//flags low calc
unsigned char flags_low= ((scientific_commanddata.flags.pitch)+ (scientific_commanddata.flags.roll<<=1)+(scientific_commanddata.flags.thrust<<=2)+(scientific_commanddata.flags.yaw<<=3)
+(scientific_commanddata.flags.acc<<=4) + (scientific_commanddata.flags.height<<=5) +(scientific_commanddata.flags.acc_height<<=6)+(scientific_commanddata.flags.trigger<<=7) );
unsigned char flags_high = scientific_commanddata.flags.freq;
//crc_low and crc_high calc
crc= crc16(ptr,length);
unsigned char crc_low = crc&0xFF;
unsigned char crc_high = crc>>8;
//data to be sent
array<unsigned char> ^ send_data = {startString[0], //1
startString[1], //2
startString[2], //3
length_high,//4
length_low,//5
scientific_commanddata.packetdescriptor,//6
scientific_commanddata.pitch&0xFF,//7
scientific_commanddata.pitch>>8,//8
scientific_commanddata.roll&0xFF,//9
scientific_commanddata.roll>>8,//10
scientific_commanddata.thrust&0xFF,//11
scientific_commanddata.thrust>>8,//12
scientific_commanddata.yaw&0xFF,//13
scientific_commanddata.yaw>>8,//14
flags_low,//15
flags_high,//16
crc_high,//17
crc_low};//18
//some string catched from testsoftware
array<unsigned char> ^ send_data1 = {72, 0x43, 0x43, 0x00, 0x0B, 0x17, 0xF0, 0x07, 76, 0x07, 0x00, 0x00, 0xF0, 0x07, 0x8C, 0x04, 0x79, 0};
array <unsigned char> ^send_data2 = {0x3E, 0x2A, 0x3E, 0x00, 0x0B, 0x17, 0xF0, 0x07, 0xF0, 0x07, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x04, 0x5C, 0x3F};
array <unsigned char> ^send_data3 = {0x3E, 0x2A, 0x3E, 0x00, 0x0B, 0x17, 0xF0, 0x07, 0xF0, 0x07, 0x00, 0x00, 0xF0, 0x07, 0x80, 0x04, 0xD0, 0xF3};
array <unsigned char> ^send_data4 = {0x3E, 0x2A, 0x3E, 0x00, 0x0B, 0x17, 0x50, 0x09, 0xF0, 0x07, 0x00, 0x00, 0xF0, 0x07, 0x00, 0x04, 0x89, 0xA9};
printf("\nsend data starstring: %d\n", sizeof(send_data));
int size =send_data->Length;
//array<unsigned char> ^ send_data1 = {0x3E, 0x2A, 0x3E, 0x00, 0x0B, 0x80, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x50, 0xFF, 0x79, 0x53};
//launch methods
sendData_String(send_data);
推荐答案
好玩具:cool:
我看到您的设备附带了一些软件.也许那可以告诉您它正在发送什么数据.另外,您可以查看程序正在发送的内容,并验证它是否正确.您可以使用虚拟的空调制解调器轻松检查发送的数据.那应该使您和您的直升机前进. :-D
http://sourceforge.net/projects/com0com/ [
Nice toy :cool:
I see you got some software with the device. Maybe that could show you what data it is sending. Also, you can have a look what your program is sending and verify this is correct. You could easily check the data sent by using a virtual null modem. That should get you, and your helicopter, going. :-D
http://sourceforge.net/projects/com0com/[^]
Good luck!
这篇关于尝试通过串行通讯驾驶直升机的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!