Teensy communicatie


  1. MIDI
    1. USB-mode
    2. Verzend midi
    3. Ontvang midi
    4. Device name
  2. Serial
    1. Data versturen

Je kan op meerdere manieren data doorsturen vanaf je Teensy naar een ander programma. Hieronder lichten we er twee toe, MIDI en serial.

MIDI

Jouw Teensy kan in een paar simpele stappen een midi-device worden waarmee je data kan versturen naar Max, SuperCollider of een DAW. Daarnaast kan je ook data ontvangen via MIDI uit een van deze programma's. Het voordeel van MIDI is dat het snel werkt en dat je het makkelijk op veel manieren kan gebruiken. Het nadeel is dat je beperkt bent in de resolutie die je door kan sturen. MIDI werkt standaard alleen met getallen tussen de 0 en 127. Als je dus waarde uit een analoge sensor wil doorsturen, dan reduceer je het bereik van 0 - 1023 wat je daar standaard mee hebt tot 0 - 127. Iets dat bij bijvoorbeeld cutoff-frequentie van een filter hoorbaar kan zijn.

Een gedetailleerde uitleg van USB MIDI op Teensy's vind je hier

USB-mode

Zorg dat je de onder Tools->USB Mode de modus Serial + MIDI selecteert. Als je nu je code opnieuw compileert zal de Arduino IDE je Teensy zich laten gedragen als een MIDI device en ook de mogelijkheid voor Seriële communicatie open laten. Het is belangrijk dat je deze modus selecteert voordat je de code waarin je usbMIDI (zie hieronder) gebruikt verifieert. Als je deze modus niet selecteert, kan je ook deze code niet gebruiken.

Verzend midi

Nu kan je gebruik maken van de volgende functies om MIDI te sturen naar je computer:

    usbMIDI.sendNoteOn(note, velocity, channel);
    usbMIDI.sendNoteOff(note, velocity, channel);
    usbMIDI.sendControlChange(control, value, channel);

Voor meer functies zie hier Let op! Zorg ervoor dat je niet met volledige kloksnelheid van de Teensy data doorstuurt, dan ontvangt de computer veel te veel data, waardoor het lastig wordt deze te verwerken. Maak dus gebruik van een delay(), ellapsedMillis of millis() om er voor te zorgen dat de verstuursnelheid wat lager ligt.

Als je de data wil filteren, kan je informatie uit de volgende link halen

Ontvang midi

Wil je MIDI ontvangen op je Teensy, dan kan je nu gebruik maken van callback functies. Dat zijn functies die worden uitgevoerd als er iets specifieks gebeurt. Dit kan bijvoorbeeld zijn dat je een functie uitvoert wanneer er een MIDI noot wordt ontvangen op je Teensy.

    usbMIDI.setHandleNoteOn(usbMIDIsetHandleNoteOn);
    usbMIDI.setHandleNoteOff(usbMIDIsetHandleNoteOff);

In dit geval behoor je zelf een void myNoteOn() { ... } functie te maken. Om dit te laten werken moet je ook nog iedere loop() de functie usbMIDI.read() aanroepen. Dit vertelt je Teensy dat deze moet kijken of er geen nieuwe MIDI berichten binnen zijn gekomen.

Voorbeeld:

void setup() {
    usbMIDI.setHandleNoteOn(usbMIDIsetHandleNoteOn);
    usbMIDI.setHandleNoteOff(usbMIDIsetHandleNoteOff);
    usbMIDI.setHandleControlChange(usbMIDIsetControlChange);
}

void loop() {
    usbMIDI.read();
}

void usbMIDIsetHandleNoteOn(byte channel, byte note, byte velocity) {
    if (channel == 1) { //lees berichten via channel 1
        playNote(note, velocity);   
    }
}

void usbMIDIsetHandleNoteOff(byte channel, byte note, byte velocity) {
    if (channel == 1) {
        stopNote(note, velocity);   
    }
}

void usbMIDIsetControlChange(byte channel, byte controller, byte value) { 
    Serial.println("Received MIDI CC on controller " + String(controller) + " with value " + String(value));   
}

Device-name

Je kan je Teensy MIDI device ook een ingebouwde MIDI naam geven. Je moet hiervoor een nieuw bestandje aanmaken naast je standaard Arduino Sketch. Dit kan je doen door op het pijltje rechtsboven te klikken en dan op New Tab te drukken.

Nu kan je een nieuw bestand aanmaken. Noem deze name.c en vul deze met de volgende code:

// To give your project a unique name, this code must be
// placed into a .c file (its own tab).  It can not be in
// a .cpp file or your main sketch (the .ino file).

#include "usb_names.h"

// Edit these lines to create your own name.  The length must
// match the number of characters in your custom name.

#define MIDI_NAME   {'M','y',' ','M','I','D','I'}
#define MIDI_NAME_LEN  7

// Do not change this part.  This exact format is required by USB.

struct usb_string_descriptor_struct usb_string_product_name = {
        2 + MIDI_NAME_LEN * 2,
        3,
        MIDI_NAME
};

Nu kan je zelf een naam invullen na MIDI_NAME. Let wel op dat je daarna het aantal letters van je nieuwe MIDI_NAME update na MIDI_NAME_LEN Zie hiervoor ook Examples->Teensy->USB_MIDI->MIDI_name


⬆️

Serial

Met seriële communicatie stuur je byte voor byte data door van de Teensy naar de computer of van de computer naar de Teensy. MIDI is een speciale vorm van seriële communicatie waarbij er een aantal afspraken zijn gemaakt over wat welke byte of volgorde van byte betekent. Je kan echter met de Teensy ook zelf je eigen afspraken bedenken en op die manier een bredere mogelijkheid hebben van wat je doorstuurt. Je kan dus in tegenstelling tot met MIDI niet slechts getallen tussen de 0 - 127 doorsturen, maar elk getal dat je maar wil. Het grote nadeel van deze manier van seriële communicatie is dat, aangezien je zelf het protocol verzint, je ook zelf aan de ontvangende kant dit protocol moet schrijven. Het werkt dus niet zomaar in een DAW. Binnen Max, P5JS of SuperCollider kan je er echter wel (vrij) makkelijk data mee ontvangen.

Data versturen

Om data te versturen via seriële communicatie moet je eerst de seriële communicatie opstarten door in de setup()-functie Serial.begin(9600) te zetten. De 9600 is de baudrate waarmee je communiceert. Of te wel, hoe snel de data doorgestuurd wordt naar de computer. De Teensy maakt gebruik van deze Arduino functie, maar stuurt data op full-USB-speed door naar de computer, dus eigenlijk kan je elk willekeurig getal invullen, er zal altijd met de maximale snelheid data verstuurd worden. 9600 wordt gebruikt omdat dit bij andere Arduino-devices de standaard is.

Vervolgens kan je, bijvoorbeeld in de loop()-functie data versturen. Dat doe je met Serial.print() en Serial.println(). De ln bij Serial.println() geeft aan dat er een nieuwe regel achter wordt gezet, daarmee kan je dus onderscheid maken tussen verschillende berichten. Een voorbeeld om twee potmeters door te sturen via seriële communicatie kan je hieronder vinden:


int pot1 = A0;
int po2 = A1;
void setup() { 
    Serial.begin(9600);
    pinMode(pot1, OUTPUT);
    pinMode(pot2, OUTPUT);
}

void loop() {
    int potdata1 = analogRead(pot1);
    int potdata2 = analogRead(pot2);
    Serial.print("pot1: ");
    Serial.println(potdata1);
    Serial.print("pot2: ");
    Serial.println(potdata2);
}

Data ontvangen in Max

Om deze seriële data in Max binnen te halen heb je een aantal objecten nodig. Hieronder staat een screenshot van hoe dit werkt.

serialMax


⬆️

Data sturen naar Teensy vanuit Max

Om MIDI te sturen vanuit Max kan je waarschijnlijk het beste MIDI CC berichten gebruiken. Die stuur je makkelijk met de volgende combinatie van objecten: maxTeensyMIDI Dubbelklik even op ctlout om je Teensy te selecteren als MIDI Device