Portable Configurator for 2.4GHz Computerized CT6A / B Radios – Part 1

It’s been a while since my last post, and I’ve been busy like a bee the past few years, with my job, masters degree and a new startup business.

Last few days I’ve got some time to put in to work on an idea which I had for a long time. Its a portable handheld configurator for the CT6A radio.

http://www.hobbyking.com/hobbyking/store/__9042__Hobby_King_2_4Ghz_6Ch_Tx_Rx_V2_Mode_2_.html
http://www.leaderhobby.com/product.asp?ID=9394001220327

These radios are computer programmable and to even reverse a servo signal you need to plug it to a computer and make changes through the t6config software.

My idea was to create an arduino based hand held configurator with an LCD display which I can then use to configure the radio in the flying field itself.

A few people have already developed similar handhelds, one for PalmV and an arduino based memory for the T6, but both didn’t seem to be what I need, Palm V is a good solution but I don’t have the device, secondly the arduino based solution wasn’t capable of changing settings on the fly. Hence I’m on my own…

The T6 Serial definitions became very useful (http://www.rcgroups.com/forums/showpost.php?p=20080351&postcount=4964) and saved a lot of reverse engineering time.

I have designed the circuit diagram and I’m now working on the software for the configurator.

The diagram is as follows.

T6 Configurator Schematic
T6 Configurator Schematic

The pin 10 and 11 connect to the T6 through a DIN4 Jack (S-Video), pin 11 being the TX which goes to the Rx pin of the T6 through the Din-4 Socket, and pin 10 being the RX should go to the TX Pin of the Din4 Socket. Need to connect the ground from the DIN Socket to the ground of the circuit. Refer http://aeroquad.com/showthread.php?2587-T6-TX-Cable-alternative&p=24855&viewfull=1#post24855 for the Din-4 Socket connections

I have written the following code so far, a little buggy and I’m stuck at reading the existing configuration, as the T6 doesn’t seem to be returning me exactly 69 bytes of data. Some times I read 85, some times 67 and some times 68 but never 69. If someone know why and can help me out on this, please comment. Your help is greatly appreciated.


#include
#include

SoftwareSerial mySerial(10, 11); // RX, TX
LiquidCrystal lcd(13, 12, 5, 4, 3, 2);

const int arrowChar = B01111110;

const int LINE_COUNT = 2;

const int NO_MENU = 0;
const int MAIN_MENU = 1;
const int SUB_MENU1 = 2;

int myInit[] = {
0x55,0x99};
int myDinit[] = {
0x55,0x88};
int configS[] = {
0x55,0xfd};
int readData[] = {
0x55,0xFA,0x0};
int currentSetting[] = {
0x55, 0xFF, 0x00, 0x15, 0x64, 0x32, 0x64, 0x32, 0x64, 0x32, 0x00, 0x00, 0x00, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x00, 0x43, 0x00, 0x34, 0x00, 0x32, 0x00, 0x4C, 0x00, 0x4F, 0x00, 0x43, 0x00, 0x2E, 0x00, 0x44, 0x00, 0x4C, 0x00, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x64, 0x64, 0x02, 0x75, 0x64, 0x64, 0x02, 0x40, 0x5D, 0x32, 0x00, 0x04, 0x01, 0x9C, 0x01, 0x0C, 0xC6};
//byte invertD[] = {0x55,0xFF,0x00,0x2A,0x64,0x32,0x64,0x32,0x64,0x32,0x00,0x00,0x00,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x64,0x64,0x02,0x75,0x64,0x64,0x02,0x40,0x5D,0x32,0x00,0x00,0x00,0x00,0x00,0x09,0xA8};

char * mainMenu[] = {
"Download Data","Directions","End Points","Sub Trims","Dual Rates", "Stick Mode", "Type", "Mixing","Save","Upload Data"};
const int MAIN_MENU_SIZE = 10;

char ** currentMenu = mainMenu;
int currentMenuSize = MAIN_MENU_SIZE;
int currentMenuState=NO_MENU;

int menuIndex = 0; // menu base index (index of menu item that is displayed in the first line)
int cursorIndex = 0;

void setup()
{
lcd.begin(16,2);

// Open serial communications and wait for port to open:
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}

// set the data rate for the SoftwareSerial port
mySerial.begin(115200);
//mySerial.println("Hello, world?");

pinMode(6,INPUT);
pinMode(7,INPUT);
pinMode(8,INPUT);
pinMode(9,INPUT);

lcd.clear();

writeToT6(configS,2);

Serial.println("Ready to go");
}

void writeToT6(int data[],int dataSize){
Serial.print("Writing ");
for (int i=0; i<dataSize; i++)
{

Serial.print(data[i],HEX);
Serial.print(",");
mySerial.write(data[i]);
}
mySerial.flush();
}

void printMainMenu(){
lcd.clear();
currentMenuState=MAIN_MENU;
currentMenu = mainMenu;
currentMenuSize = MAIN_MENU_SIZE;
updateMenu();
}

void updateMenu(){
printMenu(currentMenu,currentMenuSize,currentMenuState);
}

void printMenu(char ** menu,int menuSize,int state){
lcd.clear();
currentMenuState=state;

for(int i=0;i");

if((menuIndex+i)>=menuSize){
break;
}
lcd.print(menu[menuIndex+i]);
}
}

void goDown(){
menuIndex++;
if(menuIndex >= MAIN_MENU_SIZE){
menuIndex=MAIN_MENU_SIZE-1;
}
updateMenu();
}

void goUp(){
menuIndex--;
if(menuIndex0){
// int dataItem = mySerial.read();
// }
//writeToT6(configS,2);
// mySerial.listen();
writeToT6(readData,3);
mySerial.listen();

// wait for data.
int timer=0;
while(mySerial.available()==0){
if(timer>200)
break;
delay(10);
timer++;

}

int offset = 0;
Serial.print("Reading : ");
while(mySerial.available()>0){
int dataItem = mySerial.read();
Serial.print(dataItem,HEX);
Serial.print(",");

currentSetting[offset] = dataItem;
offset++;
}
Serial.println("");
Serial.print("Read : ");
Serial.println(offset);

//writeToT6(myDinit,2);

lcd.clear();
if(offset==69){
lcd.print("Success !");
}
else{
lcd.print("Error Reading T6");
}
}

void loop() // run over and over
{

lcd.setCursor(0,0);

int up = digitalRead(6);
int back = digitalRead(7);
int s1 = digitalRead(8);
int down = digitalRead(9);

if(up==LOW){
lcd.clear();
goUp();
}
else if(down==LOW){
lcd.clear();
goDown();
}
else if(s1==LOW){
//Serial.write("Menu state:");
//Serial.write(currentMenuState);
if(currentMenuState==NO_MENU){
printMainMenu();
}
else if(currentMenuState==MAIN_MENU){
currentMenuState = SUB_MENU1;
switch(menuIndex){
case 0:
downloadData();
break;
}
}
}
else if(back==LOW){
switch(currentMenuState){
case MAIN_MENU:
lcd.clear();
currentMenuState=NO_MENU;
break;
case SUB_MENU1:
lcd.clear();
currentMenuState=MAIN_MENU;
menuIndex=0;
break;
default:
currentMenuState=NO_MENU;
lcd.setCursor(4,0);
lcd.print("T6 Field");
lcd.setCursor(2,1);
lcd.print("Configurator");
break;

}

}
else{
if(currentMenuState==NO_MENU){
lcd.clear();
lcd.setCursor(4,0);
lcd.print("T6 Field");
lcd.setCursor(2,1);
lcd.print("Configurator");
}
}

delay(100);

if(Serial.available()){
int resp = Serial.read();
if(resp==int('i')){
for (int i=0; i<2; i++)
{
Serial.write("Writing ");
Serial.write(myInit[i]);
mySerial.write(myInit[i]);
}
}
else if(resp==int('j')){
for (int i=0; i<2; i++)
{
Serial.write("Writing ");
Serial.write(myDinit[i]);
mySerial.write(myDinit[i]);
}

}
else if(resp==int('k')){
for (int i=0; i<sizeof(currentSetting); i++)
{
Serial.write("Writing ");
mySerial.write(currentSetting[i]);
}

}
}
}

For the above code to run properly I had to change the #define _SS_MAX_RX_BUFF 64 // RX buffer size in the SoftwareSerial.h file to #define _SS_MAX_RX_BUFF 128 // RX buffer size. Otherwise the arduino stops reading 63 bytes as the buffer overflows.

Further my findings are that you can use your arduino board as a computer cable for the arduino t6config software, but you need to remove the chip from the board or it will not work.

Will post more as I progress on this.

Cheers !

Advertisements

One thought on “Portable Configurator for 2.4GHz Computerized CT6A / B Radios – Part 1

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s