How to write on DAC 0808 the perfect way?

Hello all,
i tried to rebuild the Arduino Piano critterandguitari.com/home/store/arduino-piano.php but i changed the DAC to an DAC0808 (parallel and not serial, 8bit and not 12bit). The 8 bit to 12 bit does make no difference (i think) because they use it for gain (a 8bit sine value is multiplied with the 8bit gain value 0xFF) so i changed the output directly to output the actual value of the sine on PORTA.
I think there is a failure in my thoughts because it sounds very bad. I can not hear a clear tone.

Here is the code for the output interrupt i use
(exactly the code 1:1 from the piano without the SPI stuff and the gain calculation and the direct value output on PORTA)

uint8_t sineTable[]={
  0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,
  0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,
  0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf5,
  0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,
  0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,
  0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb3,
  0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83,
  0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,0x67,0x63,0x60,0x5d,0x5a,0x57,0x54,0x51,
  0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b,0x38,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,
  0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x12,0x10,0x0f,0x0d,0x0c,0x0a,
  0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,
  0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23,
  0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3b,0x3e,0x40,0x43,0x46,0x49,0x4c,
  0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c};

uint16_t sample;     // final sample that goes to the DAC    

// variables for carrier oscillator
uint16_t phaseAccumCarrier;
uint16_t phaseDeltaCarrier;
uint8_t indexCarrier;
uint8_t carrier;
uint8_t carrierAmp;

// variables for frequency mod oscillator
uint16_t phaseAccumModulator;
uint16_t phaseDeltaModulator;
uint8_t indexModulator;
int16_t modulatorSigned;
uint16_t modulator;
uint16_t modDepth;



// timer 2 is audio interrupt timer
ISR(TIMER2_COMPA_vect) {
  OCR2A = 127;
 
  phaseDeltaModulator = (pitch * harmonicity) >> 6;   // calculate modulator frequency for a  given harmonicity ZUSAETZLICHE VERSCHIEBUNG + HARMONIZITAET
  phaseDeltaCarrier = pitch;                           // this is just pitch (although not in Hz) ZUSAETZLICHE VERSCHIEBUNG

  // calculate frequency mod
  phaseAccumModulator = phaseAccumModulator + phaseDeltaModulator;      //nun wird Modulator Delta aufaddiert
  indexModulator = phaseAccumModulator >> 8; //Zeiger des Modulators durch 256 teilen so dass er innerhalbt der Sinus Tabelle liegt
  modulator = sineTable[indexModulator];      //Sinusamplitudenwert auslesen
  modulator = (modulator * modulatorDepth) >> 3; //Sinus Wert 8Bit mal MudlatorStaerke 8Bit verrechnen und durch 8 teilen MAX: 8192
  modulatorSigned = modulator - ((128 * modulatorDepth) >> 3);   // center at 0 //MAX 8192 - (MIN 4096)

  // get carrier frequency
  phaseDeltaCarrier += modulatorSigned;

  // calculate carrier
  phaseAccumCarrier = phaseAccumCarrier + (phaseDeltaCarrier);
  indexCarrier = phaseAccumCarrier >> 8;
  carrier = sineTable[indexCarrier];

  PORTA = carrier;

}

This needs to be moved to "Interfacing" ask a mod to move it so you'll get more responses.

That substitution will require a large rewrite of the arduino code from that page. It will also require some different hookups.

The reference design here calls for +5, +10V and -15V and an op-amp that needs + and - 18V and it's been discontinued.

http://www.national.com/ds/DA/DAC0808.pdf

The part in that other schematic yeilds 0-5v and is trivial to use.

You could use a resistor ladder dac. The example on the scope shows that the output will vary in steps but ones working you can design a filter to smooth that out

http://blog.makezine.com/archive/2008/05/makeit_protodac_shield_fo.html?CMP=OTC-0D6B48984890

http://en.wikipedia.org/wiki/Resistor_ladder#R-2R_resistor_ladder_network_.28digital_to_analog_conversion.2C_or_DAC.29

Hez mrmeval,
i hooked everything up and I provide an additional power source for the dac and the op-amp.

I just wonder why it does not work the way it shoud?

this should just create a normal sine wave but surely is not:

uint16_t phase_delta;
uint16_t phase_accu;
uint8_t freq;
uint8_t index;
uint8_t sample;
uint16_t sample_rate;


uint8_t sine_table[] ={
  0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,
  0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,
  0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf5,
  0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,
  0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,
  0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,
  0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb3,
  0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83,
  0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,0x67,0x63,0x60,0x5d,0x5a,0x57,0x54,0x51,
  0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b,0x38,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,
  0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x12,0x10,0x0f,0x0d,0x0c,0x0a,
  0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
  0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,
  0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23,
  0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3b,0x3e,0x40,0x43,0x46,0x49,0x4c,
  0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c
};

void setup() {
  //Timer2 setup  This is the audio rate timer, fires an interrupt at 15625 Hz sampling rate
  TIMSK2 = 1<<OCIE2A;  // interrupt enable audio timer
  OCR2A = 127;
  TCCR2A = 2;               // CTC mode, counts up to 127 then resets
  TCCR2B = 0<<CS22 | 1<<CS21 | 0<<CS20;   // different for atmega8 (no 'B' i think)
  DDRA = B11111111;
  phase_accu = 0;
  sample_rate = 15625;
  sei();           // enable interrupts
}

void loop(void) {
  freq = analogRead(2) >> 2;  
}

ISR(TIMER2_COMPA_vect){
  OCR2A = 127;
  
  phase_delta = (65535 * freq) / sample_rate;
  phase_accu += phase_delta;
  index = phase_accu >> 8;
  sample = sine_table[index]; 

  PORTA = sample;
}

maybe having that division in the ISR is slowing it down too much?
(but i doubt it)

I based mine on this,

http://adrianfreed.com/content/arduino-sketch-high-frequency-precision-sine-wave-tone-sound-synthesis

but using (previously) DAC0808s instead of PWM.

currently i am outputting to 4 DACs (via a ROM chip) and i can send 4 8 bit ROM addresses and calculate for 4 frequencies in a 31.25 khz ISR

Here is the current ISR part of my Scarab bass synth.(now it uses 2x AD7528 instead of 4x DAC0808)

SIGNAL(PWM_INTERRUPT)  //The timer interrupt. 
{
 
  PORTB = PORTB & 11111000;  //reset DAC control bits
  PORTB = PORTB + 2; //Switch to chip 2 DAC 1  
  PORTC = WT1TOP; //send wavetable address to ROM
  PORTA = DAC2Aout;  //send actual wave address byte to ROM
  PORTB = PORTB + 1;  //Switch to chip 2 DAC 2
  //PORTC = WT1TOP;  //send address to ROM [redundant actually]
  PORTA = DAC2Bout;     
  PORTB = PORTB + 1; //Switch to chip 1 DAC 1 
  PORTC = WT0TOP;  //send address to ROM
  PORTA = DAC1Aout;
  PORTB = PORTB + 1;  //Switch to chip 1 DAC 1
  //PORTC = WT0TOP; //send address to ROM
  PORTA = DAC1Bout; 
    
  
  DAC1Aout = (((o1.phase>>16)%LUTsize)^ByteModArray[WT0xor0])- ByteModArray[WT0add];   
  DAC1Bout = ((o1.phase2>>16)%LUTsize)^ByteModArray[WT0xor1];
  DAC2Aout = (((o1.phase3>>16)%LUTsize)^ByteModArray[WT1xor0])- ByteModArray[WT1add];
  DAC2Bout = ((o1.phase4>>16)%LUTsize)^ByteModArray[WT1xor1];     
   
  ByteModArray[6] = DAC2Aout;    //a modulation source
  
  o1.phase += (uint32_t)o1.phase_increment; 
  o1.phase2 += (uint32_t)o1.phase2_increment;
  o1.phase3 += (uint32_t)o1.phase3_increment;
  o1.phase4 += (uint32_t)o1.phase4_increment;
  
  
  if (PORTA <= 1){sync = HIGH;} //pulse once at the start of each cycle  for synth sync
  

if (SYNCCONT > 0){
  
    if (sync == HIGH) {
         o1.phase2 = o1.phase;o1.phase4 = o1.phase3; //for sync         
      sync = LOW;           
    }