Skip to content

Instantly share code, notes, and snippets.

@ceiborg
Last active July 2, 2020 15:48
Show Gist options
  • Save ceiborg/068e22726015e06d1f29831ded3a25aa to your computer and use it in GitHub Desktop.
Save ceiborg/068e22726015e06d1f29831ded3a25aa to your computer and use it in GitHub Desktop.
MIDI+CapSense
/*
#############%@
#### #########%
## #########&
#% ##########
### ############
################### ceiborg.com
################### tecnotextiles
##################
#################
##############
##
#
*/
#include "FastLED.h"
#define NUM_LEDS 10
CRGB leds[NUM_LEDS];
#define PIXELLED 4
int button =3;
float minS = 1.0f;
float maxS = 1.0f;
float s = 0.0f;
int currS;
#define resolution 8
#define mains 50 // 60: north america, japan; 50: most other places
#define refresh 2 * 1000000 / mains
void setup() {
Serial.begin(9600);
FastLED.addLeds<NEOPIXEL, PIXELLED>(leds, NUM_LEDS);
// unused pins are fairly insignificant,
// but pulled low to reduce unknown variables
for(int i = 2; i < 14; i++) {
pinMode(i, OUTPUT);
digitalWrite(i, LOW);
}
for(int i = 8; i < 11; i++)
pinMode(i, INPUT);
pinMode (button, INPUT_PULLUP);
startTimer();
}
void filterSensors(float rate, float minRate, float maxRate){
s += (currS-s) * rate;
if ( (s <minS) && (s > 1.0f) )
minS= s;
if (s> maxS)
maxS = s;
minS += (s-minS)/(minRate*minS);
maxS -= (maxS-s)/(maxRate*maxS);
}
int stateButton = 0;
void loop() {
int b = digitalRead(button);
// LOW means pressed
if ((b == LOW) && (stateButton==0) ){
stateButton = 1;
sendNote(100);
}
// HIGH means released
if ((b == HIGH) && (stateButton==1) ){
stateButton = 0;
sendNote(0);
}
currS = time(9, B00000010);
filterSensors(0.05f, 0.1f, 0.1f);
//printSensor();
int hueMapped = sensorMap ( 0, 255);
for (int i=0;i<NUM_LEDS; i++){
leds[i].setHue(hueMapped);
}
//todo: only send if changed
sendCc(hueMapped/2);
FastLED.show();
delay (20);
}
void printSensor (){
Serial.print(minS);
Serial.print(",");
Serial.print(maxS);
Serial.print(",");
Serial.print(currS);
Serial.print(",");
Serial.println (s);
}
int sensorMap ( int _from, int _to){
return map (constrain (s, minS, maxS), minS, maxS, _from, _to);
}
void sendNote(byte velocity){
sendMidi(0x90, 60, velocity);
}
void sendCc(byte value){
sendMidi(0xB0, 1, value);
}
void sendMidi(byte cmd, byte data1, byte data2){
Serial.write(cmd);
Serial.write(data1);
Serial.write(data2);
}
long time(int pin, byte mask) {
unsigned long count = 0, total = 0;
while(checkTimer() < refresh) {
// pinMode is about 6 times slower than assigning
// DDRB directly, but that pause is important
pinMode(pin, OUTPUT);
PORTB = 0;
pinMode(pin, INPUT);
while((PINB & mask) == 0)
count++;
total++;
}
startTimer();
return (count << resolution) / total;
}
extern volatile unsigned long timer0_overflow_count;
void startTimer() {
timer0_overflow_count = 0;
TCNT0 = 0;
}
unsigned long checkTimer() {
return ((timer0_overflow_count << 8) + TCNT0) << 2;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment