Skip to content

Instantly share code, notes, and snippets.

@weldtype
Created October 8, 2016 23:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save weldtype/47ebc8ebd9700782b1d1ea2e28003646 to your computer and use it in GitHub Desktop.
Save weldtype/47ebc8ebd9700782b1d1ea2e28003646 to your computer and use it in GitHub Desktop.
AD9850Sinewave generator
//AD9850 sinewave generator
// edy
//
//2016/10/06 First version(ver 0.1)
//
//2016/10/08 ver 0.2
// 周波数下限を 10Hz から 1Hz へ変更。
// 変数 freq,freqOld,incr を負号なしから負号ありへ。引き算によるエラー回避のため。
// 周波数ステップ 2.5KHz を 2KHz へ変更。
// 周波数表示を3桁区切りにする。
//参考にしたweb page
// http://www.vwlowen.co.uk/arduino/AD9850-waveform-generator/AD9850-waveform-generator.htm
/* Based on AD9851 code from Andrew Smallbone - modified for AD9850
http://www.rocketnumbernine.com/2011/10/25/programming-the-ad9851-dds-synthesizer
*/
#include <Rotary.h> // Rotary encoder: https://github.com/brianlow/Rotary
#include <LiquidCrystal.h>
//LiquidCrystal(rs, enable, d4, d5, d6, d7)
LiquidCrystal lcd(7, 6, 8, 9, 10, 11);
#include <EF_AD9850.h>
// EF_AD9850(CLK,FQ_UP,RESET,DATA)
EF_AD9850 AD9850(5, 4, A3, A4);
#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 = A5; // 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 = 1000;
//long unsigned int freqOld = freq;
long freqOld = freq;
char disp_buf[16];
char* stepText[11] = {" 1Hz",
" 10Hz",
" 50Hz",
" 100Hz",
" 500Hz",
" 1KHz",
" 2KHz",
" 5KHz",
" 10KHz",
" 100KHz",
" 500KHz"
};
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();
lcd.begin( 16, 2 ); // 16文字×2行
lcd.clear(); // LCD画面消去
lcd.setCursor( 0, 0 );
lcd.print( "AD9850" );
lcd.setCursor( 0, 1 );
lcd.print( "sinewave generator" );
delay(1000);
lcd.clear();
// 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 = 50; break;
case 3: incr = 100; break;
case 4: incr = 500; break;
case 5: incr = 1000; break;
case 6: incr = 2000; break;
case 7: incr = 5000; break;
case 8: incr = 10000; break;
case 9: incr = 100000; break;
case 10: incr = 500000; break;
}
}
void updateDisplay() {
getStep();
units = stepText[stepPointer];
lcd.clear();
lcd.setCursor( 0, 0 );
lcd.print( "Step: " );
lcd.print(units );
lcd.setCursor( 0, 1 );
lcd.print("Frq:");
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);
}
lcd.print(disp_buf);
lcd.print("Hz");
}
void loop() {
// Check 'Step' rotary encoder.
unsigned char result = i.process();
if (result) {
if (result == DIR_CW) {
if (stepPointer < 10) stepPointer++;
}
if (result == DIR_CCW) {
if (stepPointer > 0) stepPointer--;
}
updateDisplay();
}
if (digitalRead(forceHzStep) == LOW) {
stepPointer = 0;
updateDisplay();
delay(50);
}
if (digitalRead(forcekHz) == LOW) {
freq = 1000;
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) <= 10000000) freq += incr;
} else {
if ((freq - incr) >= 1) freq -= incr;
}
if (freq <= 1) freq = 1;
if (freq >= 10000000) freq = 10000000;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment