Let's Make Robots!

Steampunk audio player


 

It's always funny to examine techniques at the edge of one’s knowledge. And for all MCU nerds, it’s a challenge to see how much you can make the MCU do. This project involves a lot of elements.

1. Streaming audio from SD-Card via PWM (no wave-shield)

2. MSGEQ7 Equalizer for making a mood-lamp. Colors based on music genre.

3. Selection of music genre by selection knop. 

4. A mechanical counter that show the track number of the music.

5. A lever for advancing and rewinding the mechanical counter

6. Potentiometers for sound level and maybe for speed.

I have accomplished the first two goals. The third is not a technical challenge. What I could use was some suggestions for genres to select among. Remember that the mood-lamp have to show colors according to the genre. Romantic could be red. Melancholic music should show blue lights. Etc.

The mechanical counter could be done by steppers or servos. The lever could be mechanical attached to the counter, but I think I’m just going to use a potentiometer, and then advance the number wheels by a motor.  Any other suggestions will be welcome.

I’m using an Arduino Uno. So I have to be careful counting the pins. I’m going to use shift registers for digital outputs and analog input for reading buttons. 

The picture above is only a draft. I want to get everything working before making any carpentry or decision about actual looks.  

This is current state:

It's playing music and the lamp at the lower right corner is blinking according to the music.

I use SimpleSDAudio for playing audio. Good information about this can be found on http://hackerspace-ffm.de/wiki/index.php?title=SimpleSDAudio. Could be handy for those who want their robot to speak or make sounds. SimpleSDAudio includes an Arduino library, and as a part of this, a tool for preparing sound files called SOX. So you don’t have to find and install the tool as it’s in a sub library to the Arduino library. When preparing sound files, use the tool as shown here:

sox inputfile.wav --norm=-1 -e unsigned-integer -b 8 -r 31250 -c 1 -t raw outputfile.raw 

Ordinary wav-files, that is not prepared this way, has a very poor sound quality.

For the light effects, a page about Arduino/MSGEQ7 Audio Spectrum LED display can be found at: http://www.n00bsys0p.co.uk/blog/2012/07/09/arduinomsgeq7-audio-spectrum-led-display. This is a very simple IC to use. It's a 7-band Graphic Equaliser Display Filter. Two digital pins, one analog pin and six line of code are enough to make this work.

There will of course be updates.

 

-- Update 10. January

When Dickel posted about TLC5940 I was thinking: So ein Ding muss ich auch haben. (http://letsmakerobots.com/node/35677).

My challenge was that timer interrupts and SPI were already in use by SimpleSDAudio. TLC5940 libraries often use two timer interrupts. One for GSCLK and another for initiating the update sequence. First I made a 555 circuit to make an external pwm signal for GSCLK. It worked when running TCL5940 alone, but not in combination with SimpelSDAudio. To stop using the other timer, I use a 12 bit counter in combination with my 555 circuit, to trigger interrupt on a pin instead of a timer interrupt. This also worked. But again. not together with SimpleSDAudio. Using SPI also stopped SimpleAudio. Finaly I bit banged at TCL5940 at every time I had read MSGEQ7 and calculated values for the LED’s. Apparently this was frequent enough to make the LED’s work. No need for the external counter. VPRG is sourced at 5v. With the external 555 circuit for GSCLK I only use 4 pins for running TLC5940.


My coding was based on Kevin Darrah’s code. http://www.kevindarrah.com/download/arduino_code/TimersCountersV6.ino

But this code is without interrupts and without using SPI:

byte ch=0, chbit=0, spibit=0, spibyte=0;// variables used by tlc sub routine

int SINData;//variable used to shift data to the TLC

byte transferbyte[24];// bytes (16*12=192 bits) that are sent out to the tlc5940 via shiftOut

int i, j, k, l,m,n; //misc variables

 

 

int pBlank = 6;

int pXLAT = 2;

int pSin = 4;

int pSCLK = 8;


void setup(){

  pinMode(pXLAT, OUTPUT);

  pinMode(pSin, OUTPUT);

  pinMode(pBlank, OUTPUT);

  pinMode(pSCLK, OUTPUT);

  init5940();

}

 

 

void init5940() {

  for(i=0; i<24; i++) transferbyte[i]=0; //clear out Gray Scale Data

  noInterrupts();// set up the counters, so don't go into interrupts

  //attachInterrupt(1, stateChange, RISING );

  interrupts();// kick off the timers!

  for(i=0; i<16; i++) tlc(i, 0);//wipe out the data in tlc

  pinMode(pBlank, OUTPUT);//BLANK  We set this pin up here, so it remains in a high impedance

}

 

void loop(){

  lamp_test();

}

 

 

void stateChange(){

  PORTD |= 1<<pBlank;// write blank HIGH to reset the 4096 counter in the TLC

  PORTD |= 1<<pXLAT;// write XLAT HIGH to latch in data from the last data stream

  PORTD &= 0<<pXLAT;  //XLAT can go low now

  PORTD &= 0<<pBlank;//Blank goes LOW to start the next cycle

    digitalWrite(pSCLK,HIGH);

    digitalWrite(pSCLK,LOW);  

  for(SINData=24; SINData>=0; SINData--) shiftOut(pSin, pSCLK, MSBFIRST,(transferbyte[SINData]));

}

 

 

void lamp_test(){

  for(l=0; l<16; l++){

    for(k=0; k<150; k++){

      tlc(l, k);

      stateChange();

      delay(5);

    }

    for(k=25; k<698; k++) {

      tlc(l, k*6);

      stateChange();

    } 

    tlc(l,0);

    stateChange();

  }

}

 

void tlc(int channel, int value){

  if(value>4095) value=4095;

  if(value<0) value=0;

  spibit=0;

  if(bitRead(channel, 0)) spibit=4; 

  spibyte = int(channel*3/2);//this assignes which byte the 12 bit value starts in

  for(chbit=0; chbit<12; chbit++, spibit++){// start right at where the update will go

    if(spibit==8){//during the 12 bit cycle, the limit of byte will be reached

      spibyte++;//roll into the next byte

      spibit=0;//reset the bit count in the byte

    }

    if(bitRead(value, chbit)) bitSet(transferbyte[spibyte], spibit);

    else bitClear(transferbyte[spibyte], spibit);

  }

}

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
antony's picture

i am starting my own little project, im building a steam bunk case thay will do little tricks and such one of the tricks will "hopefully" be a sound played when the button to turn on the computer is pressed, 

is there any cheap way to go about this? i want the speaker insdie the computer its self ...  

Allan B's picture

You can get an SD Card reader for 3$-5$ at e-bay. The speaker I use is from a hacked clock radio. MSGEQ7 cost maybe 3$-5$. I think it is cheap when you consider that the arduino cost around 20$.

antony's picture

i am starting my own little project, im building a steam bunk case thay will do little tricks and such one of the tricks will "hopefully" be a sound played when the button to turn on the computer is pressed, 

is there any cheap way to go about this? i want the speaker insdie the computer its self ...  

Maxhirez's picture
I like Steampunkt better than Blaupunkt. Did you consider Nixie tubes for the track number display? Those might fit with the aesthetics. Keep us updated!
Allan B's picture

I did consider nixie tubes. They need high voltage dont they? I like the idea of moving and clicking parts.