OK, this update won’t have any videos… those will come shortly, so you’ll need to take my word for it.

I learned a few things since the last post…  so here goes…

If I either flat display the BCD bytes or slow down and use the following code, the glitches go away, and the display is smoother, but slower.

again, based on data from http://forum.arduino.cc/index.php?topic=84948.0


void send_freq(long freq)
{
 char f[16],*fp;
 int i;
 unsigned char ob;
 char ichar;
 char is[16];
 
 //preamble
 Serial.write(0xFE); //preamble
 Serial.write(0xFE); //preamble
 Serial.write(0x58); //706 address
 Serial.write(0x01); //Controller Address
 Serial.write(0x05); //set freq command
 
 //test case frequency
 //Serial.write(0x76); //10 Hz, 1 Hz
 //Serial.write(0x23); // 1 kHz, 100 Hz
 //Serial.write(0x28); // 100 kHz, 10 kHz
 //Serial.write(0x14); //10 MHZ, 1 MHz
 //Serial.write(0x00); //GHz , 100 MHz

 //sprintf will format the data from "freq" into the "f" array
 sprintf(f,"%08ld",freq);
 
 fp = &f[6];
 for(i=0;i<4;i++) // For now send all 8 digits
 {
 // convert the ascii digits to pairs of BCD digits in one byte
 ob = (*fp++ & 0x0f) << 4;
 ob |= *fp++ & 0x0f;
 Serial.write(ob);
 fp -= 4;
 }
 
 Serial.write(0xFD); //complete

 delay(30);
 
 //Clear Read Buffers
 while(Serial.available()>0)
 {dump[0] = Serial.read();}

}

Using the source code from the link above, I managed to cobble together a working piece of code which would scan frequency one step at a time.  Experimenting around, i learned some of the limitations to my method:

  • this device will NEVER scan as smoothly as the internal knob or Sammie’s version.  This is because the encoder / processor within the radio operate much faster than the CI-V can communicate.  I think that, based on the purpose of this interface, I can live with that.
  • There’s some issues where it seems some data occasionally gets corrupted, and sends the radio off to some frequency and the unit looses control.
    • The solution here seems to be a check

int freqdelta=0;
int oldfreq;
int newfreq;
int freqstep; //tuning step size

read_freq();
check_encoder(); //actually, use interrupts
calculate_new_freq();
freqdelta = abs(oldfreq-newfreq);

if(freqdelta <> (3 * freqstep))
{//do nothing}
else
{write_freq(newfreq);}

Because of the limitations in the tuning speed, it would also seem that a dynamic tuning step would be useful.  this would remove some of the bigger issues – let’s face it, if you spin the knob really fast, you’ll miss just as much as if you turn it slowly with bigger frequency increments per encoder pulse.   (note, I still haven’t gotten encoder reading working, since I’m still out of jumper wires).  for now, here’s the concept:


//fine tuning 1 Hz
//slow tuning 10 Hz
//mid tuning 100 Hz
//fast tuning 1 kHz
//can't see the use in tuning faster than 1 kHz steps...

//somehow need to count time intervals between pulses, maybe average them over some time.  use that to set the tuning step, then use that as the freq delta, and adjust the freq when encoder is adjusted.