Med knappar och sensorer för att göra musik med Intel Edison (8 / 9 steg)
Steg 8: Trött på att göra beat drop? Låt oss lägga till några fler sensorer och ljud.
Glädjen i att göra en bas trumma sparkar från en fysisk knapptryck bleknar ganska snabbt, så låt oss göra det lite mer intressant. Vi kan använda Cylon till gräns flat med en enorm mängd olika sensorer och enheter. Hittills har vi fast till att använda en enda knapp push händelse för att sparka trumman. Nu, vi ska strukturera våra app.js koden för att göra det lite enklare att lägga till fler knappar, samt lägga till några analoga sensorer.
Innan du gör ändringar i koden, låt oss lägga några fler enheter att arbeta med.
För detta instructable, valde jag att koppla upp totalt 4 knappar, en potentiometer och fotocell. Detta kommer att tillåta oss att styra mer Timbre.js instrument parametrar med ett stort utbud av värden, i stället för bara ON/OFF värden från våra knappar.
Nu, låt oss refactor vår kod för att stödja fler enheter. Vi vill kunna tillåta vår klient att lyssna på specifika knapptryckningar och specifika sensormätningar, istället för att använda en generisk "knappen" händelse. Vi kommer att skicka två olika evenemang, "knappen" och "sensor", med en hash som innehåller ett id för vår enhet, liksom det värde vi vill skicka. För knappar, vi förväntar oss en 0 eller 1 och för analoga sensorer, vi förväntar oss oavsett vad värdet sensor läsning är. Gör följande ändringar i filen "app.js".
var uttryckliga = require('express')
var app = express()
var server = require('http'). Server(app)
var cylon = require('cylon')
var io = require('socket.io')(server)
app.use (express.static (__dirname + '/ offentliga'))
Server.listen(8080)
var socket = io
.of('/soundsocket')
.på ("anslutning", funktion (socket) {
Console.log ("kund ansluten")
})
var cylonReady = function(my) {
IO
.of('/soundsocket')
.på ("anslutning", funktion (socket) {
registerSocketHandlers (min, socket);
})
}
Detta kommer att kallas varje gång en socket öppnas, så varje kund kommer att få sina egna händelser när knappar skjuts.
var registerSocketHandlers = funktion (min, socket) {
knappar = [my.button0, my.button1, my.button2, my.button3]
för (var jag = 0; jag < buttons.length; i ++) {
var knapp = knappar [i];
registerButtonHandler (socket, knapp, i);
}
analogSensors = [my.potentiometer, my.photocell]
för (var jag = 0; jag < analogSensors.length; i ++) {
var sensor = analogSensors [i];
registerAnalogSensorHandler (socket, sensor, i);
}
}
bekvämlighet för knappen särskilda händelser
var registerButtonHandler = funktion (socket, knapp, buttonID) {
push, sända knapp-ID och värdet 1
Button.on ("push", function() {
socket.Emit ("knappen" {
'id': buttonID,
"värde": 1
})
})
push, sända knapp-ID och värdet 0
Button.on ("release", function() {
socket.Emit ("knappen" {
'id': buttonID,
"värde": 0
})
})
}
bekvämlighet för att lyssna på analog läsa händelser och utsändande sensor datameddelanden
var registerAnalogSensorHandler = funktion (socket, analogSensor, analogSensorID) {
på nya uppgifter, skicka sensor-ID och värdet av sensor läsning
analogSensor.on ('analogRead', function() {
fråga sensor för det värdet
sensorValue = analogSensor.analogRead()
socket.Emit ("sensor" {
'id': analogSensorID,
"värde": sensorValue
})
})
}
berätta Cylon vilka enheter vi kommer att samverka med
var getDevices = function() {
returnera {
button0: {drivrutin: "knappen", pin: 2},
Knapp1: {drivrutin: "knappen", pin: 3},
button2: {drivrutin: "knappen", pin: 4},
button3: {drivrutin: "knappen", pin: 5},
potentiometer: {drivrutin: 'analogSensor', PIN-kod: 0, lowerLimit: 100, upperLimit: 900},
fotocell: {drivrutin: 'analogSensor', pin: 1, lowerLimit: 100, upperLimit: 900}
}
}
berätta Cylon hur vi kommer att ansluta till våra enheter
var getConnections = function() {
returnera {
Edison: {adapter: "intel-iot"}
}
}
Cylon.robot({
anslutningar: getConnections(), / / Använd vår getConnections funktion för att rensa detta.
enheter: getDevices() / / Använd vår getDevices funktion för att rensa detta.
{}) .på ("ready", cylonReady)
Cylon.start()
Obs: Var noga med att din analoga sensorer är anslutna till Analoga i hamnarna i din Edison.
Gör följande ändringar för att konsumera dessa förändringar i vår klient, så att din "playsounds.js" återspeglar följande kod:
var BD
var SD
var HH1
var HH2
var CYM
var trumma
var bly
var env
var arp
var dröjsmål
var inv
T("Audio").load ("./drumkit.wav", function() {
BD = this.slice (0, 500) .set ({bang: false})
SD = this.slice (500, 1000) .set ({bang: false})
HH1 = this.slice(1000, 1500).set ({bang: falskt, mul:0.2})
HH2 = this.slice(1500, 2000).set ({bang: falskt, mul:0.2})
CYM = this.slice (2000) .set ({bang: falskt, mul:0.2})
var skala = nya sc. Skala ([0,1,3,7,8], 12, "Pelog")
var P1 = [
[BD, HH1],
[HH1],
[HH2],
[],
[BD, SD, HH1],
[HH1],
[HH2],
[SD],
] .wrapExtend(128)
var P2 = sc.series(16)
Drum = T ("lowshelf", {freq:110, vinst: 8, mul:0.6}, BD, SD, HH1, HH2, CYM).play()
leda = T ("såg", {freq:T("param")})
env = T ("perc", {r: 100})
ARP = T ("OscGen", {wave:"sin(15)", env:env, mul:0.5})
Delay = T ("dröjsmål" {tid: "BPM128 L4", fb:0.65, mix: 0.35},
T ("pan", {pos:T("tri", {freq:"BPM64 L1", mul:0.8}).kr()}, arp)
) .play();
inv = T ("intervall", {intervallet: "BPM128 L16"}, function(count) {
var jag = count % P1.length
om (jag === 0) CYM.bang()
P1[i].foreach(function(p) {
p.Bang()
})
om (Math.random() < 0,015) {
var j = (Math.random() * P1.length)|0;
P1.wrapSwap (i, j);
P2.wrapSwap (i, j);
}
var noteNum = scale.wrapAt(P2.wrapAt(count)) + 60.
om (jag % 2 === 0) {
lead.freq.linTo(noteNum.midicps() * 2, "100ms");
}
arp.noteOn (noteNum + 24, 60)
{}) .start()
})
var socketConnection = io.connect ("http://0.0.0.0:8080/soundsocket")
socketConnection.on ('connect', funktion () {
Console.log ("ansluten till uttaget")
})
socketConnection.on ("knappen", funktion (data) {
buttonID = data ['id']
värde = data [värde]
växel (buttonID) {
fall 0:
om (värde == 1) {
BD.bang()
}
bryta;
fall 1:
om (värde == 1) {
CYM.bang()
}
bryta;
fall 2:
värdet == 1? HH1.set ({mul: 1}): HH1.set ({mul: 0,2})
bryta;
fall 3:
värdet == 1? HH2.set ({mul: 1}): HH2.set ({mul: 0,2})
bryta;
standard:
}
})
socketConnection.on ("sensor", funktion (data) {
sensorID = data ['id']
värde = data [värde]
växel (sensorID) {
fall 0:
inv.set ({intervallet: värde * 2})
bryta;
fall 1:
ARP.set ({mul: 10/värde})
bryta;
standard:
}
})
Begå och skicka dina ändringar, dra dem ner till Edisonoch kör din app. Om allt fungerar som förväntat, du ska kunna använda knapparna till slå till specifika instrument, och att kunna ändra fördröjningen och Obs kompenserar med hjälp av din analoga sensorer.
Detta ger dig ett exempel på hur man kan konsumera olika typer av data, och antingen spela eller ändra parametrar av instrument inom Timbre.js.