Click here to Skip to main content
13,511,647 members
Rate this:
Please Sign up or sign in to vote.
Good evening,

I have a radio commanded quadcopter [][^]
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


my code, not working


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
	//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;
	//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;
  array<unsigned char> ^ received_data =gcnew array<unsigned char>(50);
  //open-send-close port
	 printf("\nsending data...\n");
		for(int ii=0;ii<=send_data->Length;ii++)
		 printf("%d", send_data[ii]);
	 printf("\nreceiving data...\n");
	 for (int ii=0;ii<=received_data->Length; ii++)
		       printf("%d", received_data[ii]);

//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++)
	return crc;


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.thrust=0x00; //fixed at 50

	//flags manually set 0x8C
  scientific_commanddata.flags.thrust=1; //enable motors
  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
	//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
Posted 7-Nov-10 7:21am
Updated 7-Nov-10 8:12am
Alain Rist 7-Nov-10 14:14pm
Removed C++ tag , added C++/CLI

1 solution

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

Solution 1

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[^]

Good luck!

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

  Print Answers RSS
Top Experts
Last 24hrsThis month

Advertise | Privacy |
Web01 | 2.8.180417.1 | Last Updated 8 Nov 2010
Copyright © CodeProject, 1999-2018
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