Vraag:
Software Serie te traag voor MIDI?
Michel Keijzers
2017-05-20 06:06:16 UTC
view on stackexchange narkive permalink

Ik heb geprobeerd de SoftwareSerial-bibliotheek voor MIDI te gebruiken (met 47 effecten), maar het lijkt erop dat ik regelmatig corrupte / onverwachte berichten krijg.

Het circuit dat ik gebruik, werkt perfect wanneer ik het aansluit op de HardwareSeriële oplossing (dus het probleem moet in de software liggen).

Wat ik zie is:

  • Als ik op notities en release-opmerkingen druk, gaat LED 13 correct aan en uit.
  • Als ik Serial.print gebruik voor foutopsporing, krijg ik correcte berichten. In het onderstaande voorbeeld heb ik echter de printopdrachten verwijderd om een ​​minimaal voorbeeld te hebben.)
  • Als ik SoftwareSerial gebruik, gaat LED 13 voor elke notitie correct aan en uit. Toen ik echter veel berichten verstuur (bijvoorbeeld door aftertouch / pitch bend die veel berichten in korte tijd verzendt), merkte ik dat Note On / Off-commando's met 'willekeurige' waarden worden verzonden.

Sommige bronnen zeggen dat SoftwareSerial voor MIDI zou moeten werken, maar tot nu toe is het verre van perfect. Maak ik een fout?

(trouwens, de baudrate van MIDI is 31.250 bps, als ik pitchband gebruik, worden er honderden bytes per seconde verzonden, tot dusver binnen de MIDI-specificatie).

De sketch die ik gebruik is:

  #include <MIDI.h> // Add Midi Library # include <SoftwareSerial.h>SoftwareSerial swSerial (2, 11); // RX, TXMIDI_CREATE_INSTANCE (SoftwareSerial, swSerial, midiSw1); # definieer LED 13 // Arduino Board LED staat op Pin 13 void setup () {pinMode (LED, OUTPUT); // Stel Arduino-kaartpen 13 in om midiSw1.begin (MIDI_CHANNEL_OMNI) uit te voeren; midiSw1.setHandleNoteOn (MyHandleNoteOn); midiSw1.setHandleNoteOff (MyHandleNoteOff);} void loop () {midiSw1.read ();} void MyHandleNoteOn (bytekanaal, bytepitch, bytesnelheid) {digitalWrite (LED, HIGH); // Zet LED aan} void MyHandleNoteOff (bytekanaal, bytepitch, bytesnelheid) {digitalWrite (LED, LOW); // Zet LED uit}  
Ik heb exact hetzelfde probleem ervaren. In mijn ervaring is SoftwareSerial niet snel genoeg om snelle, opeenvolgende MIDI-berichten te verwerken. Ik ontdekte dat ik de beste resultaten kreeg door de hardware-serie te gebruiken voor MIDI en door SoftwareSerial + een andere Arduino te gebruiken voor foutopsporing. Hoewel dit de beste opstelling was, was het nog steeds niet perfect. Zelfs de hardware-serie liet af en toe berichten vallen / beschadigen.
`digitalWrite` is mogelijk te traag. Probeer het te vervangen door `PORTB | = 0x20;` en `PORTB & = ~ 0x20;`. Maar er is niet veel dat u kunt doen om alle MIDI-afhandelingscodes te versnellen.
@Mazaryk ... Ik gebruik al een Mega die 4 hardware-series heeft, tot dusver gebruik ik 3 voor MIDI, een voor debuggen (voor nu kan later de 4e MIDI zijn). En als de 4e voor MIDI wordt gebruikt, zal ik waarschijnlijk een andere Arduino gebruiken als debugging. Ik heb veel getest en tot nu toe heb ik nooit verloren / beschadigde berichten gekregen ... en CL stelde voor om de nog betere H11L1-optokoppelingen te gebruiken in plaats van de 6N138 die ik nu gebruik.
@CL: Bedankt ... alles om te versnellen zou goed kunnen zijn ... maar aangezien de hardware seriële oplossing goed werkte met digitalWrite en de software niet, vind ik het nog steeds te onvoorspelbaar als ik dergelijke 'trucs' moet gebruiken ... .. later wil ik ook aanvullende bewerkingen doen die de softwareoplossing (weer) onwerkbaar kunnen maken.
Een antwoord:
Majenko
2017-05-20 16:53:46 UTC
view on stackexchange narkive permalink

Het probleem met SoftwareSerial is dat terwijl het een pakket ontvangt, de Arduino niets anders kan doen - inclusief het lezen van bytes uit de RX-buffer, dus het zal gemakkelijk overlopen als je dingen te snel verzendt. Met HardwareSerial kunt u uit de buffer lezen terwijl deze gegevens ontvangt, dus overlopen is minder een probleem.

Zodra de START-bit van een pakket is ontvangen, gaat het een ISR in en leest elk van de resterende 9 bits aan gegevens (inclusief de stopbit) in een strakke lus. Die ISR wordt niet afgesloten voordat het hele pakket is ontvangen en opgeslagen in de RX-buffer. Als er meteen een andere byte wordt verzonden, zit er weinig tijd tussen het voltooien van de ISR en het opnieuw activeren. De rest van de code, inclusief de MIDI-parseerroutines die gegevens uit de RX-buffer lezen, hebben dan geen CPU-cycli meer en kunnen niet goed werken. Stuur te veel bytes samen en de beperkte RX-buffer (64 bytes) loopt vol en loopt over, en je verliest gegevens.

Een ander probleem met SoftwareSerial is dat het de START-bit moet vastleggen op het moment dat het arriveert. Elke vertraging bij het vastleggen van die rand zal resulteren in een afwijking in de bit-bemonsteringstijdstip. Als er iets anders is dat tegelijkertijd interrupts gebruikt (zoals de millis () -timer), zal het triggeren van de PCINT-interrupt die wordt gebruikt voor de START-bitdetectie, vertragen. Zelfs de SoftwareSerial-interrupt zelf heeft een bepaalde hoeveelheid tijd nadat het klaar is met het ontvangen van het pakket, waar het het opslaat in de RX-buffer en terugkeert van de interruptroutine. Als het volgende pakket vóór arriveert, is de ISR klaar om het te onderhouden, dan zal er een vertraging zijn - en elke vertraging is erg.

Persoonlijk ben ik van mening dat SoftwareSerial nooit gebruikt voor alles, ooit. Als je meer seriële poorten nodig hebt, heb je ofwel een krachtigere chip nodig of je hebt meer dan één chip nodig en laat ze met elkaar communiceren via een ander hardwarekanaal met hogere snelheid (bijvoorbeeld SPI of I2C).

SoftwareSerial is alleen geschikt voor het verzenden van korte gegevenssalvo's (aangezien het volledig wordt geblokkeerd tijdens het verzenden) of voor het ontvangen van zeer korte berichten die niet vaak worden verzonden.

Zeer nuttige informatie (zoals altijd) ... Ik heb geprobeerd de buffer 128 bytes te maken, maar ik zag geen verbetering. Natuurlijk kan ik er 256 van misschien 512 maken, maar waarschijnlijk 'vertraagt' het de tijd voordat ik in de problemen kom als ik je uitleg lees.
Als je de hele tijd heel veel verzendt, ja, dan hoef je alleen maar de tijd te vertragen voordat je problemen ziet. Ook is er altijd de kans dat als het volgende pakket te snel komt, de ISR niet snel genoeg zal kunnen reageren en dat u de start van het volgende pakket kunt verliezen en halverwege de volgende dalende flank erin triggert.
Misschien moet ik in de toekomst (als mijn project zal groeien) naar een ander bord gaan (waardoor ik 8 hardware-series krijg). Momenteel gebruik ik een SD-schild, van plan om een ​​WIFI-schild en mogelijk een USB (host) -schild te gebruiken, ook heb ik een prototype-bord nodig voor extra componenten (verschillende opto-koppelingen enz.). Dus misschien zijn 2 Mega's goed :-)
Misschien zelfs drie;) Je kunt er nooit teveel hebben. Het kan goed zijn om een ​​project op te splitsen in componentblokken en deze afzonderlijk te laten controleren en beheren. Misschien heeft u één centrale mastercontroller die alle anderen vertelt wat ze moeten doen.
Ja klinkt mij volkomen duidelijk :-) ... ik weet niet of je bekend bent met MIDI, maar noot aan / uit geven geen probleem, maar CC-berichten (zoals pitchbending / aftertouch resulteren in veel bytes, ruim binnen de baudrate van MIDI die 31250 bps is, maar waarschijnlijk te traag voor SoftwareSerial).
Dat klinkt ook als een heel gaaf idee ... maar onthoud, dit is het eerste Arduino-project dat ik doe :-) ... aan de andere kant, als het project langzaam groeit, is het erg goed om veel te leren over Arduino's / microcontrollers en elektronica.
Ja, ik ken MIDI vrij goed. Zoals ik in een opmerking hierboven al zei, is het niet alleen de hoeveelheid die een probleem kan zijn, maar ook de kloof tussen opeenvolgende pakketten. Zelfs twee pakketten die te dicht bij elkaar worden verzonden, kunnen problematisch zijn.
En het 'probleem' is dat ik het niet erg vind om een ​​CC-bericht kwijt te raken, maar een noot van een bericht dat niet wordt verwerkt, resulteert in een noot die voor altijd klinkt (tenzij de geluiden op een synthesizer worden veranderd) ... dit is volkomen onaanvaardbaar in een live muziek situatie.
Absoluut. Het kan handig zijn om een ​​"kill switch" te programmeren die alle geluiden stopt in geval van nood. Voor de zekerheid.
Een kill-schakelaar is ook niet iets dat handig is (in mijn geval) ... ik wil de MIDI-box (zoals ik het noem) laten reageren op missages die van synths komen en deze verwerken en berichten terugsturen ... dus de box is misschien zelfs uit het zicht voor mezelf tijdens het spelen, maar ik zou een MIDI-bericht kunnen maken dat resulteert in een dergelijke kill (notes) -functionaliteit.
Ja, het hoeft geen fysieke knop te zijn die rechtstreeks is aangesloten - daarom heb ik aanhalingstekens gebruikt;) Gewoon een signaal dat kan worden verzonden om te zeggen "hou je bek". Laat hem misschien reageren op een noot die je nooit speelt (C8 of zoiets), zodat hij de hele tijd voor je op het toetsenbord staat. U kunt het zelfs in uw uitvoeringen opnemen;)
Laten we [deze discussie voortzetten in de chat] (http://chat.stackexchange.com/rooms/59042/discussion-between-michel-keijzers-and-majenko).


Deze Q&A is automatisch vertaald vanuit de Engelse taal.De originele inhoud is beschikbaar op stackexchange, waarvoor we bedanken voor de cc by-sa 3.0-licentie waaronder het wordt gedistribueerd.
Loading...