Sunday, October 12, 2014

My Arduino thinks he is an Yaesu.... and now outputs some RF

Got, last Friday, two of these:



It's a breakout board with an Silicon Labs Si5351A that can output 3 diferent clock's.

And just in time after finishing the code for the computer controled VFO on the Arduino.

Plugged one of them to the Arduino and now have some RF using the supplied example on the library.

Now it's more coding so I can change the output from the Si5351 for the first mixer and product detector. Something tells me that it's not going to be easy...

I bough two of them since I am thinking in adding another IF to the "Trevo" transceiver and then create a "shift" and "width" controls by varying the BFO, VFO and the IF LO. I will try first to implement in software and them test, I'm sure gains on the different stages must be well defined. Anyhow will be easier in software than with cristal mixing schemes.

It must be two boards since the chip in fact only has two independent PLL's from what I've seen so far.

Have a great week!

Thursday, October 09, 2014

My Arduino think's he is an Yaesu (Arduino CAT controlled, VFO)




Here goes the basic code and details for the Arduino CAT controlled or Yaesu "emulator" for remote controlling a VFO from a PC.



I tested against "Rigresident" and "Commander v5.8.7" software using 9K6 on the serial port (Arduino USB serial console) and booth Yaesu 857 and 817 command set (are the same for all that matters).
The control of the VFO chip itself (Si570, AD9850 etc) is not implemented on the code, there are comments were it should be placed.  Consider the code as a base for your own solution.


If copy past of the following code does not work for you because of blogger formatting let me know, I can send code on email.

// Code starts here
//
// Basic code for remote control of an VFO base on the Arduino platform using CAT software or Hamlib
//
// Emulates basic functions of an FT857 (and similar Yaesu) in the Arduino platform from the perspective of the CAT software
// set mode, set frequence and get frequency only at the moment
//
// By: CT2GQV - Ricardo
//
// Licence: GPL - use according, in no way I will be responsable for the magic smoke you may get!
//
// Information sources: Hamlib, FT857.h from VE3BUX
//
// to be done: add s-meter reading and sending. Add code to control Si5351, Si570, ad9850/1 etc
// any help is apreciated

#include
#include
#include

// whatever lcd is used, might need some changes
// LCD control, SDA and SCL to analog 4 and 5 pin
#define I2C_ADDR    0x27  // I2C Address for my LCD, found with I2C scanner
#define BACKLIGHT_PIN     3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7
LiquidCrystal_I2C       lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

// modes as going/coming from rig control, no need for hex since it will the last byte in the array, diferent story if it was the first....
#define LSB 0                          
#define USB 1                                        
#define CW 2                                           
#define AM 4                                             
#define FM 8
#define RTTY 10
#define PKT 12

// this could be done in a diferent way... see comments on the code about "to_bcd_be"
// ...don't remember coding so bad in the past years... oh well, get's the job done
#define HZERO 0x00                          
#define HONE 0x01                                        
#define HTWO 0x02                                           
#define HTHRE 0x03                                             
#define HFOUR 0x04
#define HFIVE 0x05
#define HSIX 0x06
#define HSEVEN 0x07 
#define HEIGHT 0x08
#define HNINE 0x09                                        
#define HTEN 0x10  
#define HTWENTY 0x20                                             
#define HTHIRTY 0x30
#define HFOURTY 0x40
#define HFIFTY 0x50
#define HSIXTY 0x60
#define HSEVENTY 0x70                                             
#define HEIGHTY 0x80
#define HNINETY 0x90

int incomingByte;   // for incoming serial data from rig control soft.
int counter_byte = 1; // just a counter for the bytes in radiocommand array
int radiocommand[5]; //  array to keep the previous commands from the rig control software...
int i; // just an aux counter
char a[8]; // will keep the hex to send to rig software when requests frequency vfo is in

// in the future get the next values (start up frequency and mode) from saved configuration...
//                 4 4 3,7 5 0.5 1 0 (this would be 443Mhz 750Khz and 513 Hz (show up as 443,750.51)
//                       8 5 0 5 1 3 ( 850 Khz and 512 Hz  (show up as  850.51)
int myfrequency[]={1,4,4,7,5,0,1,2,5};  // to rig control only first 8 values are sent...for vfo connected that a diferent story
int mymode = USB; // mode usb,lsb,cw,am,fm,rtty,pkt

// setup function of the Arduino
void setup() {
  
  Serial.begin(9600); // 9k6 speed, can be reduced.
  lcd.begin (20,4,LCD_5x8DOTS); lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE); lcd.setBacklight(HIGH); // 20x4 lines display LCD
  lcd.home(); lcd.print(" CAT controlled ");  // just dummy info, trying just to keep for 16 case lcd changes to 16x2
  lcd.setCursor(0,1);  
  switch (mymode) {case 0: lcd.print("LSB  "); break; case 1:  lcd.print("USB  "); break; case 2: lcd.print("CW   "); break; case 4: lcd.print("AM   "); break;
                   case 8: lcd.print("FM   "); break; case 10: lcd.print("RTTY "); break; case 12: lcd.print("PKT  "); break; }
  for (i = 0; i < 8; i = i + 1) { if (i==3 || i==6) {lcd.print(".");}; lcd.print(myfrequency[i]); } // print the startup frequency
////////////////////////////////////////
// put code here to initialize vfo connected to Arduino
///////////////////////////////////////
}

void loop() {

////////////// RIG CONTROL PART //////////////////////////////////////////////// 
 // do we have serial data?... 
 if (Serial.available() > 0) {
   incomingByte = Serial.read(); // read the incoming byte command from the serial line
   radiocommand[counter_byte]=incomingByte; // place the incoming byte on the array

  ////// let's start switching the commands sent from rig control software...
  
   // if the rig control software comand is 0x03 then send out current frquency by request of rig control software
   if (incomingByte==3 && radiocommand[4]==0 && radiocommand[3]==0 && radiocommand[2]==0 && radiocommand[1]==0 ) {
   // loop in myfrequency starting on the first vaule we have for frequency until the maximum of the myfrequency array (8)
   // if anyone has time to change the following this would be much better job with "to_bcd_be" from hamlib, basical convert to nibles and join and send...
   for (i = 0; i < 8; i = i + 2 ) { //loop all digits from 0 to 7 from the myfrequency array, join two by two and send the HEX value
       switch (myfrequency[i]) {
        case 0: a[i]= HZERO; break;  case 1: a[i]= HTEN;  break;  case 2: a[i]= HTWENTY; break; case 3: a[i]= HTHIRTY; break; 
        case 4: a[i]= HFOURTY;  break; case 5: a[i]= HFIFTY; break; case 6: a[i]= HSIXTY; break; case 7: a[i]= HSEVENTY;  break;
        case 8: a[i]= HEIGHTY; break; case 9: a[i]= HNINETY; break;   } // end switch first digit
       switch (myfrequency[i+1]) {
        case 0: a[i+1]= HZERO; break;  case 1: a[i+1]= HONE;  break; case 2: a[i+1]= HTWO; break; case 3: a[i+1]= HTHRE; break; 
        case 4: a[i+1]= HFOUR;  break;  case 5: a[i+1]= HFIVE; break; case 6: a[i+1]= HSIX; break; case 7: a[i+1]= HSEVEN;  break;
        case 8: a[i+1]= HEIGHT; break; case 9: a[i+1]= HNINE; break; } // end switch of the second digit
    } // end of the for loop to read frequency we are in and and convert to BCD
    // lets now send the frequency data to rig control software in this format a1a2.b1b2.c1c2.d1d2.ee (ee is mode)
    Serial.write(a[0]+a[1]); Serial.write(a[2]+a[3]); Serial.write(a[4]+a[5]); Serial.write(a[6]+a[7]); Serial.write(mymode); 
//////////////////////   
// no code is needed here because we are just sending the present frequency we are in
/////////////////////////////////////////////
   } // end send out current frequency
  
   // if the rig control software command is 0x01 then set frequency  whith the values sent aa.bb.cc.dd.0x01
   if (radiocommand[5]==1) {
         int tempo;           
         tempo = radiocommand[1]>>4; myfrequency[0]=tempo; tempo = radiocommand[1]&0x0f; myfrequency[1]=tempo;
         tempo = radiocommand[2]>>4; myfrequency[2]=tempo; tempo = radiocommand[2]&0x0f; myfrequency[3]=tempo;
         tempo = radiocommand[3]>>4; myfrequency[4]=tempo; tempo = radiocommand[3]&0x0f; myfrequency[5]=tempo;
         tempo = radiocommand[4]>>4; myfrequency[6]=tempo; tempo = radiocommand[4]&0x0f; myfrequency[7]=tempo;
         // print the new frequency we were requested to go to by rig control software
         lcd.setCursor(0,1);  
         switch (mymode) {case 0: lcd.print("LSB  "); break; case 1:  lcd.print("USB  "); break; case 2: lcd.print("CW   "); break; case 4: lcd.print("AM   "); break;
                   case 8: lcd.print("FM   "); break; case 10: lcd.print("RTTY "); break; case 12: lcd.print("PKT  "); break; }
         for (i = 0; i < 8; i = i + 1) { if (i==3 || i==6) {lcd.print(".");}; lcd.print(myfrequency[i]); }     
//////////////////////////////////
// put code here to set the new frequency on the vfo... ex: set_vfo(myfrequeny);
//////////////////////////////////
   } // end of rig control command to set a new frequency on the VFO
  
   // set mode command sent from rig control software
   if (incomingByte==7 && radiocommand[4]==0 && radiocommand[3]==0 && radiocommand[2]==0) { //rig control will set mode on the arduino
      if (radiocommand[1]==0){ mymode=LSB; }; if (radiocommand[1]==1){ mymode=USB;};
      if (radiocommand[1]==2){ mymode=CW;};  if (radiocommand[1]==8){ mymode=FM;};
      if (radiocommand[1]==4){ mymode=AM;}; if (radiocommand[1]==10){ mymode=RTTY;};
      if (radiocommand[1]==12){ mymode=PKT; };
      // will print mode on the lcd after mode change requested by rig control software..and also the frequency just to refresh the screen
      lcd.setCursor(0,1);  
      switch (mymode) {case 0: lcd.print("LSB  "); break; case 1:  lcd.print("USB  "); break; case 2: lcd.print("CW   "); break; case 4: lcd.print("AM   "); break;
                   case 8: lcd.print("FM   "); break; case 10: lcd.print("RTTY "); break; case 12:    lcd.print("PKT  "); break; }
      for (i = 0; i < 8; i = i + 1) { if (i==3 || i==6) {lcd.print(".");}; lcd.print(myfrequency[i]); } // print the startup frequency
//////////////////////////////////
// put code here to change mode ex; set_mode(mymode)
// if mymode = 1 (USB) then switch on digital pin 1...
// if mymode = 2 (CW) then switch on digital pin 2...
//////////////////////////////////
   } // end of set mode by rig control
///// end of pattern/command recognition part

  counter_byte++; // increment the position on the array read from the serial line        
  if (counter_byte>5) {counter_byte=1; }; // if we reached the end of the array.. that is previous counter byte = 5 and now 6 because we incremented before
 } // end of if serial avaiable cycle and command execution from RIG control software
///////////////// END / RIG CONTROL PART //////////////////////////////////////////////////

// put code on the next lines to read button/rotary press to change frequency, change mode etc..
// and other stuff....
/////////////////


} // end of main Arduino loop

// end of code


The LCD I used is this one (20x4  I2C connection):




I changed the code to use only 2 lines of the LCD since a 16x2 is more common than a 20x4.

LCD connection as follow:

GND from LCD to Arduino Pin Gnd (on power bus)
VCC from LCD to Arduino Pin 5v (on power bus)
SDA from LCD to Arduino Pin Analog A4 (on analog bus)
SCL from LCD to Arduino Pin Analog  A5 (on analog bus)

You can use a different LCD, just change the code.


Have a nice weekend!

Sunday, October 05, 2014

My Arduino think's he is an Yaesu

Having battling intermittently for the past two weeks to get an Arduino to "emulate" the Yaesu serial protocol I finaly got it, I can set frequency and mode from the rig control software on to the Arduino:

Setting the frequency:
 The Arduino picket up (My Freq:) and then I sent another frequency change to 446Mhz:


I didn't take the new frequency set picture (set freq) but it did worked. Mode "8" is the hex sent from the rig control software for FM mode.


Tried to find some other similar project and found none so have to make it myself, far as I know this is one of a kind! There are some projects but are to control an Yaesu radio from an Arduino, not the RIG CAT software to control the Arduino. The idea is remotely controlling the VFO of the "Trevo" transceiver (the one I've been building for the last year)
Will release the code if there's any interest and after beeing well polished... it will take time.

add: code: http://speakyssb.blogspot.ie/2014/10/my-arduino-thinks-he-is-yaesu-arduino.html

Have a good weekend!