Tuesday, May 19, 2015

Si5351 Signal Generator - 3D print of case

Now that the software is in pretty good shape (with a couple lingering issues) I turned my attention to building a case for this project.  Here is a simple front panel design I whipped up (ok, painfully slowly created after many mistakes...) using the online CAD software at www.onshape.com.  They have a pretty cool product offering there and it is certainly sufficient for these kinds of simple projects.

My little display and rotary encoder should fit nicely onto this panel.  As soon as I decide which Arduino board I am going to put into this project, I will work up a nice case back that this will snap into.  Yeah, yeah, this is my first CAD project, so I am 100% certain I will need to redesign it in some fashion.  Like for example, I suspect that I will have to put mounting screws through the panel into posts.  Don't beat me up too badly about my lack of CAD skills.

At this point it is pretty handy to have a son with a 3D printer.  Here it is printing this little guy.  I will go pick it up tomorrow and see if my display will fit into it.

Here it is, finished in 56 minutes.

More to come...

Sunday, May 17, 2015

Uh oh...

I ran across an interesting little anomaly today.  Consider the following Arduino code which prints the result of dividing an unsigned long by a float.

void setup() 
  uint32_t f = 10000005UL;

  for (int i = 0; i < 10; i++)
    Serial.print(" - ");
    Serial.println(f/1e6, 6);

void loop()


Unfortunately, the following is the output:

10000005 - 10.000005
10000004 - 10.000004
10000003 - 10.000003
10000002 - 10.000002
10000001 - 10.000001
10000000 - 10.000000
9999999  - 10.000000
9999998  - 9.999999
9999997  - 9.999998
9999996  - 9.999997

I guess I am going to have to look into the Print class a bit and see if the error is in the divide operation or the print operation.  Heads up...

UPDATED: Si5351 Signal Generator

I have been updating the UI on my Si5351 signal generator a little bit today.  I think it is about where I want it to be.  I display all three clock frequencies directly at the moment.  There is the notion of a current clock that will be displayed in yellow text.  The other two are displayed in white text.  In the image below, CLK2 is active.  The active clock is the one that will be modified if you rotate the rotary encoder.

Each of the clocks can be set anywhere in the 8 kHz to 160 MHz range.  However, I still have some anomalys as at very low frequencies and at very high frequencies, the clock output does not follow the display.  Obviously, I have more reading to do on the Si5351 datasheet to understand what I am doing wrong.

A button press will cycle through the three clocks.  The rotary encoder press will cycle through the digits of the frequency allowing you to change the tuning rate.  I may get rid of the button and have the rotary encoder button press cycle between selecting the clock (by turning the encoder) and changing the digit that is changed when the encoder is rotated.  Dunno...

I may give some thought to treating one of the clocks as a VFO and another as a BFO and displaying the difference between them for the VFO clock, but setting the output frequency to the sum of the displayed frequency and the BFO frequency.  This would allow for a receive frequency display while the actual VFO frequency is quite different.  In this mode the signal generator could be a convenient receiver display.  This could also be an update for another day.  I also want to provide some indication of which digit will be changed when you turn the encoder.  Currently no indicator is present.

Currently I am running this on my ATMega2560 but the plan is to use an ATTiny85 or perhaps one of the small ATMega328 units such as the Nano, or the Adafruit Trinket Pro.

So, once I get the frequency setting questions answered, I am going to put the arm on my oldest son to 3D print me a small box where I can package up the display, rotary encoder, power switch, Arduino and the Si5351 into a nice battery powered, portable signal generator unit.

Saturday, May 16, 2015

Progress grinds to a halt...

I have encountered a rather significant impediment to progress this afternoon in the form of one attention starved (apparently) feline by the name of Tinkerbelle.

She has planted herself between me and my keyboard and when I ignore her she sits there and purrs and lays on top of the mouse.  Might be time for a break...

Si5351 Signal Generator

I have been expanding on my initial experiments with the Si5351 today while at the same time getting some experience with my little 1.8" colour TFT display.  This is a nice little display that I picked up locally.  It has an SPI interface and using an ST7735 controller.

I initially was bit-banging the SPI protocol using arbitrary pins on the ATMega2560, but was quite dis-satisfied with the performance.  The display was very laggy and slowed down the entire experience.

By switching to use the hardware SPI support on the ATMega2560 (using pins 51 and 52 for MOSI and SCK signals respectively) the performance improvement was spectacular.  On the UNO, the hardware pins are 11 and 13 for MOSI and SCK respectively.

I am using a modified version of the Adafruit graphics library and the Adafruit ST7735 driver for my experimentation.

I found a couple of problems which I don't know if I can attribute to the Adafruit libraries or to differences with the specific LCD panel I have in hand.  I will have to order one of the Adafruit versions to determine which it is.  I found that the color mappings were reversed between RED and BLUE and also between YELLOW and CYAN.  If I can obtain a version of the Adafruit display I will test again and report my findings.

I set up my Si5351 clock generator and the TFT display as a three frequency signal generator.  There is still some UI work to be done to select between the frequencies to be changed by the rotary encoder, but here is the general idea.  I am reusing my previously published rotary encoder bits in this little project.

I will have the ability to independently set each of the clocks on the Si5351.  At the moment the code sets the initial frequency of each clock and then moves them all when the rotary encoder turns.  I plan to publish the code here when I have it all working satisfactorily.

Performance of the display is now very good, even when updating all three frequencies with the rotary encoder simultaneously.  This might be a good candidate for a little Arduino Nano or other minimal Arduino board to allow packaging this up into a useful signal source.

Monday, May 11, 2015

i2c Scanner

I wanted to share a useful script that I have written to determine the available addresses on Arduino's i2c (pronounced "eye-squared-see") bus.  When attaching new hardware where you may not have the address for the device available, this script can be useful to determine that information.  It is also useful for debugging connectivity issues on an i2c bus.

To use, connect your hardware to the bus clock and data lines.  Apply power and ground your hardware as well.  Run this script and open the serial monitor at 115200 baud.  You can change this speed to suit your preferences.  The serial monitor window will list all of the device addresses found on the bus.

As always, if you need assistance, please let me know by dropping me a note at ko7m at arrl dot net or by posting here and I will try to help you out.

// i2c_scanner

#include <Wire.h>

void setup()

  Serial.println("i2c Scanner");

void printAddress(byte address)
  if (address<16) Serial.print("0");
  Serial.println(address, HEX);

void loop()

    int nDevices = 0;
    for(int address = 1; address < 127; address++ ) 
      int error = Wire.endTransmission();
      // Just for good measure, try again
      if (error != 0)
//        Serial.print("Error ");
//        Serial.println(error, DEC);
//        Serial.println("Retrying...");
        error = Wire.endTransmission();
      if (error == 0)
        Serial.print("i2c device found at address 0x");
      else if (error == 4) 
        Serial.print("Unknown error at address 0x");
    if (nDevices == 0)
      Serial.println("No i2c devices found\n");

  // Hang the script
  while (1==1);

Si5351 clock generator

I am having a play around with a the much discussed Adafruit Si5351 clock generator board this morning while waiting for a phone interview.  It is a nice bit of kit and will be handy for a number of frequency generation needs.  The device comes on a small break-out board.  The only soldering required is to hook up the 0.1" header pins if desired for breadboard work and to mount three SMA connectors on the edge if desired.  There are three clock outputs brought out to the SMA connectors, but also to three header pins.

The device is an i2c device addressed at 0x60 so only power, ground and two i2c wires are necessary to get it oscillating.  Since so much has been written on this module previously, I won't bore you with recreating all of that here.  I decided to use (N6QW) Pete Juliano's "Let's Build Something" project as the starting point.  You can see Pete's project pages over at http://www.jessystems.com/.  Pete also has a great series of videos on his youtube channel here

For my lash-up, I am using a ATMega2560 board, Version 1.6.3 of the Arduino IDE, an old 20x4 LCD display that I have put an i2c backpack on, and the Si5351 from Adafruit.

The device is a 3V3 device, but the board sports a nice LDO voltage regulator to allow powering from a 5V rail.

Pete has the unit set up to cover the 40 metre band for a homebrew SSB rig.  The IF frequency appears to be 4.9136 MHz, for a display frequency of 7.1 Mhz, the oscillator is being set to 12.0136 MHz.  The signal looks pretty good, right off of the output pin.

I removed the IF offset from the oscillator frequency setting to output the displayed frequency.  At 7.1 MHz, the signal is somewhat less sinusoidal.  At low frequencies the device outputs a square wave with a bit of overshoot.  As you go up in frequency, the waveform below is prevalent which is really still the same thing, though the rise and fall time as a function of frequency is longer.  The waveform above is nearly sinusoidal at 12 MHz though above about 25 Mhz, the overshoot returns.

The output voltage at 1 MHz is about 3V3.  At 30 MHz, the peak-to-peak drops to about 0V5 with about a 2V positive DC offset.  Above 32 MHz the voltage level begins to rise again.  There are several of these peaks and valleys in amplitude as you continue to go up in frequency.  Above 35 MHz, the waveform appears to be mostly triangular.

As time allows, I plan to experiment more with this little device in my projects, but just wanted to have a quick experiment to get the device up and running.