Cos'è ElectroYou | Login Iscriviti

ElectroYou - la comunità dei professionisti del mondo elettrico

Problema pilotaggio 2 moduli AD9833 con Arduino Due

Progetti, interfacciamento, discussioni varie su questa piattaforma.

Moderatori: Foto UtenteWALTERmwp, Foto Utentexyz

0
voti

[1] Problema pilotaggio 2 moduli AD9833 con Arduino Due

Messaggioda Foto Utentealien75 » 28 dic 2025, 16:42

Salve, Ho collegato come segue un ARDUINODUE a due moduli AD9833:


Ho scritto il seguente codice per pilotare i due moduli in modo che la traccia gialla abbia 2Khz mentre la traccia azzurra abbia 1Khz:
Codice: Seleziona tutto
#include "Arduino.h"
#include <SPI.h>
#include <MCP4251.h>
#include "Wire.h"
unsigned int value;
const int BUFFER_SIZE = 20;
unsigned int buffer[BUFFER_SIZE]; // application buffer
int FSYNC = 52;
int FSYNC2 = 50;
int FSYNC3 = 48;
int FSYNC4 = 46;
int FSYNC5 = 44;
int FSYNC6 = 42;
int FSYNC7 = 40;
int FSYNC8 = 38;
int FSYNC9 = 36;
int FSYNC10 = 34;
#define cs1 32
#define cs2 30
#define cs3 28
#define cs4 26
#define cs5 24
#define cs6 22
//impostazione valori pot.
#define pot0ResistanceRmax 100000 // These resistance values may vary
#define pot0ResistanceRmin 0
#define pot1ResistanceRmax 100000
#define pot1ResistanceRmin 0
//creazione funzioni per gestione potenziometri 100K
MCP4251 f0(cs1, pot0ResistanceRmax, pot0ResistanceRmin, pot1ResistanceRmax, pot1ResistanceRmin);
MCP4251 f1(cs2, pot0ResistanceRmax, pot0ResistanceRmin, pot1ResistanceRmax, pot1ResistanceRmin);
MCP4251 f2(cs3, pot0ResistanceRmax, pot0ResistanceRmin, pot1ResistanceRmax, pot1ResistanceRmin);
MCP4251 f3(cs4, pot0ResistanceRmax, pot0ResistanceRmin, pot1ResistanceRmax, pot1ResistanceRmin);
MCP4251 f4(cs5, pot0ResistanceRmax, pot0ResistanceRmin, pot1ResistanceRmax, pot1ResistanceRmin);
MCP4251 f5(cs6, pot0ResistanceRmax, pot0ResistanceRmin, pot1ResistanceRmax, pot1ResistanceRmin);

uint16_t wiper0;
uint16_t wiper1;
//variabile lettura freq. di LFO
int a = 0;
int fr5a;   //oscillatore LFO da 0 a 100Hz
int SDATA = 11;
int SCLK = 13;
int i;
int k ;
unsigned long freq;     
//byte wave=1;
void setup() {
    Serial.begin(9600);
    while (!Serial)
      delay(10); // will pause Zero, Leonardo, etc until serial console open
    Serial.println("OK!");
    //Application Note AN-1070 from Analog Devices
    UpdateRegister(0x2100, FSYNC);  UpdateRegister(0x50C7, FSYNC); UpdateRegister(0x4000, FSYNC);
    UpdateRegister(0xC000, FSYNC); UpdateRegister(0x2000, FSYNC);
    for(k=0;k<41;k++)  pinMode(k, OUTPUT);
    for (i=0;i<41;i++)  digitalWrite(i,HIGH); // put pins 0-13 (FSYNC's) as output HIGH
    f0.begin();
    f0.DigitalPotTerminalBConnect(0);
    f0.DigitalPotTerminalAConnect(0);
    f0.DigitalPotWiperConnect(0);
    f1.begin();
    f1.DigitalPotTerminalBConnect(0);
    f1.DigitalPotTerminalAConnect(0);
    f1.DigitalPotWiperConnect(0);
    f2.begin();
    f2.DigitalPotTerminalBConnect(0);
    f2.DigitalPotTerminalAConnect(0);
    f2.DigitalPotWiperConnect(0);
    f3.begin();
    f3.DigitalPotTerminalBConnect(0);
    f3.DigitalPotTerminalAConnect(0);
    f3.DigitalPotWiperConnect(0);
    f4.begin();
    f4.DigitalPotTerminalBConnect(0);
    f4.DigitalPotTerminalAConnect(0);
    f4.DigitalPotWiperConnect(0);
    f5.begin();
    f5.DigitalPotTerminalBConnect(0);
    f5.DigitalPotTerminalAConnect(0);
    f5.DigitalPotWiperConnect(0);
  }

void loop() {
   a = analogRead(A0); //leggi posizione potenziometro frequenza massima 100Hz
   delay(100);
   while(Serial.available() >= 2){
        // Legge 2 byte dalla seriale
        byte byte1 = Serial.read();
        byte byte2 = Serial.read();
        value = (byte2 << 8) | byte1;
        buffer[i] = value;
        i++;
   }
   //freqa
   UpdateFreq(1000, 0x2000,  FSYNC);  //sin azzurra
   UpdateFreq(2000, 0x2000,  FSYNC2); //sin gialla
   /*UpdateFreq(3000, 0x2000,  FSYNC3);
   UpdateFreq(4000, 0x2002,  FSYNC4);
   UpdateFreq(a, 0x2020,  FSYNC5);   //LFO frequency
   //freqb
   UpdateFreq(5000, 0x2000,  FSYNC6);
   UpdateFreq(6000, 0x2000,  FSYNC7);   
   UpdateFreq(7000, 0x2000,  FSYNC8);
   UpdateFreq(8000, 0x2000,  FSYNC9); 
   UpdateFreq(9000, 0x2000,  FSYNC10); 
   delay(500); // a delay to measure your desired programmed frequencies with a scope
}

void UpdateFreq(unsigned int freq, int form, int sc){
// function to program the frequency into registers - no touch
long FreqReg;
unsigned int MSB, LSB;
  FreqReg = (freq * pow(2, 28)) / 25000000; // 25MHz Quarz
  if (form == 0x2020) FreqReg = FreqReg << 1; 
  MSB = (int)((FreqReg & 0xFFFC000) >> 14);
  LSB = (int)(FreqReg & 0x3FFF);
  LSB |= 0x4000;
  MSB |= 0x4000;
  UpdateRegister(0x2100, sc); // Control Register, Reset Bit DB8
  UpdateRegister(LSB, sc);    // Frequency Register 0 LSB
  UpdateRegister(MSB, sc);    // Frequency Register 0 MSB
  UpdateRegister(0xC000, sc); // Phase Register
  UpdateRegister(form, sc);   // Exit Reset
}
void UpdateRegister(unsigned int data, int sc)
{ // function to program registers - no touch
  unsigned int pointer = 0x8000;
  digitalWrite(sc, LOW);
  for (int i=0; i<16; i++){
    if ((data & pointer) > 0) {
      digitalWrite(SDATA, HIGH);
    }
    else {
      digitalWrite(SDATA, LOW);
    }
    digitalWrite(SCLK, LOW);
    digitalWrite(SCLK, HIGH);
    pointer = pointer >> 1 ;
  }
  digitalWrite(sc, HIGH);
}


Collegando il tutto come nello schema sopra ottengo le tracce allegate.
Non capisco perche invece di visualizzare una sinusoide da 2Khz gialla ed una a 1Khz azzurra ne vedo una piatta ed un segnale da 12Khz circa.
Aiutatemi a capire perché non funziona correttamente.
Allegati
tracce.png
Avatar utente
Foto Utentealien75
1 1 4 8
Sostenitore
Sostenitore
 
Messaggi: 588
Iscritto il: 31 lug 2011, 14:08

4
voti

[2] Re: Problema pilotaggio 2 moduli AD9833 con ARDUINODUE

Messaggioda Foto UtenteGioArca67 » 28 dic 2025, 22:33

Certo che se scrivi codice così incasinato...
1) difficile che trovi chi ti aiuta
2) è più facile commettere errori

Iniziamo con il setup
Codice: Seleziona tutto
    //Application Note AN-1070 from Analog Devices
    UpdateRegister(0x2100, FSYNC);  UpdateRegister(0x50C7, FSYNC); UpdateRegister(0x4000, FSYNC);
    UpdateRegister(0xC000, FSYNC); UpdateRegister(0x2000, FSYNC);

Perché usi UpdateRegister, che usa digitalWrite, prima di fare il setup dei pin di I/O?

Perché quest'ultima UpdateRegister(0x2000, FSYNC); senza poi scrivere i valori di frequenza?

Poi, visto che l'AD9833 sostanzialmente funziona con una logica tipo
"Invia comando" e quindi, se necessario,
"Invia dati"
è poco comprensibile usare UpdateRegister per tutto (o quanto meno commenta le varie fasi)

Non vedi nulla dalla gialla perché non l'hai resettata.

Per resettare, probabilmente, devi fare (usando le tue funzioni) per tutti gli AD9833 che hai (quindi chipEnable sarà prima FSYNC, poi FSYNC2, ecc ad es, in un for) in modo da non far uscire segnali spuri (dopo una reset la successiva scrittura semplice di una frequenza disattiva il reset)
Codice: Seleziona tutto
UpdateRegister(0x0100, chipEnable);  //CMD reset
UpdateRegister(0xC000, chipEnable); //CMD scrivi fase: imposta 0 nel registro di fase 0
UpdateRegister(0xE000, chipEnable); //CMD scrivi fase: imposta 0 nel registro di fase 1
UpdateRegister(0x2100, chipEnable);  //CMD scrivi freq 28b word in reset mode, imposta onda SIN, out da reg 0 (FSELECT=0)
// calc freq LSB  e MSB per reg 0 (D15 D14 = 0 1)
UpdateRegister(LSB, chipEnable);  //scrivi  LSB
UpdateRegister(MSB, chipEnable);  //scrivi  MSB
UpdateRegister(0x2000, chipEnable);  // CMD scrivi  28b word, imposta onda SIN, out da reg 0 (FSELECT=0) e esci da reset mode
// calc freq LSB  e MSB per reg 1  (D15 D14 = 1 0)
UpdateRegister(LSB, chipEnable);  //scrivi  LSB
UpdateRegister(MSB, chipEnable);  //scrivi  MSB


A questo punto se vuoi cambiare solo la frequenza nel tuo loop, chiami la funzione apposita che dovrai scrivere, tipo per una sinusoidale
Codice: Seleziona tutto
UpdateRegister(0x2000, chipEnable);  // CMD scrivi  28b word e imposta onda SIN
// calc freq LSB  e MSB
UpdateRegister(LSB, chipEnable);  //scrivi  LSB
UpdateRegister(MSB, chipEnable);  //scrivi  MSB


Perché fai una UpdateRegister(0x2100, sc); // Control Register, Reset Bit DB8
in UpdateFreq?

Io però costruirei una libreria o un piccolo oggetto che mi aiuti nella gestione dei vari dispositivi, soprattutto perché ne hai molti.

Potresti usare un oggetto in cui
memorizzi il pin per FSYNC
memorizzi freq e fase attuale per i 2 registri
memorizzi il registro di stato/configurazione
hai setter e getter per impostare forme d'onda, frequenza, fase
metodi per accendere, spegnere, fare il reset, abilitare disabilitare l'uscita
Un metodo di basso livello per inviare i dati

Se cerchi Arduino AD9833 vedi che trovi qualcosa di già fatto.
Avatar utente
Foto UtenteGioArca67
4.565 4 6 9
Master EY
Master EY
 
Messaggi: 4588
Iscritto il: 12 mar 2021, 9:36

-1
voti

[3] Re: Problema pilotaggio 2 moduli AD9833 con ARDUINODUE

Messaggioda Foto Utentealien75 » 29 dic 2025, 1:46

In un altro post me l'hanno sconsigliato di fare una classe per risolvere il problema.
Utilizzai qualche cosa di già fatto per AD9833 ma era una lib che non funzionava per niente.
Avatar utente
Foto Utentealien75
1 1 4 8
Sostenitore
Sostenitore
 
Messaggi: 588
Iscritto il: 31 lug 2011, 14:08

0
voti

[4] Re: Problema pilotaggio 2 moduli AD9833 con ARDUINODUE

Messaggioda Foto Utenteangus » 29 dic 2025, 9:33

Perché reinventare la ruota? Esistono delle librerie già pronte e SICURAMENTE FUNZIONANTI per AD9833, come già ti ha scritto Foto UtenteGioArca67 basta una veloce ricerca nel web.
La prima che viene fuori a me: https://github.com/Billwilliams1952/AD9 ... ry-Arduino

Ti sono già stati dati molti suggerimenti, prove da fare e domande a cui rispondere.

Natale è passato e trovare chi ti da la pappa pronta è difficile, ma visto che sono mesi che tenti di generare un'onda sinusoidale con quel coso, ci sono speranze per il 2026. O_/
in /dev/null no one can hear you scream
Avatar utente
Foto Utenteangus
8.475 4 6 9
G.Master EY
G.Master EY
 
Messaggi: 4168
Iscritto il: 20 giu 2008, 17:25

0
voti

[5] Re: Problema pilotaggio 2 moduli AD9833 con ARDUINODUE

Messaggioda Foto UtenteGioArca67 » 29 dic 2025, 14:09

alien75 ha scritto:In un altro post me l'hanno sconsigliato di fare una classe per risolvere il problema.
Utilizzai qualche cosa di già fatto per AD9833 ma era una lib che non funzionava per niente.

Bisogna contestualizzare il tutto.
Magari per un solo AD9833 era inutile costruire una classe, ma se ne vuoi mettere 8, è già un altro paio di maniche.

Non sempre le librerie sono facili da usare, magari non la usavi bene?
qual era?
Avatar utente
Foto UtenteGioArca67
4.565 4 6 9
Master EY
Master EY
 
Messaggi: 4588
Iscritto il: 12 mar 2021, 9:36

0
voti

[6] Re: Problema pilotaggio 2 moduli AD9833 con ARDUINODUE

Messaggioda Foto Utentealien75 » 30 dic 2025, 16:35

GioArca67 ha scritto:Non vedi nulla dalla gialla perché non l'hai resettata.


Codice: Seleziona tutto
UpdateRegister(0x0100, chipEnable);  //CMD reset
UpdateRegister(0xC000, chipEnable); //CMD scrivi fase: imposta 0 nel registro di fase 0
UpdateRegister(0xE000, chipEnable); //CMD scrivi fase: imposta 0 nel registro di fase 1
UpdateRegister(0x2100, chipEnable);  //CMD scrivi freq 28b word in reset mode, imposta onda SIN, out da reg 0 (FSELECT=0)
// calc freq LSB  e MSB per reg 0 (D15 D14 = 0 1)
UpdateRegister(LSB, chipEnable);  //scrivi  LSB
UpdateRegister(MSB, chipEnable);  //scrivi  MSB
UpdateRegister(0x2000, chipEnable);  // CMD scrivi  28b word, imposta onda SIN, out da reg 0 (FSELECT=0) e esci da reset mode
// calc freq LSB  e MSB per reg 1  (D15 D14 = 1 0)
UpdateRegister(LSB, chipEnable);  //scrivi  LSB
UpdateRegister(MSB, chipEnable);  //scrivi  MSB



Quel codice sopra lo devo mettere cosi come sta dentro a void UpdateFreq(unsigned int freq, int form, int sc) ?
Avatar utente
Foto Utentealien75
1 1 4 8
Sostenitore
Sostenitore
 
Messaggi: 588
Iscritto il: 31 lug 2011, 14:08

0
voti

[7] Re: Problema pilotaggio 2 moduli AD9833 con ARDUINODUE

Messaggioda Foto UtenteGioArca67 » 30 dic 2025, 16:47

No, va nel setup()

La logica di Arduino è:
Preparo i componenti che mi servono e li inizializzo nel setup()
Poi ho un loop dove faccio ripetitivamente quello che serve: tipicamente leggo dagli input e scrivo negli output
Avatar utente
Foto UtenteGioArca67
4.565 4 6 9
Master EY
Master EY
 
Messaggi: 4588
Iscritto il: 12 mar 2021, 9:36

0
voti

[8] Re: Problema pilotaggio 2 moduli AD9833 con ARDUINODUE

Messaggioda Foto Utentegvee » 30 dic 2025, 16:53

Sai usare un'oscilloscopio o quello che stai visualizzando è lasciato al caso?
Dall'immagine che hai postato (e da altre passate) non dai l'idea di sapere cosa stai facendo (lasciamo perdere il C).

Se non sai come effettuare le misure con l'oscilloscopio è un grosso problema per te, perché anche supponendo che il codice sia funzionante, non sei in grado di effettuare misure ed interpretarle.

Come al solito fai le cose a caso, tutorial di qua, sketch di la, il dasheet questo sconosciuto, ma secondo me non sai nemmeno tu cosa stai facendo.
Avatar utente
Foto Utentegvee
1.470 5 7
Sostenitore
Sostenitore
 
Messaggi: 525
Iscritto il: 11 feb 2018, 20:34

0
voti

[9] Re: Problema pilotaggio 2 moduli AD9833 con ARDUINODUE

Messaggioda Foto Utentealien75 » 30 dic 2025, 18:27

GioArca67 ha scritto:No, va nel setup()

La logica di Arduino è:
Preparo i componenti che mi servono e li inizializzo nel setup()
Poi ho un loop dove faccio ripetitivamente quello che serve: tipicamente leggo dagli input e scrivo negli output


Questa dichiarazione imagino vada globale?:
Codice: Seleziona tutto
unsigned int MSB, LSB;
Avatar utente
Foto Utentealien75
1 1 4 8
Sostenitore
Sostenitore
 
Messaggi: 588
Iscritto il: 31 lug 2011, 14:08

0
voti

[10] Re: Problema pilotaggio 2 moduli AD9833 con ARDUINODUE

Messaggioda Foto UtenteGioArca67 » 30 dic 2025, 18:33

Io cerco di evitare variabili globali.
Mettila locale

Non stai seguendo il metodo giusto.

Non devi scrivere codice. Prima di tutto devi organizzare la struttura del tuo programma, poi potrai implementarla. Es.:

Potresti usare un oggetto in cui
memorizzi il pin per FSYNC
memorizzi freq e fase attuale per i 2 registri
memorizzi il registro di stato/configurazione
hai setter e getter per impostare forme d'onda, frequenza, fase
metodi per accendere, spegnere, fare il reset, abilitare disabilitare l'uscita
Un metodo di basso livello per inviare i dati
Avatar utente
Foto UtenteGioArca67
4.565 4 6 9
Master EY
Master EY
 
Messaggi: 4588
Iscritto il: 12 mar 2021, 9:36

Prossimo

Torna a Arduino

Chi c’è in linea

Visitano il forum: Nessuno e 3 ospiti