Simple HIFI amplifier

September 2nd, 2010 by Johan

Almost a year ago I soldered up a pcb and ordered parts for putting together a small simplistic HIFI amplifier. Just recently I rediscovered the old project and finally got around to complete it.

The amplifier is based on the amp6-basic 2 x 25 W chip amp from 41hz connected to a standard switch mode power supply. It’s supplied only with a mini-jack input since thats what my ipod, phone and mac use anyway. A DACT Type 23 50K stepped attenuator acts as volume control. I put it all together in an anodized aluminum chassis with a thick custom frontplate.

Components laid out

I cut out the various holes in the back and frontplate using regular twist bits and flat wood bits on a column drill. I finished off the non round cutouts using a file. I ended up using a few hours with a dremmel to cut out the frontplate for the volume knob because I didn’t have a wide enough drill bit around. It turned out quite rough but I tried to use it as a design feature engraving the whole frontplate with the dremmel. I also mounted a blue LED as an on-off indicator, with a rather large resistor 13K Ohm to avoid it illuminating my whole room at nighttime.

I supply the amp6-basic with about 14 V which it can easily handle if it’s rather efficiently cooled. I mounted it to an aluminum plate in the side of the chassis furthest from the SMPS with cooling paste on the back of the chip. The power cables are wound around a large ferrite which should in theory reduce the noise.

The expenses add up to around DKK 1500 (~EUR 200). I am using the amplifier with two small Dali speakers and I am very satisfied with the overall sound quality.

Slackline for KulturSydhavn

August 14th, 2010 by Johan

I did a small interactive slackline project for KulturSYDHavn. A festival on the quay of Teglholmen and around the Illutron barge in conjunction with the annual KulturHavn festival on Islands Brygge on the 6, 7 and 8th of August. We created an interactive playground around the barge and together with Illutron I put up the slackline with RGB color feedback on the quay. I owe a great thanks to the Illutron crew who put a lot of energy into this festival, especially Troels Just Christoffersen who helped put the last pieces of the slackline installation up while I was gone in the week preceeding the festival. And I owe a thanks to the sponsors who made it possible, Slackline.dk and Rullegræsset.dk who sponsored a free feet slacklight15 kit and 1 metric ton of roll out grass respectively.

Documentation

The slackline is hooked up to a strain gauge that measures the weight on the slackline. An Op-Amp amplifies the signal for the arduino and two pieces of flexible high intensity RGB led strip are controlled with PWM via a ULN2003 Darlington transistor array.

Schematics

Code

// KulturSYDHavn Illutron Interactive slackline code by Johan Bichel Lindegaard

float h;
int h_int;
int r=0, g=0, b=0, intensity=100;
void h2rgb(float h, int &R, int &G, int &B);

// Select which analog input the strain gauge is connected to.
const int mPin = 0;

int m = 0;
int state = 0; // 0: inactive, 1: active, 3: pending inactive
int deactivationThreshold = 8;
int deactivationTime = 1000;
unsigned long stateTimeStamp;
unsigned long stateTime = 0;

// Select which PWM-capable pins are to be used.
const int redPin = 10;
const int greenPin = 11;
const int bluePin = 9;

long brbgPreviousMillis = 0;
long fadePreviousMillis = 0;
boolean blinkState = 0;
boolean fadeUp = 0;

// range calibration variables.
int lowPoint;
int highPoint;

void setup()          
{
  // start serial port at 9600 bps:
  // Serial.begin(9600);

  pinMode(redPin, OUTPUT);
  pinMode(greenPin, OUTPUT);
  pinMode(bluePin, OUTPUT);

  // calibrate
  lowPoint = analogRead(mPin);
  highPoint = lowPoint + 124;
  if(highPoint > 1024) {
    highPoint = 1024;
  }

  // test pins
  rgb(255,0  ,0  ); delay(500);
  rgb(0  ,255,0  ); delay(500);
  rgb(0  ,0  ,255); delay(500);
}

void loop()
{  
    int m = analogRead(mPin);

    // Check calibration, and expand range if needed.
    if(m < lowPoint) {
      lowPoint = m;
    } else if(m > highPoint) {
      highPoint = m;
    }

    // Serial.println(m);

    // keep track of how long the line has been active and inactive
    if(m > lowPoint + deactivationThreshold) {
      if(state == 0) {
        state = 1;
        stateTimeStamp = millis();
      }
      stateTime = millis() - stateTimeStamp;     
    } else if(state == 1){
      state = 3;
      stateTimeStamp = millis();
    } else {
      stateTime = millis() - stateTimeStamp;
      if(stateTime > deactivationTime) {
        state = 0;
      }     
    }

    if(state != 0){

      // Convert input to RGB through hue then output.
      h = ((float)map(m, lowPoint, highPoint, 1024, 0))/1024;
      h_int = (int) 360*h;
      h2rgb(h,r,g,b);

      // if active for a short while enter fancy blink mode then return to normal
      if(stateTime > 15000 && stateTime < 60000) {
        int btime = map(stateTime,15000,60000,1000,50);
        brgb(r,g,b,btime);       
      } else {
        rgb(r,g,b);
      }

    } else {      
      unsigned long currentMillis = millis();
      if(currentMillis - fadePreviousMillis > 100) {
        fadePreviousMillis = currentMillis;

        if(intensity > 99) { fadeUp = false;
        } else if (intensity < 1) {
          fadeUp = true; }         

        if(fadeUp) {  ++intensity;
        } else {      --intensity; } 

        rgb(255,0,0,intensity);   
      }

   }   
}

void rgb(int r, int g, int b) {
  analogWrite(redPin,r);
  analogWrite(greenPin,g);
  analogWrite(bluePin,b); 
}

void rgb(int r, int g, int b, float intensity) {
  if(intensity > 100) {
    intensity = 100;
  } else if(intensity < 0){
    intensity = 0; 
  }

  rgb(r/100*intensity, g/100*intensity, b/100*intensity);  
}

void brgb(int r, int g, int b, int interval) {
  unsigned long currentMillis = millis();
  if(currentMillis - brbgPreviousMillis > interval) {
    brbgPreviousMillis = currentMillis;
    if (!blinkState) {
      blinkState = 1;
      rgb(r,g,b);
    } else {
      blinkState = 0;
      rgb(0,0,0);
    }
  }
}

void h2rgb(float H, int& R, int& G, int& B) {

  int var_i;
  float S=1, V=1, var_1, var_2, var_3, var_h, var_r, var_g, var_b;

  if ( S == 0 )                       //HSV values = 0 √∑ 1
  {
    R = V * 255;
    G = V * 255;
    B = V * 255;
  }
  else
  {
    var_h = H * 6;
    if ( var_h == 6 ) var_h = 0;      //H must be < 1
    var_i = int( var_h ) ;            //Or ... var_i = floor( var_h )
    var_1 = V * ( 1 - S );
    var_2 = V * ( 1 - S * ( var_h - var_i ) );
    var_3 = V * ( 1 - S * ( 1 - ( var_h - var_i ) ) );

    if      ( var_i == 0 ) {
      var_r = V     ;
      var_g = var_3 ;
      var_b = var_1 ;
    }
    else if ( var_i == 1 ) {
      var_r = var_2 ;
      var_g = V     ;
      var_b = var_1 ;
    }
    else if ( var_i == 2 ) {
      var_r = var_1 ;
      var_g = V     ;
      var_b = var_3 ;
    }
    else if ( var_i == 3 ) {
      var_r = var_1 ;
      var_g = var_2 ;
      var_b = V     ;
    }
    else if ( var_i == 4 ) {
      var_r = var_3 ;
      var_g = var_1 ;
      var_b = V     ;
    }
    else                   {
      var_r = V     ;
      var_g = var_1 ;
      var_b = var_2 ;
    }

    R = (1-var_r) * 255;                  //RGB results = 0 √∑ 255
    G = (1-var_g) * 255;
    B = (1-var_b) * 255;
  }
}

Wire Storage

August 12th, 2010 by Johan

Put up a wire for storage, and conceptualized a bit; Wires are versatile, almost invisible when not in use and there is no surface to keep clean of dust. A lot of different shapes can rest on the wires and other stuff can hang from the wire in carabiners.

Screaming Potter

July 22nd, 2010 by Johan

Together with Troels Just Christoffersen I hacked together a screaming potter. The idea is to create the impression that some kind of screeching creature is living within the potter. The schematic and code are simple, a photoresistor activates the speaker when its subjected to light.

Schematic

Schematics for Screaming Potter

Schematic

Arduino code

int photoResistorPin = 0;
int startThreshold = 4;
int speakerPin = 9;
int active = false;
int activationTime;

void setup() {
    Serial.begin(9600);
}

void loop() {
    int lightReading = analogRead(photoResistorPin);
    if(lightReading > startThreshold) {
        // when first activated set timestamp
        if(active == false) {
            activationTime = millis(); 
            active = true; 
        }
        // the time could be usd to create more variation in the sound 
        // int runtime = millis()-activationTime;

        for (int i = 0; i < 6; i++) {
            int frequency = lightReading*i;
            Serial.println(frequency);     
            tone(speakerPin, frequency);
            delayMicroseconds(500);
        }
    } else {  
        noTone(speakerPin);  
    }
}