Pages: [1]   Go Down
Author Topic: [solved] Howto build a network sound recorder / osciloscope  (Read 479 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey guys,

I'm currently trying to write an audio recorder on the Arduino Ethernet, that streams data from it's A3 input to a network client.
So far I changed the prescaler of the ADC to get a higher sample rate (currently ~40kHz), also using interrupts for the ADC, to speed up the process.

It works pretty nicely together with a little program that I coded in Qt, to print out the results.

But unfortunately the interrupts from the ADC conflict with the Ethernet libs Server::write function, so that the Arduino crashes after sending the first packet of data (I'm buffering 1024 bytes before sending).

This code stopped it from crashing:
Code:
noInterrupts();
bufferPos = 0;
server.write(buffer, BUFFERSIZE);
interrupts();

But this causes my data to have little holes, which lead to a noise and distortion in the audible signal.

How can I speed up the write process? Shouldn't it simply be a simple buffer copy and send command? Why does it crash if I don't protect it from interrupts?

Thx,
Emmeran

« Last Edit: September 06, 2011, 04:38:50 am by Emmeran » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Why does it crash if I don't protect it from interrupts?
We'd need to see all of your code. Are you adding data to buffer while trying to write it out?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 26
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ahh I managed by now, your tip with the buffer helped me realize that I should use two buffers at least.

Here's my code if anyone's interested. It basically can be used as a network osciloscope or to record audio over network. Sampling rate is ~ 53kHz with the applied settings.
Still a nonfinished code tho, so use at own risk.

Code:
#include <SPI.h>
#include <Ethernet.h>
#include <utility/w5100.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,0, 177 };
byte gw[] = { 192,168,0, 1 };

#define DATA_BUFFER_SIZE 512
uint8_t buffer2[2][DATA_BUFFER_SIZE];
int bytes = 0;
int active = 0;

// Initialize the Ethernet server library
Server server(18844);

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

void addToBuffer(SOCKET s, volatile uint8_t * buf, uint16_t len)
{
  // copy data
  W5100.send_data_processing(s, (uint8_t *)buf, len);
}

void sendBuffer(SOCKET s)
{
  W5100.execCmdSn(s, Sock_SEND);
}

volatile bool needSend[2] = { false, false };
// ADC interrupt
ISR(ADC_vect)
{
  buffer2[active][bytes++] = ADCH;
 
  // buffer filled -> change buffer
  if (bytes == DATA_BUFFER_SIZE)
  {
    bytes = 0;
    needSend[active] = true;
    active = active ? 0 : 1;
  }
}

void setup()
{
  // start the Ethernet connection and the server: 
  Ethernet.begin(mac, ip, gw);
  server.begin();
 
  interrupts();

  // ADC setup (see atmega datasheet for reference)
  sbi(ADCSRA, ADEN);
  cbi(ADCSRA, ADSC);
  sbi(ADCSRA, ADATE);
  cbi(ADCSRA, ADIF);
  sbi(ADCSRA, ADIE);
  sbi(ADCSRA, ADPS2);
  cbi(ADCSRA, ADPS1);
  cbi(ADCSRA, ADPS0);
 
//  sbi(ADCSRB, ??);
  cbi(ADCSRB, ACME);
//  sbi(ADCSRB, ??);
//  sbi(ADCSRB, ??);
//  sbi(ADCSRB, ??);
  cbi(ADCSRB, ADTS2);
  cbi(ADCSRB, ADTS1);
  cbi(ADCSRB, ADTS0);
 
  cbi(ADMUX, REFS1);
  sbi(ADMUX, REFS0);
  sbi(ADMUX, ADLAR);
  //sbi(ADMUX, ??);
  cbi(ADMUX, MUX3);
  cbi(ADMUX, MUX2);
  sbi(ADMUX, MUX1);
  sbi(ADMUX, MUX0);
 
  // start measuring
  sbi(ADCSRA, ADSC);
}

int nonactive;
void loop()
{
  nonactive = active ? 0 : 1;
 
  if (needSend[nonactive])
  {
    addToBuffer(0, buffer2[nonactive], DATA_BUFFER_SIZE);
    sendBuffer(0);
    needSend[nonactive] = false;
  }
}
Logged

Pages: [1]   Go Up
Jump to: