Last active
February 4, 2017 09:06
-
-
Save stoefln/9ad571830b042fe70185ada6736c4337 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Arduino control for a solenoid valve array (currently 8 pieces), which are hooked up to tubes with liquid inside. | |
* Each solenoid valve controls a stream of air which is blown into the stream of liquid inside the tubes. | |
* By layouting the tubes on a wall it's possible to create beautiful animations | |
*/ | |
#define TRACK_NUMBER 8 | |
#define MAX_CHARS_PER_TRACK 80 | |
class Track | |
{ | |
private: | |
unsigned long lastUpdate=0; | |
int step = 0; | |
int pin; | |
float speed = 30; | |
int notesPerBeat; | |
const char* pattern; | |
public: | |
Track(){ | |
Serial.println("init new empty track"); | |
} | |
// speed: bpm / 16 | |
void loadPattern(const char* pattern) { | |
this->pattern = pattern; | |
this->notesPerBeat = strlen(pattern); | |
Serial.print("load pattern pin"); | |
Serial.print(this->pin); | |
Serial.print(": "); | |
Serial.print(this->pattern); | |
Serial.print("size: "); | |
Serial.println(this->notesPerBeat); | |
} | |
long getLastUpdate(){ | |
return lastUpdate; | |
} | |
void setSpeed(int speed) { | |
this->speed = speed; | |
} | |
void setPin(int pin) { | |
this->pin = pin; | |
} | |
const char * getPattern(){ | |
return this->pattern; | |
} | |
void update(){ | |
int timePerStep = (int) (10000.0 / (float) speed); | |
if(this->lastUpdate + timePerStep < millis()){ | |
char onOff = pattern[step]; | |
if(onOff == 'x'){ | |
digitalWrite(pin, HIGH); | |
}else{ | |
if(pin == 4 || pin == 11){ | |
Serial.print(step); | |
Serial.print("th step "); | |
Serial.print(pin); | |
Serial.print(" off "); | |
Serial.print(" onOff:"); | |
//Serial.println((int) onOff); | |
} | |
digitalWrite(pin, LOW); | |
} | |
lastUpdate = millis(); | |
step++; | |
if(step >= notesPerBeat){ | |
step = 0; | |
} | |
} | |
} | |
}; | |
class Sequencer { | |
Track tracks[TRACK_NUMBER]; | |
public: | |
Sequencer(){} | |
void init(int pins[], int speed){ | |
for(int i=0;i<TRACK_NUMBER;i++){ | |
int pin = pins[i]; | |
Serial.print("create new track on pin "); | |
Serial.println(pin); | |
//this->tracks[i] = Track(pin); | |
tracks[i].setPin(pin); | |
tracks[i].setSpeed(speed); | |
} | |
} | |
void loadPattern(const char pattern[][MAX_CHARS_PER_TRACK]){ | |
for(int i=0;i<TRACK_NUMBER;i++) { | |
tracks[i].loadPattern(pattern[i]); | |
} | |
} | |
Track getTrack(int pos){ | |
return tracks[pos]; | |
} | |
void setSpeed(int speed){ | |
for(int i=0;i<TRACK_NUMBER;i++) { | |
tracks[i].setSpeed(speed); | |
} | |
} | |
void update(){ | |
for(int i=0;i<TRACK_NUMBER;i++) { | |
tracks[i].update(); | |
} | |
} | |
}; | |
Sequencer sequencer; | |
void setup() { | |
Serial.begin(9600); | |
int pins[] = {11, 10, 9, 8, 7, 6, 5, 4}; | |
const char pattern2[TRACK_NUMBER][MAX_CHARS_PER_TRACK] = | |
{" xxxx xxxx xx x x ", | |
" x x ", | |
" x x ", | |
" x x ", | |
" x x ", | |
" x x ", | |
" x x ", | |
" xxxx xxxx xx x x ", | |
}; | |
sequencer.init(pins, 120); | |
sequencer.loadPattern(pattern2); | |
Serial.println("pattern after setup (still OK): "); | |
Serial.println(sequencer.getTrack(7).getPattern()); | |
} | |
void loop() { | |
Serial.println("pattern before update (still ok): "); | |
Serial.println(sequencer.getTrack(7).getPattern()); // <-- prints " xxxx xxxx xx x x " | |
sequencer.update(); // <-- this is where some memory issue is happening, screwing up the pattern2 var | |
Serial.println("pattern after update (messed up): "); | |
Serial.println(sequencer.getTrack(7).getPattern()); // <-- prints " xxxx xx���4" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment