Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
afd4b230b2 |
4
README
Normal file
4
README
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
WORK IN PROGRESS...
|
||||||
|
Motors & Music & Motions (M&M&M)
|
||||||
|
dviid, bill verplank, jakob bak
|
||||||
|
|
||||||
12
README.md
12
README.md
@ -1,12 +0,0 @@
|
|||||||
## Motors & Music & Motions
|
|
||||||
David Gauthier, Bill Verplank, Jakob Bak
|
|
||||||
|
|
||||||
<img src="https://git.le-club-des-sans-sujets.org/gauthiier/M-M-M/raw/branch/master/board.jpeg" width="35%"/>
|
|
||||||
|
|
||||||
Research material for:
|
|
||||||
|
|
||||||
* Bak, J., Verplank, B., & Gauthier, D. (2015). Motors, Music and Motion. In TEI '15: Proceedings of the Ninth International Conference on Tangible, Embedded, and Embodied Interaction (pp. 367-374). Association for Computing Machinery (ACM). https://doi.org/10.1145/2677199.2680590
|
|
||||||
|
|
||||||
* Verplank, B., Gauthier, D., & Bak, J. (2013). TEI 2013 studio: motors and music. In TEI '13:
|
|
||||||
Proceedings of the 7th International Conference on Tangible, Embedded and Embodied Interaction (pp. 431-434). Association for Computing Machinery (ACM). https://doi.org/10.1145/2460625.2460721
|
|
||||||
|
|
||||||
BIN
board.jpeg
BIN
board.jpeg
Binary file not shown.
|
Before Width: | Height: | Size: 88 KiB |
Binary file not shown.
BIN
hardware/doc/v0/mm.controller.v0-schema.pdf
Normal file
BIN
hardware/doc/v0/mm.controller.v0-schema.pdf
Normal file
Binary file not shown.
Binary file not shown.
36
software/apps/Motion/Center/Center.ino
Normal file
36
software/apps/Motion/Center/Center.ino
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
//Center
|
||||||
|
//uses a variable force (pwm duty)
|
||||||
|
//If it feels like a mountain - pushing away from center, then
|
||||||
|
//reverse the motor leads
|
||||||
|
//or for a quick fix in the code: change if(f < 0) to if (f > 0)
|
||||||
|
|
||||||
|
#include <Motor.h>
|
||||||
|
|
||||||
|
int pos; // position from analogRead
|
||||||
|
int force; // computed from pos and k
|
||||||
|
int k = 2; // spring constant
|
||||||
|
int duty; // pwm duty for Timer1 (range 0 - 1023) 10-bit resolution
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
|
||||||
|
MotorA.torque(100); //is this necessary?
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
|
||||||
|
pos = analogRead(A0);
|
||||||
|
|
||||||
|
force = k * (512 - pos);
|
||||||
|
duty = abs(force);
|
||||||
|
duty = min(1023, duty);
|
||||||
|
|
||||||
|
MotorA.torque(duty);
|
||||||
|
|
||||||
|
if(force < 0) MotorA.direction(FORWARD);
|
||||||
|
else MotorA.direction(BACKWARD);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
23
software/apps/Motion/Damp/Damp/Damp.ino
Normal file
23
software/apps/Motion/Damp/Damp/Damp.ino
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
//Damp - measure velocity then f=Bv
|
||||||
|
#import <Motor.h>
|
||||||
|
int x; //position measured
|
||||||
|
float v, f, t, xold; //velocity, force, time delta
|
||||||
|
byte c; //for debug print every 256th loop
|
||||||
|
|
||||||
|
void setup(){
|
||||||
|
Serial.begin(9600);
|
||||||
|
xold = analogRead(A0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop(){
|
||||||
|
x = analogRead(A0);
|
||||||
|
v = x - xold; //lag v, too?
|
||||||
|
xold += 0.1*(x-xold); //slide xold with lag
|
||||||
|
|
||||||
|
if(c++==0){
|
||||||
|
//Serial.print(xold);
|
||||||
|
//Serial.print(" ");
|
||||||
|
Serial.println(100*v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
28
software/apps/Motion/Damp2/Damp2.ino
Normal file
28
software/apps/Motion/Damp2/Damp2.ino
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
//Damp 2 with running average position
|
||||||
|
|
||||||
|
#define n 10 //number in buffer
|
||||||
|
int x; //position measured
|
||||||
|
float xf; // running average on n samples
|
||||||
|
int buff[n];
|
||||||
|
int index = 0;
|
||||||
|
float v, oldavg; // estimate of velocity
|
||||||
|
byte c;
|
||||||
|
|
||||||
|
void setup(){
|
||||||
|
Serial.begin(9600);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop(){
|
||||||
|
buff[index] = analogRead(A0);
|
||||||
|
index++;
|
||||||
|
if(index > n-1) index = 0;
|
||||||
|
int acc = 0;
|
||||||
|
for(int i=0; i<n; i++)acc+=buff[i];
|
||||||
|
float avg = acc/n;
|
||||||
|
v = avg - oldavg;
|
||||||
|
oldavg = avg;
|
||||||
|
if(c++==0)Serial.println(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
1502
software/apps/Motion/Damp3/Damp3.maxpat
Normal file
1502
software/apps/Motion/Damp3/Damp3.maxpat
Normal file
File diff suppressed because it is too large
Load Diff
48
software/apps/Motion/Damp3/Damp3/Damp3.ino
Normal file
48
software/apps/Motion/Damp3/Damp3/Damp3.ino
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
|
||||||
|
int firstSensor = 0; // first analog sensor
|
||||||
|
int secondSensor = 0; // second analog sensor
|
||||||
|
int thirdSensor = 0; // digital sensor
|
||||||
|
int inByte = 0; // incoming serial byte
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
// start serial port at 9600 bps and wait for port to open:
|
||||||
|
Serial.begin(9600);
|
||||||
|
while (!Serial) {
|
||||||
|
; // wait for serial port to connect. Needed for Leonardo only
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pinMode(2, INPUT); // digital sensor is on digital pin 2
|
||||||
|
establishContact(); // send a byte to establish contact until receiver responds
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
// if we get a valid byte, read analog ins:
|
||||||
|
if (Serial.available() > 0) {
|
||||||
|
// get incoming byte:
|
||||||
|
inByte = Serial.read();
|
||||||
|
// read first analog input:
|
||||||
|
firstSensor = analogRead(A0);
|
||||||
|
// read second analog input:
|
||||||
|
secondSensor = analogRead(A1);
|
||||||
|
// read switch, map it to 0 or 255L
|
||||||
|
thirdSensor = map(digitalRead(2), 0, 1, 0, 255);
|
||||||
|
// send sensor values:
|
||||||
|
Serial.print(firstSensor);
|
||||||
|
Serial.print(",");
|
||||||
|
Serial.print(secondSensor);
|
||||||
|
Serial.print(",");
|
||||||
|
Serial.println(thirdSensor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void establishContact() {
|
||||||
|
while (Serial.available() <= 0) {
|
||||||
|
Serial.println("0,0,0"); // send an initial string
|
||||||
|
delay(300);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
783
software/apps/Motion/Damp3/DampMax.maxpat
Normal file
783
software/apps/Motion/Damp3/DampMax.maxpat
Normal file
@ -0,0 +1,783 @@
|
|||||||
|
{
|
||||||
|
"patcher" : {
|
||||||
|
"fileversion" : 1,
|
||||||
|
"appversion" : {
|
||||||
|
"major" : 6,
|
||||||
|
"minor" : 0,
|
||||||
|
"revision" : 5
|
||||||
|
}
|
||||||
|
,
|
||||||
|
"rect" : [ 25.0, 82.0, 1184.0, 641.0 ],
|
||||||
|
"bglocked" : 0,
|
||||||
|
"openinpresentation" : 0,
|
||||||
|
"default_fontsize" : 12.0,
|
||||||
|
"default_fontface" : 0,
|
||||||
|
"default_fontname" : "Arial",
|
||||||
|
"gridonopen" : 0,
|
||||||
|
"gridsize" : [ 15.0, 15.0 ],
|
||||||
|
"gridsnaponopen" : 0,
|
||||||
|
"statusbarvisible" : 2,
|
||||||
|
"toolbarvisible" : 1,
|
||||||
|
"boxanimatetime" : 200,
|
||||||
|
"imprint" : 0,
|
||||||
|
"enablehscroll" : 1,
|
||||||
|
"enablevscroll" : 1,
|
||||||
|
"devicewidth" : 0.0,
|
||||||
|
"description" : "",
|
||||||
|
"digest" : "",
|
||||||
|
"tags" : "",
|
||||||
|
"boxes" : [ {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-36",
|
||||||
|
"maxclass" : "flonum",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 2,
|
||||||
|
"outlettype" : [ "float", "bang" ],
|
||||||
|
"parameter_enable" : 0,
|
||||||
|
"patching_rect" : [ 360.0, 393.0, 50.0, 20.0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-34",
|
||||||
|
"maxclass" : "number",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 2,
|
||||||
|
"outlettype" : [ "int", "bang" ],
|
||||||
|
"parameter_enable" : 0,
|
||||||
|
"patching_rect" : [ 229.0, 421.0, 50.0, 20.0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-32",
|
||||||
|
"maxclass" : "newobj",
|
||||||
|
"numinlets" : 2,
|
||||||
|
"numoutlets" : 1,
|
||||||
|
"outlettype" : [ "int" ],
|
||||||
|
"patching_rect" : [ 289.0, 421.0, 32.5, 20.0 ],
|
||||||
|
"text" : "* 1"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-31",
|
||||||
|
"maxclass" : "flonum",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 2,
|
||||||
|
"outlettype" : [ "float", "bang" ],
|
||||||
|
"parameter_enable" : 0,
|
||||||
|
"patching_rect" : [ 289.0, 452.0, 50.0, 20.0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-29",
|
||||||
|
"maxclass" : "newobj",
|
||||||
|
"numinlets" : 2,
|
||||||
|
"numoutlets" : 1,
|
||||||
|
"outlettype" : [ "int" ],
|
||||||
|
"patching_rect" : [ 289.0, 387.0, 32.5, 20.0 ],
|
||||||
|
"text" : "-"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-28",
|
||||||
|
"maxclass" : "message",
|
||||||
|
"numinlets" : 2,
|
||||||
|
"numoutlets" : 1,
|
||||||
|
"outlettype" : [ "" ],
|
||||||
|
"patching_rect" : [ 709.0, 345.0, 50.0, 18.0 ],
|
||||||
|
"text" : "76"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-26",
|
||||||
|
"maxclass" : "message",
|
||||||
|
"numinlets" : 2,
|
||||||
|
"numoutlets" : 1,
|
||||||
|
"outlettype" : [ "" ],
|
||||||
|
"patching_rect" : [ 649.0, 345.0, 50.0, 18.0 ],
|
||||||
|
"text" : "74"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-25",
|
||||||
|
"maxclass" : "message",
|
||||||
|
"numinlets" : 2,
|
||||||
|
"numoutlets" : 1,
|
||||||
|
"outlettype" : [ "" ],
|
||||||
|
"patching_rect" : [ 589.0, 345.0, 50.0, 18.0 ],
|
||||||
|
"text" : "71"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-24",
|
||||||
|
"maxclass" : "message",
|
||||||
|
"numinlets" : 2,
|
||||||
|
"numoutlets" : 1,
|
||||||
|
"outlettype" : [ "" ],
|
||||||
|
"patching_rect" : [ 529.0, 345.0, 50.0, 18.0 ],
|
||||||
|
"text" : "68"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-13",
|
||||||
|
"maxclass" : "message",
|
||||||
|
"numinlets" : 2,
|
||||||
|
"numoutlets" : 1,
|
||||||
|
"outlettype" : [ "" ],
|
||||||
|
"patching_rect" : [ 469.0, 345.0, 50.0, 18.0 ],
|
||||||
|
"text" : "66"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-3",
|
||||||
|
"maxclass" : "message",
|
||||||
|
"numinlets" : 2,
|
||||||
|
"numoutlets" : 1,
|
||||||
|
"outlettype" : [ "" ],
|
||||||
|
"patching_rect" : [ 409.0, 345.0, 50.0, 18.0 ],
|
||||||
|
"text" : "63"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-23",
|
||||||
|
"maxclass" : "message",
|
||||||
|
"numinlets" : 2,
|
||||||
|
"numoutlets" : 1,
|
||||||
|
"outlettype" : [ "" ],
|
||||||
|
"patching_rect" : [ 349.0, 345.0, 50.0, 18.0 ],
|
||||||
|
"text" : "61"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-1",
|
||||||
|
"maxclass" : "message",
|
||||||
|
"numinlets" : 2,
|
||||||
|
"numoutlets" : 1,
|
||||||
|
"outlettype" : [ "" ],
|
||||||
|
"patching_rect" : [ 289.0, 345.0, 50.0, 18.0 ],
|
||||||
|
"text" : "58"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-37",
|
||||||
|
"maxclass" : "message",
|
||||||
|
"numinlets" : 2,
|
||||||
|
"numoutlets" : 1,
|
||||||
|
"outlettype" : [ "" ],
|
||||||
|
"patching_rect" : [ 229.0, 345.0, 50.0, 18.0 ],
|
||||||
|
"text" : "57"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-27",
|
||||||
|
"maxclass" : "newobj",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 10,
|
||||||
|
"outlettype" : [ "int", "bang", "bang", "bang", "bang", "bang", "bang", "bang", "bang", "bang" ],
|
||||||
|
"patching_rect" : [ 206.25, 306.0, 519.5, 20.0 ],
|
||||||
|
"text" : "t i b b b b b b b b b"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-22",
|
||||||
|
"maxclass" : "newobj",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 5,
|
||||||
|
"outlettype" : [ "int", "bang", "bang", "bang", "bang" ],
|
||||||
|
"patching_rect" : [ 879.0, 313.0, 73.0, 20.0 ],
|
||||||
|
"text" : "t i b b b b"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"id" : "obj-21",
|
||||||
|
"maxclass" : "button",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 1,
|
||||||
|
"outlettype" : [ "bang" ],
|
||||||
|
"patching_rect" : [ 310.0, 6.0, 20.0, 20.0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-20",
|
||||||
|
"maxclass" : "newobj",
|
||||||
|
"numinlets" : 2,
|
||||||
|
"numoutlets" : 3,
|
||||||
|
"outlettype" : [ "bang", "bang", "int" ],
|
||||||
|
"patching_rect" : [ 325.0, 37.0, 56.0, 20.0 ],
|
||||||
|
"text" : "uzi 1024"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-19",
|
||||||
|
"maxclass" : "message",
|
||||||
|
"numinlets" : 2,
|
||||||
|
"numoutlets" : 1,
|
||||||
|
"outlettype" : [ "" ],
|
||||||
|
"patching_rect" : [ 41.0, 370.0, 37.0, 18.0 ],
|
||||||
|
"text" : "clear"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"id" : "obj-17",
|
||||||
|
"maxclass" : "button",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 1,
|
||||||
|
"outlettype" : [ "bang" ],
|
||||||
|
"patching_rect" : [ 292.0, 58.0, 20.0, 20.0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"hint" : "x 82 y -44",
|
||||||
|
"id" : "obj-15",
|
||||||
|
"maxclass" : "itable",
|
||||||
|
"name" : "",
|
||||||
|
"numinlets" : 2,
|
||||||
|
"numoutlets" : 2,
|
||||||
|
"outlettype" : [ "int", "bang" ],
|
||||||
|
"parameter_enable" : 0,
|
||||||
|
"patching_rect" : [ 150.0, 488.0, 1000.0, 145.0 ],
|
||||||
|
"range" : 128,
|
||||||
|
"signed" : 1,
|
||||||
|
"size" : 1024,
|
||||||
|
"table_data" : [ 0, 80, 4, 4, -32, -34, -36, -40, -40, -42, -50, -50, -18, -18, -22, -20, -20, -20, -16, -20, -20, -18, -14, -14, -16, -18, -22, -20, -18, -20, -18, -18, -18, -16, -14, -12, -6, -2, -2, 0, 4, 6, 8, 10, 6, 6, 6, 8, 6, 8, 8, 8, 10, 8, 8, 8, 8, 6, 8, 6, 6, 8, 8, 6, 6, 8, 6, 8, 6, 6, 6, 8, 8, 6, 8, 6, 6, 6, 6, 6, 6, 8, 6, 8, 8, 8, 8, 6, 8, 6, 8, 10, 10, 10, 10, 12, 12, 12, 10, 6, 8, 10, 10, 10, 8, 10, 12, 14, 14, 10, 10, 10, 10, 10, 8, 6, 6, 10, 10, 10, 12, 12, 12, 14, 12, 10, 10, 10, 10, 8, 8, 8, 8, 10, 10, 10, 8, 10, 12, 10, 10, 6, 8, 6, 8, 8, 6, 6, 8, 8, 8, 10, 8, 6, 8, 8, 6, 8, 10, 8, 10, 10, 10, 10, 12, 12, 10, 10, 10, 10, 10, 10, 8, 10, 8, 10, 10, 12, 12, 12, 14, 10, 12, 10, 8, 6, 6, 8, 6, 6, 6, 6, 8, 8, 8, 6, 6, 6, 6, 6, 4, 6, 6, 6, 6, 8, 6, 6, 6, 4, 0, -2, -4, -8, -10, -14, -18, -20, -20, -20, -20, -24, -22, -32, -36, -38, -44, -46, -50, -48, -50, -40, -32, -36, -32, -34, -34, -32, -38, -36, -38, -32, -30, -32, -32, -32, -24, -26, -26, -26, -26, -22, -22, -22, -24, -22, -22, -20, -18, -14, -8, -6, -4, -2, 0, 0, 2, 2, 4, 4, 4, 4, 4, 4, 2, 2, 0, 0, -2, -2, -2, -2, -2, -2, -2, -2, 0, 0, 0, 0, 0, -2, -2, -2, -2, -2, -2, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 6, 2, 4, 4, 6, 6, 6, 6, 4, 4, 2, 2, 0, 0, 0, 0, 2, 2, 2, 4, 6, 146, 140, 134, 126, 116, 104, 102, 100, -38, -30, -24, -16, -4, 10, 12, 12, 12, 12, 12, 14, 12, 18, 22, 24, 22, 18, 14, 8, 2, -12, -20, -24, -28, -28, -26, -26, -22, -18, -22, -22, -18, -18, -14, -10, -4, 0, 10, -2, -14, -28, -38, -48, -54, -56, -66, -54, -50, -36, -32, -28, -26, -28, -22, -22, -14, -12, -6, -2, -2, 6, 6, 10, 10, 12, 12, 12, 12, 8, 10, 10, 10, 8, 6, 6, 6, 4, 2, 0, 0, 2, 2, 4, 6, 10, 18, 22, 26, 34, 36, 40, 40, 38, 28, 20, 12, 2, 0, -6, -8, -10, -8, -4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, -2, -2, -2, -2, -2, -2, -2, 0, 0, 0, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 4, 6, 4, 4, 4, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, -4, -4, -4, -4, -4, -6, -6, -4, -2, -2, -2, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, -2, -2, -2, -2, -2, -2, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, -2, -2, -2, -2, -2, -4, -6, -4, -6, -8, -10, -12, -14, -16, -18, -26, -30, -34, -34, -34, -34, -34, -32, -24, -20, -18, -18, -18, -18, -14, -8, -6, 2, 8, 12, 26, 30, 40, 38, 40, 40, 40, 44, 34, 34, 26, 26, 24, 20, 20, 16, 16, 18, 18, 24, 26, 26, 34, 36, 46, 46, 44, 38, 36, 36, 26, 22, 10, 4, 0, -8, -12, -16, -26, -30, -34, -34, -30, -26, -30, -32, -26, -26, -26, -26, -28, -30, -26, -24, -22, -20, -20, -20, -20, -18, -20, -20, -22, -24, -22, -24, -28, -32, -28, -30, -30, -30, -30, -26, -20, -12, -8, 4, 16, 22, 26, 32, 38, 38, 36, 36, 30, 32, 32, 30, 34, 34, 34, 30, 32, 32, 40, 38, 30, 32, 36, 36, 40, 40, 30, 32, 34, 32, 28, 28, 20, 14, 12, 4, -4, -10, -20, -28, -38, -46, -48, -48, -46, -42, -38, -38, -34, -26, -26, -28, -32, -36, -38, -38, -38, -38, -42, -42, -36, -36, -32, -30, -26, -38, -32, -28, -36, -34, -32, -32, -30, -18, -18, -18, -12, -10, -12, -10, -10, -8, -6, -2, 2, 6, 10, 12, 16, 18, 20, 22, 24, 24, 26, 28, 28, 30, 32, 28, 28, 32, 30, 34, 32, 28, 24, 24, 20, 12, 10, 2, 0, 0, 0, 0, 0, -2, -2, -2, -2, -2, -2, -2, -2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, -2, -2, -2, -2, -2, -2, -2, 0, 2, 4, 4, 6, 6, 6, 6, 6, 4, 4, 4, 2, 2, 2, 2, 4, 4, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 4, 4, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-14",
|
||||||
|
"maxclass" : "number",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 2,
|
||||||
|
"outlettype" : [ "int", "bang" ],
|
||||||
|
"parameter_enable" : 0,
|
||||||
|
"patching_rect" : [ 150.0, 337.0, 50.0, 20.0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-12",
|
||||||
|
"maxclass" : "number",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 2,
|
||||||
|
"outlettype" : [ "int", "bang" ],
|
||||||
|
"parameter_enable" : 0,
|
||||||
|
"patching_rect" : [ 451.0, 92.0, 50.0, 20.0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"id" : "obj-11",
|
||||||
|
"maxclass" : "toggle",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 1,
|
||||||
|
"outlettype" : [ "int" ],
|
||||||
|
"parameter_enable" : 0,
|
||||||
|
"patching_rect" : [ 451.0, -4.0, 20.0, 20.0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-9",
|
||||||
|
"maxclass" : "newobj",
|
||||||
|
"numinlets" : 2,
|
||||||
|
"numoutlets" : 1,
|
||||||
|
"outlettype" : [ "bang" ],
|
||||||
|
"patching_rect" : [ 451.0, 27.0, 51.0, 20.0 ],
|
||||||
|
"text" : "metro 1"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-8",
|
||||||
|
"maxclass" : "newobj",
|
||||||
|
"numinlets" : 5,
|
||||||
|
"numoutlets" : 4,
|
||||||
|
"outlettype" : [ "int", "", "", "int" ],
|
||||||
|
"patching_rect" : [ 451.0, 60.0, 101.0, 20.0 ],
|
||||||
|
"text" : "counter 0 1 1024"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-7",
|
||||||
|
"maxclass" : "newobj",
|
||||||
|
"numinlets" : 0,
|
||||||
|
"numoutlets" : 0,
|
||||||
|
"patching_rect" : [ 310.0, 96.0, 100.0, 20.0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-6",
|
||||||
|
"maxclass" : "number",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 2,
|
||||||
|
"outlettype" : [ "int", "bang" ],
|
||||||
|
"parameter_enable" : 0,
|
||||||
|
"patching_rect" : [ 150.0, 85.0, 50.0, 20.0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"hint" : "x 79 y 127",
|
||||||
|
"id" : "obj-4",
|
||||||
|
"maxclass" : "itable",
|
||||||
|
"name" : "",
|
||||||
|
"numinlets" : 2,
|
||||||
|
"numoutlets" : 2,
|
||||||
|
"outlettype" : [ "int", "bang" ],
|
||||||
|
"parameter_enable" : 0,
|
||||||
|
"patching_rect" : [ 150.0, 153.0, 1000.0, 145.0 ],
|
||||||
|
"range" : 128,
|
||||||
|
"size" : 1024,
|
||||||
|
"table_data" : [ 0, 56, 55, 54, 53, 51, 51, 50, 48, 48, 46, 45, 42, 41, 41, 40, 40, 38, 36, 36, 35, 34, 33, 31, 29, 28, 27, 26, 26, 25, 24, 23, 22, 22, 24, 25, 25, 25, 26, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 32, 32, 32, 33, 33, 33, 34, 34, 35, 36, 36, 36, 36, 37, 37, 38, 38, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 46, 47, 47, 48, 50, 50, 51, 51, 52, 53, 53, 53, 53, 54, 56, 56, 57, 57, 58, 59, 60, 61, 61, 61, 62, 62, 63, 63, 63, 64, 66, 66, 67, 68, 69, 69, 70, 70, 71, 71, 72, 73, 73, 73, 74, 74, 76, 76, 77, 77, 78, 79, 79, 79, 79, 80, 80, 81, 82, 82, 82, 83, 83, 84, 85, 85, 85, 86, 86, 86, 87, 89, 89, 90, 90, 91, 91, 92, 93, 94, 94, 95, 95, 96, 96, 96, 98, 98, 99, 100, 101, 102, 102, 103, 103, 104, 104, 104, 104, 105, 106, 106, 106, 107, 107, 108, 108, 109, 109, 109, 109, 110, 110, 110, 111, 112, 112, 112, 113, 113, 113, 113, 113, 112, 111, 110, 109, 108, 106, 104, 103, 102, 101, 100, 97, 97, 90, 86, 84, 80, 78, 75, 73, 72, 70, 70, 66, 64, 61, 58, 57, 53, 52, 51, 50, 49, 45, 42, 41, 41, 39, 38, 37, 36, 34, 31, 30, 29, 28, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 30, 30, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 34, 35, 105, 102, 99, 96, 91, 85, 85, 85, 86, 87, 87, 88, 89, 90, 91, 91, 92, 93, 93, 95, 95, 99, 102, 103, 103, 102, 100, 99, 96, 93, 92, 91, 89, 88, 87, 86, 85, 84, 81, 80, 80, 79, 80, 81, 83, 84, 86, 79, 73, 65, 61, 57, 56, 56, 53, 52, 48, 47, 45, 43, 43, 42, 42, 41, 41, 41, 42, 42, 42, 45, 45, 46, 46, 47, 48, 48, 48, 49, 50, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 52, 52, 53, 54, 56, 60, 62, 64, 69, 70, 73, 74, 75, 74, 72, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 69, 70, 70, 70, 70, 70, 70, 71, 71, 72, 72, 72, 73, 73, 73, 73, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 73, 72, 72, 72, 72, 72, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 72, 74, 74, 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 73, 73, 73, 73, 73, 73, 72, 71, 71, 70, 69, 68, 67, 66, 64, 62, 58, 55, 52, 51, 50, 49, 47, 46, 46, 45, 43, 42, 41, 40, 40, 42, 43, 46, 47, 48, 54, 55, 60, 61, 63, 66, 67, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 81, 82, 86, 88, 89, 94, 96, 102, 104, 104, 105, 106, 107, 107, 107, 107, 106, 104, 101, 100, 99, 94, 92, 90, 89, 89, 88, 85, 83, 81, 79, 77, 76, 75, 73, 72, 71, 70, 69, 67, 66, 65, 64, 62, 61, 59, 57, 56, 54, 51, 48, 48, 46, 44, 42, 41, 41, 41, 42, 44, 48, 52, 53, 54, 57, 60, 61, 62, 66, 67, 69, 70, 72, 77, 78, 79, 81, 83, 85, 90, 91, 92, 94, 97, 99, 103, 105, 105, 107, 109, 110, 111, 113, 113, 112, 111, 109, 107, 105, 101, 99, 94, 89, 87, 85, 84, 84, 82, 80, 77, 76, 74, 71, 68, 66, 63, 61, 58, 57, 53, 50, 50, 48, 47, 46, 45, 38, 37, 36, 32, 31, 31, 30, 30, 29, 28, 27, 26, 26, 25, 25, 25, 25, 25, 26, 27, 29, 30, 31, 33, 34, 35, 37, 39, 41, 43, 45, 47, 49, 51, 51, 53, 57, 58, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 66, 66, 67, 67, 67, 67, 67, 67, 68, 68, 68, 68, 68, 68, 69, 69, 69, 69, 69, 69, 69, 69, 69, 70, 70, 70, 70, 70, 70, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 71, 73 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-2",
|
||||||
|
"maxclass" : "comment",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 0,
|
||||||
|
"patching_rect" : [ 63.0, 39.0, 150.0, 20.0 ],
|
||||||
|
"text" : "Plot Velocity from Position"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lines" : [ {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-23", 1 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-1", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-9", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-11", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-15", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-12", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-4", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-12", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-24", 1 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-13", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-8", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-17", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-15", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-19", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-8", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-20", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-20", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-21", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-3", 1 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-23", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-25", 1 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-24", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-26", 1 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-25", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-28", 1 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-26", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-1", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-27", 2 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-13", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-27", 5 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-23", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-27", 3 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-24", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-27", 6 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-25", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-27", 7 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-26", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-27", 8 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-28", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-27", 9 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-3", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-27", 4 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-37", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-27", 1 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-37", 1 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-27", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-29", 1 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-28", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-32", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-29", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-34", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-29", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-13", 1 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-3", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-15", 1 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-31", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-31", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-32", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-32", 1 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-36", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-1", 1 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-37", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-29", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-37", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-14", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-4", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-27", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-4", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-4", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-6", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-12", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-8", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-8", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-9", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dependency_cache" : [ ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
20
software/apps/Motion/Damp4/Damp4.ino
Normal file
20
software/apps/Motion/Damp4/Damp4.ino
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
//Damp3 trying integration to get velocity
|
||||||
|
// ala Kalman filtering?
|
||||||
|
|
||||||
|
int x; //position measured [0-1023]
|
||||||
|
float af, vf //acceleration, velocity estimates
|
||||||
|
float ff // force out
|
||||||
|
float K = 1.0 //spring
|
||||||
|
float B = 10.0 //damping (dominant)
|
||||||
|
float M = 1.0 //mass
|
||||||
|
|
||||||
|
void setup(){
|
||||||
|
Serial.begin(115200);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop(){
|
||||||
|
x = analogRead(A0);
|
||||||
|
ff = K*(xf-x) - B*vf; // the spring K
|
||||||
|
af = ff/M;
|
||||||
|
vf += af*T; //T is cycle time
|
||||||
|
xf += vf*T;
|
||||||
24
software/apps/Motion/DampEuler/DampEuler.ino
Normal file
24
software/apps/Motion/DampEuler/DampEuler.ino
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
//Damp Euler
|
||||||
|
|
||||||
|
#define n 10 //number in buffer "window size"
|
||||||
|
// finite difference with n samples between x(i)
|
||||||
|
int x[n]; //last n samples of position
|
||||||
|
int index = 0;
|
||||||
|
float v; // estimate of velocity
|
||||||
|
byte c;
|
||||||
|
|
||||||
|
void setup(){
|
||||||
|
Serial.begin(9600);
|
||||||
|
for(int i=0; i<n; i++) x[i]=analogRead(A0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop(){
|
||||||
|
x[index] = analogRead(A0); //position measured
|
||||||
|
v = (x[index] - x[index++%n])/n;
|
||||||
|
if(index > n-1) index = 0;
|
||||||
|
v = buff[index] - buff[(index-n)%n];
|
||||||
|
if(c++==0)Serial.println(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
1
software/apps/Motion/DampMass/DampMass/DampMass.ino
Normal file
1
software/apps/Motion/DampMass/DampMass/DampMass.ino
Normal file
@ -0,0 +1 @@
|
|||||||
|
//DampMass
|
||||||
1460
software/apps/Motion/Graph2.maxpat
Normal file
1460
software/apps/Motion/Graph2.maxpat
Normal file
File diff suppressed because it is too large
Load Diff
28
software/apps/Motion/Graph2/Graph2.ino
Normal file
28
software/apps/Motion/Graph2/Graph2.ino
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
int x, v, t; //position velocity time
|
||||||
|
#define n 10
|
||||||
|
int xtab[n]; //table of x
|
||||||
|
int i; // index for table
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
// start serial port at 9600 bps:
|
||||||
|
Serial.begin(9600);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
// if we get a valid byte, read analog ins:
|
||||||
|
if (Serial.available() > 0) {
|
||||||
|
x = analogRead(A0)/4; //just for this test
|
||||||
|
xtab[i] = x; //put it in array of x
|
||||||
|
i = i + 1; //index to last x (9 times ago)
|
||||||
|
if(i>9)i=0; //increment index
|
||||||
|
v = x - xtab[i]; //difference x vs old x
|
||||||
|
t = (t+1)%256;
|
||||||
|
// send sensor values:
|
||||||
|
Serial.write(x); // sends one byte [0-255]
|
||||||
|
Serial.write(v+128);
|
||||||
|
Serial.write(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
576
software/apps/Motion/GraphArduinoA0.maxpat
Normal file
576
software/apps/Motion/GraphArduinoA0.maxpat
Normal file
@ -0,0 +1,576 @@
|
|||||||
|
{
|
||||||
|
"patcher" : {
|
||||||
|
"fileversion" : 1,
|
||||||
|
"appversion" : {
|
||||||
|
"major" : 6,
|
||||||
|
"minor" : 0,
|
||||||
|
"revision" : 5
|
||||||
|
}
|
||||||
|
,
|
||||||
|
"rect" : [ 50.0, 94.0, 693.0, 652.0 ],
|
||||||
|
"bglocked" : 0,
|
||||||
|
"openinpresentation" : 0,
|
||||||
|
"default_fontsize" : 12.0,
|
||||||
|
"default_fontface" : 0,
|
||||||
|
"default_fontname" : "Arial",
|
||||||
|
"gridonopen" : 0,
|
||||||
|
"gridsize" : [ 15.0, 15.0 ],
|
||||||
|
"gridsnaponopen" : 0,
|
||||||
|
"statusbarvisible" : 2,
|
||||||
|
"toolbarvisible" : 1,
|
||||||
|
"boxanimatetime" : 200,
|
||||||
|
"imprint" : 0,
|
||||||
|
"enablehscroll" : 1,
|
||||||
|
"enablevscroll" : 1,
|
||||||
|
"devicewidth" : 0.0,
|
||||||
|
"description" : "",
|
||||||
|
"digest" : "",
|
||||||
|
"tags" : "",
|
||||||
|
"boxes" : [ {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-23",
|
||||||
|
"maxclass" : "flonum",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 2,
|
||||||
|
"outlettype" : [ "float", "bang" ],
|
||||||
|
"parameter_enable" : 0,
|
||||||
|
"patching_rect" : [ 561.0, 378.0, 50.0, 20.0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-20",
|
||||||
|
"maxclass" : "newobj",
|
||||||
|
"numinlets" : 2,
|
||||||
|
"numoutlets" : 1,
|
||||||
|
"outlettype" : [ "float" ],
|
||||||
|
"patching_rect" : [ 519.0, 429.0, 44.0, 20.0 ],
|
||||||
|
"text" : "+ 500."
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-18",
|
||||||
|
"maxclass" : "newobj",
|
||||||
|
"numinlets" : 2,
|
||||||
|
"numoutlets" : 1,
|
||||||
|
"outlettype" : [ "float" ],
|
||||||
|
"patching_rect" : [ 418.0, 414.0, 42.0, 20.0 ],
|
||||||
|
"text" : "* 100."
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-32",
|
||||||
|
"linecount" : 10,
|
||||||
|
"maxclass" : "comment",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 0,
|
||||||
|
"patching_rect" : [ 479.0, 6.0, 344.0, 145.0 ],
|
||||||
|
"text" : "Graph\n\nThis patch takes a string, containing ASCII formatted number from 0 to 1023, with a carriage return and linefeed at the end. It converts the string to an integer and graphs it.\n\ncreated 2006\nby David A. Mellis\nmodified 14 Apr 2009\nby Scott Fitzgerald and Tom Igoe"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-30",
|
||||||
|
"maxclass" : "newobj",
|
||||||
|
"numinlets" : 3,
|
||||||
|
"numoutlets" : 3,
|
||||||
|
"outlettype" : [ "bang", "bang", "" ],
|
||||||
|
"patching_rect" : [ 327.0, 80.0, 62.0, 20.0 ],
|
||||||
|
"text" : "select 0 1"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-26",
|
||||||
|
"maxclass" : "comment",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 0,
|
||||||
|
"patching_rect" : [ 412.0, 231.0, 206.0, 20.0 ],
|
||||||
|
"text" : "click here to close the serial port"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-27",
|
||||||
|
"maxclass" : "comment",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 0,
|
||||||
|
"patching_rect" : [ 412.0, 205.0, 206.0, 20.0 ],
|
||||||
|
"text" : "click here to open the serial port"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-21",
|
||||||
|
"maxclass" : "message",
|
||||||
|
"numinlets" : 2,
|
||||||
|
"numoutlets" : 1,
|
||||||
|
"outlettype" : [ "" ],
|
||||||
|
"patching_rect" : [ 327.0, 231.0, 39.0, 18.0 ],
|
||||||
|
"text" : "close"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-19",
|
||||||
|
"maxclass" : "message",
|
||||||
|
"numinlets" : 2,
|
||||||
|
"numoutlets" : 1,
|
||||||
|
"outlettype" : [ "" ],
|
||||||
|
"patching_rect" : [ 349.0, 205.0, 41.0, 18.0 ],
|
||||||
|
"text" : "port a"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"bgcolor" : [ 0.231373, 0.713726, 1.0, 1.0 ],
|
||||||
|
"candicane2" : [ 0.145098, 0.203922, 0.356863, 1.0 ],
|
||||||
|
"candicane3" : [ 0.290196, 0.411765, 0.713726, 1.0 ],
|
||||||
|
"candicane4" : [ 0.439216, 0.619608, 0.070588, 1.0 ],
|
||||||
|
"candicane5" : [ 0.584314, 0.827451, 0.431373, 1.0 ],
|
||||||
|
"candicane6" : [ 0.733333, 0.035294, 0.788235, 1.0 ],
|
||||||
|
"candicane7" : [ 0.878431, 0.243137, 0.145098, 1.0 ],
|
||||||
|
"candicane8" : [ 0.027451, 0.447059, 0.501961, 1.0 ],
|
||||||
|
"contdata" : 1,
|
||||||
|
"id" : "obj-1",
|
||||||
|
"maxclass" : "multislider",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 2,
|
||||||
|
"outlettype" : [ "", "" ],
|
||||||
|
"parameter_enable" : 0,
|
||||||
|
"patching_rect" : [ 302.0, 450.0, 246.0, 167.0 ],
|
||||||
|
"peakcolor" : [ 0.498039, 0.498039, 0.498039, 1.0 ],
|
||||||
|
"setminmax" : [ 0.0, 1023.0 ],
|
||||||
|
"setstyle" : 3,
|
||||||
|
"settype" : 0,
|
||||||
|
"slidercolor" : [ 0.066667, 0.058824, 0.776471, 1.0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-2",
|
||||||
|
"maxclass" : "comment",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 0,
|
||||||
|
"patching_rect" : [ 412.0, 179.0, 207.0, 20.0 ],
|
||||||
|
"text" : "Click here to get a list of serial ports"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-3",
|
||||||
|
"linecount" : 2,
|
||||||
|
"maxclass" : "comment",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 0,
|
||||||
|
"patching_rect" : [ 153.0, 409.0, 138.0, 34.0 ],
|
||||||
|
"text" : "Here's the number from Arduino's analog input"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-4",
|
||||||
|
"maxclass" : "comment",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 0,
|
||||||
|
"patching_rect" : [ 379.0, 378.0, 147.0, 20.0 ],
|
||||||
|
"text" : "Convert ASCII to symbol"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-5",
|
||||||
|
"maxclass" : "comment",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 0,
|
||||||
|
"patching_rect" : [ 379.0, 355.0, 147.0, 20.0 ],
|
||||||
|
"text" : "Convert integer to ASCII"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"bgcolor" : [ 0.866667, 0.866667, 0.866667, 1.0 ],
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"htextcolor" : [ 0.870588, 0.870588, 0.870588, 1.0 ],
|
||||||
|
"id" : "obj-6",
|
||||||
|
"maxclass" : "number",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 2,
|
||||||
|
"outlettype" : [ "int", "bang" ],
|
||||||
|
"parameter_enable" : 0,
|
||||||
|
"patching_rect" : [ 302.0, 414.0, 37.0, 20.0 ],
|
||||||
|
"triscale" : 0.9
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"color" : [ 1.0, 0.890196, 0.090196, 1.0 ],
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-7",
|
||||||
|
"maxclass" : "newobj",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 1,
|
||||||
|
"outlettype" : [ "" ],
|
||||||
|
"patching_rect" : [ 302.0, 378.0, 74.0, 20.0 ],
|
||||||
|
"text" : "fromsymbol"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"color" : [ 1.0, 0.890196, 0.090196, 1.0 ],
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-8",
|
||||||
|
"maxclass" : "newobj",
|
||||||
|
"numinlets" : 3,
|
||||||
|
"numoutlets" : 1,
|
||||||
|
"outlettype" : [ "int" ],
|
||||||
|
"patching_rect" : [ 302.0, 355.0, 46.0, 20.0 ],
|
||||||
|
"text" : "itoa"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-9",
|
||||||
|
"maxclass" : "newobj",
|
||||||
|
"numinlets" : 2,
|
||||||
|
"numoutlets" : 2,
|
||||||
|
"outlettype" : [ "", "" ],
|
||||||
|
"patching_rect" : [ 302.0, 332.0, 64.0, 20.0 ],
|
||||||
|
"text" : "zl group 4"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-10",
|
||||||
|
"maxclass" : "newobj",
|
||||||
|
"numinlets" : 3,
|
||||||
|
"numoutlets" : 3,
|
||||||
|
"outlettype" : [ "bang", "bang", "" ],
|
||||||
|
"patching_rect" : [ 244.0, 281.0, 77.0, 20.0 ],
|
||||||
|
"text" : "select 10 13"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"id" : "obj-11",
|
||||||
|
"maxclass" : "toggle",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 1,
|
||||||
|
"outlettype" : [ "int" ],
|
||||||
|
"parameter_enable" : 0,
|
||||||
|
"patching_rect" : [ 244.0, 43.0, 15.0, 15.0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-12",
|
||||||
|
"maxclass" : "newobj",
|
||||||
|
"numinlets" : 2,
|
||||||
|
"numoutlets" : 1,
|
||||||
|
"outlettype" : [ "bang" ],
|
||||||
|
"patching_rect" : [ 244.0, 80.0, 65.0, 20.0 ],
|
||||||
|
"text" : "qmetro 10"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-13",
|
||||||
|
"maxclass" : "message",
|
||||||
|
"numinlets" : 2,
|
||||||
|
"numoutlets" : 1,
|
||||||
|
"outlettype" : [ "" ],
|
||||||
|
"patching_rect" : [ 369.0, 179.0, 36.0, 18.0 ],
|
||||||
|
"text" : "print"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-14",
|
||||||
|
"maxclass" : "newobj",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 2,
|
||||||
|
"outlettype" : [ "int", "" ],
|
||||||
|
"patching_rect" : [ 244.0, 255.0, 84.0, 20.0 ],
|
||||||
|
"text" : "serial a 9600"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-15",
|
||||||
|
"linecount" : 2,
|
||||||
|
"maxclass" : "comment",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 0,
|
||||||
|
"patching_rect" : [ 53.0, 72.0, 185.0, 34.0 ],
|
||||||
|
"text" : "Read serial input buffer every 10 milliseconds"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-16",
|
||||||
|
"linecount" : 3,
|
||||||
|
"maxclass" : "comment",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 0,
|
||||||
|
"patching_rect" : [ 332.0, 269.0, 320.0, 48.0 ],
|
||||||
|
"text" : "If you get newline (ASCII 10), send the list. If you get return (ASCII 13) do nothing. Any other value, add to the list"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"box" : {
|
||||||
|
"fontname" : "Arial",
|
||||||
|
"fontsize" : 12.0,
|
||||||
|
"id" : "obj-17",
|
||||||
|
"linecount" : 2,
|
||||||
|
"maxclass" : "comment",
|
||||||
|
"numinlets" : 1,
|
||||||
|
"numoutlets" : 0,
|
||||||
|
"patching_rect" : [ 271.0, 32.0, 199.0, 34.0 ],
|
||||||
|
"text" : "Click to open/close serial port and start/stop patch"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lines" : [ {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-9", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"midpoints" : [ 311.5, 320.0, 311.5, 320.0 ],
|
||||||
|
"source" : [ "obj-10", 2 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-9", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"midpoints" : [ 253.5, 308.0, 311.5, 308.0 ],
|
||||||
|
"source" : [ "obj-10", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-12", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-11", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-30", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"midpoints" : [ 253.0, 71.0, 336.5, 71.0 ],
|
||||||
|
"source" : [ "obj-11", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-14", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-12", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-14", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"midpoints" : [ 378.5, 200.5, 253.5, 200.5 ],
|
||||||
|
"source" : [ "obj-13", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-10", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-14", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-20", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-18", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-14", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"midpoints" : [ 358.5, 228.5, 253.5, 228.5 ],
|
||||||
|
"source" : [ "obj-19", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-23", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-20", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-14", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"midpoints" : [ 336.5, 251.5, 253.5, 251.5 ],
|
||||||
|
"source" : [ "obj-21", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-1", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-23", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-19", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-30", 1 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-21", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-30", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-1", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-6", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-18", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-7", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-7", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-8", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
, {
|
||||||
|
"patchline" : {
|
||||||
|
"destination" : [ "obj-8", 0 ],
|
||||||
|
"disabled" : 0,
|
||||||
|
"hidden" : 0,
|
||||||
|
"source" : [ "obj-9", 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dependency_cache" : [ ]
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
71
software/apps/Motion/Motion0/Motion0.ino
Normal file
71
software/apps/Motion/Motion0/Motion0.ino
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#include <Motion.h>
|
||||||
|
#include <Motor.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Two motion objects are available from the MMM Motions library
|
||||||
|
(1) MotionA
|
||||||
|
(2) MotionB
|
||||||
|
|
||||||
|
MOTION {
|
||||||
|
MOTIONA ,
|
||||||
|
MOTIONB1
|
||||||
|
};
|
||||||
|
|
||||||
|
Each objects needs intialisation with a specific input
|
||||||
|
from which ADC reading will be performed.
|
||||||
|
|
||||||
|
Users may choose and identify inputs aa INPUT[A0, ... ,A7].
|
||||||
|
ex: MotionA.init(INPOUTA5);
|
||||||
|
|
||||||
|
INPUT {
|
||||||
|
INPUTA0,
|
||||||
|
INPUTA1,
|
||||||
|
INPUTA2,
|
||||||
|
INPUTA3,
|
||||||
|
INPUTA4,
|
||||||
|
INPUTA5,
|
||||||
|
INPUTA6,
|
||||||
|
INPUTA7
|
||||||
|
}
|
||||||
|
|
||||||
|
All calculation of physics (position, velocity and acceleration)
|
||||||
|
are computed internally usign interrupts and timers. To access
|
||||||
|
such information, user may call getPosition(), getVelocity()
|
||||||
|
and getAcceleration() respectively on a initialised Motion object.
|
||||||
|
|
||||||
|
int getPosition();
|
||||||
|
float getVelocity();
|
||||||
|
float getAcceleration();
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
MotionA.init(INPUTA0);
|
||||||
|
MotorA.init();
|
||||||
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
MotionA.k = 0.2f;
|
||||||
|
MotionA.m = 0.3f;
|
||||||
|
MotionA.d = 0.02f;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
if(MotionA.F < 0) MotorA.direction(FORWARD);
|
||||||
|
else MotorA.direction(BACKWARD);
|
||||||
|
|
||||||
|
float t = abs(MotionA.F);
|
||||||
|
MotorA.torque(t);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Serial.print("position: "); Serial.println(MotionA.getPosition());
|
||||||
|
Serial.print("velocity: "); Serial.println(MotionA.getVelocity());
|
||||||
|
Serial.print("accel: "); Serial.println(MotionA.getAcceleration());
|
||||||
|
Serial.println("-------");
|
||||||
|
delay(100);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
63
software/apps/Motion/Pendulum/Pendulum.ino
Normal file
63
software/apps/Motion/Pendulum/Pendulum.ino
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// "Pendulum" - spring-mass oscillator
|
||||||
|
#include <Motion.h>
|
||||||
|
#include <Motor.h>
|
||||||
|
|
||||||
|
byte incomingByte;
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
// init MotionA & MotorA
|
||||||
|
MotionA.init(INPUTA0);
|
||||||
|
MotorA.init();
|
||||||
|
|
||||||
|
// provide MotionA with initial physics constants
|
||||||
|
MotionA.k = 0.2f; // spring
|
||||||
|
MotionA.m = 0.3f; // mass
|
||||||
|
MotionA.d = 0.02f; // damping
|
||||||
|
|
||||||
|
Serial.begin(9600);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop(){
|
||||||
|
|
||||||
|
if(MotionA.F < 0) MotorA.direction(FORWARD);
|
||||||
|
else MotorA.direction(BACKWARD);
|
||||||
|
|
||||||
|
float t = abs(MotionA.F);
|
||||||
|
//if(t > 512) t = 512;
|
||||||
|
//MotorA.torque(t);
|
||||||
|
|
||||||
|
if (Serial.available() > 0) {
|
||||||
|
incomingByte = Serial.read();
|
||||||
|
if(incomingByte == '1'){
|
||||||
|
MotionA.m = MotionA.m * 1.1;
|
||||||
|
Serial.print("m: ");
|
||||||
|
Serial.println(MotionA.m);
|
||||||
|
}
|
||||||
|
else if(incomingByte == '!'){
|
||||||
|
MotionA.m = MotionA.m / 1.1;
|
||||||
|
Serial.print("m: ");
|
||||||
|
Serial.println(MotionA.m);
|
||||||
|
}
|
||||||
|
else if(incomingByte == '2'){
|
||||||
|
MotionA.k = MotionA.k * 1.1;
|
||||||
|
Serial.print("k: ");
|
||||||
|
Serial.println(MotionA.k);
|
||||||
|
}
|
||||||
|
else if(incomingByte == '@'){
|
||||||
|
MotionA.k = MotionA.k / 1.1;
|
||||||
|
Serial.print("k: ");
|
||||||
|
Serial.println(MotionA.k);
|
||||||
|
}
|
||||||
|
else if(incomingByte == '3'){
|
||||||
|
MotionA.d = MotionA.d * 1.1;
|
||||||
|
Serial.print("d: ");
|
||||||
|
Serial.println(MotionA.d);
|
||||||
|
}
|
||||||
|
else if(incomingByte == '#'){
|
||||||
|
MotionA.d = MotionA.d / 1.1;
|
||||||
|
Serial.print("d: ");
|
||||||
|
Serial.println(MotionA.d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
software/apps/Motor/Motor.ino
Normal file
16
software/apps/Motor/Motor.ino
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#include <Motor.h>
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
MotorA.init();
|
||||||
|
MotorA.torque(255);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
MotorA.direction(FORWARD);
|
||||||
|
delay(1000);
|
||||||
|
MotorA.direction(BACKWARD);
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
|
||||||
39
software/apps/Music/Basic_MIDI/Basic_MIDI.ino
Normal file
39
software/apps/Music/Basic_MIDI/Basic_MIDI.ino
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
|
||||||
|
// This needs to be in all sketches at the moment
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// The Music and Midi objects are automatically instantiated when the header file is included.
|
||||||
|
// Make calls to the Music and Midi objects with "Music.function(args)" and "Midi.function(args)"
|
||||||
|
// You still need to call Music.init() and Midi.init() in the setup() function below.
|
||||||
|
#include <Music.h>
|
||||||
|
#include <Midi.h>
|
||||||
|
|
||||||
|
// variables for this sketch
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
|
||||||
|
// We initialise the sound engine by calling Music.init() which outputs a tone
|
||||||
|
Music.init();
|
||||||
|
|
||||||
|
// We initialize the MIDI engine by calling Midi.init()
|
||||||
|
Midi.init();
|
||||||
|
|
||||||
|
// Choosing the sine wave oscillator (optional since this is already the default).
|
||||||
|
Music.setSaw();
|
||||||
|
|
||||||
|
// Detuning the three oscillators heavily to create more movement in the sound.
|
||||||
|
Music.setDetune(0.01);
|
||||||
|
|
||||||
|
// Enabling envelope, otherwise the synth would just play constant tones.
|
||||||
|
Music.enableEnvelope();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
// The MIDI must be used with the external
|
||||||
|
// "IAC2Serial.pde" Processing sketch.
|
||||||
|
Midi.checkMidi();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
21
software/apps/Music/Minimal/Minimal.ino
Normal file
21
software/apps/Music/Minimal/Minimal.ino
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
// This needs to be in all sketches at the moment
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// The Music and Midi objects are automatically instantiated when the header file is included.
|
||||||
|
// Make calls to the Music and Midi objects with "Music.function(args)" and "Midi.function(args)"
|
||||||
|
// You still need to call Music.init() and Midi.init() in the setup() function below.
|
||||||
|
#include <Music.h>
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
// We initialise the sound engine by calling Music.init() which outputs a tone
|
||||||
|
Music.init();
|
||||||
|
|
||||||
|
Music.setSquare();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
|
||||||
|
// This needs to be in all sketches at the moment
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// The Music and Midi objects are automatically instantiated when the header file is included.
|
||||||
|
// Make calls to the Music and Midi objects with "Music.function(args)" and "Midi.function(args)"
|
||||||
|
// You still need to call Music.init() and Midi.init() in the setup() function below.
|
||||||
|
#include <Music.h>
|
||||||
|
|
||||||
|
// variables for this sketch
|
||||||
|
boolean noteIsOn = false;
|
||||||
|
int note = 48;
|
||||||
|
|
||||||
|
long time = 0;
|
||||||
|
long lastTime = 0;
|
||||||
|
long beatTime = 1000;
|
||||||
|
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
|
||||||
|
// We initialise the sound engine by calling Music.init() which outputs a tone
|
||||||
|
Music.init();
|
||||||
|
|
||||||
|
// enabling the envelope lets us define an gain envelope for the synth
|
||||||
|
// without having to specify it in our loop() or physics code.
|
||||||
|
Music.enableEnvelope();
|
||||||
|
Music.setAttack(0x0FFF);
|
||||||
|
Music.setDecay(0x0004);
|
||||||
|
Music.setSustain(0x00FF);
|
||||||
|
Music.setRelease(0x0008);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
// This short routine loops note over and over again
|
||||||
|
time = millis();
|
||||||
|
if(time - lastTime > beatTime) {
|
||||||
|
if(!noteIsOn) {
|
||||||
|
Music.noteOn(note);
|
||||||
|
noteIsOn = true;
|
||||||
|
} else {
|
||||||
|
Music.noteOff();
|
||||||
|
noteIsOn = false;
|
||||||
|
}
|
||||||
|
lastTime = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@ -1,5 +1,6 @@
|
|||||||
#define NUM_OSCILLATORS 3
|
|
||||||
#define BIT_DEPTH 12
|
// This needs to be in all sketches at the moment
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
// The Music and Midi objects are automatically instantiated when the header file is included.
|
// The Music and Midi objects are automatically instantiated when the header file is included.
|
||||||
// Make calls to the Music and Midi objects with "Music.function(args)" and "Midi.function(args)"
|
// Make calls to the Music and Midi objects with "Music.function(args)" and "Midi.function(args)"
|
||||||
@ -23,7 +24,7 @@ void setup() {
|
|||||||
Music.init();
|
Music.init();
|
||||||
|
|
||||||
// Choosing the sine wave oscillator (optional since this is already the default).
|
// Choosing the sine wave oscillator (optional since this is already the default).
|
||||||
Music.setWaveform(0);
|
Music.setSine();
|
||||||
|
|
||||||
// Setting the initial frequency for all three oscillators.
|
// Setting the initial frequency for all three oscillators.
|
||||||
Music.setFrequency(c);
|
Music.setFrequency(c);
|
||||||
62
software/apps/Music/Up_and_down/Up_and_down.ino
Normal file
62
software/apps/Music/Up_and_down/Up_and_down.ino
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
|
||||||
|
// This needs to be in all sketches at the moment
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// The Music and Midi objects are automatically instantiated when the header file is included.
|
||||||
|
// Make calls to the Music and Midi objects with "Music.function(args)" and "Midi.function(args)"
|
||||||
|
// You still need to call Music.init() and Midi.init() in the setup() function below.
|
||||||
|
#include <Music.h>
|
||||||
|
|
||||||
|
// variables for this sketch
|
||||||
|
boolean noteIsOn = false;
|
||||||
|
int n = 0;
|
||||||
|
int dir = 1;
|
||||||
|
int rootNote = 48;
|
||||||
|
int note[] = {0,2,3,5,7,9,10,12,14};
|
||||||
|
|
||||||
|
long time = 0;
|
||||||
|
long lastTime = 0;
|
||||||
|
long beatTime = 100;
|
||||||
|
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
|
||||||
|
// We initialise the sound engine by calling Music.init() which outputs a tone
|
||||||
|
Music.init();
|
||||||
|
|
||||||
|
// enabling the envelope lets us define an gain envelope for the synth
|
||||||
|
// without having to specify it in our loop() or physics code.
|
||||||
|
Music.enableEnvelope();
|
||||||
|
Music.setAttack(0x00FF);
|
||||||
|
Music.setDecay(0x0008);
|
||||||
|
Music.setSustain(0x00FF);
|
||||||
|
Music.setRelease(0x0008);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
// This short routine loops note over and over again
|
||||||
|
time = millis();
|
||||||
|
if(time - lastTime > beatTime) {
|
||||||
|
if(!noteIsOn) {
|
||||||
|
Music.noteOn(rootNote+note[n]);
|
||||||
|
noteIsOn = true;
|
||||||
|
n = n + dir;
|
||||||
|
if(n > 7)
|
||||||
|
{
|
||||||
|
dir = -1;
|
||||||
|
}
|
||||||
|
else if(n < 1)
|
||||||
|
{
|
||||||
|
dir = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Music.noteOff();
|
||||||
|
noteIsOn = false;
|
||||||
|
}
|
||||||
|
lastTime = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
|
||||||
|
// This needs to be in all sketches at the moment
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// The Music and Midi objects are automatically instantiated when the header file is included.
|
||||||
|
// Make calls to the Music and Midi objects with "Music.function(args)" and "Midi.function(args)"
|
||||||
|
// You still need to call Music.init() and Midi.init() in the setup() function below.
|
||||||
|
#include <Music.h>
|
||||||
|
|
||||||
|
// variables for this sketch
|
||||||
|
boolean noteIsOn = false;
|
||||||
|
int n = 0;
|
||||||
|
int dir = 1;
|
||||||
|
int rootNote = 48;
|
||||||
|
int note[] = {0,2,3,5,7,9,10,12,14};
|
||||||
|
|
||||||
|
long time = 0;
|
||||||
|
long lastTime = 0;
|
||||||
|
long beatTime = 100;
|
||||||
|
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
|
||||||
|
// We initialise the sound engine by calling Music.init() which outputs a tone
|
||||||
|
Music.init();
|
||||||
|
|
||||||
|
// enabling the envelope lets us define an gain envelope for the synth
|
||||||
|
// without having to specify it in our loop() or physics code.
|
||||||
|
Music.enableEnvelope();
|
||||||
|
Music.setAttack(8);
|
||||||
|
Music.setDecay(70);
|
||||||
|
Music.setSustain(24);
|
||||||
|
Music.setRelease(90);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
// This short routine loops note over and over again
|
||||||
|
time = millis();
|
||||||
|
if(time - lastTime > beatTime) {
|
||||||
|
if(!noteIsOn) {
|
||||||
|
Music.noteOn(rootNote+note[n]);
|
||||||
|
noteIsOn = true;
|
||||||
|
n = n + dir;
|
||||||
|
if(n > 7)
|
||||||
|
{
|
||||||
|
dir = -1;
|
||||||
|
}
|
||||||
|
else if(n < 1)
|
||||||
|
{
|
||||||
|
dir = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Music.noteOff();
|
||||||
|
noteIsOn = false;
|
||||||
|
}
|
||||||
|
lastTime = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@ -1,33 +1,31 @@
|
|||||||
// You can set the number of oscillators (1 to 3) and the bit depth of the
|
|
||||||
// oscillators (8 or 12 bit). These settings must be defined before the
|
|
||||||
// inclusion of the MMM library files. They default to 1 osciallator
|
|
||||||
// and 8bit respectively.
|
|
||||||
|
|
||||||
#define NUM_OSCILLATORS 3
|
// This needs to be in all sketches at the moment
|
||||||
#define BIT_DEPTH 8
|
#include <stdint.h>
|
||||||
|
|
||||||
// The Music object is automatically instantiated when the header file is
|
// The Music and Midi objects are automatically instantiated when the header file is included.
|
||||||
// included. Make calls to the Music objects with "Music.function(args)".
|
// Make calls to the Music and Midi objects with "Music.function(args)" and "Midi.function(args)"
|
||||||
// You still need to call Music.init() in the setup() function below.
|
// You still need to call Music.init() and Midi.init() in the setup() function below.
|
||||||
#include <Music.h>
|
#include <Music.h>
|
||||||
|
|
||||||
|
// variables for this sketch
|
||||||
boolean noteIsOn = false;
|
boolean noteIsOn = false;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
int dir = 1;
|
int dir = 1;
|
||||||
int rootNote = 36;
|
int rootNote = 26;
|
||||||
int note[] = {0,2,3,5,7,9,10,12,14};
|
int note[] = {0,2,3,5,7,9,10,12,14};
|
||||||
|
|
||||||
long time = 0;
|
long time = 0;
|
||||||
long lastTime = 0;
|
long lastTime = 0;
|
||||||
long timeDelay = 80;
|
long beatTime = 100;
|
||||||
|
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
|
|
||||||
// We initialise the sound engine by calling Music.init() which outputs a tone
|
// We initialise the sound engine by calling Music.init() which outputs a tone
|
||||||
Music.init();
|
Music.init();
|
||||||
|
|
||||||
// Choosing the square wave oscillator.
|
// Choosing the square wave oscillator instead of the sine wave.
|
||||||
Music.setWaveform(DIGI3);
|
Music.setSquare();
|
||||||
|
|
||||||
// Detuning the three oscillators slightly to create movement in the sound.
|
// Detuning the three oscillators slightly to create movement in the sound.
|
||||||
Music.setDetune(0.008);
|
Music.setDetune(0.008);
|
||||||
@ -39,14 +37,14 @@ void setup() {
|
|||||||
Music.setDecay(90);
|
Music.setDecay(90);
|
||||||
Music.setSustain(48);
|
Music.setSustain(48);
|
||||||
Music.setRelease(64);
|
Music.setRelease(64);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
|
||||||
// This short routine loops note over and over again
|
// This short routine loops note over and over again
|
||||||
time = millis();
|
time = millis();
|
||||||
if(time - lastTime > timeDelay) {
|
if(time - lastTime > beatTime) {
|
||||||
if(!noteIsOn) {
|
if(!noteIsOn) {
|
||||||
Music.noteOn(rootNote+note[n]);
|
Music.noteOn(rootNote+note[n]);
|
||||||
noteIsOn = true;
|
noteIsOn = true;
|
||||||
34
software/apps/Music/appConnector/appConnector.ino
Normal file
34
software/apps/Music/appConnector/appConnector.ino
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
|
||||||
|
// This needs to be in all sketches at the moment
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// The Music and Midi objects are automatically instantiated when the header file is included.
|
||||||
|
// Make calls to the Music and Midi objects with "Music.function(args)" and "Midi.function(args)"
|
||||||
|
// You still need to call Music.init() and Midi.init() in the setup() function below.
|
||||||
|
#include <Music.h>
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
// We initialise the sound engine by calling Music.init() which outputs a tone
|
||||||
|
Music.init();
|
||||||
|
|
||||||
|
Music.setSquare();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void serialEvent() {
|
||||||
|
while (Serial.available()) {
|
||||||
|
// get the new byte:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int inChar = (int)Serial.read();
|
||||||
|
if (inChar == '\n') {
|
||||||
|
stringComplete = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -1,113 +0,0 @@
|
|||||||
import controlP5.*;
|
|
||||||
import processing.serial.*;
|
|
||||||
|
|
||||||
//Plots
|
|
||||||
ScopePlot plotA;
|
|
||||||
ScopePlot plotB;
|
|
||||||
ScopePlotDouble plotC;
|
|
||||||
|
|
||||||
//Communication with MMM boards
|
|
||||||
Protocol proto;
|
|
||||||
|
|
||||||
//Serial port
|
|
||||||
Serial p;
|
|
||||||
|
|
||||||
//Controlers
|
|
||||||
ControlP5 cp5;
|
|
||||||
SliderCallback scb;
|
|
||||||
|
|
||||||
// (k)
|
|
||||||
float kmin = 0.0f;
|
|
||||||
float kmax = 7.0f;
|
|
||||||
float k = 0.2f;
|
|
||||||
Slider k_slider;
|
|
||||||
|
|
||||||
// (m)
|
|
||||||
float mmin = 0.0f;
|
|
||||||
float mmax = 7.0f;
|
|
||||||
float m = 1.0f;
|
|
||||||
Slider m_slider;
|
|
||||||
|
|
||||||
// (d)
|
|
||||||
float dmin = 0.0f;
|
|
||||||
float dmax = 7.0f;
|
|
||||||
float d = 0.02f;
|
|
||||||
Slider d_slider;
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
|
|
||||||
int b = 15;
|
|
||||||
int h = 300;//(displayHeight / 4) - (3*b);
|
|
||||||
int w = displayWidth / 2;
|
|
||||||
|
|
||||||
plotA = new ScopePlot("Force", w, h, b, b + b, 512, true);
|
|
||||||
plotB = new ScopePlot("Velocity", w, h, b, h + 4*b, 512, true);
|
|
||||||
plotC = new ScopePlotDouble("Position Estimate", w, h, b, 2*h + 6*b, 512, true);
|
|
||||||
|
|
||||||
p = new Serial(this, Serial.list()[0], 9600);
|
|
||||||
proto = new Protocol(p);
|
|
||||||
|
|
||||||
// Controls
|
|
||||||
cp5 = new ControlP5(this);
|
|
||||||
scb = new SliderCallback();
|
|
||||||
|
|
||||||
int sw = w / 3;
|
|
||||||
|
|
||||||
k_slider = cp5.addSlider("k", kmin, kmax, b, b-5, sw - b, b-5);
|
|
||||||
k_slider.setColorForeground(color(127,34,255));
|
|
||||||
k_slider.setColorBackground(color(50,50,50));
|
|
||||||
k_slider.addListener(scb);
|
|
||||||
|
|
||||||
m_slider = cp5.addSlider("m", mmin, mmax, 2*b + sw, b-5, sw - b, b-5);
|
|
||||||
m_slider.setColorForeground(color(127,34,255));
|
|
||||||
m_slider.setColorBackground(color(50,50,50));
|
|
||||||
m_slider.addListener(scb);
|
|
||||||
|
|
||||||
d_slider = cp5.addSlider("d", dmin, dmax, 3*b + 2*sw, b-5, sw - b, b-5);
|
|
||||||
d_slider.setColorForeground(color(127,34,255));
|
|
||||||
d_slider.setColorBackground(color(50,50,50));
|
|
||||||
d_slider.addListener(scb);
|
|
||||||
|
|
||||||
size(w + 60, displayHeight - (h + (3*b)));
|
|
||||||
//size(w + 60, 800);
|
|
||||||
//size(600, 800);
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw() {
|
|
||||||
background(0);
|
|
||||||
plotA.draw();
|
|
||||||
plotB.draw();
|
|
||||||
plotC.draw();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
void mouseDragged()
|
|
||||||
{
|
|
||||||
plotA.mdata(mouseX, mouseY);
|
|
||||||
plotB.mdata(mouseX, mouseY);
|
|
||||||
plotC.mdata(mouseX, mouseY);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mouseClicked()
|
|
||||||
{
|
|
||||||
plotA.mdata(mouseX, mouseY);
|
|
||||||
plotB.mdata(mouseX, mouseY);
|
|
||||||
plotC.mdata(mouseX, mouseY);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void serialEvent (Serial myPort) {
|
|
||||||
proto.processData();
|
|
||||||
plotA.data(proto.F);
|
|
||||||
plotB.data(proto.V);
|
|
||||||
plotC.data(proto.X - 512, proto.Xin - 512);
|
|
||||||
}
|
|
||||||
|
|
||||||
class SliderCallback implements ControlListener {
|
|
||||||
public void controlEvent(ControlEvent ev) {
|
|
||||||
p.write(new String(ev.controller().name()+ev.controller().value()+";"));
|
|
||||||
//println(ev.controller().name() + ": " + ev.controller().value());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
import processing.serial.*;
|
|
||||||
|
|
||||||
class Protocol {
|
|
||||||
Serial port; // The serial port
|
|
||||||
Protocol() {;}
|
|
||||||
|
|
||||||
int F, V, X, Xin;
|
|
||||||
|
|
||||||
Protocol(Serial p) {
|
|
||||||
port = p;
|
|
||||||
port.bufferUntil('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
void processData() {
|
|
||||||
String in = port.readStringUntil('\n');
|
|
||||||
if(in != null){
|
|
||||||
String[] t = splitTokens(in);
|
|
||||||
F = int(t[0]);
|
|
||||||
V = int(t[1]);
|
|
||||||
X = int(t[2]);
|
|
||||||
Xin = int(t[3]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,161 +0,0 @@
|
|||||||
class ScopePlot {
|
|
||||||
|
|
||||||
int d = 4, s = 4;
|
|
||||||
int indx, max, min;
|
|
||||||
int w, h;
|
|
||||||
int px, py;
|
|
||||||
int by;
|
|
||||||
int[] values;
|
|
||||||
int[] pixelvalues;
|
|
||||||
String title;
|
|
||||||
|
|
||||||
ScopePlot(String t, int w, int h, int x, int y, int maxval, boolean mid){
|
|
||||||
this.title = t;
|
|
||||||
this.w = w + d;
|
|
||||||
this.h = h + d;
|
|
||||||
this.indx = s;
|
|
||||||
this.px = x - d;
|
|
||||||
this.py = y + d;
|
|
||||||
this.max = maxval;
|
|
||||||
this.min = -maxval;
|
|
||||||
noFill();
|
|
||||||
textSize(12);
|
|
||||||
values = new int[w / s];
|
|
||||||
pixelvalues = new int[w / s];
|
|
||||||
if(mid) by = h / 2;
|
|
||||||
else by = this.h;
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw(){
|
|
||||||
|
|
||||||
pushMatrix();
|
|
||||||
|
|
||||||
translate(px, py);
|
|
||||||
|
|
||||||
stroke(255,255,255);
|
|
||||||
line( -d, h, w + d + d, h);
|
|
||||||
line( 0, -d, 0, h + d);
|
|
||||||
line( -d, 0, w + d + d, 0);
|
|
||||||
line( w + d, h + d, w + d , -d);
|
|
||||||
|
|
||||||
fill(255,255,255);
|
|
||||||
textSize(10);
|
|
||||||
text(title, d, -d+2);
|
|
||||||
noFill();
|
|
||||||
if(by != h) {
|
|
||||||
line(-d, by, w + d, by);
|
|
||||||
text(Integer.toString(this.max), w + d + d + d, 0);
|
|
||||||
text(Integer.toString(this.min), w + d + d + d, h + d);
|
|
||||||
} else {
|
|
||||||
text(Integer.toString(this.max), w + d + d + d, 0);
|
|
||||||
text(Integer.toString(values.length), w + d + d + d, h + d + d + d);
|
|
||||||
}
|
|
||||||
|
|
||||||
int x = s;
|
|
||||||
for(int i = 0; i < pixelvalues.length; i++) {
|
|
||||||
stroke(127,34,255);
|
|
||||||
line(x, by, x, by - pixelvalues[i]);
|
|
||||||
stroke(255,34,127);
|
|
||||||
if(i == indx - 1) {
|
|
||||||
stroke(255);
|
|
||||||
text(Integer.toString(values[i]), w + d + d + d, by - pixelvalues[i]);
|
|
||||||
}
|
|
||||||
ellipse(x, by - pixelvalues[i], 3, 3);
|
|
||||||
x += s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
popMatrix();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void data(int d) {
|
|
||||||
values[indx] = d;
|
|
||||||
float i = (float) d / (float)this.max;
|
|
||||||
if(by != h) pixelvalues[indx++] = (int)(i * h / 2);
|
|
||||||
else pixelvalues[indx++] = (int)(i * h);
|
|
||||||
indx %= (w / s) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class ScopePlotDouble extends ScopePlot {
|
|
||||||
|
|
||||||
int[] values_second;
|
|
||||||
int[] pixelvalues_second;
|
|
||||||
|
|
||||||
ScopePlotDouble(String t, int w, int h, int x, int y, int maxval, boolean mid){
|
|
||||||
super(t, w, h, x, y, maxval, mid);
|
|
||||||
values_second = new int[values.length];
|
|
||||||
pixelvalues_second = new int[pixelvalues.length];
|
|
||||||
}
|
|
||||||
|
|
||||||
void data(int d0, int d1) {
|
|
||||||
values_second[indx] = d1;
|
|
||||||
float i = (float) d1 / (float)this.max;
|
|
||||||
if(by != h) pixelvalues_second[indx] = (int)(i * h / 2);
|
|
||||||
else pixelvalues_second[indx] = (int)(i * h);
|
|
||||||
super.data(d0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw() {
|
|
||||||
|
|
||||||
pushMatrix();
|
|
||||||
|
|
||||||
translate(px, py);
|
|
||||||
|
|
||||||
int x = s;
|
|
||||||
for(int i = 0; i < pixelvalues_second.length; i++) {
|
|
||||||
stroke(255,34,127);
|
|
||||||
line(x, by, x, by - pixelvalues_second[i]);
|
|
||||||
stroke(127,34,255);
|
|
||||||
if(i == indx - 1) {
|
|
||||||
stroke(255);
|
|
||||||
text(Integer.toString(values_second[i]), w + d + d + d, by - pixelvalues_second[i]);
|
|
||||||
}
|
|
||||||
ellipse(x, by - pixelvalues_second[i], 3, 3);
|
|
||||||
x += s;
|
|
||||||
}
|
|
||||||
|
|
||||||
popMatrix();
|
|
||||||
|
|
||||||
super.draw();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class ScopePlotInteract extends ScopePlot {
|
|
||||||
|
|
||||||
int[] cpoints;
|
|
||||||
int[] cpointsvalues;
|
|
||||||
|
|
||||||
int mx, my;
|
|
||||||
|
|
||||||
ScopePlotInteract(String t, int w, int h, int x, int y, int maxval, boolean mid) {
|
|
||||||
super(t, w, h, x, y, maxval, mid);
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw() {
|
|
||||||
mx = 0;
|
|
||||||
super.draw();
|
|
||||||
}
|
|
||||||
|
|
||||||
void mdata(int mousex, int mousey) {
|
|
||||||
if(mousex < px + w && mousex > px && mousey > py && mousey < py + h) {
|
|
||||||
mx = (mousex - px) / s;
|
|
||||||
my = mousey;
|
|
||||||
if(mx < pixelvalues.length)
|
|
||||||
pixelvalues[mx] = (by + py) - my;
|
|
||||||
// compute real values here
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
else if((mousex > px + w && mousex < px + w + d) || (mousex < px && mousex > px - d) ||
|
|
||||||
(mousey < py && mousey > py - d) || (mousey > py + h && mousey < py + h + d)) {
|
|
||||||
px += (mousex - mx);
|
|
||||||
py += (my - mousey);
|
|
||||||
}
|
|
||||||
mx = mousex;
|
|
||||||
my = mousey;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,82 +0,0 @@
|
|||||||
#include <Motion.h>
|
|
||||||
#include <Motor.h>
|
|
||||||
#include <Music.h>
|
|
||||||
|
|
||||||
char buf[16] = "";
|
|
||||||
|
|
||||||
char b = 'x';
|
|
||||||
String inputString = "";
|
|
||||||
boolean stringComplete = false;
|
|
||||||
|
|
||||||
float k, m, d;
|
|
||||||
|
|
||||||
int cnt = 0;
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
|
|
||||||
// MOTOR
|
|
||||||
MotorA.init();
|
|
||||||
|
|
||||||
// MUSIC
|
|
||||||
Music.init();
|
|
||||||
|
|
||||||
// MOTION
|
|
||||||
MotionA.init(INPUTA0);
|
|
||||||
MotionA.k = 5.2f; // spring
|
|
||||||
MotionA.m = 1.0f; // mass
|
|
||||||
MotionA.d = 8.02f; // damping
|
|
||||||
|
|
||||||
// Serial
|
|
||||||
Serial.begin(9600);
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
|
|
||||||
MotionA.update_mass_spring_damper();
|
|
||||||
|
|
||||||
MotorA.torque(MotionA.F);
|
|
||||||
|
|
||||||
int f = map(abs(MotionA.F), 0, 512, 64, 76);
|
|
||||||
Music.noteOn(f);
|
|
||||||
|
|
||||||
cnt++;
|
|
||||||
|
|
||||||
if(cnt == 10) {
|
|
||||||
sprintf(buf, "%d %d %d %d", (int)MotionA.F, (int)MotionA.V, (int)MotionA.X, (int)MotionA.Xin);
|
|
||||||
Serial.println(buf);
|
|
||||||
cnt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stringComplete) {
|
|
||||||
if(b == 'k') {
|
|
||||||
MotionA.k = convertToFloat(inputString);
|
|
||||||
} else if(b == 'm') {
|
|
||||||
MotionA.m = convertToFloat(inputString);
|
|
||||||
} else if(b == 'd') {
|
|
||||||
MotionA.d = convertToFloat(inputString);
|
|
||||||
}
|
|
||||||
b = 'x';
|
|
||||||
stringComplete = false;
|
|
||||||
inputString = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void serialEvent() {
|
|
||||||
while (Serial.available()) {
|
|
||||||
char inChar = (char)Serial.read();
|
|
||||||
if(inChar == 'k' || inChar == 'm' || inChar == 'd') {
|
|
||||||
b = inChar;
|
|
||||||
} else {
|
|
||||||
if (inChar == ';') {
|
|
||||||
stringComplete = true;
|
|
||||||
} else
|
|
||||||
inputString += inChar;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float convertToFloat(String str) {
|
|
||||||
char buf[16] = "";
|
|
||||||
str.toCharArray(buf, str.length() + 1);
|
|
||||||
return atof(buf);
|
|
||||||
}
|
|
||||||
@ -1,128 +0,0 @@
|
|||||||
import controlP5.*;
|
|
||||||
import processing.serial.*;
|
|
||||||
|
|
||||||
static char NEW = '!';
|
|
||||||
static char OK = '*';
|
|
||||||
static char PRINT = '&';
|
|
||||||
|
|
||||||
ForceProfilePlot fpp;
|
|
||||||
Button send;
|
|
||||||
Button print;
|
|
||||||
|
|
||||||
//Serial port
|
|
||||||
Serial p;
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
|
|
||||||
int b = 15;
|
|
||||||
//int h = (displayHeight / 3); (work in certain resolution)
|
|
||||||
//int w = displayWidth / 2; (work in certain resolution)
|
|
||||||
int w = 720;
|
|
||||||
int h = 300;
|
|
||||||
|
|
||||||
println("w: " + w + " h: " + h);
|
|
||||||
|
|
||||||
fpp = new ForceProfilePlot("Force Profile - Perception Terrain", w, h, b, b, 80, true);
|
|
||||||
|
|
||||||
ControlP5 cp5 = new ControlP5(this);
|
|
||||||
|
|
||||||
send = cp5.addButton("send");
|
|
||||||
send.setPosition(w - 20, 2*h + 2*b + 7);
|
|
||||||
send.setSize(35, 15);
|
|
||||||
send.setColorForeground(color(127,34,255));
|
|
||||||
send.setColorBackground(color(50,50,50));
|
|
||||||
|
|
||||||
print = cp5.addButton("print");
|
|
||||||
print.setPosition(w - 140, 2*h + 2*b + 7);
|
|
||||||
print.setSize(35, 15);
|
|
||||||
print.setColorForeground(color(127,34,255));
|
|
||||||
print.setColorBackground(color(50,50,50));
|
|
||||||
|
|
||||||
size(w + 60, 2*h + 60);
|
|
||||||
|
|
||||||
p = new Serial(this, Serial.list()[0], 9600);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw() {
|
|
||||||
background(0);
|
|
||||||
fpp.draw();
|
|
||||||
|
|
||||||
if(p.available() > 0) {
|
|
||||||
String in = p.readStringUntil('\n');
|
|
||||||
if(in != null) {
|
|
||||||
println(in);
|
|
||||||
String[] t = splitTokens(in);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void mouseDragged() {
|
|
||||||
fpp.drag(mouseX, mouseY);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mouseClicked()
|
|
||||||
{
|
|
||||||
fpp.click(mouseX, mouseY);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mouseReleased() {
|
|
||||||
fpp.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void send() {
|
|
||||||
|
|
||||||
send.setOff();
|
|
||||||
|
|
||||||
p.write(NEW);
|
|
||||||
println("1");
|
|
||||||
while(p.available() <= 0);
|
|
||||||
println("2");
|
|
||||||
char in = p.readChar();
|
|
||||||
println("3");
|
|
||||||
if(in == OK) {
|
|
||||||
println("GO!");
|
|
||||||
int s = 800 / fpp.forces.length;
|
|
||||||
int len = s * (fpp.forces.length - 1);
|
|
||||||
serial_send(len);
|
|
||||||
float dx = 1023.0f / (fpp.forces.length - 1);
|
|
||||||
float ddx = dx / s;
|
|
||||||
for(int i = 0; i < fpp.forces.length-1; i++) {
|
|
||||||
float k = fpp.forces[i];
|
|
||||||
float m = (fpp.forces[i+1] - k) / dx;
|
|
||||||
for(int j = 0; j < s; j++) {
|
|
||||||
int d = (int)(k + m*j);
|
|
||||||
serial_send(d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
send.setOn();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void print() {
|
|
||||||
println("print");
|
|
||||||
print.setOff();
|
|
||||||
p.write(PRINT);
|
|
||||||
while(p.available() <= 0); // block
|
|
||||||
while(p.available() > 0) {
|
|
||||||
String s = p.readStringUntil('#');
|
|
||||||
if(s != null)
|
|
||||||
println(s);
|
|
||||||
}
|
|
||||||
send.setOn();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean serial_send(int i) {
|
|
||||||
p.clear();
|
|
||||||
char msb = (char) (i / 256);
|
|
||||||
char lsb = (char) (i & 0xff);
|
|
||||||
p.write(lsb);
|
|
||||||
p.write(msb);
|
|
||||||
while(p.available() <= 0);
|
|
||||||
char in = p.readChar();
|
|
||||||
return (in == OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,144 +0,0 @@
|
|||||||
class ForceProfilePlot {
|
|
||||||
|
|
||||||
int d = 4, s = 4;
|
|
||||||
float steps = 4;
|
|
||||||
int max, min;
|
|
||||||
int w, h, by;
|
|
||||||
int px, py;
|
|
||||||
|
|
||||||
int res = 800;
|
|
||||||
|
|
||||||
int[] forces;
|
|
||||||
int[] forces_pixelvalues;
|
|
||||||
|
|
||||||
int mx, my;
|
|
||||||
|
|
||||||
String title;
|
|
||||||
|
|
||||||
TerrainPlot tr;
|
|
||||||
|
|
||||||
|
|
||||||
ForceProfilePlot(String t, int w, int h, int x, int y, int nbr_ctrpoints, boolean terrain) {
|
|
||||||
this.title = t;
|
|
||||||
this.w = w + d;
|
|
||||||
this.h = h + d;
|
|
||||||
this.px = x - d;
|
|
||||||
this.py = y + d;
|
|
||||||
this.max = 512;
|
|
||||||
this.min = -512;
|
|
||||||
noFill();
|
|
||||||
textSize(12);
|
|
||||||
this.s = 800 / nbr_ctrpoints;
|
|
||||||
this.steps = (float)(w + 2*d) / (nbr_ctrpoints - 1);
|
|
||||||
this.by = h / 2;
|
|
||||||
forces = new int[nbr_ctrpoints]; // zeros???
|
|
||||||
forces_pixelvalues = new int[nbr_ctrpoints];
|
|
||||||
if (terrain)
|
|
||||||
tr = new TerrainPlot("Terrain", w, h, x, y + h + 2 * d, nbr_ctrpoints, steps);
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw() {
|
|
||||||
|
|
||||||
pushMatrix();
|
|
||||||
|
|
||||||
translate(px, py);
|
|
||||||
|
|
||||||
stroke(255, 255, 255);
|
|
||||||
line( -d, h, w + d + d, h);
|
|
||||||
line( 0, -d, 0, h + d);
|
|
||||||
line( -d, 0, w + d + d, 0);
|
|
||||||
line( w + d, h + d, w + d, -d);
|
|
||||||
|
|
||||||
fill(255, 255, 255);
|
|
||||||
textSize(10);
|
|
||||||
text(title, d, -d+2);
|
|
||||||
noFill();
|
|
||||||
line(-d, by, w + d, by);
|
|
||||||
text(Integer.toString(this.max), w + d + d + d, 0);
|
|
||||||
text(Integer.toString(this.min), w + d + d + d, h + d);
|
|
||||||
|
|
||||||
float x = 0;
|
|
||||||
for (int i = 0; i < forces_pixelvalues.length; i++) {
|
|
||||||
|
|
||||||
stroke(127, 34, 255);
|
|
||||||
line(x, by, x, by - forces_pixelvalues[i]);
|
|
||||||
|
|
||||||
stroke(255, 34, 127);
|
|
||||||
ellipse(x, by - forces_pixelvalues[i], 5, 5);
|
|
||||||
|
|
||||||
if (i != 0) {
|
|
||||||
stroke(255, 255, 255);
|
|
||||||
line(x, by - forces_pixelvalues[i], x - steps, by - forces_pixelvalues[i - 1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(steps > 20)
|
|
||||||
text(Integer.toString(forces[i]), x, by - forces_pixelvalues[i] + (forces[i] < 0 ? 7 : -7));
|
|
||||||
|
|
||||||
x += steps;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (mx > 0) {
|
|
||||||
int e = round((float) mx / steps);
|
|
||||||
stroke(255, 34, 127);
|
|
||||||
line(e * steps, by - forces_pixelvalues[e], mx, my);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
popMatrix();
|
|
||||||
|
|
||||||
if (tr != null) tr.draw();
|
|
||||||
}
|
|
||||||
|
|
||||||
void forces_from_pixels() {
|
|
||||||
for (int i = 0; i < forces_pixelvalues.length; i++) {
|
|
||||||
forces[i] = (int)(((by - forces_pixelvalues[i]) / h * 2) * 512);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void pixels_from_forces() {
|
|
||||||
for (int i = 0; i < forces.length; i++) {
|
|
||||||
forces_pixelvalues[i] = (int)(((float) forces[i] / (float)this.max) * h / 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void drag(int mousex, int mousey) {
|
|
||||||
if (hit(mousex, mousey))
|
|
||||||
position_point(mousex, mousey);
|
|
||||||
}
|
|
||||||
|
|
||||||
void click(int mousex, int mousey) {
|
|
||||||
if (hit(mousex, mousey))
|
|
||||||
position_point(mousex, mousey);
|
|
||||||
}
|
|
||||||
|
|
||||||
void release() {
|
|
||||||
mx = -1;
|
|
||||||
my = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void position_point(int mousex, int mousey) {
|
|
||||||
int i = round((float) (mousex - px - d) / steps);
|
|
||||||
forces_pixelvalues[i] = h / 2 - (mousey - py - d);
|
|
||||||
forces[i] = (int)((((float)forces_pixelvalues[i]) / h * 2) * 512);
|
|
||||||
|
|
||||||
my = mousey - py - d;
|
|
||||||
mx = mousex - px - d;
|
|
||||||
|
|
||||||
if (tr != null) {
|
|
||||||
tr.data(forces_pixelvalues);
|
|
||||||
/*
|
|
||||||
if (i > 0)
|
|
||||||
tr.data(i - 1, forces_pixelvalues[i - 1], i, forces_pixelvalues[i]);
|
|
||||||
if (i < forces_pixelvalues.length - 1)
|
|
||||||
tr.data(i, forces_pixelvalues[i], i + 1, forces_pixelvalues[i + 1]);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean hit(int mousex, int mousey) {
|
|
||||||
return (mousex < px + w) && (mousex > px) && (mousey > py) && (mousey < py + h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,95 +0,0 @@
|
|||||||
class TerrainPlot {
|
|
||||||
|
|
||||||
int d = 4;
|
|
||||||
float max, min;
|
|
||||||
int w, h;
|
|
||||||
int px, py;
|
|
||||||
|
|
||||||
float steps_per_index; // this should not exceed step_index;
|
|
||||||
float s, step_index;
|
|
||||||
|
|
||||||
String title;
|
|
||||||
float pixelvalues[];
|
|
||||||
|
|
||||||
TerrainPlot(String t, int w, int h, int x, int y, int nbr_index, float step_index) {
|
|
||||||
this.title = t;
|
|
||||||
this.w = w + d;
|
|
||||||
this.h = h + d;
|
|
||||||
this.px = x - d;
|
|
||||||
this.py = y + d;
|
|
||||||
noFill();
|
|
||||||
textSize(12);
|
|
||||||
this.step_index = step_index;
|
|
||||||
this.steps_per_index = (step_index / 3);
|
|
||||||
this.s = 3;
|
|
||||||
/*
|
|
||||||
|
|
||||||
if(step_index > steps_per_index) {
|
|
||||||
this.s = ((float) step_index / steps_per_index);
|
|
||||||
} else {
|
|
||||||
this.s = step_index;
|
|
||||||
this.steps_per_index = 1;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
pixelvalues = new float[(int)((nbr_index - 1) * steps_per_index) + 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw() {
|
|
||||||
pushMatrix();
|
|
||||||
|
|
||||||
pushMatrix();
|
|
||||||
|
|
||||||
translate(px, py);
|
|
||||||
|
|
||||||
stroke(255, 255, 255);
|
|
||||||
line( -d, h, w + d + d, h);
|
|
||||||
line( 0, -d, 0, h + d);
|
|
||||||
line( -d, 0, w + d + d, 0);
|
|
||||||
line( w + d, h + d, w + d, -d);
|
|
||||||
|
|
||||||
fill(255, 255, 255);
|
|
||||||
textSize(10);
|
|
||||||
//text(title, d, -d+2);
|
|
||||||
|
|
||||||
popMatrix();
|
|
||||||
|
|
||||||
translate(px, py + h);
|
|
||||||
|
|
||||||
for(int i = 0; i < pixelvalues.length; i++) {
|
|
||||||
float y = pixelvalues[i];
|
|
||||||
if(abs(min) > h) {
|
|
||||||
y = (y / abs(min)) * h;
|
|
||||||
}
|
|
||||||
line(i * s, 0, i * s, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
popMatrix();
|
|
||||||
}
|
|
||||||
|
|
||||||
void data(int[] forces_points) {
|
|
||||||
|
|
||||||
float FF = 0;//forces[0]; // forces interpolated
|
|
||||||
float top = 0; // terrain value (integral of forces)
|
|
||||||
float inc; // interpolated slope ( F[i+1] - F[i] ) / s
|
|
||||||
|
|
||||||
max = 0; min = 0;
|
|
||||||
for(int i = 0; i < forces_points.length - 1; i++) {
|
|
||||||
inc = 0.005 * (forces_points[i+1] - forces_points[i]) ;
|
|
||||||
for(int j = 0; j < steps_per_index; j++) {
|
|
||||||
FF += inc;
|
|
||||||
top = top + FF;
|
|
||||||
pixelvalues[(int)(i * steps_per_index) + j] = top;
|
|
||||||
if(top > max) max = top;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < pixelvalues.length; i++) {
|
|
||||||
pixelvalues[i] = (int)(pixelvalues[i] - max);
|
|
||||||
if(pixelvalues[i] < min) {
|
|
||||||
min = pixelvalues[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
mode.id=processing.mode.java.JavaMode
|
|
||||||
mode=Java
|
|
||||||
@ -1,427 +0,0 @@
|
|||||||
String[] knobName = { "FREQ1",
|
|
||||||
"SEMI1",
|
|
||||||
"DETUNE1",
|
|
||||||
"GAIN1",
|
|
||||||
"WAVE1",
|
|
||||||
"FM1",
|
|
||||||
"FREQ2",
|
|
||||||
"SEMI2",
|
|
||||||
"DETUNE2",
|
|
||||||
"GAIN2",
|
|
||||||
"WAVE2",
|
|
||||||
"FM2",
|
|
||||||
"FREQ3",
|
|
||||||
"SEMI3",
|
|
||||||
"DETUNE3",
|
|
||||||
"GAIN3",
|
|
||||||
"WAVE3",
|
|
||||||
"FM3",
|
|
||||||
"ATTACK",
|
|
||||||
"DECAY",
|
|
||||||
"SUSTAIN",
|
|
||||||
"RELEASE"
|
|
||||||
};
|
|
||||||
|
|
||||||
String[] controllerName = { "freq1",
|
|
||||||
"semi1",
|
|
||||||
"detune1",
|
|
||||||
"gain1",
|
|
||||||
"wave1",
|
|
||||||
"fm1",
|
|
||||||
"freq2",
|
|
||||||
"semi2",
|
|
||||||
"detune2",
|
|
||||||
"gain2",
|
|
||||||
"wave2",
|
|
||||||
"fm2",
|
|
||||||
"freq3",
|
|
||||||
"semi3",
|
|
||||||
"detune3",
|
|
||||||
"gain3",
|
|
||||||
"wave3",
|
|
||||||
"fm3",
|
|
||||||
"attack",
|
|
||||||
"decay",
|
|
||||||
"sustain",
|
|
||||||
"release"
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
String[] waveform = { "SINE",
|
|
||||||
"SQUARE",
|
|
||||||
"PULSE",
|
|
||||||
"TRIANGLE",
|
|
||||||
"SAW",
|
|
||||||
"FUZZ",
|
|
||||||
"DIGI1",
|
|
||||||
"DIGI2",
|
|
||||||
"DIGI3",
|
|
||||||
"DIGI4",
|
|
||||||
"NOISE",
|
|
||||||
"DIGI6",
|
|
||||||
"TAN1",
|
|
||||||
"TAN2",
|
|
||||||
"TAN3",
|
|
||||||
"TAN4"
|
|
||||||
};
|
|
||||||
|
|
||||||
Knob freq1,semi1,detune1,gain1,wave1,fm1,freq2,semi2,detune2,gain2,wave2,fm2,freq3,semi3,detune3,gain3,wave3,fm3,attack,decay,sustain,release;
|
|
||||||
Knob[] knobs = {freq1,semi1,detune1,gain1,wave1,fm1,freq2,semi2,detune2,gain2,wave2,fm2,freq3,semi3,detune3,gain3,wave3,fm3,attack,decay,sustain,release};
|
|
||||||
|
|
||||||
int[] knobMin = { 0,-24, 0, 0, 0, 0, 0,-24, 0, 0, 0, 0, 0,-24, 0, 0, 0, 0, 0, 0, 0, 0};
|
|
||||||
int[] knobMax = {127, 24,127,127, 15,127,127, 24,127,127, 15,127,127, 24,127,127, 15,127,127,127,127,127};
|
|
||||||
int[] knobValue = { 40, 0, 64,127, 2, 0, 40, 7, 64,127, 3, 0, 40,-12, 64,127, 5, 0, 12, 96, 64, 72};
|
|
||||||
int[] knobMidiCC= { 10, 11, 12, 13, 14, 15, 20, 21, 22, 23, 24, 25, 30, 31, 32, 33, 34, 35,114,115,116,117};
|
|
||||||
int numKnobs = knobValue.length;
|
|
||||||
|
|
||||||
|
|
||||||
int posX = 20;
|
|
||||||
int posY = 20;
|
|
||||||
int posEnvSpacer = 40;
|
|
||||||
int posW = 65;
|
|
||||||
int posH = 70;
|
|
||||||
int knobS = 40;
|
|
||||||
|
|
||||||
|
|
||||||
void setupKnobs() {
|
|
||||||
|
|
||||||
controlP5 = new ControlP5(this);
|
|
||||||
PFont p = createFont("Georgia",24);
|
|
||||||
controlP5.setControlFont(p,12);
|
|
||||||
controlP5.setColorLabel(color(255,128));
|
|
||||||
/*
|
|
||||||
Textlabel labelFreq = controlP5.addTextlabel("freqLabel","FREQ",posX+posW*0,posY-20);
|
|
||||||
Textlabel labelSemi = controlP5.addTextlabel("semiLabel","SEMI",posX+posW*1,posY-20);
|
|
||||||
Textlabel labelDetune = controlP5.addTextlabel("detuneLabel","DETUNE",posX+posW*2,posY-20);
|
|
||||||
Textlabel labelGain = controlP5.addTextlabel("gainLabel","GAIN",posX+posW*3,posY-20);
|
|
||||||
Textlabel labelWave = controlP5.addTextlabel("waveLabel","WAVE",posX+posW*4,posY-20);
|
|
||||||
|
|
||||||
Textlabel labelAttack = controlP5.addTextlabel("attackLabel","A",posX+16+posW*0,posY+posH*4-20);
|
|
||||||
Textlabel labelDecay = controlP5.addTextlabel("decayLabel","D",posX+16+posW*1,posY+posH*4-20);
|
|
||||||
Textlabel labelsustain = controlP5.addTextlabel("sustainLabel","S",posX+16+posW*2,posY+posH*4-20);
|
|
||||||
Textlabel labelReleasek = controlP5.addTextlabel("releaseLabel","R",posX+16+posW*3,posY+posH*4-20);
|
|
||||||
|
|
||||||
Knob freq1 = controlP5.addKnob("freq1", 0,127,knobValue[0], posX+posW*0,posY+posH*0,knobS);
|
|
||||||
Knob semi1 = controlP5.addKnob("semi1", -24,24,knobValue[1], posX+posW*1,posY+posH*0,knobS);
|
|
||||||
Knob detune1 = controlP5.addKnob("detune1",0,127,knobValue[2], posX+posW*2,posY+posH*0,knobS);
|
|
||||||
Knob gain1 = controlP5.addKnob("gain1", 0,127,knobValue[3], posX+posW*3,posY+posH*0,knobS);
|
|
||||||
Knob wave1 = controlP5.addKnob("wave1", 0,15,knobValue[4], posX+posW*4,posY+posH*0,knobS);
|
|
||||||
*/
|
|
||||||
for(int i=0; i<18; i++) {
|
|
||||||
knobs[i] = controlP5.addKnob(controllerName[i])
|
|
||||||
.setRange(knobMin[i],knobMax[i])
|
|
||||||
.setValue(knobValue[i])
|
|
||||||
.setPosition(posX+posW*(i%6),posY+posH*int(i/6))
|
|
||||||
.setRadius(knobS/2)
|
|
||||||
.setDragDirection(Knob.VERTICAL)
|
|
||||||
.setViewStyle(Knob.ELLIPSE)
|
|
||||||
.setNumberOfTickMarks(knobMax[i]-knobMin[i])
|
|
||||||
.snapToTickMarks(true)
|
|
||||||
.showTickMarks(false);
|
|
||||||
/*
|
|
||||||
if(i%6==1) {
|
|
||||||
knobs[i].setNumberOfTickMarks(49)
|
|
||||||
.snapToTickMarks(true)
|
|
||||||
.showTickMarks(false);
|
|
||||||
}
|
|
||||||
if(i%6==4) {
|
|
||||||
knobs[i].setNumberOfTickMarks(16)
|
|
||||||
.snapToTickMarks(true)
|
|
||||||
.showTickMarks(false);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
for(int i=18; i<22; i++) {
|
|
||||||
knobs[i] = controlP5.addKnob(controllerName[i])
|
|
||||||
.setRange(knobMin[i],knobMax[i])
|
|
||||||
.setValue(knobValue[i])
|
|
||||||
.setPosition(posX+posW*(i%6),posY+posEnvSpacer+posH*int(i/6))
|
|
||||||
.setRadius(knobS/2)
|
|
||||||
.setDragDirection(Knob.VERTICAL)
|
|
||||||
.setViewStyle(Knob.ELLIPSE);
|
|
||||||
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
Knob freq2 = controlP5.addKnob("freq2", 0,127,knobValue[5], posX+posW*0,posY+posH*1,knobS);
|
|
||||||
Knob semi2 = controlP5.addKnob("semi2", -24,24,knobValue[6], posX+posW*1,posY+posH*1,knobS);
|
|
||||||
Knob detune2 = controlP5.addKnob("detune2",0,127,knobValue[7], posX+posW*2,posY+posH*1,knobS);
|
|
||||||
Knob gain2 = controlP5.addKnob("gain2", 0,127,knobValue[8], posX+posW*3,posY+posH*1,knobS);
|
|
||||||
Knob wave2 = controlP5.addKnob("wave2", 0,15,knobValue[9], posX+posW*4,posY+posH*1,knobS);
|
|
||||||
|
|
||||||
Knob freq3 = controlP5.addKnob("freq3", 0,127,knobValue[10], posX+posW*0,posY+posH*2,knobS);
|
|
||||||
Knob semi3 = controlP5.addKnob("semi3", -24,24,knobValue[11], posX+posW*1,posY+posH*2,knobS);
|
|
||||||
Knob detune3 = controlP5.addKnob("detune3",0,127,knobValue[12], posX+posW*2,posY+posH*2,knobS);
|
|
||||||
Knob gain3 = controlP5.addKnob("gain3", 0,127,knobValue[13], posX+posW*3,posY+posH*2,knobS);
|
|
||||||
Knob wave3 = controlP5.addKnob("wave3", 0,15,knobValue[14], posX+posW*4,posY+posH*2,knobS);
|
|
||||||
|
|
||||||
Knob attack = controlP5.addKnob("attack", 0,127,knobValue[15], posX+posW*0, posY+posH*4, knobS);
|
|
||||||
Knob decay = controlP5.addKnob("decay", 0,127,knobValue[16], posX+posW*1, posY+posH*4, knobS);
|
|
||||||
Knob sustain = controlP5.addKnob("sustain",0,127,knobValue[17], posX+posW*2, posY+posH*4, knobS);
|
|
||||||
Knob release = controlP5.addKnob("release",0,127,knobValue[18], posX+posW*3, posY+posH*4, knobS);
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void writeKnobValues() {
|
|
||||||
textAlign(CENTER);
|
|
||||||
fill(255);
|
|
||||||
text("FREQ",40,30);
|
|
||||||
text("SEMI",100,30);
|
|
||||||
text("DETUNE",160,30);
|
|
||||||
text("GAIN",220,30);
|
|
||||||
text("WAVE",280,30);
|
|
||||||
|
|
||||||
text("A",40,270);
|
|
||||||
text("D",100,270);
|
|
||||||
text("S",160,270);
|
|
||||||
text("R",220,270);
|
|
||||||
|
|
||||||
|
|
||||||
fill(128);
|
|
||||||
text(knobValue[0],40,90);
|
|
||||||
text(knobValue[1],100,90);
|
|
||||||
text(knobValue[2],160,90);
|
|
||||||
text(knobValue[3],220,90);
|
|
||||||
text(waveform[knobValue[4]],280,90);
|
|
||||||
text(knobValue[5],40,150);
|
|
||||||
text(knobValue[6],100,150);
|
|
||||||
text(knobValue[7],160,150);
|
|
||||||
text(knobValue[8],220,150);
|
|
||||||
text(waveform[knobValue[9]],280,150);
|
|
||||||
text(knobValue[10],40,210);
|
|
||||||
text(knobValue[11],100,210);
|
|
||||||
text(knobValue[12],160,210);
|
|
||||||
text(knobValue[13],220,210);
|
|
||||||
text(waveform[knobValue[14]],280,210);
|
|
||||||
text(knobValue[15],40,330);
|
|
||||||
text(knobValue[16],100,330);
|
|
||||||
text(knobValue[17],160,330);
|
|
||||||
text(knobValue[18],220,330);
|
|
||||||
}
|
|
||||||
|
|
||||||
void freq1(int val)
|
|
||||||
{
|
|
||||||
int knob = 0;
|
|
||||||
if(knobValue[knob] != val) {
|
|
||||||
knobValue[knob] = val;
|
|
||||||
if(printChange) println(knobName[knob] + " is: " + (int)(pow(2,(knobValue[knob]-69)/12.0)*440) + " Hz");
|
|
||||||
//(2^((p-69)/12))*440
|
|
||||||
sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void semi1(int val)
|
|
||||||
{
|
|
||||||
int knob = 1;
|
|
||||||
if(knobValue[knob] != val) {
|
|
||||||
knobValue[knob] = val;
|
|
||||||
if(printChange) println(knobName[knob] + " is: " + knobValue[knob]);
|
|
||||||
int semi =(knobValue[knob]+24)*2+16;
|
|
||||||
sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)semi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void detune1(int val)
|
|
||||||
{
|
|
||||||
int knob = 2;
|
|
||||||
if(knobValue[knob] != val) {
|
|
||||||
knobValue[knob] = val;
|
|
||||||
if(printChange) println(knobName[knob] + " is: " + map(knobValue[knob],0,127,-100,100)*0.0005946);
|
|
||||||
sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void gain1(int val)
|
|
||||||
{
|
|
||||||
int knob = 3;
|
|
||||||
if(knobValue[knob] != val) {
|
|
||||||
knobValue[knob] = val;
|
|
||||||
if(printChange) println(knobName[knob] + " is: " + knobValue[knob]/127.0);
|
|
||||||
sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void wave1(int val)
|
|
||||||
{
|
|
||||||
int knob = 4;
|
|
||||||
if(knobValue[knob] != val) {
|
|
||||||
knobValue[knob] = val;
|
|
||||||
if(printChange) println(knobName[knob] + " is: " + knobValue[knob] + " (" + waveform[knobValue[knob]] + ")");
|
|
||||||
sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)(knobValue[knob]*8));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void fm1(int val)
|
|
||||||
{
|
|
||||||
int knob = 5;
|
|
||||||
if(knobValue[knob] != val) {
|
|
||||||
knobValue[knob] = val;
|
|
||||||
if(printChange) println(knobName[knob] + " is: " + knobValue[knob]);
|
|
||||||
sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void freq2(int val)
|
|
||||||
{
|
|
||||||
int knob = 6;
|
|
||||||
if(knobValue[knob] != val) {
|
|
||||||
knobValue[knob] = val;
|
|
||||||
if(printChange) println(knobName[knob] + " is: " + (int)(pow(2,(knobValue[knob]-69)/12.0)*440) + " Hz");
|
|
||||||
//(2^((p-69)/12))*440
|
|
||||||
sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void semi2(int val)
|
|
||||||
{
|
|
||||||
int knob = 7;
|
|
||||||
if(knobValue[knob] != val) {
|
|
||||||
knobValue[knob] = val;
|
|
||||||
if(printChange) println(knobName[knob] + " is: " + knobValue[knob]);
|
|
||||||
int semi =(knobValue[knob]+24)*2+16;
|
|
||||||
sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)semi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void detune2(int val)
|
|
||||||
{
|
|
||||||
int knob = 8;
|
|
||||||
if(knobValue[knob] != val) {
|
|
||||||
knobValue[knob] = val;
|
|
||||||
if(printChange) println(knobName[knob] + " is: " + map(knobValue[knob],0,127,-100,100)*0.0005946);
|
|
||||||
sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void gain2(int val)
|
|
||||||
{
|
|
||||||
int knob = 9;
|
|
||||||
if(knobValue[knob] != val) {
|
|
||||||
knobValue[knob] = val;
|
|
||||||
if(printChange) println(knobName[knob] + " is: " + knobValue[knob]/127.0);
|
|
||||||
sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void wave2(int val)
|
|
||||||
{
|
|
||||||
int knob = 10;
|
|
||||||
if(knobValue[knob] != val) {
|
|
||||||
knobValue[knob] = val;
|
|
||||||
if(printChange) println(knobName[knob] + " is: " + knobValue[knob] + " (" + waveform[knobValue[knob]] + ")");
|
|
||||||
sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)(knobValue[knob]*8));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void fm2(int val)
|
|
||||||
{
|
|
||||||
int knob = 11;
|
|
||||||
if(knobValue[knob] != val) {
|
|
||||||
knobValue[knob] = val;
|
|
||||||
if(printChange) println(knobName[knob] + " is: " + knobValue[knob]);
|
|
||||||
sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void freq3(int val)
|
|
||||||
{
|
|
||||||
int knob = 12;
|
|
||||||
if(knobValue[knob] != val) {
|
|
||||||
knobValue[knob] = val;
|
|
||||||
if(printChange) println(knobName[knob] + " is: " + (int)(pow(2,(knobValue[knob]-69)/12.0)*440) + " Hz");
|
|
||||||
sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void semi3(int val)
|
|
||||||
{
|
|
||||||
int knob = 13;
|
|
||||||
if(knobValue[knob] != val) {
|
|
||||||
knobValue[knob] = val;
|
|
||||||
if(printChange) println(knobName[knob] + " is: " + knobValue[knob]);
|
|
||||||
int semi =(knobValue[knob]+24)*2+16;
|
|
||||||
sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)semi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void detune3(int val)
|
|
||||||
{
|
|
||||||
int knob = 14;
|
|
||||||
if(knobValue[knob] != val) {
|
|
||||||
knobValue[knob] = val;
|
|
||||||
if(printChange) println(knobName[knob] + " is: " + map(knobValue[knob],0,127,-100,100)*0.0005946);
|
|
||||||
sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void gain3(int val)
|
|
||||||
{
|
|
||||||
int knob = 15;
|
|
||||||
if(knobValue[knob] != val) {
|
|
||||||
knobValue[knob] = val;
|
|
||||||
if(printChange) println(knobName[knob] + " is: " + knobValue[knob]/127.0);
|
|
||||||
sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void wave3(int val)
|
|
||||||
{
|
|
||||||
int knob = 16;
|
|
||||||
if(knobValue[knob] != val) {
|
|
||||||
knobValue[knob] = val;
|
|
||||||
if(printChange) println(knobName[knob] + " is: " + knobValue[knob] + " (" + waveform[knobValue[knob]] + ")");
|
|
||||||
sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)(knobValue[knob]*8));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void fm3(int val)
|
|
||||||
{
|
|
||||||
int knob = 17;
|
|
||||||
if(knobValue[knob] != val) {
|
|
||||||
knobValue[knob] = val;
|
|
||||||
if(printChange) println(knobName[knob] + " is: " + knobValue[knob]);
|
|
||||||
sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void attack(int val)
|
|
||||||
{
|
|
||||||
int knob = 18;
|
|
||||||
if(knobValue[knob] != val) {
|
|
||||||
knobValue[knob] = val;
|
|
||||||
if(printChange) println(knobName[knob] + " is: " + knobValue[knob]);
|
|
||||||
sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void decay(int val)
|
|
||||||
{
|
|
||||||
int knob = 19;
|
|
||||||
if(knobValue[knob] != val) {
|
|
||||||
knobValue[knob] = val;
|
|
||||||
if(printChange) println(knobName[knob] + " is: " + knobValue[knob]);
|
|
||||||
sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void sustain(int val)
|
|
||||||
{
|
|
||||||
int knob = 20;
|
|
||||||
if(knobValue[knob] != val) {
|
|
||||||
knobValue[knob] = val;
|
|
||||||
if(printChange) println(knobName[knob] + " is: " + knobValue[knob]);
|
|
||||||
sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void release(int val)
|
|
||||||
{
|
|
||||||
int knob = 21;
|
|
||||||
if(knobValue[knob] != val) {
|
|
||||||
knobValue[knob] = val;
|
|
||||||
if(printChange) println(knobName[knob] + " is: " + knobValue[knob]);
|
|
||||||
sendControlChange((byte)0, (byte)knobMidiCC[knob], (byte)knobValue[knob]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
//import oscP5.*;
|
|
||||||
//import netP5.*;
|
|
||||||
import controlP5.*;
|
|
||||||
import rwmidi.*; // watch out for this
|
|
||||||
import processing.serial.*;
|
|
||||||
|
|
||||||
ControlP5 controlP5;
|
|
||||||
MidiInput input;
|
|
||||||
Serial port0;
|
|
||||||
|
|
||||||
boolean printChange = true;
|
|
||||||
boolean serialBusy = false;
|
|
||||||
|
|
||||||
int backgroundColor = color(0,0,0);
|
|
||||||
int knobColor = color(235,103,295);
|
|
||||||
|
|
||||||
long time = 0;
|
|
||||||
long lastTime = 0;
|
|
||||||
long timePassed;
|
|
||||||
long timeAllowed = 10;
|
|
||||||
|
|
||||||
int delayTime = 40;
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
|
|
||||||
size(400,400);
|
|
||||||
smooth();
|
|
||||||
background(0);
|
|
||||||
|
|
||||||
setupKnobs();
|
|
||||||
|
|
||||||
//println("print MIDI input devices:");
|
|
||||||
//println(RWMidi.getInputDeviceNames());
|
|
||||||
input = RWMidi.getInputDevices()[0].createInput(this);
|
|
||||||
|
|
||||||
println(Serial.list());
|
|
||||||
port0 = new Serial(this, Serial.list()[0], 9600);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void draw() {
|
|
||||||
background(backgroundColor);
|
|
||||||
//writeKnobValues();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void keyPressed() {
|
|
||||||
if(key=='s' || key=='S') {
|
|
||||||
saveKnobValues();
|
|
||||||
}
|
|
||||||
if(key=='l' || key=='L') {
|
|
||||||
loadKnobValues();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void keyReleased() {
|
|
||||||
if(key=='l' || key=='L') {
|
|
||||||
sendMidiKnobs();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
@ -1,70 +0,0 @@
|
|||||||
void noteOnReceived(Note note) {
|
|
||||||
|
|
||||||
byte channel = byte(note.getChannel());
|
|
||||||
byte pitch = byte(note.getPitch());
|
|
||||||
byte velocity = byte(note.getVelocity());
|
|
||||||
|
|
||||||
sendNoteOn(channel, pitch, velocity);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void noteOffReceived(Note note) {
|
|
||||||
|
|
||||||
byte channel = byte(note.getChannel());
|
|
||||||
byte pitch = byte(note.getPitch());
|
|
||||||
byte velocity = byte(note.getVelocity());
|
|
||||||
|
|
||||||
sendNoteOff(channel, pitch, velocity);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void controllerChangeReceived(rwmidi.Controller controller) {
|
|
||||||
|
|
||||||
byte channel = byte(controller.getChannel());
|
|
||||||
byte CC = byte(controller.getCC());
|
|
||||||
byte value = byte(controller.getValue());
|
|
||||||
|
|
||||||
sendControlChange(channel, CC, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void sendNoteOn(byte channel, byte pitch, byte velocity) {
|
|
||||||
|
|
||||||
byte noteOn = byte(0x90 | channel);
|
|
||||||
|
|
||||||
serialBusy = true;
|
|
||||||
port0.write(noteOn);
|
|
||||||
port0.write(pitch);
|
|
||||||
port0.write(velocity);
|
|
||||||
//println('\n' + hex(noteOn) + " " + hex(pitch) + " " + hex(velocity));
|
|
||||||
serialBusy = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sendNoteOff(byte channel, byte pitch, byte velocity) {
|
|
||||||
|
|
||||||
byte noteOff = byte(0x80 | channel);
|
|
||||||
|
|
||||||
serialBusy = true;
|
|
||||||
port0.write(noteOff);
|
|
||||||
port0.write(pitch);
|
|
||||||
port0.write(velocity);
|
|
||||||
//println('\n' + hex(noteOff) + " " + hex(pitch) + " " + hex(velocity));
|
|
||||||
serialBusy = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sendControlChange(byte channel, byte CC, byte value) {
|
|
||||||
time = millis();
|
|
||||||
timePassed = time - lastTime;
|
|
||||||
if(timePassed > timeAllowed) {
|
|
||||||
lastTime = time;
|
|
||||||
|
|
||||||
byte controlChange = byte(0xB0 | channel);
|
|
||||||
|
|
||||||
serialBusy = true;
|
|
||||||
port0.write(controlChange);
|
|
||||||
port0.write(CC);
|
|
||||||
port0.write(value);
|
|
||||||
serialBusy = false;
|
|
||||||
//println('\n' + hex(controlChange) + " " + hex(CC) + " " + hex(value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,124 +0,0 @@
|
|||||||
byte[] savedKnobValues = new byte[numKnobs];
|
|
||||||
byte[] loadedKnobValues = new byte[numKnobs];
|
|
||||||
|
|
||||||
|
|
||||||
void loadKnobValues() {
|
|
||||||
|
|
||||||
loadedKnobValues = loadBytes("knobValues.txt");
|
|
||||||
|
|
||||||
for(int i=0; i<numKnobs; i++) {
|
|
||||||
knobValue[i] = loadedKnobValues[i];
|
|
||||||
controlP5.controller(controllerName[i]).setValue(knobValue[i]);
|
|
||||||
}
|
|
||||||
println();
|
|
||||||
println("Loaded Knob Values");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void saveKnobValues() {
|
|
||||||
|
|
||||||
for(int i=0;i<numKnobs;i++) {
|
|
||||||
savedKnobValues[i] = (byte)knobValue[i];
|
|
||||||
}
|
|
||||||
saveBytes("knobValues.txt", savedKnobValues);
|
|
||||||
println();
|
|
||||||
println("Saved Knob Values");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void sendMidiKnobs() {
|
|
||||||
|
|
||||||
sendControlChange((byte)0, (byte)knobMidiCC[0],(byte)knobValue[0]);
|
|
||||||
delay(delayTime);
|
|
||||||
//semi1(knobValue[1]);
|
|
||||||
int semi =(knobValue[1]+24)*2+16;
|
|
||||||
if(!serialBusy) sendControlChange((byte)0, (byte)knobMidiCC[1], (byte)semi);
|
|
||||||
|
|
||||||
delay(delayTime);
|
|
||||||
//detune1(knobValue[2]);
|
|
||||||
if(!serialBusy) sendControlChange((byte)0, (byte)knobMidiCC[2], (byte)knobValue[2]);
|
|
||||||
|
|
||||||
delay(delayTime);
|
|
||||||
//gain1(knobValue[3]);
|
|
||||||
if(!serialBusy) sendControlChange((byte)0, (byte)knobMidiCC[3], (byte)knobValue[3]);
|
|
||||||
|
|
||||||
delay(delayTime);
|
|
||||||
//wave1(knobValue[4]);
|
|
||||||
if(!serialBusy) sendControlChange((byte)0, (byte)knobMidiCC[4], (byte)(knobValue[4]*8));
|
|
||||||
|
|
||||||
delay(delayTime);
|
|
||||||
//fm1(knobValue[5]);
|
|
||||||
if(!serialBusy) sendControlChange((byte)0, (byte)knobMidiCC[5], (byte)knobValue[5]);
|
|
||||||
|
|
||||||
delay(delayTime);
|
|
||||||
//freq2(knobValue[6]);
|
|
||||||
if(!serialBusy) sendControlChange((byte)0, (byte)knobMidiCC[6], (byte)knobValue[6]);
|
|
||||||
|
|
||||||
delay(delayTime);
|
|
||||||
//semi2(knobValue[7]);
|
|
||||||
semi = (knobValue[7]+24)*2+16;
|
|
||||||
if(!serialBusy) sendControlChange((byte)0, (byte)knobMidiCC[7], (byte)semi);
|
|
||||||
|
|
||||||
delay(delayTime);
|
|
||||||
//detune2(knobValue[8]);
|
|
||||||
if(!serialBusy) sendControlChange((byte)0, (byte)knobMidiCC[8], (byte)knobValue[8]);
|
|
||||||
|
|
||||||
delay(delayTime);
|
|
||||||
//gain2(knobValue[7]);
|
|
||||||
if(!serialBusy) sendControlChange((byte)0, (byte)knobMidiCC[9], (byte)knobValue[9]);
|
|
||||||
|
|
||||||
delay(delayTime);
|
|
||||||
//wave2(knobValue[10]);
|
|
||||||
if(!serialBusy) sendControlChange((byte)0, (byte)knobMidiCC[10], (byte)(knobValue[10]*8));
|
|
||||||
|
|
||||||
delay(delayTime);
|
|
||||||
//fm2(knobValue[11]);
|
|
||||||
if(!serialBusy) sendControlChange((byte)0, (byte)knobMidiCC[11], (byte)knobValue[11]);
|
|
||||||
|
|
||||||
delay(delayTime);
|
|
||||||
//freq3(knobValue[12]);
|
|
||||||
if(!serialBusy) sendControlChange((byte)0, (byte)knobMidiCC[12], (byte)knobValue[12]);
|
|
||||||
|
|
||||||
delay(delayTime);
|
|
||||||
//semi3(knobValue[13]);
|
|
||||||
semi =(knobValue[13]+24)*2+16;
|
|
||||||
if(!serialBusy) sendControlChange((byte)0, (byte)knobMidiCC[13], (byte)semi);
|
|
||||||
|
|
||||||
delay(delayTime);
|
|
||||||
//detune3(knobValue[14]);
|
|
||||||
if(!serialBusy) sendControlChange((byte)0, (byte)knobMidiCC[14], (byte)knobValue[14]);
|
|
||||||
|
|
||||||
delay(delayTime);
|
|
||||||
//gain3(knobValue[15]);
|
|
||||||
if(!serialBusy) sendControlChange((byte)0, (byte)knobMidiCC[15], (byte)knobValue[15]);
|
|
||||||
|
|
||||||
delay(delayTime);
|
|
||||||
//wave3(knobValue[16]);
|
|
||||||
if(!serialBusy) sendControlChange((byte)0, (byte)knobMidiCC[16], (byte)(knobValue[16]*8));
|
|
||||||
|
|
||||||
delay(delayTime);
|
|
||||||
//fm3(knobValue[17]);
|
|
||||||
if(!serialBusy) sendControlChange((byte)0, (byte)knobMidiCC[17], (byte)knobValue[17]);
|
|
||||||
|
|
||||||
delay(delayTime);
|
|
||||||
//attack(knobValue[18]);
|
|
||||||
if(!serialBusy) sendControlChange((byte)0, (byte)knobMidiCC[18], (byte)knobValue[18]);
|
|
||||||
|
|
||||||
delay(delayTime);
|
|
||||||
//decay(knobValue[19]);
|
|
||||||
if(!serialBusy) sendControlChange((byte)0, (byte)knobMidiCC[19], (byte)knobValue[19]);
|
|
||||||
|
|
||||||
delay(delayTime);
|
|
||||||
//sustain(knobValue[20]);
|
|
||||||
if(!serialBusy) sendControlChange((byte)0, (byte)knobMidiCC[20], (byte)knobValue[20]);
|
|
||||||
|
|
||||||
delay(delayTime);
|
|
||||||
//release(knobValue[21]);
|
|
||||||
if(!serialBusy) sendControlChange((byte)0, (byte)knobMidiCC[21], (byte)knobValue[21]);
|
|
||||||
|
|
||||||
println();
|
|
||||||
println("Sent Knob Values over MIDI");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
248
software/lib/MMM/Midi.cpp
Normal file
248
software/lib/MMM/Midi.cpp
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
/*
|
||||||
|
Midi.cpp - Music library
|
||||||
|
Copyright (c) 2012 Copenhagen Institute of Interaction Design.
|
||||||
|
All right reserved.
|
||||||
|
|
||||||
|
This library is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser Public License
|
||||||
|
along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
+ author: Jakob Bak
|
||||||
|
+ contact: j.bak@ciid.dk
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
#include <hardwareSerial.h>
|
||||||
|
//#include <MidiTables.h>
|
||||||
|
#include <Music.h>
|
||||||
|
#include <Midi.h>
|
||||||
|
|
||||||
|
prog_uint16_t hertzTable[] PROGMEM = {8,8,9,9,10,10,11,12,12,13,14,15,16,17,18,19,20,21,23,24,25,27,29,30,32,34,36,38,41,43,46,48,51,54,58,61,65,69,73,77,82,87,92,97,103,109,116,123,130,138,146,155,164,174,184,195,207,219,233,246,261,277,293,311,329,349,369,391,415,440,466,493,523,554,587,622,659,698,739,783,830,880,932,987,1046,1108,1174,1244,1318,1396,1479,1567,1661,1760,1864,1975,2093,2217,2349,2489,2637,2793,2959,3135,3322,3520,3729,3951,4186,4434,4698,4978,5274,5587,5919,6271,6644,7040,7458,7902,8372,8869,9397,9956,10548,11175,11839,12543};
|
||||||
|
|
||||||
|
MMidi Midi;
|
||||||
|
|
||||||
|
bool midiRead = false;
|
||||||
|
|
||||||
|
|
||||||
|
void MMidi::init()
|
||||||
|
{
|
||||||
|
Serial.begin(115200);
|
||||||
|
|
||||||
|
midiBufferIndex = 0;
|
||||||
|
midiChannel = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMidi::checkMidi()
|
||||||
|
{
|
||||||
|
while(Serial.available() > 0) {
|
||||||
|
|
||||||
|
data = Serial.read();
|
||||||
|
|
||||||
|
if(data & 0x80 && (data & 0x0F) == midiChannel) { // bitmask with 10000000 to see if byte is over 127 (data&0x80)
|
||||||
|
midiBufferIndex = 0; // and check if the midi channel corresponds to the midiChannel
|
||||||
|
midiRead = true; // the device is set to listen to.
|
||||||
|
} else if(data & 0x80) { // Else if the byte is over 127 (but not on the device's
|
||||||
|
midiRead = false; // midiChannel, don't read this or any following bytes.
|
||||||
|
}
|
||||||
|
|
||||||
|
if(midiRead) {
|
||||||
|
midiBuffer[midiBufferIndex] = data;
|
||||||
|
midiBufferIndex++;
|
||||||
|
if (midiBufferIndex > 2) {
|
||||||
|
midiHandler();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMidi::midiHandler() {
|
||||||
|
|
||||||
|
uint8_t midiChannel = (midiBuffer[0] & 0x0F);
|
||||||
|
|
||||||
|
|
||||||
|
switch(midiBuffer[0] & 0xF0) { // bit mask with &0xF0 ?
|
||||||
|
case 0x80:
|
||||||
|
noteOff (midiBuffer[0] & 0x0F, // midi channel 0-16
|
||||||
|
midiBuffer[1] & 0x7F, // note value 0-127
|
||||||
|
midiBuffer[2] & 0x7F); // note velocity 0-127
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x90:
|
||||||
|
noteOn (midiBuffer[0] & 0x0F, // midi channel 0-16
|
||||||
|
midiBuffer[1] & 0x7F, // note value 0-127
|
||||||
|
midiBuffer[2] & 0x7F); // note velocity 0-127
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xA0:
|
||||||
|
aftertouch (midiBuffer[0] & 0x0F, // midi channel 0-16
|
||||||
|
midiBuffer[1] & 0x7F, // note value 0-127
|
||||||
|
midiBuffer[2] & 0x7F);// note velocity 0-127
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xB0:
|
||||||
|
controller (midiBuffer[0] & 0x0F, // midi channel 0-16
|
||||||
|
midiBuffer[1] & 0x7F, // controller number 0-127
|
||||||
|
midiBuffer[2] & 0x7F);// controller value 0-127
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xC0:
|
||||||
|
programChange (midiBuffer[0] & 0x0F, // midi channel 0-16
|
||||||
|
midiBuffer[1] & 0x7F); // program number 0-127
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xD0:
|
||||||
|
channelPressure (midiBuffer[0] & 0x0F, // midi channel 0-16
|
||||||
|
midiBuffer[1] & 0x7F); // pressure amount 0-127
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xE0:
|
||||||
|
pitchWheel (midiBuffer[0] & 0x0F, // midi channel 0-16
|
||||||
|
midiBuffer[1] & 0x7F, // higher bits 0-6
|
||||||
|
midiBuffer[2] & 0x7F);// lower bits 7-13
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMidi::noteOff(uint8_t channel, uint8_t note, uint8_t vel) {
|
||||||
|
|
||||||
|
if(notePlayed == note) {
|
||||||
|
Music.setEnvStage(4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMidi::noteOn(uint8_t channel, uint8_t note, uint8_t vel) {
|
||||||
|
|
||||||
|
Music.setEnvStage(1);
|
||||||
|
Music.setVelSustain(vel);
|
||||||
|
Music.setVelPeak(vel);
|
||||||
|
notePlayed = note;
|
||||||
|
memcpy_P(&frequency, &hertzTable[notePlayed],2);
|
||||||
|
Music.setFrequency1(frequency);
|
||||||
|
Music.setFrequency2(frequency);
|
||||||
|
Music.setFrequency3(frequency);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMidi::aftertouch(uint8_t channel, uint8_t note, uint8_t pressure) {
|
||||||
|
// Write code here for Aftertouch
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMidi::controller(uint8_t channel, uint8_t number, uint8_t value) {
|
||||||
|
|
||||||
|
switch(number) {
|
||||||
|
case DETUNE:
|
||||||
|
Music.setDetune(value/5120.0);
|
||||||
|
break;
|
||||||
|
case PORTAMENTO:
|
||||||
|
//Music.setPortamento(value); // function to be defined, also argument
|
||||||
|
break;
|
||||||
|
case DETUNE1:
|
||||||
|
Music.setDetune1(value/5120.0);
|
||||||
|
break;
|
||||||
|
case DETUNE2:
|
||||||
|
Music.setDetune2(value/5120.0);
|
||||||
|
break;
|
||||||
|
case DETUNE3:
|
||||||
|
Music.setDetune3(value/5120.0);
|
||||||
|
break;
|
||||||
|
case SEMITONE1:
|
||||||
|
if(15 < value && value < 113) {
|
||||||
|
int8_t val = (((value-16)/2)-24);
|
||||||
|
Music.setSemitone1(val);
|
||||||
|
} else if (value < 16) {
|
||||||
|
Music.setSemitone1(-24);
|
||||||
|
} else {
|
||||||
|
Music.setSemitone1(24);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SEMITONE2:
|
||||||
|
if(15 < value && value < 113) {
|
||||||
|
int8_t val = (((value-16)/2)-24);
|
||||||
|
Music.setSemitone2(val);
|
||||||
|
} else if (value < 16) {
|
||||||
|
Music.setSemitone2(-24);
|
||||||
|
} else {
|
||||||
|
Music.setSemitone2(24);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SEMITONE3:
|
||||||
|
if(15 < value && value < 113) {
|
||||||
|
int8_t val = (((value-16)/2)-24);
|
||||||
|
Music.setSemitone3(val);
|
||||||
|
} else if (value < 16) {
|
||||||
|
Music.setSemitone3(-24);
|
||||||
|
} else {
|
||||||
|
Music.setSemitone3(24);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GAIN1:
|
||||||
|
Music.setGain1(uint16_t(value * 512));
|
||||||
|
break;
|
||||||
|
case GAIN2:
|
||||||
|
Music.setGain2(uint16_t(value * 512));
|
||||||
|
break;
|
||||||
|
case GAIN3:
|
||||||
|
Music.setGain3(uint16_t(value * 512));
|
||||||
|
break;
|
||||||
|
case WAVEFORM:
|
||||||
|
Music.setWaveform(value / 8);
|
||||||
|
break;
|
||||||
|
case WAVEFORM1:
|
||||||
|
Music.setWaveform1(value / 8);
|
||||||
|
break;
|
||||||
|
case WAVEFORM2:
|
||||||
|
Music.setWaveform2(value / 8);
|
||||||
|
break;
|
||||||
|
case WAVEFORM3:
|
||||||
|
Music.setWaveform3(value / 8);
|
||||||
|
break;
|
||||||
|
case ENV_ATTACK:
|
||||||
|
Music.setAttack(value);
|
||||||
|
break;
|
||||||
|
case ENV_DECAY:
|
||||||
|
Music.setDecay(value);
|
||||||
|
break;
|
||||||
|
case ENV_SUSTAIN:
|
||||||
|
Music.setSustain(value);
|
||||||
|
break;
|
||||||
|
case ENV_RELEASE:
|
||||||
|
Music.setRelease(value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMidi::programChange(uint8_t channel, uint8_t number) {
|
||||||
|
// Write code here for Program Change
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMidi::channelPressure(uint8_t channel, uint8_t pressure) {
|
||||||
|
// Write code here for Channel Pressure
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMidi::pitchWheel(uint8_t channel, uint8_t highBits, uint8_t lowBits) {
|
||||||
|
// Write code here for Pitch Wheel
|
||||||
|
}
|
||||||
101
software/lib/MMM/Midi.h
Normal file
101
software/lib/MMM/Midi.h
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
Midi.h - Music library
|
||||||
|
Copyright (c) 2012 Copenhagen Institute of Interaction Design.
|
||||||
|
All right reserved.
|
||||||
|
|
||||||
|
This library is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser Public License
|
||||||
|
along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
+ author: Jakob Bak
|
||||||
|
+ contact: j.bak@ciid.dk
|
||||||
|
*/
|
||||||
|
|
||||||
|
// MIDI specific constants
|
||||||
|
|
||||||
|
#ifndef MIDI_CHANNEL
|
||||||
|
#define MIDI_CHANNEL 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// SYSEX constants
|
||||||
|
#define SYSEX_LIMIT 16
|
||||||
|
#define CFO_MANUFACTURER_ID 44
|
||||||
|
#define CFO_DEVICE_GROUP_ID 3
|
||||||
|
#define SET_CHANNEL 0
|
||||||
|
|
||||||
|
|
||||||
|
//synth parameters as MIDI controller numbers
|
||||||
|
#define DETUNE 4
|
||||||
|
#define WAVEFORM 5
|
||||||
|
#define PORTAMENTO 6
|
||||||
|
|
||||||
|
#define FREQUENCY1 10
|
||||||
|
#define SEMITONE1 11
|
||||||
|
#define DETUNE1 12
|
||||||
|
#define GAIN1 13
|
||||||
|
#define WAVEFORM1 14
|
||||||
|
|
||||||
|
#define FREQUENCY2 20
|
||||||
|
#define SEMITONE2 21
|
||||||
|
#define DETUNE2 22
|
||||||
|
#define GAIN2 23
|
||||||
|
#define WAVEFORM2 24
|
||||||
|
|
||||||
|
#define FREQUENCY3 30
|
||||||
|
#define SEMITONE3 31
|
||||||
|
#define DETUNE3 32
|
||||||
|
#define GAIN3 33
|
||||||
|
#define WAVEFORM3 34
|
||||||
|
|
||||||
|
#define ENV_ATTACK 114
|
||||||
|
#define ENV_DECAY 115
|
||||||
|
#define ENV_SUSTAIN 116
|
||||||
|
#define ENV_RELEASE 117
|
||||||
|
|
||||||
|
#define ENV2_ATTACK 124
|
||||||
|
#define ENV2_DECAY 125
|
||||||
|
#define ENV2_SUSTAIN 126
|
||||||
|
#define ENV2_RELEASE 127
|
||||||
|
|
||||||
|
|
||||||
|
// Synth parameters used in MIDI code
|
||||||
|
#define ENV_MAX_GAIN (65536 * 4 - 1)
|
||||||
|
|
||||||
|
|
||||||
|
class MMidi {
|
||||||
|
public:
|
||||||
|
void init();
|
||||||
|
void checkMidi();
|
||||||
|
|
||||||
|
void midiHandler();
|
||||||
|
void noteOff(uint8_t channel, uint8_t note, uint8_t vel);
|
||||||
|
void noteOn(uint8_t channel, uint8_t note, uint8_t vel);
|
||||||
|
void aftertouch(uint8_t channel, uint8_t note, uint8_t pressure);
|
||||||
|
void controller(uint8_t channel, uint8_t number, uint8_t value);
|
||||||
|
void programChange(uint8_t channel, uint8_t number);
|
||||||
|
void channelPressure(uint8_t channel, uint8_t pressure);
|
||||||
|
void pitchWheel(uint8_t channel, uint8_t highBits, uint8_t lowBits);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// MIDI
|
||||||
|
uint8_t data;
|
||||||
|
uint8_t midiBuffer[SYSEX_LIMIT];
|
||||||
|
uint8_t midiChannel;
|
||||||
|
|
||||||
|
int midiBufferIndex;
|
||||||
|
uint16_t frequency;
|
||||||
|
uint8_t notePlayed;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern MMidi Midi;
|
||||||
@ -23,50 +23,102 @@
|
|||||||
|
|
||||||
#include "Motion.h"
|
#include "Motion.h"
|
||||||
|
|
||||||
#include "Arduino.h"
|
|
||||||
|
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
//bool motion_reg_init = false;
|
#define PB0 PORTB0
|
||||||
|
|
||||||
|
bool motion_reg_init = false;
|
||||||
|
|
||||||
Motion MotionA(MOTIONA);
|
Motion MotionA(MOTIONA);
|
||||||
Motion MotionB(MOTIONB);
|
Motion MotionB(MOTIONA);
|
||||||
|
|
||||||
|
uint8_t lb;
|
||||||
|
uint8_t hb;
|
||||||
|
|
||||||
|
float T = N * 0.004f; // 4ms (see TCNT1)
|
||||||
|
int xin, dx;
|
||||||
|
|
||||||
|
float MAX_POS = 1023;
|
||||||
|
float MAX_VEL = MAX_POS / T;
|
||||||
|
float MAX_ACC = MAX_VEL / T;
|
||||||
|
|
||||||
int MAX_POS = 1023;
|
|
||||||
|
|
||||||
Motion::Motion(MOTION m){
|
Motion::Motion(MOTION m){
|
||||||
_m = m;
|
_m = m;
|
||||||
_i = false;
|
_i = false;
|
||||||
_fcb = NULL;
|
_fcb = NULL;
|
||||||
}
|
};
|
||||||
|
|
||||||
void Motion::init(SENSOR_INPUT sensor)
|
void Motion::init(INPUT sensor)
|
||||||
{
|
{
|
||||||
|
if(!motion_reg_init){
|
||||||
|
TCNT1 = 1000; //4 ms (TCNT1)
|
||||||
|
TIMSK1 = (1 << TOIE1);
|
||||||
|
motion_reg_init = true;
|
||||||
|
}
|
||||||
_i = true;
|
_i = true;
|
||||||
_s = sensor;
|
_s = sensor;
|
||||||
|
|
||||||
tick = millis();
|
// initial values
|
||||||
|
d = 0;
|
||||||
|
k = 1;
|
||||||
|
m = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Motion::update_position() {
|
void Motion::set_force_callback(force_callback fcb, PHY physics) {
|
||||||
Xin = analogRead(_s); // may take some time
|
_fcb = fcb;
|
||||||
|
_fcb_phy = physics;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Motion::update_mass_spring_damper() {
|
|
||||||
|
// clocked at 4ms period
|
||||||
|
ISR(TIMER1_OVF_vect) {
|
||||||
|
TCNT1 = 1000;
|
||||||
|
|
||||||
// todo: filtering
|
if(MotionA._i) {
|
||||||
|
ADMUX = MotionA._s & 0x07;
|
||||||
|
ADCSRA |= (1 << ADSC);
|
||||||
|
while (ADCSRA & (1 << ADSC));
|
||||||
|
lb = ADCL;
|
||||||
|
hb = ADCH;
|
||||||
|
|
||||||
|
xin = (hb << 8) | lb;
|
||||||
|
|
||||||
|
MotionA.F = MotionA.k * (xin - MotionA.X) - (MotionA.d * MotionA.V);
|
||||||
|
MotionA.A = MotionA.F / MotionA.m;
|
||||||
|
MotionA.V += MotionA.A * T;
|
||||||
|
MotionA.X += MotionA.V * T;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
long t = millis();
|
/*
|
||||||
float dt = (float)(t - tick) / 100.0f;
|
if(MotionB._i) {
|
||||||
|
ADMUX = MotionB._s & 0x07;
|
||||||
|
ADCSRA |= (1 << ADSC);
|
||||||
|
while (ADCSRA & (1 << ADSC));
|
||||||
|
lb = ADCL;
|
||||||
|
hb = ADCH;
|
||||||
|
x = (hb << 8) | lb;
|
||||||
|
MotionB._xv[MotionB._ix] = x;
|
||||||
|
MotionB._ix++;
|
||||||
|
MotionB._ix %= N;
|
||||||
|
|
||||||
|
|
||||||
|
xx = x - MotionB._x;
|
||||||
|
if(abs(xx) < 2) {
|
||||||
|
v = 0;
|
||||||
|
} else {
|
||||||
|
v = xx / T;
|
||||||
|
}
|
||||||
|
|
||||||
|
MotionB._a = (v - MotionB._v) / T;
|
||||||
|
MotionB._v = v;
|
||||||
|
MotionB._x = x;
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
int xin = analogRead(_s); // may take some time, put: 512 - analogRead(_s);
|
|
||||||
|
|
||||||
Xin = xin;
|
|
||||||
F = k * (xin - X) - (d * V);
|
|
||||||
V += (F / m) * dt;
|
|
||||||
X += V * dt;
|
|
||||||
|
|
||||||
tick = t;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -32,7 +32,7 @@ enum MOTION {
|
|||||||
MOTIONB = 1
|
MOTIONB = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SENSOR_INPUT {
|
enum INPUT {
|
||||||
INPUTA0 = 0x0000,
|
INPUTA0 = 0x0000,
|
||||||
INPUTA1 = 0x0001,
|
INPUTA1 = 0x0001,
|
||||||
INPUTA2 = 0x0010,
|
INPUTA2 = 0x0010,
|
||||||
@ -43,32 +43,36 @@ enum SENSOR_INPUT {
|
|||||||
INPUTA7 = 0x0111
|
INPUTA7 = 0x0111
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum PHY {
|
||||||
|
POSITION = 0,
|
||||||
|
VELOCITY = 1,
|
||||||
|
ACCELERATION = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class Motion {
|
class Motion {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Motion(MOTION m);
|
Motion(MOTION m);
|
||||||
|
|
||||||
void init(SENSOR_INPUT sensor);
|
void init(INPUT sensor);
|
||||||
|
|
||||||
|
void set_force_callback(force_callback fcb, PHY physics);
|
||||||
|
|
||||||
|
|
||||||
void update_position();
|
|
||||||
void update_mass_spring_damper();
|
|
||||||
|
|
||||||
// raw position vector
|
// raw position vector
|
||||||
int _xv[N];
|
int _xv[N];
|
||||||
int _ix;
|
int _ix;
|
||||||
|
|
||||||
float X, V, F;
|
float X, V, A, F;
|
||||||
float m, k, d;
|
float m, k, d;
|
||||||
int Xin;
|
|
||||||
|
|
||||||
long tick;
|
|
||||||
|
|
||||||
MOTION _m;
|
MOTION _m;
|
||||||
SENSOR_INPUT _s;
|
INPUT _s;
|
||||||
bool _i;
|
bool _i;
|
||||||
|
|
||||||
force_callback _fcb; // not used in current version
|
force_callback _fcb;
|
||||||
|
PHY _fcb_phy;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Motion MotionA;
|
extern Motion MotionA;
|
||||||
|
|||||||
38
software/lib/MMM/Motor.cpp
Executable file → Normal file
38
software/lib/MMM/Motor.cpp
Executable file → Normal file
@ -23,8 +23,6 @@
|
|||||||
|
|
||||||
#include "Motor.h"
|
#include "Motor.h"
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <avr/interrupt.h>
|
|
||||||
|
|
||||||
#define RESOLUTION 65536
|
#define RESOLUTION 65536
|
||||||
|
|
||||||
@ -47,48 +45,30 @@ void MMotor::init()
|
|||||||
{
|
{
|
||||||
|
|
||||||
if(!reg_init){
|
if(!reg_init){
|
||||||
|
|
||||||
//cli();
|
|
||||||
//direction pins are outputs
|
//direction pins are outputs
|
||||||
DDRD |= (1 << PD7);
|
DDRD |= (1 << PD7);
|
||||||
DDRB |= (1 << PB0) | (1 << PB1) | (1 << PB2);
|
DDRB = (1 << PB0) | (1 << PB1) | (1 << PB2);
|
||||||
|
|
||||||
TCCR1A = (1 << COM1A1) | (1 << COM1B1);
|
TCCR1A = (1 << COM1A1) | (1 << COM1B1);
|
||||||
//TCCR1A = (1 << COM1A1) | (1 << COM1B1) | (1 << WGM10);
|
|
||||||
|
|
||||||
// clear the bits
|
// clear the bits
|
||||||
//TCCR1B &= ~((1 << CS10) | (1 << CS11) | (1 << CS12));
|
TCCR1B &= ~((1 << CS10) | (1 << CS11) | (1 << CS12));
|
||||||
|
|
||||||
TCCR1B = (1 << WGM13) | (1 << CS10);
|
TCCR1B = (1 << WGM13) | (1 << CS10);
|
||||||
|
|
||||||
|
//ICR1 = 512;
|
||||||
ICR1 = 512;
|
ICR1 = 512;
|
||||||
//OCR1A = 512;
|
|
||||||
|
|
||||||
reg_init = true;
|
reg_init = true;
|
||||||
//sei();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MMotor::torque(int value)
|
void MMotor::torque(int value)
|
||||||
{
|
{
|
||||||
if(value < 0) {
|
if(_m == MOTORA) OCR1A = value;
|
||||||
_d = BACKWARD;
|
else if(_m == MOTORB) OCR1B = value;
|
||||||
} else {
|
|
||||||
_d = FORWARD;
|
|
||||||
}
|
|
||||||
value = abs(value);
|
|
||||||
if(value > 512) value = 512;
|
|
||||||
//else value = abs(512);
|
|
||||||
if(_m == MOTORA) {
|
|
||||||
OCR1A = value;
|
|
||||||
direction(_d);
|
|
||||||
}
|
|
||||||
else if(_m == MOTORB) {
|
|
||||||
OCR1B = value;
|
|
||||||
direction(_d);
|
|
||||||
}
|
|
||||||
_t = value;
|
_t = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,8 +82,8 @@ void MMotor::direction(DIRECTION d)
|
|||||||
_d = d;
|
_d = d;
|
||||||
if(_m == MOTORA && _d == FORWARD) PORTD |= (1 << PD7);
|
if(_m == MOTORA && _d == FORWARD) PORTD |= (1 << PD7);
|
||||||
else if(_m == MOTORA && _d == BACKWARD) PORTD &= ~(1 << PD7);
|
else if(_m == MOTORA && _d == BACKWARD) PORTD &= ~(1 << PD7);
|
||||||
else if(_m == MOTORB && _d == BACKWARD) PORTB &= ~(1 << PB0); // The direction of FORWARD and BACKWARD is
|
else if(_m == MOTORB && _d == BACKWARD) PORTB |= (1 << PB0);
|
||||||
else if(_m == MOTORB && _d == FORWARD) PORTB |= (1 << PB0); // switched for MOTORB due to hardware design
|
else if(_m == MOTORB && _d == FORWARD) PORTB &= ~(1 << PB0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MMotor::stop()
|
void MMotor::stop()
|
||||||
|
|||||||
3
software/lib/MMM/Motor.h
Executable file → Normal file
3
software/lib/MMM/Motor.h
Executable file → Normal file
@ -53,7 +53,8 @@ protected:
|
|||||||
|
|
||||||
MOTOR _m;
|
MOTOR _m;
|
||||||
DIRECTION _d;
|
DIRECTION _d;
|
||||||
int _t; // torque
|
int _t;
|
||||||
|
long _p;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
623
software/lib/MMM/Music.cpp
Normal file
623
software/lib/MMM/Music.cpp
Normal file
@ -0,0 +1,623 @@
|
|||||||
|
/*
|
||||||
|
Music.cpp - Music library
|
||||||
|
Copyright (c) 2012 Copenhagen Institute of Interaction Design.
|
||||||
|
All right reserved.
|
||||||
|
|
||||||
|
This library is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser Public License
|
||||||
|
along with Foobar. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
+ author: Jakob Bak
|
||||||
|
+ contact: j.bak@ciid.dk
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
|
||||||
|
#include <Wavetable.h>
|
||||||
|
#include <Music.h>
|
||||||
|
#include <hardwareSerial.h>
|
||||||
|
|
||||||
|
// Table of MIDI note values to frequency in Hertz
|
||||||
|
prog_uint16_t hertsTable[] PROGMEM = {8,8,9,9,10,10,11,12,12,13,14,15,16,17,18,19,20,21,23,24,25,27,29,30,32,34,36,38,41,43,46,48,51,54,58,61,65,69,73,77,82,87,92,97,103,109,116,123,130,138,146,155,164,174,184,195,207,219,233,246,261,277,293,311,329,349,369,391,415,440,466,493,523,554,587,622,659,698,739,783,830,880,932,987,1046,1108,1174,1244,1318,1396,1479,1567,1661,1760,1864,1975,2093,2217,2349,2489,2637,2793,2959,3135,3322,3520,3729,3951,4186,4434,4698,4978,5274,5587,5919,6271,6644,7040,7458,7902,8372,8869,9397,9956,10548,11175,11839,12543};
|
||||||
|
|
||||||
|
prog_uint32_t envTimeTable[] PROGMEM = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,33,34,35,36,37,38,39,41,42,43,45,46,48,49,51,53,55,57,59,61,63,65,67,70,73,75,78,81,85,88,92,96,100,104,109,114,119,125,131,138,146,154,163,172,183,195,209,225,242,261,284,310,341,379,425,482,556,654,792,998,1342,2030,4095};
|
||||||
|
|
||||||
|
float semitoneTable[] = {0.25,0.2648658,0.2806155,0.29730177,0.31498027,0.33370996,0.35355338,0.37457678,0.39685026,0.4204482,0.44544938,0.47193715,0.5,0.5297315,0.561231,0.59460354,0.62996054,0.6674199,0.70710677,0.74915355,0.7937005,0.8408964,0.8908987,0.9438743,1.0,1.0594631,1.122462,1.1892071,1.2599211,1.3348398,1.4142135,1.4983071,1.587401,1.6817929,1.7817974,1.8877486,2.0,2.1189263,2.244924,2.3784142,2.5198421,2.6696796,2.828427,2.9966142,3.174802,3.3635857,3.563595,3.7754972,4.0};
|
||||||
|
|
||||||
|
MMusic Music;
|
||||||
|
|
||||||
|
// Defining which pins the SPI interface is connected to.
|
||||||
|
#define SPI_SCK 5
|
||||||
|
#define SPI_MOSI 3
|
||||||
|
|
||||||
|
// timer 2 is audio interrupt timer
|
||||||
|
ISR(TIMER2_COMPA_vect) {
|
||||||
|
|
||||||
|
OCR2A = 127;
|
||||||
|
|
||||||
|
Music.synthInterrupt();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
//
|
||||||
|
// INITIALIZING FUNCTION
|
||||||
|
//
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
void MMusic::init()
|
||||||
|
{
|
||||||
|
// clear interrupts. to make sure the interrupt timer doesn't start until we've set it up.
|
||||||
|
cli();
|
||||||
|
|
||||||
|
// set up syntheziser
|
||||||
|
// this is the timer 2 audio rate timer, fires an interrupt at 15625 Hz sampling rate
|
||||||
|
TIMSK2 = 1<<OCIE2A; // interrupt enable audio timer
|
||||||
|
OCR2A = 127;
|
||||||
|
TCCR2A = 2; // CTC mode, counts up to 127 then resets
|
||||||
|
TCCR2B = 0<<CS22 | 1<<CS21 | 0<<CS20;
|
||||||
|
|
||||||
|
// OUTPUTS
|
||||||
|
// sck + mosi + ss
|
||||||
|
DDRB = (1 << DDB2) | (1 << DDB3) | (1 << DDB5);
|
||||||
|
// dac_cs output
|
||||||
|
DDRD = (1 << DDD6);
|
||||||
|
|
||||||
|
// set up SPI port
|
||||||
|
SPCR = 0x50;
|
||||||
|
SPSR = 0x01;
|
||||||
|
|
||||||
|
// DAC frame sync HIGH, so that the SPI port doesn't start wirting straight away
|
||||||
|
PORTD |= (1<<6);
|
||||||
|
|
||||||
|
// waveform setup
|
||||||
|
//setSine();
|
||||||
|
setWaveform(0);
|
||||||
|
|
||||||
|
// frequency setup
|
||||||
|
setFrequency(440);
|
||||||
|
setSemitone1(0);
|
||||||
|
setSemitone2(0);
|
||||||
|
setSemitone3(0);
|
||||||
|
setDetune(0);
|
||||||
|
|
||||||
|
// gain setup
|
||||||
|
setGain(1.0f);
|
||||||
|
setGain1(1.0f);
|
||||||
|
setGain2(1.0f);
|
||||||
|
setGain3(1.0f);
|
||||||
|
|
||||||
|
// envelope setup
|
||||||
|
setEnvStage(0);
|
||||||
|
disableEnvelope();
|
||||||
|
env = 0;
|
||||||
|
|
||||||
|
setAttack(4);
|
||||||
|
setDecay(90);
|
||||||
|
setSustain(32);
|
||||||
|
setRelease(64);
|
||||||
|
setVelSustain(0);
|
||||||
|
|
||||||
|
sei(); // global interrupt enable
|
||||||
|
|
||||||
|
Serial.println("MUSIC INITIALIZED!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
//
|
||||||
|
// FREQUENCY AND DETUNE FUNCTIONS
|
||||||
|
//
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
void MMusic::setFrequency(float freq)
|
||||||
|
{
|
||||||
|
period1 = uint16_t(((freq * semi1 * (1 + detune1 + bend)) * 65536.0) / SAMPLE_RATE);
|
||||||
|
period2 = uint16_t(((freq * semi2 * (1 + detune2 + bend)) * 65536.0) / SAMPLE_RATE);
|
||||||
|
period3 = uint16_t(((freq * semi3 * (1 + detune3 + bend)) * 65536.0) / SAMPLE_RATE);
|
||||||
|
frequency = freq;
|
||||||
|
frequency1 = freq;
|
||||||
|
frequency2 = freq;
|
||||||
|
frequency3 = freq;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setFrequency1(float freq)
|
||||||
|
{
|
||||||
|
frequency1 = freq;
|
||||||
|
period1 = uint16_t(((frequency1 * semi1 * (1 + detune1 + bend)) * 65536.0) / SAMPLE_RATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setFrequency2(float freq)
|
||||||
|
{
|
||||||
|
frequency2 = freq;
|
||||||
|
period2 = uint16_t(((frequency2 * semi2 * (1 + detune2 + bend)) * 65536.0) / SAMPLE_RATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setFrequency3(float freq)
|
||||||
|
{
|
||||||
|
frequency3 = freq;
|
||||||
|
period3 = uint16_t(((frequency3 * semi3 * (1 + detune3 + bend)) * 65536.0) / SAMPLE_RATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setSemitone1(int8_t semi)
|
||||||
|
{
|
||||||
|
if(-25 < semi && semi < 25){
|
||||||
|
semi1 = semitoneTable[semi+24];
|
||||||
|
} else if (semi < -24) {
|
||||||
|
semi1 = semitoneTable[0];
|
||||||
|
} else {
|
||||||
|
semi1 = semitoneTable[48];
|
||||||
|
}
|
||||||
|
period1 = uint16_t(((frequency1 * semi1 * (1 + detune1 + bend)) * 65536.0) / SAMPLE_RATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setSemitone2(int8_t semi)
|
||||||
|
{
|
||||||
|
if(-25 < semi && semi < 25){
|
||||||
|
semi2 = semitoneTable[semi+24];
|
||||||
|
} else if (semi < -24) {
|
||||||
|
semi2 = semitoneTable[0];
|
||||||
|
} else {
|
||||||
|
semi2 = semitoneTable[48];
|
||||||
|
}
|
||||||
|
period2 = uint16_t(((frequency2 * semi2 * (1 + detune2 + bend)) * 65536.0) / SAMPLE_RATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setSemitone3(int8_t semi)
|
||||||
|
{
|
||||||
|
if(-25 < semi && semi < 25){
|
||||||
|
semi3 = semitoneTable[semi+24];
|
||||||
|
} else if (semi < -24) {
|
||||||
|
semi3 = semitoneTable[0];
|
||||||
|
} else {
|
||||||
|
semi3 = semitoneTable[48];
|
||||||
|
}
|
||||||
|
period3 = uint16_t(((frequency3 * semi3 * (1 + detune3 + bend)) * 65536.0) / SAMPLE_RATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setDetune(float detune)
|
||||||
|
{
|
||||||
|
detune1 = 0.0;
|
||||||
|
detune2 = detune;
|
||||||
|
detune3 = -detune;
|
||||||
|
period2 = uint16_t(((frequency2 * semi2 * (1 + detune2 + bend)) * 65536.0) / SAMPLE_RATE);
|
||||||
|
period3 = uint16_t(((frequency3 * semi3 * (1 + detune3 + bend)) * 65536.0) / SAMPLE_RATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setDetune1(float detune)
|
||||||
|
{
|
||||||
|
detune1 = detune;
|
||||||
|
period1 = uint16_t(((frequency1 * semi1 * (1 + detune1 + bend)) * 65536.0) / SAMPLE_RATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setDetune2(float detune)
|
||||||
|
{
|
||||||
|
detune2 = detune;
|
||||||
|
period2 = uint16_t(((frequency2 * semi2 * (1 + detune2 + bend)) * 65536.0) / SAMPLE_RATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setDetune3(float detune)
|
||||||
|
{
|
||||||
|
detune3 = detune;
|
||||||
|
period3 = uint16_t(((frequency3 * semi3 * (1 + detune3 + bend)) * 65536.0) / SAMPLE_RATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::pitchBend(float b)
|
||||||
|
{
|
||||||
|
bend = b;
|
||||||
|
period1 = uint16_t(((frequency1 * semi1 * (1 + detune1 + bend)) * 65536.0) / SAMPLE_RATE);
|
||||||
|
period2 = uint16_t(((frequency2 * semi2 * (1 + detune2 + bend)) * 65536.0) / SAMPLE_RATE);
|
||||||
|
period3 = uint16_t(((frequency3 * semi3 * (1 + detune3 + bend)) * 65536.0) / SAMPLE_RATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
//
|
||||||
|
// WAVEFORM FUNCTIONS
|
||||||
|
//
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setWaveform(uint16_t waveForm)
|
||||||
|
{
|
||||||
|
waveForm1 = waveForm * 256;
|
||||||
|
waveForm2 = waveForm * 256;
|
||||||
|
waveForm3 = waveForm * 256;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setWaveform1(uint16_t waveForm)
|
||||||
|
{
|
||||||
|
waveForm1 = waveForm * 256;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setWaveform2(uint16_t waveForm)
|
||||||
|
{
|
||||||
|
waveForm2 = waveForm * 256;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setWaveform3(uint16_t waveForm)
|
||||||
|
{
|
||||||
|
waveForm3 = waveForm * 256;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
//
|
||||||
|
// GAIN FUNCTIONS
|
||||||
|
//
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setGainFloat(float value)
|
||||||
|
{
|
||||||
|
gain = uint16_t(value * 65535);
|
||||||
|
gain1 = gain;
|
||||||
|
gain2 = gain;
|
||||||
|
gain3 = gain;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setGain16bit(uint16_t value)
|
||||||
|
{
|
||||||
|
gain = value;
|
||||||
|
gain1 = value;
|
||||||
|
gain2 = value;
|
||||||
|
gain3 = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setGain(float value)
|
||||||
|
{
|
||||||
|
gain = uint16_t(value * 65535);
|
||||||
|
gain1 = gain;
|
||||||
|
gain2 = gain;
|
||||||
|
gain3 = gain;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setGain(uint16_t value)
|
||||||
|
{
|
||||||
|
gain = value;
|
||||||
|
gain1 = value;
|
||||||
|
gain2 = value;
|
||||||
|
gain3 = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setGain1(float value)
|
||||||
|
{
|
||||||
|
gain1 = uint16_t(value * 65535);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setGain2(float value)
|
||||||
|
{
|
||||||
|
gain2 = uint16_t(value * 65535);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setGain3(float value)
|
||||||
|
{
|
||||||
|
gain3 = uint16_t(value * 65535);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setGain1(uint16_t value)
|
||||||
|
{
|
||||||
|
gain1 = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setGain2(uint16_t value)
|
||||||
|
{
|
||||||
|
gain2 = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setGain3(uint16_t value)
|
||||||
|
{
|
||||||
|
gain3 = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float MMusic::getGainFloat()
|
||||||
|
{
|
||||||
|
return float(gain);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t MMusic::getGain()
|
||||||
|
{
|
||||||
|
return gain;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
//
|
||||||
|
// NOTE_ON/OFF FUNCTIONS
|
||||||
|
//
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::noteOn(uint8_t note, uint8_t vel)
|
||||||
|
{
|
||||||
|
envStage = 1;
|
||||||
|
velSustain = vel;
|
||||||
|
notePlayed = note;
|
||||||
|
memcpy_P(&frequency16bit, &hertsTable[notePlayed],2);
|
||||||
|
setFrequency1(frequency16bit);
|
||||||
|
setFrequency2(frequency16bit);
|
||||||
|
setFrequency3(frequency16bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::noteOn(uint8_t note)
|
||||||
|
{
|
||||||
|
envStage = 1;
|
||||||
|
velSustain = 127;
|
||||||
|
notePlayed = note;
|
||||||
|
memcpy_P(&frequency16bit, &hertsTable[notePlayed],2);
|
||||||
|
setFrequency1(frequency16bit);
|
||||||
|
setFrequency2(frequency16bit);
|
||||||
|
setFrequency3(frequency16bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::noteOff(uint8_t note)
|
||||||
|
{
|
||||||
|
if(notePlayed == note) {
|
||||||
|
envStage = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::noteOff()
|
||||||
|
{
|
||||||
|
envStage = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
//
|
||||||
|
// ENVELOPE FUNCTIONS
|
||||||
|
//
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
void MMusic::enableEnvelope()
|
||||||
|
{
|
||||||
|
envelopeOn = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::disableEnvelope()
|
||||||
|
{
|
||||||
|
envelopeOn = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setEnvStage(uint8_t stage)
|
||||||
|
{
|
||||||
|
envStage = stage;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setAttack16bit(uint16_t att)
|
||||||
|
{
|
||||||
|
attack = att;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setDecay16bit(uint16_t dec)
|
||||||
|
{
|
||||||
|
decay = dec;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setSustain16bit(uint16_t sus)
|
||||||
|
{
|
||||||
|
sustain = sus;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setRelease16bit(uint16_t rel)
|
||||||
|
{
|
||||||
|
release = rel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setAttack(uint8_t att)
|
||||||
|
{
|
||||||
|
if(att>127) att = 127;
|
||||||
|
memcpy_P(&attack, &envTimeTable[127 - att],2);
|
||||||
|
//attack = envTimeTable[127 - att];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setDecay(uint8_t dec)
|
||||||
|
{
|
||||||
|
if(dec>127) dec = 127;
|
||||||
|
memcpy_P(&decay, &envTimeTable[127 - dec],2);
|
||||||
|
//decay = envTimeTable[127 - dec];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setSustain(uint8_t sus)
|
||||||
|
{
|
||||||
|
sustain = ((sus * MAX_ENV_GAIN)/128);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setRelease(uint8_t rel)
|
||||||
|
{
|
||||||
|
if(rel>127) rel = 127;
|
||||||
|
memcpy_P(&release, &envTimeTable[127 - rel],2);
|
||||||
|
//release = envTimeTable[127 - rel];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setVelSustain(uint8_t vel)
|
||||||
|
{
|
||||||
|
velSustain = vel * (sustain / 128);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MMusic::setVelPeak(uint8_t vel)
|
||||||
|
{
|
||||||
|
velPeak = vel * (MAX_ENV_GAIN / 128);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
//
|
||||||
|
// AUDIO INTERRUPT SERVICE ROUTINE
|
||||||
|
//
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
void inline MMusic::synthInterrupt()
|
||||||
|
{
|
||||||
|
// Frame sync low for SPI (making it low here so that we can measure lenght of interrupt with scope)
|
||||||
|
PORTD &= ~(1<<6);
|
||||||
|
|
||||||
|
// The accumulator (16bit) keeps track of the pitch by adding the
|
||||||
|
// the amount of "index" points that the frequency has "travelled"
|
||||||
|
// since the last sample was sent to the DAC, i.e. the current phase
|
||||||
|
// of the waveform.
|
||||||
|
accumulator1 = accumulator1 + period1;
|
||||||
|
accumulator2 = accumulator2 + period2;
|
||||||
|
accumulator3 = accumulator3 + period3;
|
||||||
|
|
||||||
|
// To use the accumulator position to find the right index in the
|
||||||
|
// waveform look-up table, we truncate it to 8bit.
|
||||||
|
index1 = accumulator1 >> 8;
|
||||||
|
index2 = accumulator2 >> 8;
|
||||||
|
index3 = accumulator3 >> 8;
|
||||||
|
|
||||||
|
oscil1 = 0;
|
||||||
|
oscil2 = 0;
|
||||||
|
oscil3 = 0;
|
||||||
|
|
||||||
|
memcpy_P(&oscil1, &waveTable[index1 + waveForm1],1);
|
||||||
|
memcpy_P(&oscil2, &waveTable[index2 + waveForm2],1);
|
||||||
|
memcpy_P(&oscil3, &waveTable[index3 + waveForm3],1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// The DAC formatting routine below assumes the sample to be transmitted
|
||||||
|
// is in the higher 12 bits of the 2 byte variable, so we shift the
|
||||||
|
// sample up 6 bits each which adds up to 4 bits.
|
||||||
|
// The individual gains for each oscillator is added.
|
||||||
|
sample = (oscil1 * gain1);
|
||||||
|
sample += (oscil2 * gain2);
|
||||||
|
sample += (oscil3 * gain3);
|
||||||
|
sample >>= 10;
|
||||||
|
|
||||||
|
|
||||||
|
// AMPLIFICATION ENVELOPE
|
||||||
|
// Amplification envelope is calculated here
|
||||||
|
if(envelopeOn) {
|
||||||
|
|
||||||
|
// Attack
|
||||||
|
if(envStage == 1) {
|
||||||
|
env += attack;
|
||||||
|
if(velPeak < env) {
|
||||||
|
env = velPeak;
|
||||||
|
envStage = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Decay
|
||||||
|
else if(envStage == 2) {
|
||||||
|
env -= decay;
|
||||||
|
if(env < velSustain || MAX_ENV_GAIN < env) {
|
||||||
|
env = velSustain;
|
||||||
|
envStage = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Sustain
|
||||||
|
else if (envStage == 3) {
|
||||||
|
env = velSustain;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release
|
||||||
|
else if (envStage == 4) {
|
||||||
|
env -= release;
|
||||||
|
if(MAX_ENV_GAIN < env) {
|
||||||
|
env = 0;
|
||||||
|
envStage = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No gain
|
||||||
|
else if (envStage == 0) {
|
||||||
|
env = 0;
|
||||||
|
accumulator1 = 0;
|
||||||
|
accumulator2 = 0;
|
||||||
|
accumulator3 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
env = 65535;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adding the amplification envelope (16bit) we bring it back to the 16bit frame again afterwards.
|
||||||
|
sample = (env * sample) >> 16;
|
||||||
|
|
||||||
|
|
||||||
|
// Formatting the samples to be transfered to the MCP4921 DAC
|
||||||
|
dacSPI0 = sample >> 8;
|
||||||
|
dacSPI0 >>= 4;
|
||||||
|
dacSPI0 |= 0x30;
|
||||||
|
dacSPI1 = sample >> 4;
|
||||||
|
|
||||||
|
SPCR |= (1 << MSTR);
|
||||||
|
|
||||||
|
// transmit value out the SPI port
|
||||||
|
SPDR = dacSPI0;
|
||||||
|
while (!(SPSR & (1<<SPIF))); // Maybe this can be optimised
|
||||||
|
SPDR = dacSPI1;
|
||||||
|
while (!(SPSR & (1<<SPIF))); // Maybe this can be optimised
|
||||||
|
|
||||||
|
// Frame sync high
|
||||||
|
PORTD |= (1<<6);
|
||||||
|
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Wavetable.h - Music library
|
Music.h - Music library
|
||||||
Copyright (c) 2012 Copenhagen Institute of Interaction Design.
|
Copyright (c) 2012 Copenhagen Institute of Interaction Design.
|
||||||
All right reserved.
|
All right reserved.
|
||||||
|
|
||||||
@ -21,6 +21,10 @@
|
|||||||
+ contact: j.bak@ciid.dk
|
+ contact: j.bak@ciid.dk
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
//uint32_t envTimeTable[] = {1,2,5,8,11,14,18,22,27,31,36,41,46,52,58,64,70,76,82,89,96,103,110,117,125,132,140,148,156,164,172,181,189,198,207,216,225,234,243,252,262,272,281,291,301,311,322,332,343,353,364,374,385,396,407,419,430,441,453,464,476,488,500,512,524,536,548,560,573,585,598,610,623,636,649,662,675,688,702,715,729,742,756,769,783,797,811,825,839,853,868,882,896,911,925,940,955,970,985,1000,1015,1030,1045,1060,1075,1091,1106,1122,1137,1153,1169,1185,1201,1217,1233,1249,1265,1281,1298,1314,1331,1347,1364,1380,1397,1414,1431,1448,1465,1482,1499,1516,1533,1551,1568,1586,1603,1621,1638,1656,1674,1692,1710,1728,1746,1764,1782,1800,1818,1837,1855,1873,1892,1911,1929,1948,1967,1986,2004,2023,2042,2061,2081,2100,2119,2138,2158,2177,2197,2216,2236,2255,2275,2295,2315,2334,2354,2374,2394,2414,2435,2455,2475,2495,2516,2536,2557,2577,2598,2618,2639,2660,2681,2702,2723,2744,2765,2786,2807,2828,2849,2870,2892,2913,2935,2956,2978,2999,3021,3043,3064,3086,3108,3130,3152,3174,3196,3218,3240,3263,3285,3307,3330,3352,3375,3397,3420,3442,3465,3488,3510,3533,3556,3579,3602,3625,3648,3671,3694,3718,3741,3764,3787,3811,3834,3858,3881,3905,3929,3952,3976,4000,4024,4048,4072,4095};
|
||||||
|
|
||||||
|
//prog_uint16_t hertzTable[] PROGMEM = {8,8,9,9,10,10,11,12,12,13,14,15,16,17,18,19,20,21,23,24,25,27,29,30,32,34,36,38,41,43,46,48,51,54,58,61,65,69,73,77,82,87,92,97,103,109,116,123,130,138,146,155,164,174,184,195,207,219,233,246,261,277,293,311,329,349,369,391,415,440,466,493,523,554,587,622,659,698,739,783,830,880,932,987,1046,1108,1174,1244,1318,1396,1479,1567,1661,1760,1864,1975,2093,2217,2349,2489,2637,2793,2959,3135,3322,3520,3729,3951,4186,4434,4698,4978,5274,5587,5919,6271,6644,7040,7458,7902,8372,8869,9397,9956,10548,11175,11839,12543};
|
||||||
|
|
||||||
// Look-up table for sine waveform in 12 bit resolution in
|
// Look-up table for sine waveform in 12 bit resolution in
|
||||||
// both amplitude and time.
|
// both amplitude and time.
|
||||||
|
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
Put Motion Tutorial sketches in this folder
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
//"Pulse" - small duration positive then negative force
|
|
||||||
// parameters: F1, T1, D1, F2, T2, D2
|
|
||||||
|
|
||||||
#define BIT_DEPTH 12
|
|
||||||
|
|
||||||
#include <Motor.h>
|
|
||||||
#include <Music.h>
|
|
||||||
|
|
||||||
void setup(){
|
|
||||||
MotorA.init();
|
|
||||||
Music.init();
|
|
||||||
|
|
||||||
Music.setWaveform(SINE);
|
|
||||||
Music.enableEnvelope();
|
|
||||||
Music.setAttack(10);
|
|
||||||
Music.setDecay(10);
|
|
||||||
Music.setRelease(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop(){
|
|
||||||
MotorA.torque(200);
|
|
||||||
Music.noteOn(map(analogRead(A3),0,1023,30,60));
|
|
||||||
delay (20);
|
|
||||||
Music.noteOff();MotorA.torque(0);
|
|
||||||
delay (150);
|
|
||||||
MotorA.torque(-200);
|
|
||||||
Music.noteOn(map(analogRead(A3),0,1023,35,65));
|
|
||||||
delay (40);
|
|
||||||
Music.noteOff();MotorA.torque(0);
|
|
||||||
MotorA.torque(0);
|
|
||||||
delay (750);
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
// Center - both motors A and B
|
|
||||||
// feels like "Double Toggle"!
|
|
||||||
|
|
||||||
#include <Motor.h>
|
|
||||||
|
|
||||||
int duty, count, fout;
|
|
||||||
int xA, xB, foutA, foutB;
|
|
||||||
|
|
||||||
void setup(){
|
|
||||||
Serial.begin(9600);
|
|
||||||
MotorA.init();
|
|
||||||
MotorB.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop(){
|
|
||||||
|
|
||||||
xA = analogRead(A0);
|
|
||||||
xB = analogRead(A3);
|
|
||||||
foutA = 6*(xB-512); // this will peak at x=1024/6
|
|
||||||
MotorA.torque(foutA); // 1/4 or 1/2 ?
|
|
||||||
|
|
||||||
foutB = 6*(xA-512); // this will peak at x=1024/6
|
|
||||||
MotorB.torque(foutB); // 1/4 or 1/2 ?
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
// CenterAB - both motors
|
|
||||||
// xA->Freqequency1, xB->Frequency2
|
|
||||||
//CenterA at xB, CenterB at xA
|
|
||||||
//feels like "Slave"
|
|
||||||
|
|
||||||
#include <Motor.h>
|
|
||||||
#include <Music.h>
|
|
||||||
#define BIT_DEPTH 8
|
|
||||||
#define NUM_OSCILLATORS 2
|
|
||||||
|
|
||||||
int duty, count, fout;
|
|
||||||
int xA, xB, foutA, foutB;
|
|
||||||
|
|
||||||
void setup(){
|
|
||||||
Serial.begin(9600);
|
|
||||||
MotorA.init();
|
|
||||||
MotorB.init();
|
|
||||||
Music.init();
|
|
||||||
Music.setWaveform1(0);//8bit default?
|
|
||||||
Music.setWaveform2(0);
|
|
||||||
Music.setGain1(1.0f);
|
|
||||||
Music.setGain2(1.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop(){
|
|
||||||
|
|
||||||
xA = analogRead(A0);
|
|
||||||
Music.setFrequency1(map (xA, 0, 1023, 40, 2000));
|
|
||||||
|
|
||||||
xB = analogRead(A3);
|
|
||||||
Music.setFrequency2(map (xB, 0, 1023, 40, 2000));
|
|
||||||
|
|
||||||
foutA = -6*(xA-xB); // this will peak at x=1024/6
|
|
||||||
MotorA.torque(foutA); // 1/4 or 1/2 ?
|
|
||||||
|
|
||||||
foutB = -6*(xB-xA); // this will peak at x=1024/6
|
|
||||||
MotorB.torque(foutB); // 1/4 or 1/2 ?
|
|
||||||
|
|
||||||
Music.setGain(float(abs(xA-xB))/1024.0f);
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
// Theremin
|
|
||||||
// A: pitch, B: volume
|
|
||||||
|
|
||||||
#include <Music.h>
|
|
||||||
int xA, xB; //10bit A/D gives 0-1023
|
|
||||||
float p; //midi note number 0-127
|
|
||||||
double frequency, volume;
|
|
||||||
byte c; //print every 256 cycles
|
|
||||||
|
|
||||||
void setup(){
|
|
||||||
Music.init();
|
|
||||||
Serial.begin(9600);
|
|
||||||
}
|
|
||||||
void loop(){
|
|
||||||
xA = analogRead(A3); // A position
|
|
||||||
p = float(xA)/8; //pitch (midi)
|
|
||||||
|
|
||||||
p = 80.*(p/128.)+20.;
|
|
||||||
// p = map(p, 0,127,20,100);
|
|
||||||
//linear mapping of p
|
|
||||||
//The map() function uses integer math so will
|
|
||||||
//not generate fractions, when the math might
|
|
||||||
//indicate that it should do so. Fractional
|
|
||||||
//remainders are truncated, and are not rounded
|
|
||||||
//or averaged.
|
|
||||||
//
|
|
||||||
frequency = pow(2,((p-69.)/12.))*440; //midi 69 -> 440hz
|
|
||||||
Music.setFrequency(frequency);
|
|
||||||
|
|
||||||
xB = analogRead(A0);
|
|
||||||
volume = -float(xB)/1024.; // B position
|
|
||||||
volume = pow(10,volume);
|
|
||||||
Music.setGain(volume);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,48 +0,0 @@
|
|||||||
//Pluck: one pluck at x=512
|
|
||||||
|
|
||||||
int x, fout, count;
|
|
||||||
float f;
|
|
||||||
float w = 50; //width of pluck
|
|
||||||
float h = 500; //height of pluck
|
|
||||||
float slope = h/w;
|
|
||||||
boolean forward = true;
|
|
||||||
|
|
||||||
#include <Motor.h>
|
|
||||||
|
|
||||||
void setup(){
|
|
||||||
MotorA.init();
|
|
||||||
MotorB.init();
|
|
||||||
Serial.begin(9600);
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop(){
|
|
||||||
x = analogRead(A0) - 512;
|
|
||||||
if (forward){
|
|
||||||
if (x <= - w/2) f = 0;
|
|
||||||
if (x > -w/2 && x< w/2) f = - slope*(x + w/2);
|
|
||||||
if (x > w/2){
|
|
||||||
f = 0;
|
|
||||||
forward = false;
|
|
||||||
Serial.println("pluck forward");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (x > w/2) f = 0;
|
|
||||||
if (x < w/2 && x > -w/2) f = - slope*(x - w/2);
|
|
||||||
if (x < -w/2){
|
|
||||||
f = 0;
|
|
||||||
forward = true;
|
|
||||||
Serial.println("pluck back");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fout = int(f);
|
|
||||||
MotorA.torque(fout);
|
|
||||||
|
|
||||||
if(count++>=0){
|
|
||||||
count=-1000; // wait 1000 loops before print
|
|
||||||
Serial.print(x,DEC);
|
|
||||||
Serial.print(" ");
|
|
||||||
Serial.println(fout,DEC);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,90 +0,0 @@
|
|||||||
<<<<<<< HEAD:software/lib/MMM/examples/Motion/_6_Bumps/_6_Bumps.ino
|
|
||||||
//Plucks - four bumps / three notes (400,500,600hz)
|
|
||||||
#define NUM_OSCILLATORS 3
|
|
||||||
=======
|
|
||||||
//plucks - four bumps
|
|
||||||
//three notes (400,500,600hz)
|
|
||||||
//can't get Music.setGain1, etc to work only Music.setGain() starts all of them.
|
|
||||||
#define NUM_OSCILLATORS 3
|
|
||||||
#define BIT_DEPTH 8
|
|
||||||
>>>>>>> update notes to motion.cpp:software/apps/Modeling/Bumps4/Bumps4.ino
|
|
||||||
#include <Music.h>
|
|
||||||
#include <Motor.h>
|
|
||||||
|
|
||||||
int x, xold, xt, F; // input position x, output force F
|
|
||||||
int K = 10; // slope constant
|
|
||||||
byte count; //for print count-down
|
|
||||||
|
|
||||||
void setup(){
|
|
||||||
Music.init();
|
|
||||||
Music.setFrequency1(200);
|
|
||||||
Music.setFrequency2(250);
|
|
||||||
Music.setFrequency3(300);
|
|
||||||
|
|
||||||
MotorA.init();
|
|
||||||
|
|
||||||
Serial.begin(9600);
|
|
||||||
x = analogRead(A0); // initialize x
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop(){
|
|
||||||
|
|
||||||
xold = x;
|
|
||||||
x = analogRead(A0);
|
|
||||||
|
|
||||||
if (((xold <= 125) && (x > 125)) || ((xold >= 125) && (x < 125))){
|
|
||||||
Music.setGain1(1.0f);
|
|
||||||
<<<<<<< HEAD:software/lib/MMM/examples/Motion/_6_Bumps/_6_Bumps.ino
|
|
||||||
}
|
|
||||||
if (((xold <= 375) && (x > 375)) || ((xold >= 375) && (x < 375))){
|
|
||||||
Music.setGain2(1.0f);
|
|
||||||
}
|
|
||||||
if (((xold <= 625) && (x > 625)) || ((xold >= 625) && (x < 625))){
|
|
||||||
Music.setGain3(1.0f);
|
|
||||||
}
|
|
||||||
if (((xold <= 875) && (x > 875)) || ((xold >= 875) && (x < 875))){
|
|
||||||
Music.setGain1(1.0f);
|
|
||||||
=======
|
|
||||||
Music.setFrequency1(200);
|
|
||||||
}
|
|
||||||
if (((xold <= 375) && (x > 375)) || ((xold >= 375) && (x < 375))){
|
|
||||||
Music.setGain2(1.0f);
|
|
||||||
Music.setFrequency2(250);
|
|
||||||
}
|
|
||||||
if (((xold <= 625) && (x > 625)) || ((xold >= 625) && (x < 625))){
|
|
||||||
Music.setGain3(1.0f);
|
|
||||||
Music.setFrequency3(300);
|
|
||||||
}
|
|
||||||
if (((xold <= 875) && (x > 875)) || ((xold >= 875) && (x < 875))){
|
|
||||||
Music.setGain1(1.0f);
|
|
||||||
Music.setFrequency1(400);
|
|
||||||
>>>>>>> update notes to motion.cpp:software/apps/Modeling/Bumps4/Bumps4.ino
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
Music.setGain1(0.995f*Music.getGain1());
|
|
||||||
Music.setGain2(0.995f*Music.getGain2());
|
|
||||||
Music.setGain3(0.995f*Music.getGain3());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
xt = x % 250; //same force for each 250 ranage
|
|
||||||
F = 0;
|
|
||||||
if (xt > 60) F = - K * (xt - 60);
|
|
||||||
if (xt > 80) F = - K * (100 - xt);
|
|
||||||
if (xt > 120) F = K * (140 - xt);
|
|
||||||
if (xt > 140) F = 0;
|
|
||||||
MotorA.torque(F);
|
|
||||||
|
|
||||||
|
|
||||||
// print every 256 cycles
|
|
||||||
if(count++==0){
|
|
||||||
Serial.print(x);
|
|
||||||
Serial.print(" ");
|
|
||||||
Serial.print(xt);
|
|
||||||
Serial.print(" ");
|
|
||||||
Serial.println(F);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,86 +0,0 @@
|
|||||||
/*
|
|
||||||
This sketch runs with Processing sketch Oscilloscope.pde
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <Motion.h>
|
|
||||||
#include <Motor.h>
|
|
||||||
#include <Music.h>
|
|
||||||
|
|
||||||
char buf[16] = "";
|
|
||||||
|
|
||||||
char b = 'x';
|
|
||||||
String inputString = "";
|
|
||||||
boolean stringComplete = false;
|
|
||||||
|
|
||||||
float k, m, d;
|
|
||||||
|
|
||||||
int cnt = 0;
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
|
|
||||||
// MOTOR
|
|
||||||
MotorA.init();
|
|
||||||
|
|
||||||
// MUSIC
|
|
||||||
Music.init();
|
|
||||||
|
|
||||||
// MOTION
|
|
||||||
MotionA.init(INPUTA0);
|
|
||||||
MotionA.k = 5.2f; // spring
|
|
||||||
MotionA.m = 1.0f; // mass
|
|
||||||
MotionA.d = 8.02f; // damping
|
|
||||||
|
|
||||||
// Serial
|
|
||||||
Serial.begin(9600);
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
|
|
||||||
MotionA.update_mass_spring_damper();
|
|
||||||
|
|
||||||
MotorA.torque(MotionA.F);
|
|
||||||
|
|
||||||
int f = map(abs(MotionA.F), 0, 512, 64, 76);
|
|
||||||
Music.noteOn(f);
|
|
||||||
|
|
||||||
cnt++;
|
|
||||||
|
|
||||||
if(cnt == 10) {
|
|
||||||
sprintf(buf, "%d %d %d %d", (int)MotionA.F, (int)MotionA.V, (int)MotionA.X, (int)MotionA.Xin);
|
|
||||||
Serial.println(buf);
|
|
||||||
cnt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stringComplete) {
|
|
||||||
if(b == 'k') {
|
|
||||||
MotionA.k = convertToFloat(inputString);
|
|
||||||
} else if(b == 'm') {
|
|
||||||
MotionA.m = convertToFloat(inputString);
|
|
||||||
} else if(b == 'd') {
|
|
||||||
MotionA.d = convertToFloat(inputString);
|
|
||||||
}
|
|
||||||
b = 'x';
|
|
||||||
stringComplete = false;
|
|
||||||
inputString = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void serialEvent() {
|
|
||||||
while (Serial.available()) {
|
|
||||||
char inChar = (char)Serial.read();
|
|
||||||
if(inChar == 'k' || inChar == 'm' || inChar == 'd') {
|
|
||||||
b = inChar;
|
|
||||||
} else {
|
|
||||||
if (inChar == ';') {
|
|
||||||
stringComplete = true;
|
|
||||||
} else
|
|
||||||
inputString += inChar;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float convertToFloat(String str) {
|
|
||||||
char buf[16] = "";
|
|
||||||
str.toCharArray(buf, str.length() + 1);
|
|
||||||
return atof(buf);
|
|
||||||
}
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
//FM synthes of a sort
|
|
||||||
//hang on! it's unstable and wants to limit cycle
|
|
||||||
|
|
||||||
#define BIT_DEPTH 8 // gives us 16 Waveforms
|
|
||||||
|
|
||||||
#include <Music.h>
|
|
||||||
|
|
||||||
#include <Motor.h>
|
|
||||||
|
|
||||||
byte cnt;
|
|
||||||
float xf, vf; //
|
|
||||||
float k = 10.0; // increase FM frequency
|
|
||||||
float b = 0.40; // increase
|
|
||||||
float Tf = .030 ; //integration time
|
|
||||||
|
|
||||||
void setup(){
|
|
||||||
Serial.begin(9600);
|
|
||||||
Music.init();
|
|
||||||
Music.setWaveform(0);
|
|
||||||
Music.setGain(1.0f);
|
|
||||||
MotorA.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop(){
|
|
||||||
xf += vf * Tf;
|
|
||||||
vf += (k * (analogRead(A0) - xf) - b*vf) * Tf;
|
|
||||||
Music.setFrequency(100+vf);
|
|
||||||
Music.setGain(.001*abs(vf));
|
|
||||||
MotorA.torque(-500+xf);
|
|
||||||
//if(cnt++==0)Serial.println(.001*abs(vf));
|
|
||||||
}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Put Motor Tutorial sketches in this folder
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
#include <Motor.h>
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
MotorA.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
MotorA.torque(500);
|
|
||||||
delay(2000);
|
|
||||||
MotorA.torque(-500);
|
|
||||||
delay(2000);
|
|
||||||
}
|
|
||||||
@ -1,67 +0,0 @@
|
|||||||
|
|
||||||
#include <Motion.h>
|
|
||||||
#include <Motor.h>
|
|
||||||
|
|
||||||
#define NEW '!'
|
|
||||||
#define OK '*'
|
|
||||||
#define PRINT '&'
|
|
||||||
|
|
||||||
int table[800];
|
|
||||||
int len = 800;
|
|
||||||
|
|
||||||
char buf[32] = "";
|
|
||||||
int cnt = 0;
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
Serial.begin(9600);
|
|
||||||
MotorA.init();
|
|
||||||
MotionA.init(INPUTA0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
MotionA.update_position();
|
|
||||||
int i = (int) (((float) MotionA.Xin / 1023.0) * len);
|
|
||||||
int f = table[i];
|
|
||||||
MotorA.torque(f);
|
|
||||||
|
|
||||||
// TODO - send position back to interface
|
|
||||||
/*
|
|
||||||
cnt++;
|
|
||||||
if(cnt == 1000) {
|
|
||||||
sprintf(buf, "%d %d %d", MotionA.Xin, i, f);
|
|
||||||
Serial.println(buf);
|
|
||||||
cnt = 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void serialEvent() {
|
|
||||||
|
|
||||||
if(Serial.available()) {
|
|
||||||
char in = (char)Serial.read();
|
|
||||||
if(in == NEW) {
|
|
||||||
Serial.print(OK);
|
|
||||||
len = serial_read();
|
|
||||||
for(int i = 0; i < len; i++) {
|
|
||||||
table[i] = serial_read();
|
|
||||||
}
|
|
||||||
} else if(in == PRINT) {
|
|
||||||
Serial.println(len);
|
|
||||||
for(int i = 0; i < len; i++) {
|
|
||||||
Serial.print(table[i]);
|
|
||||||
Serial.print(';');
|
|
||||||
}
|
|
||||||
Serial.print('#');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int serial_read() {
|
|
||||||
while(Serial.available() < 2);
|
|
||||||
int l = Serial.read();
|
|
||||||
int h = Serial.read();
|
|
||||||
Serial.write(OK);
|
|
||||||
return (h * 256) + l;
|
|
||||||
}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Put Music Tutorial sketches in this folder
|
|
||||||
@ -1,126 +0,0 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////
|
|
||||||
// DON'T TRY TO RUN THIS SKETCH, IT IS FOR DOCUMENTATION PURPOSES ONLY //
|
|
||||||
/////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
// These are the music functions that are available for you to use in you sketches.
|
|
||||||
// You can see examples of how some of them are used (the most basic ones) in the
|
|
||||||
// Apps folder that downloaded with the MM library.
|
|
||||||
|
|
||||||
// In the following you can see the variable type that the function takes as an argument (float, uint8_t or uint16_t)
|
|
||||||
// The weirdly looking "uint16_t" and "uint8_t" is just unsigned 16 and 8 bit integers. So instead of having
|
|
||||||
// both negative and positive values, they only have positive values from 0 - 255 (8bit) and 0 - 65535 (16bit).
|
|
||||||
// If you copy a function from here to your arduino sketch, just change the word "float", "uint8_t", etc into the
|
|
||||||
// variable name that you uses in your sketch.
|
|
||||||
|
|
||||||
// PRE-PROCESSING COMMANDS
|
|
||||||
#define NUM_OSCILLATORS 3 // define the use of 1, 2 or 3 oscillators
|
|
||||||
#define BIT_DEPTH 12 // define the bit depth resolution of 8 or 12 bit waveforms
|
|
||||||
#define MIDI // tell the system you will be using the MIDI part of the sound engine
|
|
||||||
#define MIDI_CHANNEL 1 // set the MIDI channel to listen to. Between 1 and 16
|
|
||||||
#define FM // tell the library to use the FM synthesis mode
|
|
||||||
|
|
||||||
#include <Music.h>
|
|
||||||
|
|
||||||
// INITIALIZERS
|
|
||||||
// Use this in the setup() function to start the synth engine.
|
|
||||||
// It defaults to a sine tone at 110Hz, no envelope and no detune.
|
|
||||||
Music.init();
|
|
||||||
|
|
||||||
// Use this in the setup() function to start the MIDI engine. It sets up the serial communication.
|
|
||||||
Midi.init();
|
|
||||||
|
|
||||||
// MIDI FUNCTIONS
|
|
||||||
Midi.checkMidi() // put this function in the loop() function in your
|
|
||||||
// Arduino sketch to check for incoming MIDI activity
|
|
||||||
|
|
||||||
// FREQUENCY AND DETUNE FUNCTIONS
|
|
||||||
// Use these functions to set the frequency and detune parameters of the synth.
|
|
||||||
Music.setFrequency(float); // Set base frequencies of all oscillators at once. Does _not_ affect detune or semitone
|
|
||||||
Music.setFrequency1(float); // Set base frequency of individual oscillators.
|
|
||||||
Music.setFrequency2(float); // Sounds best between 20Hz and 4000Hz
|
|
||||||
Music.setFrequency3(float); //
|
|
||||||
Music.setDetune(float); // Set the detune offset of all oscillators at once. Oscillator 1 stays fixed at it's base frequency
|
|
||||||
Music.setDetune1(float); // Set the detune of oscillator 1,2 and 3 individually
|
|
||||||
Music.setDetune2(float); // Sounds best between 0.00 and 0.02
|
|
||||||
Music.setDetune3(float); //
|
|
||||||
Music.setSemitone1(int8_t); // Set the semitone offset of base frequency in musical halftones relative to base frequency
|
|
||||||
Music.setSemitone2(int8_t); // Goes from -24 halftones to +24 halftones
|
|
||||||
Music.setSemitone3(int8_t);
|
|
||||||
Music.setFM2(uint8_t); // Set the amount of frequency modulation (FM) on oscillator2.
|
|
||||||
|
|
||||||
|
|
||||||
// WAVEFORM FUNCTIONS
|
|
||||||
// Switch between the different waveforms for the oscillators. ONLY FOR 8BIT MODE!
|
|
||||||
Music.setWaveform(uint16_t); // This sets waveform of all oscillators at once.
|
|
||||||
Music.setWaveform1(uint16_t); // Takes a number from 0-15
|
|
||||||
Music.setWaveform2(uint16_t); // Or take one of the macro names (in capitals) below for waveform types.
|
|
||||||
Music.setWaveform3(uint16_t);
|
|
||||||
// WAVEFORM TYPES
|
|
||||||
SINE
|
|
||||||
SQUARE
|
|
||||||
PULSE
|
|
||||||
TRIANGLE
|
|
||||||
SAW
|
|
||||||
FUZZ
|
|
||||||
DIGI1
|
|
||||||
DIGI2
|
|
||||||
DIGI3
|
|
||||||
DIGI4
|
|
||||||
NOISE
|
|
||||||
DIGI6
|
|
||||||
TAN1
|
|
||||||
TAN2
|
|
||||||
TAN3
|
|
||||||
TAN4
|
|
||||||
|
|
||||||
// GAIN FUNCTIONS
|
|
||||||
// Set the gain of the oscillators all at once or individually. Use floats between 0.0 and 1.0
|
|
||||||
Music.setGain(float); // 0.0 - 1.0
|
|
||||||
Music.setGain1(float); // 0.0 - 1.0
|
|
||||||
Music.setGain2(float); // 0.0 - 1.0
|
|
||||||
Music.setGain3(float); // 0.0 - 1.0
|
|
||||||
// You can also ask the sound engine
|
|
||||||
Music.getGain(); // outputs a float between 0.0 and 1.0
|
|
||||||
Music.getGain1(); //
|
|
||||||
Music.getGain2(); //
|
|
||||||
Music.getGain3(); //
|
|
||||||
|
|
||||||
|
|
||||||
// NOTE FUNCTIONS
|
|
||||||
// These functions triggers a note to be played. The noteOff() functions turns the note off again.
|
|
||||||
// They come both with note and velocity information (for noteOn). If you don't know what that is,
|
|
||||||
// just use the ones with the least arguments.
|
|
||||||
// To get a proper note sound call Music.enableEnvelopes() [see below] before calling the noteOn function.
|
|
||||||
// You just have to do that once in the setup for example.
|
|
||||||
Music.noteOn(uint8_t, uint8_t); // 0 - 127, first argument is the note number, the second is the velocity
|
|
||||||
Music.noteOn(uint8_t); // 0 - 127, here it is only note number and velocity defaults to 127
|
|
||||||
Music.noteOff(uint8_t); // 0 - 127, specify which note should be turned off (not necessary yet)
|
|
||||||
Music.noteOff(); // turns off last played note
|
|
||||||
// This function returns the frequency of a MIDI note number sent to it.
|
|
||||||
Music.getNoteFrequency(uint8_t); // input 0 - 127, returns a frequency in unsigned 16bit integers
|
|
||||||
|
|
||||||
|
|
||||||
// ENVELOPE FUNCTIONS
|
|
||||||
// These functions enables and sets the parameters of the internal envelope which creates dynamics for the notes
|
|
||||||
// being played. You can read about ADSR envelopes here: http://en.wikipedia.org/wiki/Synthesizer#ADSR_envelope
|
|
||||||
// When using the envelope you can only hear sound when you are triggering the notes with the note functions. In order
|
|
||||||
// to get dynamics without triggering the note object you must have the envelope turned off, for example using
|
|
||||||
// the Music.disableEnvelope() function [already set by default in the init() function]. You can then control the
|
|
||||||
// dynamics of the sound with the overall or individual setGain() functions.
|
|
||||||
Music.enableEnvelope();
|
|
||||||
Music.disableEnvelope();
|
|
||||||
|
|
||||||
// Alternately to using the noteOn/NoteOff functions you can set the envelope stage. Experiment with it :)
|
|
||||||
Music.setEnvStage(uint8_t); // 0 - 4, where 0 is in "silent" stage, 1 is attack, 2 is decay, 3 is sustain and 4 is release stage.
|
|
||||||
|
|
||||||
// Setting the parameters for the envelope you send an 8bit number between 0 and 127 to the functions below. 0 is a very fast
|
|
||||||
// rise or decay in sound, whereas 127 is very long. Sustain is the sound level where 0 is silent and 127 is full gain.
|
|
||||||
// You must experiment with what suits your musical taste :)
|
|
||||||
// These parameters can of course be adjusted during the physics code for interesting results, but be aware that when
|
|
||||||
// using the sine wave oscillator (which is more processor intensive) the sound can hang or have glitches if you alter
|
|
||||||
// these parameters too quickly or set them at extremes. Try it out.
|
|
||||||
Music.setAttack(uint8_t); // 0 - 127
|
|
||||||
Music.setDecay(uint8_t); // 0 - 127
|
|
||||||
Music.setSustain(uint8_t); // 0 - 127
|
|
||||||
Music.setRelease(uint8_t); // 0 - 127
|
|
||||||
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
// You can set the number of oscillators (1 to 3) and the bit depth of the
|
|
||||||
// oscillators (8 or 12 bit). These settings must be defined before the
|
|
||||||
// inclusion of the MMM library files. They default to 1 osciallator
|
|
||||||
// and 8bit respectively.
|
|
||||||
|
|
||||||
#define NUM_OSCILLATORS 1
|
|
||||||
#define BIT_DEPTH 12
|
|
||||||
|
|
||||||
// The Music object is automatically instantiated when the header file is
|
|
||||||
// included. Make calls to the Music objects wit "Music.function(args)".
|
|
||||||
// You still need to call Music.init() in the setup() function below.
|
|
||||||
#include <Music.h>
|
|
||||||
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
|
|
||||||
// We initialise the sound engine by calling Music.init() which outputs a tone
|
|
||||||
Music.init();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,56 +0,0 @@
|
|||||||
// You can set the number of oscillators (1 to 3) and the bit depth of the
|
|
||||||
// oscillators (8 or 12 bit). These settings must be defined before the
|
|
||||||
// inclusion of the MMM library files. They default to 1 osciallator
|
|
||||||
// and 8bit respectively.
|
|
||||||
|
|
||||||
#define NUM_OSCILLATORS 1
|
|
||||||
#define BIT_DEPTH 8
|
|
||||||
|
|
||||||
// The Music object is automatically instantiated when the header file is
|
|
||||||
// included. Make calls to the Music objects with "Music.function(args)".
|
|
||||||
// You still need to call Music.init() in the setup() function below.
|
|
||||||
#include <Music.h>
|
|
||||||
|
|
||||||
int delayTime = 2000;
|
|
||||||
int cnt = 0;
|
|
||||||
long timeNow;
|
|
||||||
long lastTime = 0;
|
|
||||||
|
|
||||||
byte waveFormArray[] = { SINE,
|
|
||||||
SQUARE,
|
|
||||||
PULSE,
|
|
||||||
TRIANGLE,
|
|
||||||
SAW,
|
|
||||||
FUZZ,
|
|
||||||
DIGI1,
|
|
||||||
DIGI2,
|
|
||||||
DIGI3,
|
|
||||||
DIGI4,
|
|
||||||
NOISE,
|
|
||||||
DIGI6,
|
|
||||||
TAN1,
|
|
||||||
TAN2,
|
|
||||||
TAN3,
|
|
||||||
TAN4
|
|
||||||
};
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
|
|
||||||
// We initialise the sound engine by calling Music.init() which outputs a tone
|
|
||||||
Music.init();
|
|
||||||
Music.setFrequency(220);
|
|
||||||
Music.setWaveform(SINE);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
|
|
||||||
timeNow = millis();
|
|
||||||
if((timeNow-lastTime) > delayTime) {
|
|
||||||
cnt = cnt + 1;
|
|
||||||
if(cnt>15) cnt = 0;
|
|
||||||
Music.setWaveform(waveFormArray[cnt]);
|
|
||||||
lastTime = timeNow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
// You can set the number of oscillators (1 to 3) and the bit depth of the
|
|
||||||
// oscillators (8 or 12 bit). These settings must be defined before the
|
|
||||||
// inclusion of the MMM library files. They default to 1 osciallator
|
|
||||||
// and 8bit respectively.
|
|
||||||
|
|
||||||
#define NUM_OSCILLATORS 3
|
|
||||||
#define BIT_DEPTH 8
|
|
||||||
|
|
||||||
// The Music object is automatically instantiated when the header file is
|
|
||||||
// included. Make calls to the Music objects with "Music.function(args)".
|
|
||||||
// You still need to call Music.init() in the setup() function below.
|
|
||||||
#include <Music.h>
|
|
||||||
|
|
||||||
int delayTime = 400;
|
|
||||||
int cnt = 0;
|
|
||||||
float baseFrequency = 110;
|
|
||||||
long timeNow;
|
|
||||||
long lastTime = 0;
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
|
|
||||||
// We initialise the sound engine by calling Music.init() which outputs a tone
|
|
||||||
Music.init();
|
|
||||||
Music.setFrequency(220);
|
|
||||||
Music.setDetune(0.001); // ranges from 0.00 - 0.02 are usually good
|
|
||||||
Music.setWaveform(SAW);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
|
|
||||||
timeNow = millis();
|
|
||||||
if((timeNow-lastTime) > delayTime) {
|
|
||||||
cnt = cnt + 1;
|
|
||||||
if(cnt>3) cnt = 0;
|
|
||||||
Music.setFrequency1(baseFrequency*1*cnt);
|
|
||||||
Music.setFrequency2(baseFrequency*1.3333*cnt);
|
|
||||||
Music.setFrequency3(baseFrequency*1.5*cnt);
|
|
||||||
lastTime = timeNow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
// You can set the number of oscillators (1 to 3) and the bit depth of the
|
|
||||||
// oscillators (8 or 12 bit). These settings must be defined before the
|
|
||||||
// inclusion of the MMM library files. They default to 1 osciallator
|
|
||||||
// and 8bit respectively.
|
|
||||||
|
|
||||||
#define NUM_OSCILLATORS 3
|
|
||||||
#define BIT_DEPTH 8
|
|
||||||
|
|
||||||
// The Music object is automatically instantiated when the header file is
|
|
||||||
// included. Make calls to the Music objects with "Music.function(args)".
|
|
||||||
// You still need to call Music.init() in the setup() function below.
|
|
||||||
#include <Music.h>
|
|
||||||
|
|
||||||
int delayTime = 100;
|
|
||||||
int cnt = 0;
|
|
||||||
float baseFrequency = 110;
|
|
||||||
long timeNow;
|
|
||||||
long lastTime = 0;
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
|
|
||||||
// We initialise the sound engine by calling Music.init() which outputs a tone
|
|
||||||
Music.init();
|
|
||||||
Music.setFrequency(220);
|
|
||||||
Music.setDetune(0.005); // ranges from 0.00 - 0.02 are usually good
|
|
||||||
Music.setWaveform(PULSE);
|
|
||||||
Music.setFrequency1(baseFrequency*1);
|
|
||||||
Music.setFrequency2(baseFrequency*1.3333);
|
|
||||||
Music.setFrequency3(baseFrequency*1.5);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
|
|
||||||
timeNow = millis();
|
|
||||||
if((timeNow-lastTime) > delayTime) {
|
|
||||||
cnt = cnt + 1;
|
|
||||||
if(cnt>16) cnt = 0;
|
|
||||||
float counter = float(cnt);
|
|
||||||
Music.setGain1(1.0/cnt);
|
|
||||||
Music.setGain2(1.0/cnt);
|
|
||||||
Music.setGain3(1.0/cnt);
|
|
||||||
lastTime = timeNow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
// You can set the number of oscillators (1 to 3) and the bit depth of the
|
|
||||||
// oscillators (8 or 12 bit). These settings must be defined before the
|
|
||||||
// inclusion of the MMM library files. They default to 1 osciallator
|
|
||||||
// and 8bit respectively.
|
|
||||||
|
|
||||||
#define NUM_OSCILLATORS 3
|
|
||||||
#define BIT_DEPTH 8
|
|
||||||
|
|
||||||
// The Music object is automatically instantiated when the header file is
|
|
||||||
// included. Make calls to the Music objects with "Music.function(args)".
|
|
||||||
// You still need to call Music.init() in the setup() function below.
|
|
||||||
#include <Music.h>
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
|
|
||||||
// We initialise the sound engine by calling Music.init() which outputs a tone
|
|
||||||
Music.init();
|
|
||||||
Music.setFrequency(110);
|
|
||||||
Music.setDetune(0.005); // ranges from 0.00 - 0.02 are usually good
|
|
||||||
Music.setWaveform(DIGI2);
|
|
||||||
Music.setSemitone1(0);
|
|
||||||
Music.setSemitone2(7);
|
|
||||||
Music.setSemitone3(-12);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,36 +0,0 @@
|
|||||||
// The Music object is automatically instantiated when the header file is
|
|
||||||
// included. Make calls to the Music objects with "Music.function(args)".
|
|
||||||
// You still need to call Music.init() in the setup() function below.
|
|
||||||
#define NUM_OSCILLATORS 3
|
|
||||||
#define BIT_DEPTH 8
|
|
||||||
#define MIDI
|
|
||||||
#define MIDI_CHANNEL 1
|
|
||||||
#include <Music.h>
|
|
||||||
|
|
||||||
long timeNow = 0;
|
|
||||||
long lastTime = 0;
|
|
||||||
long delayTime = 400; //in milliseconds
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
|
|
||||||
// We initialise the sound engine by calling Music.init() which outputs a tone
|
|
||||||
Music.init();
|
|
||||||
Music.enableEnvelope();
|
|
||||||
Midi.init();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
|
|
||||||
// In order to send MIDI to the sketch, use the Music_Controls_4.pde Processing sketch
|
|
||||||
Midi.checkMidi();
|
|
||||||
|
|
||||||
// The below code is an example of triggering the noteOn function to play some sounds
|
|
||||||
timeNow = millis();
|
|
||||||
if((timeNow - lastTime) > delayTime) {
|
|
||||||
Music.noteOn(64);
|
|
||||||
lastTime = timeNow;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
// You can set the number of oscillators (1 to 3) and the bit depth of the
|
|
||||||
// oscillators (8 or 12 bit). These settings must be defined before the
|
|
||||||
// inclusion of the MMM library files. They default to 1 oscallator
|
|
||||||
// and 8bit respectively.
|
|
||||||
#define FM // tell the library to use FM synthesis
|
|
||||||
#define NUM_OSCILLATORS 2
|
|
||||||
#define BIT_DEPTH 12
|
|
||||||
|
|
||||||
#include <Music.h>
|
|
||||||
|
|
||||||
long time;
|
|
||||||
long lastTime = 0;
|
|
||||||
long eventTime = 10;
|
|
||||||
int cnt = 0;
|
|
||||||
int dir = 1;
|
|
||||||
|
|
||||||
void setup() {
|
|
||||||
|
|
||||||
// We initialise the sound engine by calling Music.init() which outputs a tone
|
|
||||||
Music.init();
|
|
||||||
Music.setFM2(0); // this value is already defaulted to 0 in Music.init()
|
|
||||||
Music.setFrequency2(148.3); // This is the base frequency of the audible oscillator
|
|
||||||
Music.setFrequency1(487.78); // This is the modulating frequency
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void loop() {
|
|
||||||
// This code increases the FM amount from 0 to 127 and back again in intervals defined by "eventTime"
|
|
||||||
time = millis();
|
|
||||||
if(time-lastTime > eventTime) {
|
|
||||||
Music.setFM2(cnt);
|
|
||||||
cnt += dir;
|
|
||||||
if(cnt <= 0 || cnt >= 127) dir *= -1;
|
|
||||||
lastTime = time;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,91 +0,0 @@
|
|||||||
#######################################
|
|
||||||
# Syntax Coloring Map For MMM Library
|
|
||||||
#######################################
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Datatypes (KEYWORD1)
|
|
||||||
#######################################
|
|
||||||
|
|
||||||
Music KEYWORD1
|
|
||||||
MotorA KEYWORD1
|
|
||||||
MotorB KEYWORD1
|
|
||||||
MotionA KEYWORD1
|
|
||||||
MotionB KEYWORD1
|
|
||||||
Midi KEYWORD1
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Methods and Functions (KEYWORD2)
|
|
||||||
#######################################
|
|
||||||
|
|
||||||
init KEYWORD2
|
|
||||||
checkMidi KEYWORD2
|
|
||||||
enableEnvelope KEYWORD2
|
|
||||||
disableEnvelope KEYWORD2
|
|
||||||
setEnvStage KEYWORD2
|
|
||||||
setDetune KEYWORD2
|
|
||||||
setDetune1 KEYWORD2
|
|
||||||
setDetune2 KEYWORD2
|
|
||||||
setDetune3 KEYWORD2
|
|
||||||
setFrequency KEYWORD2
|
|
||||||
setFrequency1 KEYWORD2
|
|
||||||
setFrequency2 KEYWORD2
|
|
||||||
setFrequency3 KEYWORD2
|
|
||||||
setSemitone1 KEYWORD2
|
|
||||||
setSemitone2 KEYWORD2
|
|
||||||
setSemitone3 KEYWORD2
|
|
||||||
setWaveform KEYWORD2
|
|
||||||
setWaveform1 KEYWORD2
|
|
||||||
setWaveform2 KEYWORD2
|
|
||||||
setWaveform3 KEYWORD2
|
|
||||||
setGain KEYWORD2
|
|
||||||
setGain1 KEYWORD2
|
|
||||||
setGain2 KEYWORD2
|
|
||||||
setGain3 KEYWORD2
|
|
||||||
getGain KEYWORD2
|
|
||||||
getGain1 KEYWORD2
|
|
||||||
getGain2 KEYWORD2
|
|
||||||
getGain3 KEYWORD2
|
|
||||||
noteOn KEYWORD2
|
|
||||||
noteOff KEYWORD2
|
|
||||||
getNoteFrequency KEYWORD2
|
|
||||||
setAttack KEYWORD2
|
|
||||||
setDecay KEYWORD2
|
|
||||||
setSustain KEYWORD2
|
|
||||||
setRelease KEYWORD2
|
|
||||||
update_position KEYWORD2
|
|
||||||
update_mass_spring_damper KEYWORD2
|
|
||||||
torque KEYWORD2
|
|
||||||
direction KEYWORD2
|
|
||||||
stop KEYWORD2
|
|
||||||
start KEYWORD2
|
|
||||||
restart KEYWORD2
|
|
||||||
setFM2 KEYWORD2
|
|
||||||
|
|
||||||
|
|
||||||
#######################################
|
|
||||||
# Constants (LITERAL1)
|
|
||||||
#######################################
|
|
||||||
|
|
||||||
NUM_OSCILLATORS LITERAL1
|
|
||||||
BIT_DEPTH LITERAL1
|
|
||||||
MIDI LITERAL1
|
|
||||||
MIDI_CHANNEL LITERAL1
|
|
||||||
FM LITERAL1
|
|
||||||
CFO LITERAL1
|
|
||||||
|
|
||||||
SINE LITERAL1
|
|
||||||
SQUARE LITERAL1
|
|
||||||
PULSE LITERAL1
|
|
||||||
TRIANGLE LITERAL1
|
|
||||||
SAW LITERAL1
|
|
||||||
FUZZ LITERAL1
|
|
||||||
DIGI1 LITERAL1
|
|
||||||
DIGI2 LITERAL1
|
|
||||||
DIGI3 LITERAL1
|
|
||||||
DIGI4 LITERAL1
|
|
||||||
NOISE LITERAL1
|
|
||||||
DIGI6 LITERAL1
|
|
||||||
TAN1 LITERAL1
|
|
||||||
TAN2 LITERAL1
|
|
||||||
TAN3 LITERAL1
|
|
||||||
TAN4 LITERAL1
|
|
||||||
Loading…
x
Reference in New Issue
Block a user