DDSファンクションジェネレータのコントロールを
行うためのスケッチ、とりあえず書けた。
http://picavr.uunyan.com/avr_m2_dds_fg.html
これに繋いで使うコントローラ部分。シリアルで
制御コマンドをI/Fするためのもの。LCD画面で
見ながら、操作内容にしたがってDDSファンクション
ジェネレータにコマンド送信するので、PCが要らない。
オイラの場合、使っているオシロがUSB接続タイプで
PC画面で操作/表示するヤツだから、PCで操作しなくて
いいファンクションジェネレータは、何かと便利。
スケッチはこんな感じ。
/* AVR DDS function generator controller */
/* with aitendo LCD keypad shield */
/* http://www.dfrobot.com/wiki/index.php/Arduino_LCD_KeyPad_Shield_%28SKU:_DFR0009%29 */
/* */
/* *input : keypad on LCD shield */
/* *output : LCD and USART */
/* */
/* created by nekosan */
/* created : 2013.10.21 V0.1 */
/* */
#include <LiquidCrystal.h>
/* I/O pins for aitendo lcd shield */
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
/**********************************?
/*** declare global variables */
/**********************************?
/* key names table */
char key_name[][10] = {
"none ",
"select ",
"left ",
"down ",
"up ",
"right " };
/* wave form name table */
char wave_name[][4] = {
"sin",
"sq ",
"tr ",
"sw1",
"sw2"};
/* freq and wave memory */
char num_data[6] = {0,0,0,0,0 ,0}; // initial = 0Hz , sine wave
/* limit table */
char limit[6] = {2,9,9,9,9 ,4};
// limit freq = 29999hz
// limit wave = 4 (sw2)
/* cursor position X */
int cur_x[7] = {0,1,2,3,4,7 ,15};
int pos_x = 0;
/*****************************/
/*** declare functions ***/
/*****************************/
/* cognition witch button is pushed */
int key_sense() {
/* last key */
static char last_key = 0; // initial = none
/* key record ( for sensing key-change ) */
static char key_record[3] = { 0,0,0 }; // initial = none, none, none
/* define threshold for keypads */
const int keypad_th[] = {
(1023 + 720) / 2, /* none - select */
(720 + 479) / 2, /* select - left */
(479 + 307) / 2, /* left - down */
(307 + 132) / 2, /* down - up */
(132 + 0) / 2 }; /* up - right */
int key_in;
int i;
key_in = analogRead(0);
key_record[2] = key_record[1];
key_record[1] = key_record[0];
int now_key = 0;
for (i=0; iif (key_in if ((key_record[0] == key_record[1]) &&
(key_record[1] == key_record[2])) {
last_key = now_key;
}
delay(1);
return last_key;
}
/* pick up key changing */
int key_check(int new_key) {
static int old_key = 0; //initial = none
int ret = 0;
if (new_key != old_key) {
old_key = new_key;
ret = new_key;
}
return ret;
}
/* change a value */
void change_value(int key_change) {
int i;
switch (key_change) {
case 1: // select
if (pos_x == 6) {
reset_dds(); // send reset command
for (i=0;i// all clear
}
}
break;
case 2: // left
pos_x--;
if (pos_x < 0) {
pos_x = 0;
}
break;
case 3: // down
if (pos_x // declement
if (num_data[pos_x] < 0) {
num_data[pos_x] = 0;
}
}
break;
case 4: // up
if (pos_x // inclement
if (num_data[pos_x] > limit[pos_x]) {
num_data[pos_x] = limit[pos_x];
}
if (num_data[0] >= 2) { // if over 20000hz
num_data[0] = 2;
for (i=1;ibreak;
case 5: // right
pos_x++;
if (pos_x > 6) {
pos_x = 6;
}
break;
default:
break;
}
print_lcd(); // print freq and wave data on lcd
}
/* print out on lcd */
void print_lcd() {
int i;
/* print freq data */
lcd.setCursor(0, 0);
for (i=0;iwrite(num_data[i] + '0');
}
lcd.print("F ");
/* print wave data */
lcd.write(num_data[5] + '0');
lcd.print("W(");
lcd.print(wave_name[num_data[5]]);
lcd.print(") R"); // 'R' means 'reset'
/* set cursor */
lcd.setCursor(cur_x[pos_x],0);
}
/* output to dds via uart */
void uart_out() {
int i;
/* output freq data */
for (i=0;iSerial.write(num_data[i] + '0');
}
Serial.print("F");
/* output wave data */
Serial.write(num_data[5] + '0');
Serial.print("W");
}
/* reset dds */
void reset_dds(){
Serial.print("R");
}
/************************/
/*** main process ***/
/************************/
void setup()
{
/* setup LCD */
analogWrite(10,127); // back light brightness
lcd.begin(16, 2);
lcd.clear();
lcd.cursor(); // display cursor on
// lcd.blink(); // blink cursor on
print_lcd(); // print freq and wave on lcd
Serial.begin(19200); // to DDS synthesizer
Serial.println( (int)pow(10.0,4.0-(float)0.0 ) );
}
void loop() {
int i=0;
int key_in;
int key_change;
key_in = key_sense();
key_change = key_check(key_in);
if (key_change != 0) {
change_value(key_change);
uart_out();
//Serial.println();
}
}
まだ実機には繋いでないので、ちゃんと動作するか
は責任持てないんだけど、単純な代物なので、
まぁ動かないことはないんじゃないかと。
http://www.aitendo.com/product/7410
LCDキーパッドシールドに繋いで、電源入れたの
がこれ。PCに繋いでデバッグ中の様子。
ストロボ使って撮ると、こんな風に見づらいけど、
上1行の16文字分に
00000F 0W(sin) R
^
こんな風に書いてある。カーソルは一番左に。
左から、周波数が00000Hz、波形0(sin波)で、
Rはリセットスイッチという意味。
「左右」キーでカーソルを動かして、各数値
(周波数部分、波形番号)か「R」の部分を選択、
「上下」で数値を上下、「R」のときに「セレクト」
を押すと、DDSファンクションジェネレータを
システムリセット。
何か変更が行われた場合に、周波数と波形の
制御信号を出力。(目下、シリアルモニタで動作
確認をした状態)
キー入力は、面倒なので、リピートが掛からない
処理方法。PCのキーボードみたいにリピート効くと
便利なんだけど。
上1行しか使っていないのは、以前作った
http://brown.ap.teacup.com/nekosan0/1733.html
http://brown.ap.teacup.com/nekosan0/1739.html
この2ch出力のDDSファンクションジェネレータを
動かすときに、残りのもう1行を使う予定だから。
なんにしても、DDSファンクションジェネレータと
実機を繋いで動かしてみるには、LCDシールドに
ピンヘッダをハンダづけする必要があるので、
またこんど。
コイツが動くようになったら、ウクレレ用の
クロマチックチューナと繋いでテストに使う
目論見なのだ。
あっちはあっちで、ちゃんと進めないとな。
それにしても、LCDとキーパッドが一つの
シールドに纏まってるだけで、なにかと
便利だな。