Audio Delay

I got it working! now lets see if i can save audio in it.
But I have some problems with understanding the test code below.

in the for loop there is no occurance of the variable i, i had expected something like
for (unsigned int i=0; i< 32768; i++) {
SRAM2.RWdata(i);
}
but there is no i in between the brackets, how does it work then?

SRAM2.writestream1(0);  // write to SRAM 1
unsigned long stopwatch = millis(); //start stopwatch
for(unsigned int i = 0; i < 32768; i++)
SRAM2.RWdata(0x55); //write to every SRAM 1 address 
Serial.print(millis() - stopwatch);
Serial.println("   ms to write full SRAM 1");
SRAM2.readstream1(0);   // start address from 0 
for(unsigned int i = 0; i < 32768; i++)
{
if(SRAM2.RWdata(0xFF) != 0x55)  //check every address in the SRAM1
{
Serial.print("error in SRAM 1 at location  ");
Serial.println(i);
break;
}//end of print error
if(i == 32767)
Serial.println("no errors for SRAM 1 in its 32768 bytes");
}//end of get byte
Serial.println(" ");

SRAM2.writestream2(0);  // write to SRAM 2
stopwatch = millis(); //start stopwatch
for(unsigned int i = 0; i < 32768; i++)
SRAM2.RWdata(0xaa); //write to every SRAM 2 address 
Serial.print(millis() - stopwatch);
Serial.println("   ms to write full SRAM 2");
SRAM2.readstream2(0);   // start address from 0 
for(unsigned int i = 0; i < 32768; i++)
{javascript:void(0);
if(SRAM2.RWdata(0xFF) != 0xaa)  //check every address in the SRAM2
{
Serial.print("error in SRAM 2 at location  ");
Serial.println(i);
break;
}//end of print error
if(i == 32767)
Serial.println("no errors for SRAM 2 in its 32768 bytes");
}//end of get byte
Serial.println(" ");

delay(1000);

I haven't read the datasheet, but some devices auto-increment. In other words, they assume that, if you don't specify a new address, you want to read/write to consecutive ones. This assumption saves sending an address for every single access when you might want to store 20 bytes in a row.

Im following this closely , as ill soon start working on a delay as well to implement in the dub siren im developing.
Thanks for sharing it all !!

Thats it Nick! Thank you!

Can someone help me out with creating a shift register from an octal d-type flipflop chip?

http://pdf1.alldatasheet.com/datasheet-pdf/view/28018/TI/SN74LS377N.html

I want to serially load it with 8 bit for the DAC

Do i have to connected Q1 with D2 and Q2 with D3 and Q3 with D4 etc ?

That sounds about right, Crossroads is always posting a circuit to do this.

Why not use the right chip for the job?


Rob

I dont wont to order via internet just to test the delay, because i try to find a 12 serial input dac later anyway

#include <SRAM2.h>
byte eingang;
unsigned int tcnt1= 65203;
unsigned int data = 0;
boolean clock = false;
boolean first = false;
void setup() {
 TCCR1A = 0;
 TCCR1B = 0;
 TIMSK1 = 0;
 TCCR1B = 1; //no prescaler
 TCNT1=tcnt1;
 TIMSK1 |= (1<<TOIE1); //set the timer on 
 DDRD = 0x00; // set PORTD to all INPUTS - digital pins 0 - 7
 DDRC |= B11110000;
 Serial.begin(9600);
}
ISR(TIMER1_OVF_vect) {  
  TCNT1=tcnt1;
  PORTC |= (1<<4); //generate 48kHz clock for ADC
  PORTC &= ~(1<<4);
  clock = true;
}
void loop() {
if (clock == true) {
 for (int i = 0; i<8; i++) {
   bitWrite(eingang,i,bitRead(PIND,7-i));
  }
  PORTC |= (1<<5); //set DAC to HOLD
  for (int i = 0; i<8; i++) {
    if (bitRead(eingang,7-i)==1) { // 7- i because I dont know which is the MSB and which is the LSB 
      PORTC |= (1<<6); 
    } else {
      PORTC &= ~(1<<6);
    }
  PORTC |= (1<<7); // clock for the shift register made of the Dtype octal flip flop
  PORTC &= ~(1<<7);
}
PORTC &= ~(1<<5); //enable DAC 
clock = false;
} 
//end of loop

HI,
The thing is not workin yet, perhaps i made a mistake someone can see.

What i planned to do with this code is :

set a 16 bit timer to start from around 62000 with a prescaler of 1 so it needs 1/48000 Seconds to overflow.

on overflow set one pin high and low again -> this is the way to get the 48kHz clock for the ADC

then in the timer between the overflows, i want to fill a shift register, which later contains the bits for the DAC.
it should function like this (also described in the comments from the code):

first of all disable the DAC so that it wont do strange things on the loadup of the register. (btw the dac is the AD7528)

then in the for loop read every bit from the byte coming from the input port (portD) and verify if it is 1 or 0, if it is one then the input of the shift register
is set to 1, if its 0 it is set to zero.
after this comes the clock signal for the shift register, then the next bit from the input byte is loaded in the register, this is done the whole for loop long.
when it is finished the outputs of the shift register should contain the byte from the input. so the dac is ready to be enabled again.

Now what happens is a strange signal coming out of the DAC

http://www.analog.com/static/imported-files/data_sheets/AD7528.pdf

I connected the WR and the DAC A Pin to ground, the CS Pin is the pin i use to disable or enable the DAC.

for testing i connected the Vref A with 5 V RFbA is not connected.
the input data is connected with the shift register.

I have no idea why it doesnt work. i hope i forgot something obvious, can anyone see a mistake?

-Flo

You don't need an interrupt to output 48 KHz.

const byte LED = 9;

void setup() {
  pinMode (LED, OUTPUT);
  
  // set up Timer 1
  TCCR1A = _BV (COM1A0);  // toggle OC1A on Compare Match
  TCCR1B = _BV(WGM12) | _BV(CS10);   // CTC, no prescaler
  OCR1A =  166;       // compare A register value (167 * clock speed)
}  // end of setup

void loop() { }

That code outputs 48 KHz on pin 9.

well, does it matter if i use a compare match instead of the overflow to get the intervall i am aiming to?

Now i got the DAC workin. I made the mistake to use 15V as positive Power Supply for it, so every signal was low...

Now i see that it outputs a 24kHz resolution signal. Does anyone see the reason for this in the code?

EDIT: i found it myself i doubled the timer frequency... well but the thing is that the ADC frequency (set by the timer overflow) is twice 96kHz now.

I am trying to save those samples now.

measure = micros();
SRAM2.writestream1(32767);  //open writestream address from 0 to 32767

SRAM2.RWdata(73); //the byte to write to SRAM at current address

SRAM2.readstream1(032767;   //open readstream address from 0 to 32767

int data2 = SRAM2.RWdata(0xff);  //read byte from SRAM at current address
Serial.println(micros()-measure);
Serial.println(data2);  //check data

delay(1000);

this code gives me around 28 µS for saving and reading the data. Now 48kHz means 1/48k = 20µS to Sample, save and output samples.
Now i have to buffer with the 512 kByte internal SRAM of the board.

i dont get how to use a buffer to compensate the lack of speed of the sram. can someone give me a hint to start with? my mind is not clear enough at the moment.

I can play (guitar) already an hear my delayed signal. There is digital noise, perhaps i can filter it out, but I want to get a better 12 bit dac anyway, so this is just for testing.

this is the recent code

#include <SRAM2.h>
byte eingang;
int test;
unsigned long measure;
unsigned int tcnt1= 65203;
unsigned int data = 0;
unsigned int delays = 15000;
unsigned int delay_byte;
boolean clock = false;
boolean first = true;
void setup() {
 TCCR1A = 0;
 TCCR1B = 0;
 TIMSK1 = 0;
 TCCR1B = 1; //no prescaler
 TCNT1=tcnt1;
 TIMSK1 |= (1<<TOIE1); //set the timer on 
 DDRD = 0x00; // set PORTD to all INPUTS - digital pins 0 - 7
 DDRC |= B11110000;
 Serial.begin(9600);
}
ISR(TIMER1_OVF_vect) {  
  TCNT1=tcnt1;
  PORTC |= (1<<4);
  PORTC &= ~(1<<4);
  eingang = PIND;
  clock = true;
}
void loop() {
if (clock == true) {
  if (data > 32766) {
    data = 0;
  } else {
    data++;
  }
  first = false;
  PORTC |= (1<<5);
  for (int i = 0; i<8; i++) {
    if (bitRead(test,i)==1) {
      PORTC |= (1<<6);
    } else {
      PORTC &= ~(1<<6);
    }
    PORTC |= (1<<7);
    PORTC &= ~(1<<7);
  }
  PORTC &= ~(1<<5);
  clock = false;
} else {
  SRAM2.writestream1(data);
  SRAM2.RWdata(eingang);
    if (data < delays) {
    delay_byte = 32766 - delays + data;
  } else {
    delay_byte = data - delays;
  }
    SRAM2.readstream1(delay_byte);
    test = SRAM2.RWdata(0xff);
}
}

Not sure by what you mean by lack of speed of RAM.
Audio speeds are glacial compared to just about any RAM device I've ever used.

yeah but this is this sram chip is a serial device and this code block takes 30µS

@Nick Gammon
Now I see the point of avoiding the interrupt. I didnt get your tip before :blush:

  SRAM2.writestream1(data);
  SRAM2.RWdata(eingang);
  if (data < delays) {
    delay_byte = 32767 - delays + data;
  } else {
    delay_byte = data - delays;
  }
    SRAM2.readstream1(delay_byte);
    test = SRAM2.RWdata(0xff);

it seems like i have to split the recorder and playback section hardware wise in order to get the 48kHz resolution I aimed too.
My Dac has a Serial Output, perhaps I can make it write directly into the hardware chips, mh.

HI!

my teensy burned, so i bought a arduino nano .

Now i connected the ADC parallel to the arduino nano (12 bit all in all)

To begin I started to just read all inputs .

//#include <SRAM2.h>
unsigned int eingang;
unsigned int out;
int test = 1;
byte lbyte;
byte hbyte;
unsigned long measure;
unsigned int tcnt1= 65203;
unsigned int data = 0;
unsigned int delays = 3500;
unsigned int delay_byte;
boolean clock = false;
boolean first = false;
void setup() {
//TIMER
 TCCR1A = 0;
 TCCR1B = 0;
 TIMSK1 = 0;
 TCCR1B = 1; //no prescaler
 TCNT1=tcnt1;
 TIMSK1 |= (1<<TOIE1); //set the timer on 
  
//CLOCK COMMAND PIN  = A2 PORTC 2

//BIT 1  =  A3  PORTC 3  
//BIT 2  =  A4  PORTC 4
//BIT 3  =  A5  PORTC 5
//  PORTC EINGÄNGE einstellen 0011 1000
DDRC &= ~(0x38); 
PORTC &= ~(0x38);
DDRC |= (1<<2);
//BIT 4  =  D10 PORTB 2
//BIT 5  =  D9  PORTB 1
//BIT 6  =  D8  PORTB 0 
//  PORTB EINGÄNGE einstellen 0000 0111
DDRB &= ~(0x07);
PORTB &= ~(0x07);
//BIT 7  =  D7  PORTD 7 
//BIT 8  =  D6  PORTD 6 
//BIT 9  =  D5  PORTD 5
//BIT 10  = D4  PORTD 4
//BIT 11  = D3  PORTD 3
//BIT 12  = D2  PORTD 2
//  PORTD EINGÄNGE einstellen 1111 1100
DDRD &= ~(0xFC);
PORTD &= ~(0xFC);

//SS1 = A1 PORTC 1
//SS2 = A0 PORTC 0 

Serial.begin(9600);
}
ISR(TIMER1_OVF_vect) {  
  TCNT1=tcnt1;
  data++;
   clock = true;
  PORTC |= (1<<2); //ADC COMMAND CLOCK
  PORTC &= ~(1<<2);
}
void loop() {
  if (clock == true) { 
    hbyte = (PINC & 0x08) | ((PINC & 0x10) >> 2) | ((PINC & 0x20) >> 4) | ((PINB & 0x04) >> 2);
    lbyte = ((PINB & 0x03) << 6) | ((PIND & 0xFC) >> 2);
    eingang = word(hbyte, lbyte);
    clock = false;
  }
  if (data > 50000) {
    Serial.println(lbyte, BIN);
    data= 0;
   
  }
}

the problem is that the lbyte is changing randomly and i get no fixed values.
Does anyone see any problems with the code?

I also used those analaog input pins as digital inputs... but i dont know if i have to set them to be digital or analog or what...
Damn, I dont know why the values just wont be fix...

_flo

#include <SRAM2.h>
unsigned int eingang= 0;
unsigned int out;
int bitnumber = 12;
byte lbyte;
byte hbyte;
unsigned long measure;
unsigned int tcnt1= 65203;
unsigned int data = 0;
unsigned int delays = 3500;
unsigned int delay_byte;
boolean clock = false;
boolean ready = true;
void setup() {
DDRD &= 0xF3;
//SS1 = A1 PORTC 1
//SS2 = A0 PORTC 0 
DDRB |= (1<<1);
//TIMER
TCCR1A = _BV (COM1A0);  // toggle OC1A on Compare Match
TCCR1B = _BV(WGM12) | _BV(CS10);   // CTC, no prescaler
OCR1A =  800;       // compare A register value (167 * clock speed)
 // OCR1A =  166;
Serial.begin(115200);
}

void loop() {
  if ((PIND & (1<<2)) == 0) {
      if (ready == false) {
        SRAM2.readstream1(0);
        hbyte = SRAM2.RWdata(0);
        lbyte = SRAM2.RWdata(1);
        
        eingang = word(hbyte, lbyte);
        ready = true;
        data = data + 2;
        SRAM2.writestream1(0);
      }
      if ( data > 40000) {
        Serial.println(lbyte,BIN);
        data = 0;
      }
  } else {
    if (ready == true) {
      ready = false;
    }
  }
}

Now the ADC writes directly into the 23K256 chip. it seems to work but there is one problem.

the ADC s serial signal is 13 clock pulses the first pulse has no data value to it (the rest are the 12 bit)

Now the SRAM chip is put in sequential write mode, so these 13 clocks + the data signal should fill one and a half bytes .

the first byte is the one empty MSB and the first seven bits (given from the adc starting with the msb)

the second byte are the other 5 bits.

but when i check the high and low bytes i read from the SRAM by sending them with Serial.println

I see that the bytes are not structured like i described, because i can set every bit for the two bytes, eventhough i acutally should only be able to affect 13 of them because i ve got 13 clock pulses.

is there an obvious mistake in my code? Please give me some advice if you can!

regards,
Flo

I'm not familiar with this SRAM2 library, where does SRAM2.writestream1(0); get its data from?

Also what purpose does 'data' serve, it's not used anywhere.

high and low bytes i read from the SRAM by sending them with Serial.println

I see that the bytes are not structured like i described,

You are only printing lbyte, how do you know things aren't right?


Rob

Hi,
the method writestream just sets the chip into sequential writemode starting from the adress ( in this case the first byte of the memory byte 0).
once the chip is set like this, it just records bit for bit coming in in.

i am just trying around so data will be the variable which contains the number of the byte i am saving to at the moment.

now I found a mistake.

I wrote hbyte >> 3 ; instead of hbyte >>= 3;

but the problem is that when thw value would go under 2060 or so it is 16 for a long time.

#include <SRAM2.h>
unsigned int eingang= 0;
unsigned int out;
int bitnumber = 12;
byte lbyte;
byte hbyte;
byte hbyte2;
unsigned long measure;
unsigned int tcnt1= 65203;
unsigned int data = 0;
unsigned int delays = 3500;
unsigned int delay_byte;
boolean clock = false;
boolean ready = true;
void setup() {
DDRD &= 0xF3;
//SS1 = A1 PORTC 1
//SS2 = A0 PORTC 0 
DDRB |= (1<<1);
//TIMER
TCCR1A = _BV (COM1A0);  // toggle OC1A on Compare Match
TCCR1B = _BV(WGM12) | _BV(CS10);   // CTC, no prescaler
OCR1A =  166;       // compare A register value (167 * clock speed)
 // OCR1A =  166;
Serial.begin(115200);
}

void loop() {
  if ((PIND & (1<<2)) == 0) {
      if (ready == false) {
        SRAM2.readstream1(0);
        hbyte = SRAM2.RWdata(0xFF);
        lbyte = SRAM2.RWdata(0xFF);
        hbyte &= 0x7F;
        lbyte &= 0xF8; 
        lbyte = (lbyte >> 3) | (hbyte<<5);
        hbyte >>= 3;
        eingang = (unsigned int)(word(hbyte, lbyte));
        ready = true;
        data = data + 2;
        SRAM2.writestream1(0);
      }
      if ( data > 40000) {
        Serial.println(eingang);
        data = 0;
      }
  } else {
    if (ready == true) {
      ready = false;
    }
  }
}