FC2ブログ

迷走の果て・Tiny Objects

迷走する日々の覚え書きです。自分で分かってることは省略してますので、念のため。

AD9833 DDSモジュールを試す(13) 現状

今現在の回路です。念のため、間違いがないことを保証しません。

(↓クリックで拡大)
AD9833Signal_Generator3_20180602144550ca4.png

スイッチ付きのロータリーエンコーダを二つ使っています。
・出力周波数変更と出力周波数丸めスイッチ。
・ステップ周波数変更と出力周波数をステップ周波数と同じにするスイッチ。

回路図上には出力波形切り替えスイッチもあるが、まだつけていません、ちょっと問題があるので。
正弦波、三角波出力が300mVp-p程なのに対して、方形波出力は4Vp-p程と一桁違ってます。
例えばアンプの測定中にうっかり矩形波出力なんかにしたらえらいことになりそうです。

回路図上のスイッチの名前の付け方にも問題があります。まぁ本人が分かっていればそれでいいんです。

出力アンプをつけたいところです。部品は集めたのですが、ここしばらくの気温の乱高下に体調がおかしくなってしまいました。
歳ですねぇ。
今現在のスケッチです。念のため、バグがないことを保証しません。

つぎはぎだらけなのですが、とりあえず動いてます。
#Define と const int を混在させたり、変数名のつけ方に統一性がなかったりします、キャメルだったりスネークだったり(汗)
数年後(いや数か月後か)に読んだら分からんでしょうね。


//AD9833 Signal  generator
// edy
//2016/10/25 First version(ver 0.1)
//2018/05/09 ver 0.2
//2018/05/18 round追加
//2018/05/18 早くまわしたときのバグを修正
//2018/05/23 setFreq追加。round,setFreq,waveのピン配置変更
//
//参考にしたweb page
//AD9833 Waveform Generator
//http://www.vwlowen.co.uk/arduino/AD9833-waveform-generator/AD9833-waveform-generator.htm

// PCF8574を使ったI2C接続モジュールを使う
// https://www.amazon.co.jp/dp/B010Q000V2/
// arduino用ライブラリ
// https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library
//
//  Rotary encoder: https://github.com/brianlow/Rotary
/*It's also possible to use 'half-step' mode.
  This just emits an event at both the 0-0 and 1-1 positions.
  This might be useful for some encoders where you want to detect all positions.
  In rotary.h, uncomment  `#define HALF_STEP` to enable half-step mode.
*/
#include <Rotary.h>
#include <SPI.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);

#define MAXFREQ 10000000
const int SINE = 0x2000;                    // Define AD9833's waveform register value.
const int SQUARE = 0x2020;                  // When we update the frequency, we need to
const int TRIANGLE = 0x2002;                // define the waveform when we end writing.

int wave = 0;
int waveType = SINE;
int roundPin = 7;
int setFreqPin = 4;
int wavePin = 8;
int freqUpPin = 2;                          // Define rotary encoder pins.
int freqDownPin = 3;
int stepUpPin = 5;
int stepDownPin = 6;
int stepLen;
const float refFreq = 25000000.0;           // On-board crystal reference frequency

const int FSYNC = 10;                       // Standard SPI pins for the AD9833 waveform generator.
const int CLK = 13;                         // CLK and DATA pins are shared with the TFT display.
const int DATA = 11;

Rotary r = Rotary(freqUpPin, freqDownPin);    // Rotary encoder for frequency connects to interrupt pins
Rotary i = Rotary(stepUpPin, stepDownPin);    // Rotart encoder for setting increment.

long freq = 100000;               // Set initial frequency.
long freqOld = freq;

long incr = 1000;
long oldIncr = 1000;
char disp_buf[16];
long step[] = {
 1, 5, 10, 50, 100, 500, 1000, 5000, 10000, 50000, 100000, 500000, 1000000
};
int stepPointer = 5;

void setup() {

 pinMode(freqUpPin, INPUT_PULLUP);      // Set pins for rotary encoders as INPUTS and enable
 pinMode(freqDownPin, INPUT_PULLUP);    // internal pullup resistors.
 pinMode(stepUpPin, INPUT_PULLUP);
 pinMode(stepDownPin, INPUT_PULLUP);
 pinMode(wavePin, INPUT_PULLUP);
 pinMode(roundPin, INPUT_PULLUP);
 pinMode(setFreqPin, INPUT_PULLUP);

 // Configure interrupt and enable for rotary encoder.
 PCICR |= (1 << PCIE2);
 PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
 sei();
 SPI.begin();
 delay(50);

 lcd.begin();
 lcd.clear();  // LCD画面消去
 lcd.setCursor( 0, 0 );
 lcd.print( "AD9833" );
 lcd.setCursor( 0, 1 );
 lcd.print( "Signal Generator" );
 delay(1000);
 lcd.clear();
 stepLen = sizeof step / sizeof step[0];
 AD9833reset();                                   // Reset AD9833 module after power-up.
 delay(50);
 AD9833setFrequency(freq, SINE);                  // Set the frequency and Sine Wave output
 updateDisplay(freq);
}

void updateDisplay(long frequency) {
 // display step
 //noInterrupts();
 incr = step[stepPointer];
 lcd.setCursor( 0, 1 );
 lcd.print( "Stp:" );
 if (incr < 1000) {
   sprintf(disp_buf, "%10ld", incr);
 }
 else if (incr < 1000000) {
   int freqL = incr % 1000;
   int freqM = incr / 1000;
   sprintf(disp_buf, "%6d,%03d", freqM, freqL);
 }
 else {
   int freqL = incr  % 1000;
   int freqM = (incr / 1000) % 1000;
   int freqH = incr / 1000000;
   sprintf(disp_buf, "%2d,%03d,%03d", freqH, freqM, freqL);
 }
 lcd.print(disp_buf);
 //lcd.print("Hz");

 // Display Freq
 lcd.setCursor( 0, 0 );
 lcd.print("Frq:");
 if (frequency < 1000) {
   sprintf(disp_buf, "%10ld", frequency);
 }
 else if (freq < 1000000) {
   int freqL = frequency % 1000;
   int freqM = frequency / 1000;
   sprintf(disp_buf, "%6d,%03d", freqM, freqL);
 }
 else {
   int freqL = frequency  % 1000;
   int freqM = (frequency / 1000) % 1000;
   int freqH = frequency / 1000000;
   sprintf(disp_buf, "%2d,%03d,%03d", freqH, freqM, freqL);
 }
 lcd.print(disp_buf);
 //lcd.print("Hz");
 switch (wave) {
   case 0: lcd.print(" S"); break; // 正弦波
   case 1: lcd.print(" P"); break; // 方形波 pulse
   case 2: lcd.print(" T"); break; // 三角波
 }
}

void loop() {

 if (oldIncr != incr) {
   updateDisplay(freq);
   oldIncr = incr;
 }

 // Check 'increment' rotary encoder. Increase or decrease 'increment'
 // if encoder has been turned.
 unsigned char result = i.process();
 if (result) {
   if (result == DIR_CW)  {
     stepPointer++;
     if (stepPointer >= stepLen) stepPointer = 0;
   }
   if (result == DIR_CCW) {
     stepPointer--;
     if (stepPointer < 0) stepPointer = stepLen - 1;
   }
   updateDisplay(freq);
 }

 // Check if push button wavePin is pushed and set Wave Type accordingly.
 if (digitalRead(wavePin) == LOW) {
   wave += 1;
   if (wave > 2) wave = 0;
   switch (wave) {
     case 0: waveType = SINE; break;
     case 1: waveType = SQUARE; break;
     case 2: waveType = TRIANGLE; break;
   }
   AD9833setFrequency(freq, waveType);     // Set AD9833 to frequency and selected wave type.
   updateDisplay(freq);
   delay(100);
 }

 // Check setFreqPin
 if (digitalRead(setFreqPin) == LOW) {
   freq = incr;
   delay(100);
 }

 // Check roundPin
 if (digitalRead(roundPin) == LOW) {
   freq = (freq / incr) * incr;
   if (freq == 0) freq = incr;
   delay(100);
 }
 /*
   オリジナルのままでは処理中にfreqが割り込みによって変化してしまうと
   AD9833setFrequency()とupdateDisplay()で使うfreqが一致しなくなる場合がある
   そこでfreqを一時変数tempにいれて処理するようにした。
   そのためupdateDisplay()を変更した。
 */
 long temp = freq;
 if (temp != freqOld) {                    // If frequency has changed, interrupt rotary encoder
   AD9833setFrequency(temp, waveType);     // must have been turned so update AD9833 and display.
   updateDisplay(temp);
   freqOld = temp;                         // Remember new frequency to avoid unwanted display
 }                                         // and AD9833 updates.
}
// end of void loop()

// AD9833 documentation advises a 'Reset' on first applying power.
void AD9833reset() {
 WriteRegister(0x100);   // Write '1' to AD9833 Control register bit D8.
 delay(10);
}

// Set the frequency and waveform registers in the AD9833.
void AD9833setFrequency(long frequency, int Waveform) {

 long FreqWord = (frequency * pow(2, 28)) / refFreq;

 int MSB = (int)((FreqWord & 0xFFFC000) >> 14);    //Only lower 14 bits are used for data
 int LSB = (int)(FreqWord & 0x3FFF);

 //Set control bits 15 ande 14 to 0 and 1, respectively, for frequency register 0
 LSB |= 0x4000;
 MSB |= 0x4000;

 WriteRegister(0x2100);
 WriteRegister(LSB);                  // Write lower 16 bits to AD9833 registers
 WriteRegister(MSB);                  // Write upper 16 bits to AD9833 registers.
 WriteRegister(0xC000);               // Phase register
 WriteRegister(Waveform);             // Exit & Reset to SINE, SQUARE or TRIANGLE

}
void WriteRegister(int dat) {

 // Display and AD9833 use different SPI MODES so it has to be set for the AD9833 here.
 SPI.setDataMode(SPI_MODE2);

 digitalWrite(FSYNC, LOW);           // Set FSYNC low before writing to AD9833 registers
 delayMicroseconds(10);              // Give AD9833 time to get ready to receive data.

 SPI.transfer(highByte(dat));        // Each AD9833 register is 32 bits wide and each 16
 SPI.transfer(lowByte(dat));         // bits has to be transferred as 2 x 8-bit bytes.

 digitalWrite(FSYNC, HIGH);          //Write done. Set FSYNC high
}

// Interrupt service routine for the 'frequency' rotary encoder.

ISR(PCINT2_vect) {
 unsigned char result = r.process();
 if (result) {
   if (result == DIR_CW) {
     if ((freq + incr) <= MAXFREQ) freq += incr;
   }
   else {
     if ((freq - incr) >= 1) freq -= incr;
   }
   if (freq <= 1)  freq = 1;
   if (freq >= MAXFREQ) freq = MAXFREQ;
 }
}

関連記事
スポンサーサイト

コメント

コメントの投稿

管理者にだけ表示を許可する

トラックバック

この記事へのトラックバックURL
https://edycube.blog.fc2.com/tb.php/1046-027778f9

 | HOME | 

文字サイズの変更

プロフィール

edy

最新記事一覧(サムネイル画像付き)

obniz(8)obnizフォーラム開設、obnizはクラウド経由のI/Oポート。 2018/08/19
obniz(6)obnizがマイナーアップデートされるらしい。 2018/08/02
obniz(5)電源ラインのリプル・LM35・LED 2018/07/29
obniz(4) obnizをブレッドボードに載せる・ブロックプログラミングでLM35を使ってみる 2018/07/21
obniz(3) ブロックプログラミング 2018/07/15
obniz(2) obniz ID とアクセストークン発行について 2018/07/14
obniz 2018/07/13
メイカーズバザール大阪 2018/07/10
AliExpressでお買い物:PogoPin 2018/07/08
ダイソー ペンダントライト・Arduino Pro Miniを組み込む 2018/06/24

全記事表示リンク

全ての記事を表示する

リンク

このブログをリンクに追加する

月別アーカイブ

08  07  06  05  04  03  02  01  12  11  10  09  08  07  06  05  04  03  02  01  12  11  10  09  08  07  06  05  04  03  02  01  12  11  10  09  08  07  06  05  04  03  02  01  12  11  10  09  08  07  06  05  04  03  02  12  11  10  09  07  05  04  03  04  03  01  12  11  10  08  07  06  05  03  02  01  12  11  10  09  08  07  06  05  04  03  02  01  12  11  10  09  08  07  06  05  04  02  01  12  10  09  08  07  06  05  04  03  02  01  12  11  10  09  08  07  06  05  03  02  01  12  11  10  09  08  07  06  05  04  03  02  01  12  10  09  08  07  06  05  04  03  02  01 

カテゴリ

プログラミング (0)
freescale (1)
AVR (3)
テルミン (16)
緊急警報放送 (3)
78K (1)
PSoC (295)
地上デジタル放送 (2)
電子工作 (456)
HX711 (2)
ACS712 (6)
DDS (3)
数学 (6)
パソコン (12)
PLC (14)
未分類 (40)
ブログ関係 (20)
スカイプ (37)
ロボット (1)
LTSpice (8)
OCXO (0)
arduino (33)
maxima (1)
フランクリン発振回路 (3)
GPS (3)
DTMF (1)
Linux (1)
KOMAINO (7)
Android (1)
obniz (7)

タグリスト

最近のコメント

最近のトラックバック

メールフォーム

名前:
メール:
件名:
本文:

検索フォーム

アクセス

RSSリンクの表示

ブログリンク

FC2Ad

まとめ

Template by たけやん