MiniGen Hookup Guide
Arduino Library
The MiniGen has a fairly comprehensive Arduino Library to help users write Arduino code easily.
Accessing the Library
The library can be downloaded as part of the Github repository for the MiniGen board. Simply download the zip file of the entire repository, then copy the "libraries" directory from the "Arduino" folder in the unzipped repository into your Arduino Sketchbook directory. The location of your Sketchbook can be found in the "Preferences" window of the Arduino IDE. If you have trouble installing the library, please consult our tutorial.
Using the Library
To use the library, add the following two lines to the top of your sketch:
language:c
#include <MiniGen.h>
#include <SPI.h>
Note that both lines must be present; failure to include the SPI library will cause code compilation to fail.
Once you've included the library, you must instantiate a MiniGen object in your sketch, like this:
language:c
MiniGen sig_gen;
You can replace the name sig_gen
with any name you like; our example sketches will use that name, however.
If you're using the board with something other than an Arduino Pro Mini, you can change the chip select pin (referred to in the library and datasheet as the FSYNC pin) used by the code by calling the constructor like this, instead:
language:c
sig_gen = MiniGen(pin_number);
Change pin_number
to the desired pin on the Arduino; note, however, that the SPI functionality of the Atmega requires that pin 10 be an output, so you'll lose the ability to do other things with that pin.
Library Commands
Once you've created your MiniGen object, there are several commands that you can send to the MiniGen board to operate it.
language:c
sig_gen.reset();
This command will reset the MiniGen to its default behavior: it clears the phase offset registers, resets the frequency to 100Hz, and disables the output, resulting in a DC voltage at approximately 1/2 the supply voltage on the output.
language:c
sig_gen.setMode(newMode);
The newMode
parameter can be one of the following values: MiniGen::TRIANGLE
, MiniGen::SINE
, MiniGen::SQUARE
, or MiniGen::SQUARE_2
. The frequency of the output will depend on the value in the selected frequency register; more on that below. For the first three options, the frequency will be at the set frequency; for the fourth, it will be one-half the set frequency.
language:c
sig_gen.selectFreqReg(reg);
The AD9837 chip has two registers that store possible output frequencies. These can be selected by passing the parameters MiniGen::FREQ0
and MiniGen::FREQ1
to this function. This allows the user to adjust the frequency by swapping registers rather than writing to the active register; since a full adjust of the frequency requires two SPI writes, this allows the change to take effect at once with no intermediate frequency step.
The FREQ registers are divided into a low word and a high word, each of which is 14-bits long; the output frequency is equal to the low word times 0.0596Hz plus the high word times 976.5Hz. The total output frequency is equal to the sum of the two registers.
language:c
uint32_t freqRegVal = sig_gen.freqCalc(desiredFrequency);
This helper function returns a 32-bit value (an unsigned long
Arduino data type, or uint32_t
in more general terms), which, when written to the AD9837 frequency register, will result in an output at desiredFrequency
. The value passed to the function should be a floating point number, in Hz. When this 32-bit value is written to the FREQ registers, the result will be (approximately) desiredFrequency
.
To write the value to the FREQ registers, there are several functions of interest. The reason for this is simple: speed. Writing the frequency value to the AD9837 can take anywhere from one to three SPI transactions; using the appropriate function allows the user to save execution time where possible.
language:c
sig_gen.adjustFreq(reg, mode, newFreq);
This method takes the longest. reg
can be either MiniGen::FREQ0
or MiniGen::FREQ1
, depending on where the user wants to write the value. mode
can be either MiniGen::FULL
, MiniGen::COARSE
, or MiniGen::FINE
. For the first, newFreq
should be an 32-bit unsigned value (as returned by freqCalc()
, or calculated by the user elsewhere); in that case, the frequency setting operation will require three SPI transactions. For the second and third, 'newFreq' should be a 16-bit unsigned value, and the operation will require two SPI transactions.
When the mode
parameter is MiniGen::FULL
, the value of the output will be equal to the passed parameter times 0.0596 Hz. When mode
is MiniGen::COARSE
, you will be writing to the high word of the register, and each count will increase the frequency by 976.5Hz. When mode
is MiniGen::FINE
, you'll be writing to the low word, and each count will increase the frequency of the output by .0596Hz. Splitting the writes into coarse and fine allows the user to minimize the number of writes required to change the frequency.
language:c
sig_gen.FreqAdjustMode(newMode);
sig_gen.adjustFreq(reg, newFreq);
If speed is important, you can pre-select the mode
. This reduces the write time to two SPI writes for FULL
and one for COARSE
or FINE
. Note that this requires care on the part of the user to pass the appropriate value to adjustFreq()
; if the mode is set to FULL
and a 32-bit value isn't passed, or to COARSE
or FINE
and a 16-bit value isn't passed, the result will not be as desired.
language:c
sig_gen.selectPhaseReg(reg);
sig_gen.adjustPhaseShift(reg, newPhase);
It's possible to adjust the phase shift between the input clock and the output signal. As is the case with setting the frequency, there are two phase shift registers. They can be selected by passing MiniGen::PHASE0
or MiniGen::PHASE1
as the reg
parameter in the above functions.
For the newPhase
parameter, the value should be a 16-bit unsigned value. Only 12 bits of that value are used, so it should be a maximum of 4095. Each count represents .00153 radians (.551 degrees). However, since the phase is measured relative to the input frequency, this setting is of limited value.