Click here to Skip to main content
11,410,379 members (58,238 online)
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++/CLI Visual-Studio COM , +
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);
Posted 7-Nov-10 8:21am
Edited 7-Nov-10 9:12am
Alain Rist31.8K
v2
Comments
Alain Rist at 7-Nov-10 14:14pm
   
Removed C++ tag , added C++/CLI

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

Nice toy Cool | :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. Big Grin | :-D

http://sourceforge.net/projects/com0com/[^]

Good luck!
  Permalink  

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 Sergey Alexandrovich Kryukov 8,755
1 OriginalGriff 6,915
2 Maciej Los 3,390
3 Abhinav S 3,248
4 Peter Leow 3,059


Advertise | Privacy | Mobile
Web04 | 2.8.150414.5 | Last Updated 8 Nov 2010
Copyright © CodeProject, 1999-2015
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100