top of page
Search
  • Writer's picture1/4" Jack Of All Trades

Physical Computing Christmas 5 - Final Adjustments and Soldering

Updated: Jan 10, 2021

This is my final blog entry post for my physical computing project! As I write this, most of the soldering is done and works as intended. I suffered two small set backs during the final steps of preparation and testing, the first was when I accidentally fried my LED strip tower by making a bad connection without paying attention, but this was easily solved by peeling off the strip and soldering hook up wire onto the pads of the spare strip that I had cut off from the original reel. The second was a lack of foresight when soldering my original row of potentiometers, I had not cut long enough sections of hookup wire to reach from some of the potentiometers to their corresponding analog inputs. Furthermore, my plan to make a panel with soldered header pins for the Arduino was going to get very messy very quickly if I had power, ground and data running from each pot. Details on how I circumvented this issue in the next section.


 

Soldering:


I started the sodlering process by adding header pins to the board corresponding to all the analog inputs on the Arduino, most pf the digital pins (even though my design only uses two), ground and V-in pins. Once these were soldered I was forced to unsolder my data wires from the potentiometer rack that I had made and cut longer bits of hookup wire that I partially braided and soldered into place on the arduino solder board. Next I soldered the ground and Vin pins to their own rails on the board and ran a single wire from each to the potentiometer rack, checking each connection with a voltmeter as I went. Following this, I cut the power and ground pins of the potentiometers very short and soldered them onto the rails corresponding to the wires that I had connected to the Arduino, solving the issue of space I had previously encountered. Finally I soldered the wires from the LED strip tower into place (power, ground and digital pin 5) and connected the audio cable to ground and digital pin 9. For the audio cable I opted to use a male 1/4" jack running directly from the synth. As previously mentioned, at the time of writing the only remaining tasks are: to cut a hole for the power switch and to add it between the battery and the power rail; solder the stability capacitor between power and ground.


Above: The header board for the Arduino

Above: The fixed potentiometer rack.

Above: Adding the audio cable.

 

Final Code Tweaks:


Adding delay & tweaking some values:

#include <MozziGuts.h>
#include <Oscil.h>
#include <tables/cos8192_int8.h>
#include <tables/cos2048_int8.h>
#include <AutoMap.h>
#include <FastLED.h>
#include <EventDelay.h>
#include <AudioDelayFeedback.h>

//FAST LED Stuff
FASTLED_USING_NAMESPACE
#if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000)
#warning "Requires FastLED 3.1 or later; check github for latest code."
#endif
#define DATA_PIN    5
#define LED_TYPE    WS2811
#define COLOR_ORDER GRB
#define NUM_LEDS    119
CRGB leds[NUM_LEDS];
#define BRIGHTNESS          96
#define FRAMES_PER_SECOND  120

// main oscillators - note to self expierment with different oscil tables
Oscil<COS8192_NUM_CELLS, AUDIO_RATE> aCos1(COS8192_DATA);
Oscil<COS8192_NUM_CELLS, AUDIO_RATE> aCos2(COS8192_DATA);
Oscil<COS8192_NUM_CELLS, AUDIO_RATE> aCos3(COS8192_DATA);
Oscil<COS8192_NUM_CELLS, AUDIO_RATE> aCos4(COS8192_DATA);
Oscil<COS8192_NUM_CELLS, AUDIO_RATE> aCos5(COS8192_DATA);

// duplicate oscillators to be combined with variation param to create beating effect
Oscil<COS8192_NUM_CELLS, AUDIO_RATE> aCos1b(COS8192_DATA);
Oscil<COS8192_NUM_CELLS, AUDIO_RATE> aCos2b(COS8192_DATA);
Oscil<COS8192_NUM_CELLS, AUDIO_RATE> aCos3b(COS8192_DATA);
Oscil<COS8192_NUM_CELLS, AUDIO_RATE> aCos4b(COS8192_DATA);
Oscil<COS8192_NUM_CELLS, AUDIO_RATE> aCos5b(COS8192_DATA);
Oscil<COS2048_NUM_CELLS, CONTROL_RATE> kDelSamps(COS2048_DATA);

const int KNOB_PIN_1 = 0; // set the first voice pitch to analog pin 0
const int KNOB_PIN_2 = 1; // set the second voice pitch to analog pin 1
const int KNOB_PIN_3 = 2; // set the third voice pitch to analog pin 2
const int KNOB_PIN_4 = 3; // set the fourth voice pitch to analog pin 3
const int KNOB_PIN_5 = 4; // set the fifth voice pitch to analog pin 4
const int KNOB_PIN_6 = 5; // set variaton to analog pin 5

const int PITCH_MIN = 22;
const int PITCH_MAX = 666; //  \m/ 
const int MIN_VARY = 1;
const int MAX_VARY = 50;
const int MINLED= 10;
const int MAXLED = 50;
const int MINCOL = 50; // I found that a min 0 can look ruin percieved AV interaction with some settings that otherwise sound good
const int MAXCOL = 255;
AutoMap kMapPitch(0,1023,PITCH_MIN,PITCH_MAX);
AutoMap kMapVary(0,1023,MIN_VARY,MAX_VARY);
AutoMap kMapLEDs(0,1023,MINLED,MAXLED);
AutoMap kMapColor(0,1023,MINCOL,MAXCOL);

AudioDelayFeedback <128> aDel;
byte del_samps;
Q16n16 deltime;
const int Feedback = -111;
const float DelModFreq = 0.163f;
EventDelay EvDel;

void setup()
{
  delay(3000); // 3 second delay for recovery
  FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.setBrightness(BRIGHTNESS);
  startMozzi();
  EvDel.set(1000/FRAMES_PER_SECOND);
  kDelSamps.setFreq(DelModFreq); // set the delay time modulation frequency (ie. the sweep frequency)
  aDel.setFeedbackLevel(Feedback);
}

void loop()
{
  audioHook();
}

void updateControl()
{
  int knob_value_1 = mozziAnalogRead(KNOB_PIN_1);
  int knob_value_2 = mozziAnalogRead(KNOB_PIN_2); 
  int knob_value_3 = mozziAnalogRead(KNOB_PIN_3);
  int knob_value_4 =  mozziAnalogRead(KNOB_PIN_4);
  int knob_value_5 =  mozziAnalogRead(KNOB_PIN_5);
  int knob_value_6 =  mozziAnalogRead(KNOB_PIN_6);

  int f1 = kMapPitch(knob_value_1);
  int f2 = kMapPitch(knob_value_2)/2; // sub osc 
  int f3 = kMapPitch(knob_value_3)*2; // do I like the double pitch? Is /4 more interesting?
  int f4 = kMapPitch(knob_value_4);
  int f5 = kMapPitch(knob_value_5);
  int variation = kMapVary(knob_value_6);

  aCos1.setFreq(f1);
  aCos2.setFreq(f2);
  aCos3.setFreq(f3);
  aCos4.setFreq(f4);
  aCos5.setFreq(f5);

  aCos1b.setFreq(f1+variation);
  aCos2b.setFreq(f2+variation);
  aCos3b.setFreq(f3+variation);
  aCos4b.setFreq(f4+variation);
  aCos5b.setFreq(f5+variation);

  deltime = Q8n0_to_Q16n16(17) + ((long)kDelSamps.next()<<12);
  
  //FastLED Stuff
  int led_speed = kMapLEDs(knob_value_6);
  int red = kMapColor(knob_value_3);
  int green = kMapColor(knob_value_4);
  int blue = kMapColor(knob_value_5);

  if(EvDel.ready())
    { 
      FastLED.show();
      EvDel.start();
    }

  if (knob_value_1 > 500 && knob_value_2 > 500) //ratio between knobs 1 & 2 determines pattern
    {
      confetti(led_speed, red, green, blue);
    }
    
  else if (knob_value_1 < 500 && knob_value_2 < 500) 
    {
      sinelon(led_speed, red, green, blue);
    }
    
  else
    {
      juggle(led_speed, red, green, blue);
    }

}

int updateAudio(){

  int asig1 =
    aCos1.next() + aCos1b.next() +
    aCos2.next() + aCos2b.next() +
    aCos3.next() + aCos3b.next() +
    aCos4.next() + aCos4b.next() +
    aCos5.next() + aCos5b.next();
  int asig = asig1 + aDel.next(asig1 + deltime);
  return asig >> 3;
}

void sinelon(int speed, int r, int g, int b)
{
  // a colored dot sweeping back and forth, with fading trails
  fadeToBlackBy( leds, NUM_LEDS, speed);
  int pos = beatsin16( 13, 0, NUM_LEDS-1 );
  leds[pos] += CHSV( g, r, b);
}

void confetti(int speed, int r, int g, int b) 
{
  // random colored speckles that blink in and fade smoothly
  fadeToBlackBy( leds, NUM_LEDS, speed);
  int pos = random16(NUM_LEDS);
  leds[pos] += CHSV( g + random8(64), r + random8(64), b + random8(64));
}

void juggle(int speed, int r, int g, int b) {
  // eight colored dots, weaving in and out of sync with each other
  fadeToBlackBy( leds, NUM_LEDS, speed);
  //byte dothue = 0;
  for( int i = 0; i < 8; i++) {
    leds[beatsin16( i+7, 0, NUM_LEDS-1 )] |= CHSV(g, r, b);
    //dothue += 32;
  }
}

 

Experimenting with different wave forms:


#include <MozziGuts.h>
#include <Oscil.h>
#include <tables/triangle_hermes_2048_int8.h>
#include <tables/cos2048_int8.h>
#include <AutoMap.h>
#include <FastLED.h>
#include <EventDelay.h>
#include <AudioDelayFeedback.h>

//FAST LED Stuff
FASTLED_USING_NAMESPACE
#if defined(FASTLED_VERSION) && (FASTLED_VERSION < 3001000)
#warning "Requires FastLED 3.1 or later; check github for latest code."
#endif
#define DATA_PIN    5
#define LED_TYPE    WS2811
#define COLOR_ORDER GRB
#define NUM_LEDS    119 // double check LED count
CRGB leds[NUM_LEDS];
#define BRIGHTNESS          96
#define FRAMES_PER_SECOND  120

// main oscillators - note to self expierment with different oscil tables
Oscil<TRIANGLE_HERMES_2048_NUM_CELLS, AUDIO_RATE> aCos1(TRIANGLE_HERMES_2048_DATA);
Oscil<TRIANGLE_HERMES_2048_NUM_CELLS, AUDIO_RATE> aCos2(TRIANGLE_HERMES_2048_DATA);
Oscil<TRIANGLE_HERMES_2048_NUM_CELLS, AUDIO_RATE> aCos3(TRIANGLE_HERMES_2048_DATA);
Oscil<TRIANGLE_HERMES_2048_NUM_CELLS, AUDIO_RATE> aCos4(TRIANGLE_HERMES_2048_DATA);
Oscil<TRIANGLE_HERMES_2048_NUM_CELLS, AUDIO_RATE> aCos5(TRIANGLE_HERMES_2048_DATA);

// duplicate oscillators to be combined with variation param to create beating effect
Oscil<TRIANGLE_HERMES_2048_NUM_CELLS, AUDIO_RATE> aCos1b(TRIANGLE_HERMES_2048_DATA);
Oscil<TRIANGLE_HERMES_2048_NUM_CELLS, AUDIO_RATE> aCos2b(TRIANGLE_HERMES_2048_DATA);
Oscil<TRIANGLE_HERMES_2048_NUM_CELLS, AUDIO_RATE> aCos3b(TRIANGLE_HERMES_2048_DATA);
Oscil<TRIANGLE_HERMES_2048_NUM_CELLS, AUDIO_RATE> aCos4b(TRIANGLE_HERMES_2048_DATA);
Oscil<TRIANGLE_HERMES_2048_NUM_CELLS, AUDIO_RATE> aCos5b(TRIANGLE_HERMES_2048_DATA);
Oscil<COS2048_NUM_CELLS, CONTROL_RATE> kDelSamps(COS2048_DATA);

const int KNOB_PIN_1 = 0; // set the first voice pitch to analog pin 0
const int KNOB_PIN_2 = 1; // set the second voice pitch to analog pin 1
const int KNOB_PIN_3 = 2; // set the third voice pitch to analog pin 2
const int KNOB_PIN_4 = 3; // set the fourth voice pitch to analog pin 3
const int KNOB_PIN_5 = 4; // set the fifth voice pitch to analog pin 4
const int KNOB_PIN_6 = 5; // set variaton to analog pin 5

const int PITCH_MIN = 30;
const int PITCH_MAX = 666; //  \m/
const int MIN_VARY = 1;
const int MAX_VARY = 50;
const int MINLED= 10;
const int MAXLED = 50;
const int MINCOL = 50; // I found that a min 0 can look ruin percieved AV interaction with some settings that otherwise sound good
const int MAXCOL = 255;
AutoMap kMapPitch(0,1023,PITCH_MIN,PITCH_MAX);
AutoMap kMapVary(0,1023,MIN_VARY,MAX_VARY);
AutoMap kMapLEDs(0,1023,MINLED,MAXLED);
AutoMap kMapColor(0,1023,MINCOL,MAXCOL);

AudioDelayFeedback <128> aDel;
byte del_samps;
Q16n16 deltime;
const int Feedback = -111;
const float DelModFreq = 0.163f;
EventDelay EvDel;

void setup()
{
  delay(3000); // 3 second delay for recovery
  FastLED.addLeds<LED_TYPE,DATA_PIN,COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
  FastLED.setBrightness(BRIGHTNESS);
  startMozzi();
  EvDel.set(1000/FRAMES_PER_SECOND);
  kDelSamps.setFreq(DelModFreq);
  aDel.setFeedbackLevel(Feedback);
}

void loop()
{
  audioHook();
}

void updateControl()
{
  int knob_value_1 = mozziAnalogRead(KNOB_PIN_1);
  int knob_value_2 = mozziAnalogRead(KNOB_PIN_2); 
  int knob_value_3 = mozziAnalogRead(KNOB_PIN_3);
  int knob_value_4 =  mozziAnalogRead(KNOB_PIN_4);
  int knob_value_5 =  mozziAnalogRead(KNOB_PIN_5);
  int knob_value_6 =  mozziAnalogRead(KNOB_PIN_6);

  int f1 = kMapPitch(knob_value_1);
  int f2 = kMapPitch(knob_value_2)/2;
  int f3 = kMapPitch(knob_value_3)*2; // tweak these values a bit (maybe alter variation amount per voice?)
  int f4 = kMapPitch(knob_value_4);
  int f5 = kMapPitch(knob_value_5);
  int variation = kMapVary(knob_value_6);

  aCos1.setFreq(f1);
  aCos2.setFreq(f2);
  aCos3.setFreq(f3);
  aCos4.setFreq(f4);
  aCos5.setFreq(f5);

  aCos1b.setFreq(f1+variation);
  aCos2b.setFreq(f2+variation);
  aCos3b.setFreq(f3+variation);
  aCos4b.setFreq(f4+variation);
  aCos5b.setFreq(f5+variation);

  deltime = Q8n0_to_Q16n16(17) + ((long)kDelSamps.next()<<12);

  int led_speed = kMapLEDs(knob_value_6);
  int red = kMapColor(knob_value_3);
  int green = kMapColor(knob_value_4);
  int blue = kMapColor(knob_value_5);


  //FastLED Stuff
  if(EvDel.ready())
    { 
      FastLED.show();
      EvDel.start();
    }

  if (knob_value_1 > 500 && knob_value_2 > 500)
    {
      confetti(led_speed, red, green, blue);
    }
    
  else if (knob_value_1 < 500 && knob_value_2 < 500) 
    {
      sinelon(led_speed, red, green, blue);
    }
    
  else
    {
      juggle(led_speed, red, green, blue);
    }
 
}

int updateAudio(){

  int asig1 =
    aCos1.next() + aCos1b.next() +
    aCos2.next() + aCos2b.next() +
    aCos3.next() + aCos3b.next() +
    aCos4.next() + aCos4b.next() +
    aCos5.next() + aCos5b.next();
  int asig = asig1 + aDel.next(asig1 + deltime);
  return asig >> 3;
}

void sinelon(int speed, int r, int g, int b)
{
  // a colored dot sweeping back and forth, with fading trails
  fadeToBlackBy( leds, NUM_LEDS, speed);
  int pos = beatsin16( 13, 0, NUM_LEDS-1 );
  leds[pos] += CHSV( g, r, b);
}

void confetti(int speed, int r, int g, int b) 
{
  // random colored speckles that blink in and fade smoothly
  fadeToBlackBy( leds, NUM_LEDS, speed);
  int pos = random16(NUM_LEDS);
  leds[pos] += CHSV( g + random8(64), r + random8(64), b + random8(64));
}

void juggle(int speed, int r, int g, int b) {
  // eight colored dots, weaving in and out of sync with each other
  fadeToBlackBy( leds, NUM_LEDS, speed);
  //byte dothue = 0;
  for( int i = 0; i < 8; i++) {
    leds[beatsin16( i+7, 0, NUM_LEDS-1 )] |= CHSV(g, r, b);
    //dothue += 32;
  }
}

11 views0 comments
bottom of page