2022年8月9日火曜日

ツートーンジェネレーター AD9833


ツートーンジェネレータ
DDS信号発生モジュールを使ってツートーンジェネレータ作れないか? 最初に思いついたのが、Si5351A 3CH出力プログラマブル周波数ジェネレータ(8KHzから150MHzまでの任意の周波数を生成)低い周波数(400Hzから2500Hz)が使えないでAD9833を2個使うことにした。(AD9833 DDS信号発生器 モジュール 波形発生器 0〜12.5MHz 正弦波/三角波/方形波信号生成)注意、方形波は確認していませんが電源電圧の方形波が出力されるみたいです。


接続構成















SDR-3 ツートーン波形
2個のAD9833をArduino Nanoで制御、ロータリエンコーダで発振周波数を指定、エンコーダSWでA Bを切替えています。
A --- 0Hz, 400~1300Hz(100HzStep)
B --- 0Hz, 1400~2300HZ(100HzStep)
A Bをミックス、VRで出力調整、同ブログ:【SDR-3トランシーバー】のマイクに入力して送信するとのTX MONTR にA Bの2個の発振周波数が確認できます。
(A-700Hz B-1700Hz)


RF Power Meter



SDR-3 トランシーバー(-14dBμ 表示)
RF Power  -10.8dBm
(0.8317mW = 約0.1mW)



ユーティリティ : V RMS / dBm / dBu /dBV 計算ツール【https://www.analog.com/jp/design-center/interactive-design-tools/dbconvert.html



デジタルオシロスコープ
オシロスコープで測定したA-700Hz B-1700Hzミックス波形

デジタルオシロスコープ


これがツートーン波形?
(A-700Hz B-1700Hz)










デジタルオシロスコープ


シングルトーン波形(A-700Hz B-0Hz)











tinySAスペアナ


tinySAスペアナ測定、シングルトーン(A-700Hz B-0Hz)でも幅広波形なので、ツートーンで2つの波形を確認できませんでした。






SDR受信機
アッテネーター -90db挿入
SDR受信機ウォーターフォール表示2つの波形が確認できます。


SDR-3 TEST


SDR-3 TEST用
ツートーンジェネレーター
(1000Hz 1300Hz?)

デジタルオシロスコープ
ツートーン波形


回路図        A Bミックス回路アバウトです。


プログラム
#include "OLED_SSD1306.h" // https://github.com/askn37/OLED_SSD1306#start-of-content
#include <AD9833.h>
#include <Rotary.h> // https://github.com/brianlow/Rotary
#include <Arduino.h>
OLED_M091P oled;

#define ENC_A 2
#define ENC_B 3
Rotary r = Rotary(ENC_A,ENC_B);
#define ENC_SW 4

#define FNC_PINa 9
#define FNC_PINb 10 
int FREQa;
int FREQb;
int ab=0 ;
int Update=0;

char disp_bufA[16];
char* modeTextA[11] = {  
  "0000",  
  "0400",  
  "0500",  
  "0600",
  "0700",
  "0800",
  "0900",
  "1000",
  "1100",
  "1200",
  "1300",
};
char disp_bufB[16];
char* modeTextB[11] = {  
  "0000",
  "1400",  
  "1500",  
  "1600",  
  "1700",
  "1800",
  "1900",
  "2000",
  "2100",
  "2200",
  "2300",
}; 

int modePointerA = 0;
String unitsA = modeTextA[modePointerA];
int modePointerB = 0;
String unitsB = modeTextB[modePointerB];

void setup() { 
    r.begin();
    attachInterrupt(digitalPinToInterrupt(ENC_A),rotary_encoder,CHANGE);
    attachInterrupt(digitalPinToInterrupt(ENC_B),rotary_encoder,CHANGE);
    //pinMode(ENC_A, INPUT_PULLUP); r.begin()で行われる
    //pinMode(ENC_B, INPUT_PULLUP);
    pinMode(ENC_SW, INPUT_PULLUP); 
    oled.begin();
    oled.mirror(); //左右表示反転
    oled.flip();   //上下表示反転
    oled.setCursor (0, 2); 
    oled.print("A");
    oled.setCursor (1, 2); 
    oled.print(">");        
    oled.setCursor (0, 3);   
    oled.print("B");
            
     
    

 
void loop() {
    if (Update == 0){
    updateDisplayA();
    updateDisplayB();
    }
    if (digitalRead(ENC_SW) == LOW ){  
    delay(200);   
    if(ab == 0){   
    ab=1;
    oled.setCursor (1, 2); 
    oled.print(" ");  
    oled.setCursor (1, 3); 
    oled.print(">");  
       
   }
    else if(ab == 1){ 
    ab=0;
    oled.setCursor (1, 3); 
    oled.print(" ");  
    oled.setCursor (1, 2); 
    oled.print(">"); 
     
    }
    }  
}
void getmodeA() {
  switch (modePointerA) {    
    case 0: FREQa=0 ; break;  
    case 1: FREQa=400 ; break;    
    case 2: FREQa=500 ; break;   
    case 3: FREQa=600 ; break;
    case 4: FREQa=700 ; break;
    case 5: FREQa=800 ; break;
    case 6: FREQa=900 ; break;
    case 7: FREQa=1000 ; break;
    case 8: FREQa=1100 ; break;
    case 9: FREQa=1200 ; break;
    case 10: FREQa=1300 ; break;
  }
}
 void updateDisplayA() {
  getmodeA(); 
  unitsA = modeTextA[modePointerA];  
  oled.setCursor(2, 2); 
  oled.print(unitsA);
  ad9833A();
  Update=0;
  delay(50);  
 }

void getmodeB() {
  switch (modePointerB) {    
    case 0: FREQb=0 ; break;  
    case 1: FREQb=1400 ; break;    
    case 2: FREQb=1500 ; break;   
    case 3: FREQb=1600 ; break;
    case 4: FREQb=1700 ; break;
    case 5: FREQb=1800 ; break;
    case 6: FREQb=1900 ; break;
    case 7: FREQb=2000 ; break;
    case 8: FREQb=2100 ; break;
    case 9: FREQb=2200 ; break;
    case 10: FREQb=2300 ; break;
  }
}
 void updateDisplayB() {
  getmodeB(); 
  unitsB = modeTextB[modePointerB];  
  oled.setCursor(2, 3); 
  oled.print(unitsB);
  ad9833B(); 
  Update=1;
  delay(50); 
 }
 
 void rotary_encoder(){
  unsigned char result = r.process();
  if (result) {
    Update=0;
    if (result == DIR_CW)  {
      if (ab == 0){     
      if (modePointerA < 10){ modePointerA++;
    }
    }
    else if(ab == 1){
      if (modePointerB < 10){ modePointerB++;
    }
    }
    }
    if (result == DIR_CCW) {
      if (ab == 0){
      if (modePointerA > 0){ modePointerA--;       
    }
    } 
    else if(ab == 1){ 
      if (modePointerB > 0){ modePointerB--;       
    } 
    }      
  }   
  }   
 }
 
  void ad9833A() {
    AD9833 gen(FNC_PINa);  
    gen.Begin();              
    gen.ApplySignal(SINE_WAVE, REG0, FREQa);  // サイン波
    //gen.ApplySignal(TRIANGLE_WAVE, REG0, FREQ); //三角波
    //gen.ApplySignal(SQUARE_WAVE, REG0, FREQ); //矩形波    
    gen.EnableOutput(true); 
  }

  void ad9833B() {
    AD9833 gen(FNC_PINb);
    gen.Begin();              
    gen.ApplySignal(SINE_WAVE, REG0, FREQb);  // サイン波
    //gen.ApplySignal(TRIANGLE_WAVE, REG0, FREQ); //三角波
    //gen.ApplySignal(SQUARE_WAVE, REG0, FREQ); //矩形波 VCC   
    gen.EnableOutput(true); 
  }


0 件のコメント:

コメントを投稿

Raspberry Pi Donkey Car スマートカー

  2020年に製作したDonkey Car スマートカー について記事にしました。 Donkey CarはRaspberry Pi のカメラからコースを ディープラーニングさせ自動走行を行います。(動画は白線上を自動走行)   動画