Browse Source

loopstepper

main
Hendrik Langer 4 years ago
parent
commit
5d0a64b851
  1. BIN
      Bizet Carmen Prelude.mid
  2. BIN
      MapleLeafRag.mid
  3. BIN
      OMFG-Hello by Bagio.mid
  4. BIN
      lestoreadorscl.mid
  5. 1
      platformio.ini
  6. 57
      send2.py
  7. BIN
      shakira-medley.mid
  8. 75
      src/main.cpp
  9. 142
      src/stepper.h
  10. BIN
      starwarsmedley.mid
  11. BIN
      wannabe05.mid
  12. BIN
      william_tell_overture.mid

BIN
Bizet Carmen Prelude.mid

Binary file not shown.

BIN
MapleLeafRag.mid

Binary file not shown.

BIN
OMFG-Hello by Bagio.mid

Binary file not shown.

BIN
lestoreadorscl.mid

Binary file not shown.

1
platformio.ini

@ -20,6 +20,7 @@ lib_deps =
[env]
framework = arduino
build_flags = -O2
#build_flags = ${common.build_flags}
lib_deps = ${common.lib_deps}
monitor_speed = 115200

57
send2.py

@ -0,0 +1,57 @@
#!/usr/bin/env python3
import sys, argparse
import time
import threading
import mido
import serial
drum_channels = [9]
def serialreceive(ser):
print("Serial running")
while ser:
try:
line = ser.readline().decode()
print(line)
except Exception:
pass
def main(argv):
inputfile = ''
outputport = ''
parser = argparse.ArgumentParser()
parser.add_argument('-P', '--serialport', help="serial port to open", default="/dev/ttyUSB0")
parser.add_argument('--with-drums', action="store_true", help="send percussion track 10")
args = parser.parse_args()
with serial.Serial(args.serialport, 115200, timeout=12) as ser:
receivethread = threading.Thread(target=serialreceive, args=(ser,))
receivethread.daemon = True
receivethread.start()
time.sleep(1)
# portmidi = mido.Backend('mido.backends.portmidi')
with mido.open_input() as mid:
for msg in mid:
time.sleep(msg.time)
if not msg.is_meta:
if msg.type == 'note_on' or msg.type == 'note_off' or msg.type == 'pitchwheel':
if (not (msg.channel in drum_channels)) or args.with_drums:
print(msg)
ser.write(msg.bin())
else:
print("skipped percussion: " + str(msg))
else:
print("not sent: " + str(msg))
if msg.type == 'program_change' and msg.program in [50,]:
drum_channels.append(msg.channel)
else:
print("meta message: " + str(msg))
print("EOF")
print("done")
print("serial closed")
if __name__ == "__main__":
main(sys.argv[1:])

BIN
shakira-medley.mid

Binary file not shown.

75
src/main.cpp

@ -10,8 +10,10 @@
#include <Tone.h>
#include <MIDI.h>
#include "midi/noteList.h"
#include "midi/pitches.h"
//#include "midi/noteList.h"
//#include "midi/pitches.h"
#include "stepper.h"
struct MySettings : public midi::DefaultSettings
{
@ -22,7 +24,7 @@ MIDI_CREATE_CUSTOM_INSTANCE(HardwareSerial, Serial, MIDI, MySettings);
const int NUM_STEPPER = 5;
Tone freq[NUM_STEPPER];
TimerStepper stepper[NUM_STEPPER];
unsigned long previousMillis[NUM_STEPPER] = {0}; // will store last time LED was updated
const long interval = 1000; // interval at which to blink (milliseconds)
@ -34,7 +36,6 @@ struct playing_t {
};
volatile playing_t playing[NUM_STEPPER] = {0,255};
int findSameNotes(byte noteNumber) {
int candidate = -1;
bool alreadyPlayingHarmonic = false;
@ -66,15 +67,10 @@ void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity)
//if (inChannel == 0 || inChannel >= 32) return;
//if (inChannel == 8) return;
long f = sNotePitches[inNumber];
f *= 4;
while (f > 12000) f/=2;
//digitalWrite(LED_PIN, HIGH);
bool sent = false;
for (int i=0; i<NUM_STEPPER; i++) {
if (playing[i].noteNumber == 0) {
digitalWrite(enable_pin[i], LOW);
freq[i].play(f);
stepper[i].playNote(inNumber);
playing[i].noteNumber = inNumber;
playing[i].channel = inChannel;
previousMillis[i] = millis();
@ -87,8 +83,7 @@ void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity)
digitalWrite(LED_PIN, HIGH);
int i = findSameNotes(inNumber);
if (i >= 0) {
digitalWrite(enable_pin[i], LOW);
freq[i].play(f);
stepper[i].playNote(inNumber);
playing[i].noteNumber = inNumber;
playing[i].channel = inChannel;
previousMillis[i] = millis();
@ -109,7 +104,7 @@ void handleNoteOff(byte inChannel, byte inNumber, byte inVelocity)
digitalWrite(LED_PIN, LOW);
for (int i=0; i<NUM_STEPPER; i++) {
if (playing[i].noteNumber == inNumber) {
freq[i].stop();
stepper[i].stopTone();
playing[i].noteNumber = 0;
playing[i].channel = 255;
break;
@ -121,9 +116,7 @@ void handlePitchBend(byte inChannel, int inValue) {
int bend = inValue >> 7;
for (int i=0; i<NUM_STEPPER; i++) {
if (inChannel == playing[i].channel) {
long f = sNotePitches[playing[i].noteNumber];
long f_b = f * pow(2, (double)inValue/(4096.0*12));
freq[i].play(f_b);
stepper[i].bend(inValue);
previousMillis[i] = millis();
}
}
@ -141,42 +134,17 @@ void setup()
// initialize LED digital pin as an output.
pinMode(LED_PIN, OUTPUT);
pinMode(X_DIR_PIN, OUTPUT);
pinMode(X_STEP_PIN, OUTPUT);
pinMode(X_ENABLE_PIN, OUTPUT);
pinMode(Y_DIR_PIN, OUTPUT);
pinMode(Y_STEP_PIN, OUTPUT);
pinMode(Y_ENABLE_PIN, OUTPUT);
pinMode(Z_DIR_PIN, OUTPUT);
pinMode(Z_STEP_PIN, OUTPUT);
pinMode(Z_ENABLE_PIN, OUTPUT);
pinMode(E0_DIR_PIN, OUTPUT);
pinMode(E0_STEP_PIN, OUTPUT);
pinMode(E0_ENABLE_PIN, OUTPUT);
pinMode(E1_DIR_PIN, OUTPUT);
pinMode(E1_STEP_PIN, OUTPUT);
pinMode(E1_ENABLE_PIN, OUTPUT);
for (int i=0; i<NUM_STEPPER; i++) {
digitalWrite(enable_pin[i], HIGH);
}
stepper[0].begin( X_DIR_PIN, X_STEP_PIN, X_ENABLE_PIN);
stepper[1].begin( Y_DIR_PIN, Y_STEP_PIN, Y_ENABLE_PIN);
stepper[2].begin( Z_DIR_PIN, Z_STEP_PIN, Z_ENABLE_PIN);
stepper[3].begin(E0_DIR_PIN, E0_STEP_PIN, E0_ENABLE_PIN);
stepper[4].begin(E1_DIR_PIN, E1_STEP_PIN, E1_ENABLE_PIN);
MIDI.setHandleNoteOn(handleNoteOn);
MIDI.setHandleNoteOff(handleNoteOff);
MIDI.setHandlePitchBend(handlePitchBend);
MIDI.begin(MIDI_CHANNEL_OMNI);
freq[0].begin(X_STEP_PIN);
freq[1].begin(Y_STEP_PIN);
freq[2].begin(Z_STEP_PIN);
freq[3].begin(E0_STEP_PIN);
freq[4].begin(E1_STEP_PIN);
}
void loop()
@ -185,7 +153,7 @@ void loop()
for (int i=0; i<NUM_STEPPER; i++) {
if (currentMillis - previousMillis[i] >= interval || previousMillis[i] == 0) {
digitalWrite(enable_pin[i], HIGH);
stepper[i].disable();
playing[i].noteNumber = 0;
playing[i].channel = 255;
}
@ -193,18 +161,7 @@ void loop()
//Serial.println("test");
MIDI.read();
//readMIDI();
// turn the LED on (HIGH is the voltage level)
//digitalWrite(LED_PIN, HIGH);
//tone(X_STEP_PIN, 16*440U);
// wait for a second
//delay(100);
// turn the LED off by making the voltage LOW
//digitalWrite(LED_PIN, LOW);
//tone(X_STEP_PIN, 120U);
// wait for a second
//delay(100);
for (int i=0; i<NUM_STEPPER; i++) stepper[i].loop();
}

142
src/stepper.h

@ -0,0 +1,142 @@
#ifndef _STEPPER_H
#define _STEPPER_H
#include <Arduino.h>
#include <Tone.h>
class FrequencyLUT {
public:
FrequencyLUT();
uint16_t* frequencies;
uint16_t& operator[](int);
};
FrequencyLUT::FrequencyLUT() {
int pitch = 24;
frequencies = malloc(128*sizeof(uint16_t));
for (int d=0; d<128; d++) {
frequencies[d] = pow(2.0, (d-69.0+pitch)/12.0) * 440.0;
}
}
uint16_t& FrequencyLUT::operator[](int index) {
return frequencies[index];
}
FrequencyLUT frequencies;
class Stepper {
public:
virtual void begin(int dir_pin, int step_pin, int enable_pin);
virtual void playTone(uint16_t freq) = 0;
virtual void playNote(int8_t midi_note);
virtual void bend(int value);
virtual void loop();
virtual void stopTone() = 0;
void enable();
void disable();
protected:
int8_t currentNote;
int dir_pin;
int step_pin;
int enable_pin;
uint8_t multiplicator = 4;
};
class TimerStepper : public Stepper {
public:
void begin(int dir_pin, int step_pin, int enable_pin) override;
void playTone(uint16_t freq) override;
void stopTone() override;
void loop() {};
private:
Tone tone;
};
class LoopStepper : public Stepper {
public:
void begin(int dir_pin, int step_pin, int enable_pin) override;
void playTone(uint16_t freq) override;
void stopTone() override;
void loop() override;
private:
unsigned long currentStepMicros;
unsigned long prevStepMicros;
};
void Stepper::begin(int dir_pin, int step_pin, int enable_pin) {
this->dir_pin = dir_pin;
this->step_pin = step_pin;
this->enable_pin = enable_pin;
pinMode(dir_pin, OUTPUT);
pinMode(step_pin, OUTPUT);
pinMode(enable_pin, OUTPUT);
digitalWrite(enable_pin, HIGH);
}
void Stepper::enable() {
digitalWrite(enable_pin, LOW);
}
void Stepper::disable() {
digitalWrite(enable_pin, HIGH);
}
void Stepper::playNote(int8_t midi_note) {
currentNote = midi_note;
uint16_t f = frequencies[midi_note];
f *= multiplicator;
while (f > 12000) f/=2;
playTone(f);
}
void Stepper::bend(int value) {
uint16_t f = frequencies[currentNote];
uint16_t f_b = f * pow(2, (double)value/(4096.0*12));
playTone(f_b);
}
void TimerStepper::begin(int dir_pin, int step_pin, int enable_pin) {
Stepper::begin(dir_pin, step_pin, enable_pin);
tone.begin(step_pin);
}
void TimerStepper::playTone(uint16_t freq) {
enable();
tone.play(freq);
}
void TimerStepper::stopTone() {
currentNote = 0;
tone.stop();
}
void LoopStepper::begin(int dir_pin, int step_pin, int enable_pin) {
Stepper::begin(dir_pin, step_pin, enable_pin);
multiplicator = 1;
}
void LoopStepper::playTone(uint16_t freq) {
enable();
prevStepMicros = micros();
currentStepMicros = 1000000UL / freq;
}
void LoopStepper::stopTone() {
currentStepMicros = 0;
}
void LoopStepper::loop() {
if (currentStepMicros == 0) return;
if (micros() - prevStepMicros >= currentStepMicros) {
prevStepMicros += currentStepMicros;
digitalWrite(step_pin, HIGH);
digitalWrite(step_pin, LOW);
}
}
#endif /* _STEPPER_H */

BIN
starwarsmedley.mid

Binary file not shown.

BIN
wannabe05.mid

Binary file not shown.

BIN
william_tell_overture.mid

Binary file not shown.
Loading…
Cancel
Save