Problems of compability

Hi guys,

how can I read a signal, code it in PCM and the see this signal as output of the DAC. This is what I have so far.

and the result is really bad.

ARDUINO NANO + DAC MCP4901

Anykind of help would be really helpfull.

/*
NECESSARIO METTERE NEL PIN DI USCITA UN FILTRO ANTIALIASING RC NEL NOSTRO CASO I VALORI SONO 33OHM E 10NF IL SEGNALE é MISURATO PRIMA DEL FILTRO COME SE FOSSE IL FILTRO UN PULL DOWN;
SEGNALE R POI C.
*/
#include <SPI.h>         // Remember this line!
#include <DAC_MCP49x1.h>
#define SS_PIN 10
DAC_MCP49x1 dac(DAC_MCP49x1::MCP4901, SS_PIN );
// The Arduino pin used for the slave select / chip select


int  i;
unsigned int x, y;
float accum, fval = .20;    // these are variables for a simple low-pass (smoothing) filter - fval of 1 = no filter - .001 = max filter
long fout;

int period = 33;


byte sineovertones[] = {87,-25,110,-127,55,-23,-4, 25,-101,127};


byte sine[] = {0, 22, 44, 64, 82, 98, 111, 120, 126, 128, 126, 120, 111, 98, 82, 64, 44, 22, 0, -22, -44, -64, -82, -98, -111, -120, -126, -128, -126, -120, -111, -98, -82, -64, -44, -22};
//a simple sine wave with 36 samples

int analog0 = 1000; //variable used to store analog input pin 0

byte speakerpin = 3;  //audio playback on pin 3.  This can also be set to pin 11.

volatile byte waveindex = 0; //index variable for position in waveform array Sine[]
volatile byte currentvalue = 0;

void setup() {
  
Serial.begin(57600);
dac.setSPIDivider(SPI_CLOCK_DIV32);
dac.setPortWrite(true);
 dac.setGain(2);
  
/************************** PWM audio configuration ****************************/
// Configures PWM on pins 3 and 11 to run at maximum speed, rather than the default
// 500Hz, which is useless for audio output

pinMode(3,OUTPUT); //Speaker on pin 3

cli(); //disable interrupts while registers are configured

bitSet(TCCR2A, WGM20);
bitSet(TCCR2A, WGM21); //set Timer2 to fast PWM mode (doubles PWM frequency)

bitSet(TCCR2B, CS20);
bitSet(TCCR2B, CS21);
bitClear(TCCR2B, CS22);
/* set prescaler to /1 (no prescaling).  The timer will overflow every 
*  62.5nS * 256ticks = 16uS, giving a PWM frequency of 62,500Hz, I think.   */

sei(); //enable interrupts now that registers have been set
  
  
/************************* Timer 1 interrupt configuration *************************/

cli(); //disable interrupts while registers are configured

bitClear(TCCR1A, COM1A1);
bitClear(TCCR1A, COM1A1);
bitClear(TCCR1A, COM1A1);
bitClear(TCCR1A, COM1A1);
/* Normal port operation, pins disconnected from timer operation (breaking pwm).  
*  Should be set this way by default, anyway. */

bitClear(TCCR1A, WGM10);
bitClear(TCCR1A, WGM11);
bitSet(TCCR1B, WGM12);
bitClear(TCCR1B, WGM13);
/* Mode 4, CTC with TOP set by register OCR1A.  Allows us to set variable timing for
*  the interrupt by writing new values to OCR1A. */

bitSet(TCCR1B, CS10);
bitClear(TCCR1B, CS11);
bitSet(TCCR1B, CS12);
/* set the clock prescaler to /8.  Since the processor ticks every 62.5ns, the timer
*  will increment every .5uS.  Timer 1 is a 16-bit timer, so the maximum value is 65536,
*  Giving us a theoretical range of .5us-32.7mS.  There are 48 samples, so the 
*  theoretical frequency range is 41.7KHz - .635Hz, which neatly covers the audio 
*  spectrum of 20KHz-20Hz.  Theoretical, because I wouldn't recommend actually calling
*  the Timer1 interrupt every .5uS :)  */

bitClear(TCCR1C, FOC1A);
bitClear(TCCR1C, FOC1B);
/* Disable Force Output Compare for Channels A and B, whatever that is.
*  Should be set this way by default anyway. */

OCR1A = 1000;
/* Initializes Output Compare Register A at 32,8ç, so a match will be generated every 
*  62.5nS * 32 * 1000 = , for a 1/(80uS*10) = 50Hz tone. */

bitClear(TIMSK1, ICIE1); //disable input capture interrupt
bitClear(TIMSK1, OCIE1B); //disable Output Compare B Match Interrupt
bitSet(TIMSK1, OCIE1A); //enable Output Compare A Match Interrupt
bitClear(TIMSK1, TOIE1); //disable Overflow Interrupt Enable

sei(); //enable interrupts now that registers have been set

delay(1000);

}//end setup()



ISR(TIMER1_COMPA_vect) {
/* timer1 ISR.  Every time it is called it sets
*  speakerpin to the next value in Sine[].  frequency modulation is done by changing
*  the timing between successive calls of this function, e.g. for a 1KHz tone,
*  set the timing so that it runs through Sine[] 1000 times a second. */

if (waveindex > 9) { //reset waveindex if it has reached the end of the array
  waveindex = 0;
  }

analogWrite(speakerpin, sineovertones[waveindex] + 128);
//analogWrite(speakerpin, sine[waveindex]);
waveindex++;

OCR1A = period;

} //end Timer1 ISR

void loop()
{
  
analog0 = analogRead(0) + 4;
Serial.println(analog0);
  
 y = 0;        // clear out variables
 x = 0;

 for (i=0; i < 4 ; i++ ){       // do it four times to build up an average - not really neccessary but takes out some jitter

   // LOW-to-HIGH transition
   digitalWrite(8, HIGH);    
   // output pin is PortB0 (Arduino 8), sensor pin is PortB1 (Arduinio 9)                                   

   while ((PINB & B100) != B100 ) {        // while the sense pin is not high
     //  while (digitalRead(9) != 1)     // same as above port manipulation above - only 20 times slower!                
     x++;
   }
   delay(1);

   //  HIGH-to-LOW transition
   digitalWrite(8, LOW);              
   while((PINB & B100) != 0 ){            // while pin is not low  -- same as below only 20 times faster
     // while(digitalRead(9) != 0 )      // same as above port manipulation - only 20 times slower!
     y++;  
   }

   delay(1);
 }

 fout =  (fval * (float)x) + ((1-fval) * accum);  // Easy smoothing filter "fval" determines amount of new data in fout
 accum = fout;   
period = constrain(fout / 3, 50, 500);
Serial.println(period);
  dac.output(sineovertones[waveindex]);

}//end loop()

and the result is really bad.

Sounds terrible.

What result? In what way is it bad? What did you expect? What did you get?

the result is the output of the DAC.

I am reading a sinewave in analog input A0. and the output of the DAC is a square wave with differentamplitude. HOw can I post a picture of it.

I mean. SIGNAL - ADC - DIGITAL - DAC - SIGNAL is not that write?
I am aspecting to see again my original signal.

HOw can I post a picture of it.

Well, you could consider attaching a picture to your post.

I need to upload them somewhere on interenet first?

what I am reading with analog A0

What I am converting in PCM

Output of the DAC

byte doesn't cover your range.

add 128 to all numbers. deal with numbers >255