Comunicazione DAC8812 via SPI

Buongiorno a tutti,

Ho collegato il DAC8812 al mio arduino uno e sto cercando di farlo funzionare ma ho qualche problemino.

Ovviamente sulle due uscite del dac ho collegato degli opamp in configurazione transimpedenza per visualizzare il valore in tensione.

Il problema è che non conosco bene la comunicazione SPI e facendomi aiutare da Gemini e dopo mille tentativi fallimentari sono arrivato ad ottenere uno sketch che riesce a comandare il dac ma in maniera errata, quando cerco di comandare il primo canale li comanda entrambi mentre cercando di comandare il secondo non fa nulla, da datasheet ho visto che se si cerca di comandare il canale 3 in realtà si dovrebbe ottenere l'effetto che ho io quindi presumo che il problema sia nei timing dei segnali.

Lo sketch che sta girando so che non è per niente elegante e professionale, chiedo aiuto a chi ne sa di più per riuscire a far funzionare il dispositivo.

Ringrazio anticipatamente tutti e allego lo sketch:

#include <Arduino.h>

// --- CONFIGURAZIONE PIN ---
const int SDI_PIN = 11; 
const int CLK_PIN = 13;
const int CS_PIN  = 10;
const int RST_PIN = 4;

// --- PARAMETRI SINUSOIDE ---
const int SAMPLES = 256;      // Risoluzione della sinusoide
uint16_t sineTable[SAMPLES];

// Funzione per inviare esattamente 18 bit al DAC8812
// Indirizzo Canale A: 1, Canale B: 2
void sendToDAC(byte channel, uint16_t value) {
  digitalWrite(CS_PIN, LOW);
  
  // 1. Invia 2 bit di indirizzo (A1, A0)
  for (int i = 1; i >= 0; i--) {
    digitalWrite(SDI_PIN, (channel >> i) & 0x01);
    digitalWrite(CLK_PIN, HIGH);
    digitalWrite(CLK_PIN, LOW);
  }

  // 2. Invia 16 bit di dati
  for (int i = 15; i >= 0; i--) {
    digitalWrite(SDI_PIN, (value >> i) & 0x01);
    digitalWrite(CLK_PIN, HIGH);
    digitalWrite(CLK_PIN, LOW);
  }

  digitalWrite(CS_PIN, HIGH);
}

void setup() {
  // Configurazione Pin
  pinMode(SDI_PIN, OUTPUT);
  pinMode(CLK_PIN, OUTPUT);
  pinMode(CS_PIN, OUTPUT);
  pinMode(RST_PIN, OUTPUT);
  
  // Stato iniziale
  digitalWrite(CS_PIN, HIGH);
  digitalWrite(CLK_PIN, LOW);
  
  // SEQUENZA DI RESET
  digitalWrite(RST_PIN, LOW);
  delay(50);
  digitalWrite(RST_PIN, HIGH);
  delay(50);

  // Pre-calcolo della tabella seno (valori da 0 a 65535)
  for (int i = 0; i < SAMPLES; i++) {
    float sinVal = (sin(2.0 * PI * i / SAMPLES) + 1.0) * 32767.5;
    sineTable[i] = (uint16_t)sinVal;
  }
}

void loop() {
  for (int i = 0; i < SAMPLES; i++) {
    uint16_t val = sineTable[i];   
    // Aggiorna entrambi i canali il più velocemente possibile
    sendToDAC(1, val); // Canale A
    sendToDAC(2, val); // Canale B
    
  }
}

Ma perché reinventare, MALE, l'acqua calda ???

Potevi usare Google per cercare se ci fosse già una libreria già fatta, come QUESTA (che usa VERAMENTE il bus SPI e non una finta emulazione software), completa di esempi e ... probabilmente risolvevi prima :roll_eyes:

Guglielmo