Hello,
I Am currently building a DDS Frequency Generator using an Arduino and a AD9835 http://arduino.cc/forum/index.php?topic=67958.0 I got from Spark fun.
I am using a 3x4 matrix keypad to set the output frequency and a rotary encoder for fine tuning.. I have most of this working except the rotary encoder is way to sensitive. I am using hardware debouncing found here Arduino Playground - RotaryEncoders and this works great in that the decoder increments in single steps. My problem is that I am using interrupts to control the rotary encoder and am using a large dial type knob on the encoder and find it very hard to make small adjustments to it. When I spin at a reasonable pace the frequency is going up too fast. I have never used interrupts in the past but read that there is no way to put in a delay in the code. how do I go about slowing down the interrupts so it only reads every 2nd or 3rd pulse from the encoder? Can this be done in softwre or do I need to use some kind of hardware methord to slow it down.
I have attached my encoder and keypad section of the code below. any help or comments would be appreciated
/**
* sinusoid Frequency generator.
*
* This program produces a sinusoidal signal using the AD9835 IC
*/
// variables will change:
long Rotate=10000;
long Frequency =0;
int jump = 1;
long num = 0;
//*********************************************************LCD Setup Start******************************************
#include <SoftwareSerial.h>
#define txPin 5
SoftwareSerial LCD = SoftwareSerial(0, txPin);
// since the LCD does not send data back to the Arduino, we should only define the txPin
const int LCDdelay=10; // conservative, 2 actually works
//*************************************AD9835 setup*************************************
#include <SPI.h>
#include "AD9835.h"
//setup Keypad Pins\
#include <Keypad.h>
const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
{
'1','2','3' }
,
{
'4','5','6' }
,
{
'7','8','9' }
,
{
'*','0','#' }
};
byte rowPins[ROWS] = {
48, 46, 44, 42}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {
40, 38, 36}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
// We begin by creating the AD9835 object with the pin assignments
// that are used. If another pinout is used, this must be
// modified.
//First We must first set up all of our DDS AD9385 output pins.
AD9835 dds(
13, // FSYNC
9, // SCLK
8, // SDATA
12, // FSEL
11, // PSEL1Arduino Serial USB Board
10, // PSEL0
50000000 // hzMasterClockFrequency (50MHz)
);
//***********************************Encoder setup Start**********************************
#define encoder0PinA 2
#define encoder0PinB 4
//*************************************Encoder Setup**************************************
pinMode(encoder0PinA, INPUT);
digitalWrite(encoder0PinA, HIGH); // turn on pullup resistor
pinMode(encoder0PinB, INPUT);
digitalWrite(encoder0PinB, HIGH); // turn on pullup resistor
attachInterrupt(0, doEncoder, CHANGE); // encoder pin on interrupt 0 - pin 2
}//end setup
void loop(){
while(1)
{
InputKeys();
SerialSend();
//*************************************Keypad Setup***************************************
void InputKeys(){
char key = keypad.getKey();
if (key){
switch (key) {
case '#':
Frequency = num ;//Set Frequency to number entered
dds.setFrequencyHz(0, (Frequency)); //Send new Frequency to DDS IC
dds.selectFrequencyRegister(0);
// Without modulation the choice of phase offset does not matter,
// but we set it to zero for good measure.
dds.setPhaseDeg(0,0);
dds.selectPhaseRegister(0);
Serial.println("---------------------");
Serial.println("the frequency is");
Serial.print(Frequency);
Serial.print(" Hz");
Serial.println("");
Serial.println("--------------------");
num=0;
clearLCD();
delay (100);
break;
case '*'://clear input
num=0;
clearLCD();
break;
default:
key=key-'0'; //convert from Char to integer otherwise will be out by 48
num =(num*10 + key); //move left 1 decimal place and enter next digit
//Serial.println(num); //print number
Serial.println(num); //print number
break;
}//end switch
}//end if
delay(10);
}//end keypad subrutine
//************************************Rotary Encoder**************************************
void doEncoder(){
if (digitalRead(encoder0PinA) == HIGH) { // found a low-to-high on channel A
if (digitalRead(encoder0PinB) == LOW) { // check channel B to see which way
// encoder is turning
Rotate = Rotate; // CCW
}//end if (digitalRead(encoder0PinB) == LOW)
else {
Rotate = Rotate; // CW
}//end else
}//end if (digitalRead(encoder0PinA) == HIGH)
else // found a high-to-low on channel A
{
if (digitalRead(encoder0PinB) == LOW) { // check channel B to see which way
// encoder is turning
Rotate = Rotate + jump; // CW
}//end if
else {
Rotate = Rotate - jump; // CCW
}//end else
}//end else if (digitalRead(encoder0PinB) == LOw
}//end subroutine
void SerialSend(){
//***************************************DDS STUFF**************************************
//clearLCD();
Frequency = Rotate;
// Start the dds Libary
dds.begin();
// We then set the board to produce a signal.
dds.setFrequencyHz(0, (Frequency));
dds.selectFrequencyRegister(0);
// Without modulation the choice of phase offset does not matter,
// but we set it to zero for good measure.
dds.setPhaseDeg(0,0);
dds.selectPhaseRegister(0);
// Finally, we turn on the IC.
dds.enable();
}