Drumleds

From RevSpace
Revision as of 00:40, 25 May 2017 by Merethan (talk | contribs)
Jump to navigation Jump to search
Project Drumleds
Drumleds merethan.jpg
Een project wat ik voor een bekende van mij gedaan heb, tevens mijn eerste project bij revspace. Het betreft een kastje wat leds laat flitsen wanneer de drummer de basskick intrapt. Die bekende van mij heeft dit kastje momenteel in gebruik op een drumstel wat hij geheel zelf gemaakt heeft.
Status Completed
Contact merethan
Last Update 2017-05-25

Project

Dit project is begonnen toen iemand die ik kende via een muzikantencentrum mij benaderde met de vraag of ik hem kon helpen. Hij was een eigen drumstel aan het bouwen en als show-element wilde hij een ledstrip met witte powerleds in de bassdrum laten knipperen op het ritme van de kick. Zelf had hij al een paar onderdelen (voeding, ledstrip, sensor). Aan mij de vraag of ik iets kon maken om het geheel aan elkaar te knopen.

Onderdelen

Behuizing

Een onderdeel waar je gemakkelijk overheen kijkt is de behuizing. Dat alles veilig zit opgeborgen is een must voor iets wat van optreden naar optreden gaat, daarom heb ik gekozen voor een project box van Hammond Manufacturing. Doet gewoon wat het moet doen. Gewoon goed.

Voedingen

De grote voeding (het witte blok) gaat van 230v naar 12v, met een vermogen van 2.5A (volgens mij). Genoeg prik om de powerleds van stroom te voorzien in elk geval. Diezelfde voeding wordt ook voor de schakel-elektronica gebruikt via een DC-DC converter (rode print), die van de 12v naar 5v gaat. Deze 5v voed het relais-board en de Arduino Pro mini.

Arduino

Tja wat anders. Een Arduino. In dit project heb ik een Arduino Pro mini 5v model gebruikt. Tamelijk klein model, maar meer was er niet nodig.

Relais-board

Voor dit project heb ik een print met twee relais gebruikt, ook al gebruik ik nu slecht een enkele relais. Ik voorzie dat de beste man binnenkort meer lampjes op zijn drumstel wil, vandaar dat die tweede er maar alvast zit. (En het was de kleinste print die ik had liggen.) De relais worden door een opto-coupler aangestuurd die van 3.3v (het voltage op de GPIO's van de Arduino) gelijk ook naar 5v gaan, en de relais activeren. De relais zouden tot 250v AC kunnen hebben, nu schakelen ze slechts 12v DC.

Sensor

Een RT-10K van Roland. Gewoon een goede drumtrigger, verder niets speciaals aan. Het zijn in feite microfoontjes met een andere spoelwikkeling waardoor ze een relatief hoog voltage genereren. Ook hebben ze geen membraam wat mee beweegt op de trilling in de lucht maar een schuimpje wat tegen het vel van een tom of kick moet zitten. Er zit ook een mooi beugeltje bij om het stevig aan een trommel vast te maken.

Werking

Nog te schrijven. WIP!

Verbeterpunten

Mosfets! Drumtrigger ging over de 5v (max meetbereik Pro mini is 5v).

Arduino code

/*

  Drumkit lights is a custom piece of code written
  to switch on/off a LED strip in a drumkit.
  Essentially, it is a simple system listening on
  analog inputs and switching digital ones accordingly.
  The analog inputs are to be wired to drumtriggers
  (those are basically very weird microphones) and
  the outputs to mosfets or relay boards, controlling LEDs.
  Currently it is written to run on a Pro mini board.
  • /

void setup() {

 // IO setup
 pinMode(2, OUTPUT); // First relay
 pinMode(3, OUTPUT); // Second relay
 pinMode(4, OUTPUT); // Third relay
 pinMode(5, OUTPUT); // Fourth relay
 pinMode(13, OUTPUT); // Arduino PCB LED
 // Initialize outputs
 digitalWrite(2, HIGH); // Open the first relay
 digitalWrite(3, HIGH); // Open the second relay
 digitalWrite(4, HIGH); // Open the third relay
 digitalWrite(5, HIGH); // Open the fourth relay
 digitalWrite(13, LOW); // Turn off the PCB LED

}

// Default values const unsigned short flashduration = 42; // Duration, in miliseconds const unsigned int calibrationinterval = 250; // Minimum interval in between threshold calibrations, in miliseconds

// Global vars const unsigned short iocount = 4; // The number of drumtrigger input and led output pairs this piece of software has to process unsigned short current[iocount] = {0, 0, 0, 0}; // The last measured value on an drumtrigger's analog in port unsigned short peakvalue[iocount] = {0, 0, 0, 0}; // The highest current value seen so far on the drumtrigger's port unsigned short threshold[iocount] = {0, 0, 0, 0}; // The analog input value we consider a strike for this port unsigned long lasttrigger[iocount] = {0, 0, 0, 0}; // The last moment a strike was detected on this port (in miliseconds, counted since the start of the program) unsigned long lastcalcycle = 0; // The last moment a threshold calibration cycle was performed (in miliseconds, counted since the start of the program) const unsigned short smoothcount = 128; // The number of samples the smoothing algorithm operates with unsigned short smoothiter[iocount] = {0, 0, 0, 0}; // The iterator for each input, used for cycling trough the history array used for smoothing each input unsigned short currenthistory[iocount][smoothcount]; // A two-dimensional array holding a history for each analog input, where the history is $smoothcount in size

void loop() {

 // Each input is processed in a sequential fashion
 for (int i = 0; i < iocount; i++) {
   // The first part is about establishing whether a piece of the drumkit was struck or not
   current[i] = analogRead(i); // Read the input on analog pin i. Goes from 0-1023, representing 0-5v for this model Arduino
   if (current[i] > threshold[i]) {
     lasttrigger[i] = millis(); // Write time of last trigger
   }
   // The second part is about turning lights on or off, depending on how long ago a hit was detected
   if ((millis() - lasttrigger[i]) < flashduration) {
     digitalWrite(i + 2, LOW); // Close the relay
     digitalWrite(13, HIGH); // Activate the LED
   } else {
     digitalWrite(i + 2, HIGH); // Open the relay
     digitalWrite(13, LOW); // Turn off the LED
   }
   // The third part is about self-calibrating threshold values
   if (current[i] > peakvalue[i]) {
     peakvalue[i] = current[i]; // Save the highest detected value so far
   }
   threshold[i] = peakvalue[i] / 1.2; // ~83% of the highest peak so far is considered the threshold
   // Lowering the threshold is based on current value. But since it is noise, smoothing is needed. Therefore, a history needs to be kept
   currenthistory[i][smoothiter[i]] = current[i];
   if (smoothiter[i] < (smoothcount - 1)) {
     smoothiter[i]++;
   } else {
     smoothiter[i] = 0;
   }
   unsigned long totalcurr = 0;
   for (int j = 0; j < smoothcount; j++) {
     totalcurr += currenthistory[i][j];
   }
   unsigned short smoothed = totalcurr / smoothcount;
   if ((millis() - lastcalcycle) > calibrationinterval) {
     lastcalcycle = millis(); // Write time of last threshold calibration
     if (smoothed < (peakvalue[i] / 2)) { // Only reduce the peakvalue if the noise level is less than 50% of the peakvalue
       peakvalue[i]--;
     }
   }
 }

}