Hello.
So, recently I have been working in signal generator project evolving AD9850 DDS module, with success I did it the module works and see the signal module through oscilloscope and change the frequency with rotative encoder. But my objective is control the level (or amplitude) pin out signal of DDS module (zout1,zout2,Qout1,Qout2).
My attempts I get control the signal level with a analog potentiometer, but I thought ''Would be possible use a digital potentiometer with encoder to control the signal level?''. So I bought another rotative encoder and x9c103s digital potentiometer. I did research about it but nothing that I could fix it in this project. I still have doubts and difficulties with the programming and connections at this stage with the digital potentiometer and encoder to control the signal level. With someone have idea or suggestion I appreciate.
The video that I found with similar function.
Site and code that I did adapt to my project.
Thats my code for now
#include <AD9850SPI.h>
#include <SPI.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Pinos do AD9850
const int W_CLK_PIN = 13;
const int FQ_UD_PIN = 8;
const int RESET_PIN = 9;
// Pinos do Encoder KY-040
const int CLK_PIN = 2;
const int DT_PIN = 3;
const int SW_PIN = 4;
// Pino do Potenciômetro
const int POT_PIN = A0;
// Variáveis de frequência e amplitude
double freq = 0;
double trimFreq = 124999500;
int phase = 0;
float amplitudeVolts = 0;
// Variáveis do encoder
int encoderPos = 0;
int lastCLKState = HIGH;
// Variáveis para filtragem de leitura do potenciômetro
const int numReadings = 10;
int readings[numReadings];
int readIndex = 0;
int total = 0;
// Inicializa o LCD I2C (20x4)
LiquidCrystal_I2C lcd(0x27, 20, 4);
void setup() {
// Inicializa o AD9850
DDS.begin(W_CLK_PIN, FQ_UD_PIN, RESET_PIN);
DDS.calibrate(trimFreq);
// Configura os pinos do encoder
pinMode(CLK_PIN, INPUT);
pinMode(DT_PIN, INPUT);
pinMode(SW_PIN, INPUT_PULLUP);
pinMode(POT_PIN, INPUT);
for (int i = 0; i < numReadings; i++) {
readings[i] = 0;
}
// Inicializa o LCD
lcd.init();
lcd.backlight(); // Liga a luz de fundo do LCD
lcd.setCursor(0, 0);
lcd.print("Freq: 0 Hz");
lcd.setCursor(0, 1);
lcd.print("Amp: 0.00 V");
Serial.begin(9600);
}
void loop() {
// Leitura do encoder
int currentCLKState = digitalRead(CLK_PIN);
if (currentCLKState != lastCLKState) {
// Se o estado do CLK mudou, o encoder foi girado
if (digitalRead(DT_PIN) != currentCLKState) {
// Sentido horário: aumenta a frequência
freq += 100; // Incremento de 100 Hz
} else {
// Sentido anti-horário: diminui a frequência
freq -= 100; // Decremento de 100 Hz
}
// Limita a frequência entre 0 Hz e 1 MHz
if (freq < 0) freq = 0;
if (freq > 1000000) freq = 1000000;
// Atualiza a frequência no AD9850
DDS.setfreq(freq, phase);
// Exibe a frequência atual no LCD
lcd.setCursor(0, 0);
lcd.print("Freq: ");
lcd.print(freq);
lcd.print(" Hz "); // Espaços para limpar caracteres antigos
}
lastCLKState = currentCLKState;
// Leitura do potenciômetro com filtragem (média móvel)
total -= readings[readIndex]; // Subtrai a leitura mais antiga
readings[readIndex] = analogRead(POT_PIN); // Lê o valor do potenciômetro
total += readings[readIndex]; // Adiciona a nova leitura ao total
readIndex = (readIndex + 1) % numReadings; // Avança o índice
int averagePotValue = total / numReadings;
amplitudeVolts = (averagePotValue * 5.0) / 1023.0;
// Exibe a amplitude em volts no LCD
lcd.setCursor(0, 1);
lcd.print("Amp: ");
lcd.print(amplitudeVolts, 2); // Exibe com 2 casas decimais
lcd.print(" V "); // Espaços para limpar caracteres antigos
if (digitalRead(SW_PIN) == LOW) {
// Se o botão for pressionado, redefine a frequência para 0 Hz
freq = 0;
DDS.setfreq(freq, phase);
lcd.setCursor(0, 0);
lcd.print("Freq: 0 Hz ");
delay(500); // Debounce do botão
}
// Pequeno delay para evitar leituras muito rápidas
delay(10);
}