期することがあって、ライブラリを利用しようと思います。AD9833で検索すると”Billwilliams1952/AD9833-Library-Arduino”がまず出てきます。しかし、これはESP32が未サポートなのかもしれませんが、私の環境では動きませんでした。(FNC_PIN以外のSPI接続先は既定のPINに接続するようにソフトで行っている模様)
Arduino AD9833 GPIO-only library
ESP32が動くライブラリとして、GitHubに公開されているArduino AD9833 GPIO-only libraryを利用します。ただ、このライブラリは使用例が少ないので使い方を整理しておこうと思います。
このライブラリは最初にESP32で使えると紹介されていました。また、SPIの接続先は比較的自由にユーザが決めれるようです。AD9833はSPI_MODE2なのですが、それを意識しないで使えました。
AD9833用の小さなCPPライブラリです。これはESP-32で使用されるArduinoベースのライブラリですが、他のArduinoプラットフォームでも機能するはずです。このライブラリは、いくつかのメソッドを含む1つの大きなクラスオブジェクトです。このライブラリは、SPIハードウェアピンとして、SCK、FSYNC(CS)、およびDATA(MOSI)の3つのIOピンを使用します。
詳細については、https://daumemo.com/diy-generator-ad9833-library-and-further-output-noise-reduction-part-13/をご覧ください。
使い方:Function
AD9833_IC generator(int pinSCK, int pinFSYNC, int pinDATA);
object generatorを作成する
generator.setFrequency(double hz, uint8_t reg);
Sets Frequency(Hz) in selected frequency register (0 or 1)
選択した周波数レジスタ(0または1)に周波数(Hz)のデータを書き込みます
hz frquency value in Hz
reg selected register value, 0 or 1
generator.setPhase(double phase, uint8_t reg);
Sets phase in a selected phase register (0 or 1)
選択した位相レジスタ(0または1)に位相のデータを書き込みます
phase phase value in degrees
reg selected register value, 0 or 1
generator.setFrequencyRegister(uint8_t reg);
Sets frquency register which value is used for output
周波数レジスタ0または1をICの周波数出力レジスタとして設定します
reg selected register value, 0 or 1
generator.setPhaseRegister(uint8_t reg);
Sets phase register which value is used for output
位相レジスタ0または1をICの位相出力レジスタとして設定します
reg selected register value, 0 or 1
generator.setWaveForm(uint8_t waveform);
Sets output signal's waveform
出力波形を設定します
waveform 0-sine, 1-triangle, 2-square, 3-square/2
generator.start(uint8_t waveform, uint8_t freqRegist, uint8_t phaseRegist);
Start waveform generation
引数パラメータで波形生成を開始します
waveform 0-sine, 1-triangle, 2-square, 3-square/2
freqRegist used frequency register, 0 or 1
phaseRegist used phase register, 0 or 1
generator.start();
Start waveform generation with predefined values
事前に定義されたレジスタを使って波形生成を開始します
generator.stop();
Stops signal generation (puts IC to sleep and reset states)
波形生成を停止します(ICをスリープ状態にして状態をリセットします)
generator.reset(bool status);
Enables or disables chip's reset, puts IC to sleep
チップのリセットを有効または無効にし、ICをスリープ状態にします
status enables(true) or disables(false) reset
generator.directRegWrite(uint16_t data);
Writes 16 bit of data directly to the AD9833 chip - it is up to the user to write a correct value
16ビットのデータをAD9833チップに直接書き込みます-正しい値を書き込むのはユーザーの責任です
data 16bit of RAW data
generator.getPhase(uint8_t reg);
reg from which phase register to return the value, 0 or 1
0または1の位相レジスタの値を返します
return phase value which was written by the user
返される値はユーザーが書き込んだ値です
generator.getFrequency(uint8_t reg);
reg from which frequency register to return the value, 0 or 1
0または1の周波数レジスタの値を返します
return frequency value which was written by the user
返される値はユーザーが書き込んだ値です
generator.getPhaseRaw(uint8_t reg);
reg from which phase register to return the value, 0 or 1
0または1の位相レジスタの値を返します
return RAW integer phase value which was written to IC
返される値はICに書き込まれたRAW型の整数値(バイナリーデータ?)です
generator.getFreqRaw(uint8_t reg);
reg from which frequency register to return the value, 0 or 1
0または1の周波数レジスタの値を返します
@return RAW integer frequency value which was written to IC
返される値はICに書き込まれたRAW型の整数値(バイナリーデータ?)です
generator.getControlRegister();
return RAW integer control register value which was written to IC
ICに書き込まれたコントロールレジスタのRAW型の整数値(バイナリーデータ?)を返します
スケッチ例
generator.setFrequency(1000, REG0); // 周波数レジスタREG0へ、1000(Hz)を書き込む
generator.start(SINE_WAVE, REG0, REG0); // サイン波、REG0の周波数、REG0の位相で波形を作り出力をスタート
generator.setFrequency(2000, REG0);
#include <Arduino.h>
#include "ad9833.h"
#define REG0 0
#define REG1 1
#define SINE_WAVE 0
#define TRIANGLE_WAVE 1
#define SQUARE_WAVE 2
#define HALF_SQUARE_WAVE 3
AD9833_IC generator(14, 17, 13); // creates new object with pins 14,17,13 as SCK, FSYNC, DATA
// and initialises IC with stopped state
// (reset and sleep states are ON);
void setup(){
generator.setFrequency(1000, REG0); // sets 4kHz frequency in the register 0;
generator.start(SINE_WAVE, REG0, REG0); // starts generation with sine wave with
// selected frequency and phase registers (0 and 0).
delay(1000);
}
void loop(){
generator.stop(); // stops generation;
delay(2000);
generator.start(); // starts generation again;
delay(5000);
IncrementFrequencyTest();
delay(5000);
generator.start(TRIANGLE_WAVE,REG0,REG0); // starts generation with sine wave with
delay(2000);
}
/*
* Setup a manual ramp from a Start frequency to a Stop frequency in some increment
* over a ramp time.
*/
void IncrementFrequencyTest () {
float startHz = 1000, stopHz = 10000, incHz = 1, sweepTimeSec = 10.0;
// Calculate the delay between each increment.
uint16_t numMsecPerStep = (sweepTimeSec * 1000.0) / ((uint16_t)((stopHz - startHz) / incHz) + 1);
if ( numMsecPerStep == 0 ) numMsecPerStep = 1;
// Apply a signal to the output. If phaseReg is not supplied, then
// a phase of 0.0 is applied to the same register as freqReg
// gen.ApplySignal(SINE_WAVE,REG1,startHz);
generator.setFrequency(startHz, REG1); // Sets Frequency(Hz) in selected frequency register (0 or 1)
generator.setWaveForm(SINE_WAVE); // Set param waveform 0-sine, 1-triangle, 2-square, 3-square/2
//while ( true ) {
//gen.SetFrequency(REG1,startHz-incHz);
generator.setFrequency(startHz-incHz, REG1);// Sets Frequency(Hz) in selected register value, 1
generator.start(SINE_WAVE, REG1, REG1);
for ( float i = startHz ; i <= stopHz; i += incHz ) {
//YIELD_ON_CHAR
//gen.IncrementFrequency(REG1,incHz);
// Add/subtract a value from the current frequency programmed in freqReg by the amount given
// freqRegでプログラムされた現在の周波数から指定された量だけ値を加算/減算します
// float frequency = (freqReg == REG0) ? frequency0 : frequency1;
// SetFrequency(freqReg,frequency+freqIncHz);
generator.setFrequency( i + incHz, REG1);// Sets Frequency(Hz) in selected register value, 1
//generator.start(SINE_WAVE, REG1, REG1);
delay(numMsecPerStep);
}
//}
}