2022年6月12日日曜日

RF信号発生器

DDS AD9850

RF信号発生器

0MHz〜40MHz DDS AD9850 信号発生器 2個のロータリーエンコーダで桁と周波数を操作しています。見直しが必要なプログラムですが使えるので今だに修正していません。









10MHz波形

























回路図





プログラム
#include <Rotary.h>       //  https://github.com/brianlow/Rotary 
#include <Arduino.h>
#include "OLED_SSD1306.h" // https://github.com/askn37/OLED_SSD1306#start-of-content
#include <EF_AD9850.h>
// EF_AD9850(CLK,FQ_UP,RESET,DATA)
EF_AD9850 AD9850(9, 10, 11, 8);
OLED_M091P oled;


#define stepPin1 A0                    // Set 'Step' rotary encoder pins
#define stepPin2 A1
int forceHzStep = A2;                  // 'Step' rotary encoder's push button - Set 1 Hz steps.
int forcekHz = A3;                     // Interrupt-driven encoder's push button - force 1kHz freq.

Rotary i = Rotary(stepPin1, stepPin2); // Rotart encoder for setting increment.
Rotary r = Rotary(2, 3);              // Rotary encoder for frequency connects to interrupt pins

//long unsigned int freq = 1000;         // Set initial frequency.
long freq = 10000000;
//long unsigned int freqOld = freq;
long freqOld = freq;

char disp_buf[16];

char* stepText[11] = {
  "         _",
  "        _ ",  
  "       _  ",  
  "     _    ",  
  "    _     ",
  "   _      ",
  " _        ",
  "_         ",
}; 

int stepPointer = 0;
long  incr = 0;
String units = stepText[stepPointer];

void setup() {

  pinMode(2, INPUT_PULLUP);            // Pins for interrupt-driven rotary encoder and push buttons
  pinMode(3, INPUT_PULLUP);
  pinMode(forceHzStep, INPUT_PULLUP);
  pinMode(forcekHz, INPUT_PULLUP);

  // Configure interrupt and enable for rotary encoder.
  PCICR |= (1 << PCIE2);
  PCMSK2 |= (1 << PCINT18) | (1 << PCINT19);
  sei();
  oled.begin();
  oled.mirror(); //左右表示反転
  oled.flip();   //上下表示反転
  oled.setCursor (0, 2); 
  oled.println("AD9850");  
  oled.setCursor(0, 3);  
  oled.print("OSC"); 
  
  delay(2000);
  //display.clearDisplay();

  // Initialise the AD9850 module.
  AD9850.init();
  AD9850.reset();
  AD9850.wr_serial(0x00, freq);
  updateDisplay();
}

void getStep() {
  switch (stepPointer) {
    case 0:  incr = 1; break;
    case 1:  incr = 10; break;  
    case 2:  incr = 100; break;    
    case 3:  incr = 1000; break;   
    case 4:  incr = 10000; break;
    case 5:  incr = 100000; break;
    case 6:  incr = 1000000; break;
    case 7:  incr = 10000000; break;
  }
}

void updateDisplay() {
  getStep();
  units = stepText[stepPointer];
       
  if (freq < 1000) {
    sprintf(disp_buf, "%10ld", freq);
  }
  else if (freq < 1000000) {
    int freqL = freq % 1000;
    int freqM = freq / 1000;
    sprintf(disp_buf, "%6d,%03d", freqM, freqL);
  }
  else {
    int freqL = freq  % 1000;
    int freqM = (freq / 1000) % 1000;
    int freqH = freq / 1000000;
    sprintf(disp_buf, "%2d,%03d,%03d", freqH, freqM, freqL);
  }
  
  oled.setCursor(0, 2);  
  //oled.print( "STEP:" );
  oled.print(units);   
  oled.setCursor(0, 3);
  oled.print(disp_buf);
  oled.print(" Hz"); 
 
}

void loop() {
  // Check 'Step' rotary encoder.
  unsigned char result = i.process();
  if (result) {
    if (result == DIR_CW)  {
      if (stepPointer < 8) stepPointer++;
    }
    if (result == DIR_CCW) {
      if (stepPointer > 0) stepPointer--;
    }
    updateDisplay();
  }

  if (digitalRead(forceHzStep) == LOW) {
    stepPointer = 0;
    updateDisplay();
    delay(50);
  }

  if (digitalRead(forcekHz) == LOW) {
    freq = 10000000;
    AD9850.wr_serial(0x00, freq);
    updateDisplay();
    delay(350);
  }
  if (freqOld != freq) {
    AD9850.wr_serial(0x00, freq);
    updateDisplay();
    freqOld = freq;
  }
}

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


0 件のコメント:

コメントを投稿

Raspberry Pi Donkey Car スマートカー

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