fbpx


The MIDI Forum

  Thursday, 09 February 2023
  28 Replies
  6.2K Visits
16
Votes
Undo
  Subscribe
I have made this Serial MIDI reader to catch song changes as MIDI ProgramChanges.
The problem is if I turn the song-knob fast on my external MIDI-device then it appears like it looses some of the ProgramChanges (192/C0h byte codes).

Any suggestions why?

I wanted to upload picture, but it seems like this froum doesn give that opportunity!?

But the trace output looks like this:

09:44:57.326 -> 192=PC:
09:44:57.372 -> 67
09:44:57.961 -> 192=PC:
09:44:58.148 -> 68
09:44:58.798 -> 192=PC:
09:44:58.920 -> 69
09:44:58.920 -> 75 ........here it didnt get the ProgramChange byte before the data byte
09:44:59.013 -> 192=PC:
09:44:59.169 -> 76
09:44:59.388 -> 192=PC:
09:44:59.435 -> 77
09:44:59.528 -> 192=PC:
09:44:59.668 -> 89
09:44:59.931 -> 192=PC:
09:44:59.931 -> 90
09:45:00.008 -> 192=PC:
09:45:00.134 -> 97
09:45:00.179 -> 98 ........here it didnt get the ProgramChange byte before the data byte
09:45:00.225 -> 192=PC:
09:45:00.309 -> 89
09:45:00.309 -> 240=SYSEX: -1
09:45:00.309 -> 240=SYSEX: -1 -1
09:45:00.309 -> 240=SYSEX: -1 -1 -1
09:45:00.309 -> 240=SYSEX: -1 -1 -1 -1
09:45:00.348 -> 240=SYSEX: -1 -1 -1 -1 -1


Also note that it appears to in the end that it goes into endless SysEx data if I turn the knob very fast. But doesnt catch the SystemExclusiveEnd.

CODE:


/////////////////////////////////////////////////////////////////////////////////////
// MIDI INPUT FOR PROGRAM CHANGE
/////////////////////////////////////////////////////////////////////////////////////
const byte SystemExclusiveStart = 0xF0; ///< System Exclusive
const byte SystemExclusiveEnd = 0xF7; ///< System Exclusive End


const int MIDI_BaudRate = 31250;
volatile int MIDI_Byte = 0;
const byte SERIAL_ProgramChange = 192; //~C0 i HEX
volatile bool lastByteWasProgramChange = false;
volatile byte lastSongNumber = 0;
String MIDI_data_str = "";

/////////////////////////////////////////////////////////////////////////////////////
// handleSerialMIDIinput() INTERRUPT ROUTINE
/////////////////////////////////////////////////////////////////////////////////////
void handleSerialMIDIinput() {
noInterrupts();
MIDI_data_str = "";
//WHile there is MIDI data available, stay in reading loop:
while (Serial1.available() > 0) {
MIDI_Byte = Serial1.read();
if (MIDI_Byte !=254) {
MIDI_data_str = String(MIDI_Byte);
}
switch (MIDI_Byte) {
case SystemExclusiveStart:
MIDI_data_str = MIDI_data_str + "=SYSEX: ";
while (MIDI_Byte != SystemExclusiveEnd) {
MIDI_Byte = Serial1.read();
MIDI_data_str = MIDI_data_str + String(MIDI_Byte) + " ";
Serial.println(MIDI_data_str);
}
MIDI_data_str = MIDI_data_str + "END.";
break;
case SERIAL_ProgramChange:
MIDI_data_str = MIDI_data_str + String("=PC: ");
break;
}
if (MIDI_data_str != "") {
Serial.println(MIDI_data_str);
}
// if (MIDI_Byte == SERIAL_ProgramChange) {
// MIDI_data_str = MIDI_data_str + " PC:";
// }
//MIDI_data_str = MIDI_data_str + String(MIDI_Byte) + " ";
//IF its a ProgramChange start the action by reading the next data byte
if (MIDI_Byte == SERIAL_ProgramChange) {
lastByteWasProgramChange = true;
} else { // if (MIDI_Byte = SERIAL_ProgramChange)
if (lastByteWasProgramChange) {
lastByteWasProgramChange = false;
}
}
} // while (Serial1.available() > 0)
interrupts();
}

/////////////////////////////////////////////////////////////////////////////////////
// SETUP()
/////////////////////////////////////////////////////////////////////////////////////
void setup(void) {
Serial1.begin(MIDI_BaudRate); //Start lytning på SERIEL-porten (som anvendes til MIDI in) via RX1=Seriel1.

Serial.begin(31250); // debug output to serial monitor. OBS: SKAL sættes til 9600 i baud-rate, ellers vises volapyk!

attachInterrupt(digitalPinToInterrupt(19), handleSerialMIDIinput, FALLING);
} //setup()


/////////////////////////////////////////////////////////////////////////////////////
// LOOP()
/////////////////////////////////////////////////////////////////////////////////////
void loop() {
//Serial.println(MIDI_data_str);
} //loop() end
Martin set the type of the post as  Technical Question — 10 months ago
10 months ago
·
#17571
0
Votes
Undo
Hello,

What devices are you using?

More important, how are they connected?

Are you using a midi <--> USB connector? There is one of these that seems to lose data as you describe. It's got a treble clef symbol on it. There's a pic of it linked on another recent post here.

Geoff
10 months ago
·
#17573
1
Votes
Undo
This post also appears on an Arduino forum: MIDI ProgramChange.

In that thread, user ardunew appears to be using a DIN MIDI cable to connect a Boss RC-505mkII Loop Station to a MIDI shield board on an Ardunio. Ardunew is programming the Arduino to do something with the incoming MIDI data.

Various replies there suggest trying to do everything in an interrupt handler could be causing problems.

It also appears user ardunew may be unaware of Running Status:

In the MIDI 1.0 specification, see the sections on Running Status on PDF pages 10, 64, and 65 (printed pages 5, A-1, and A-2).
  • In MIDI messages on a DIN MIDI cable, any status byte that has a channel number can be omitted if it is the same as the previous status byte with a channel number.
  • System Real-Time messages can appear in the middle of other messages and do not change the previous status byte remembered.
  • All other System messages cause the previous status byte to be forgotten, so the next message must have a status byte sent.
10 months ago
·
#17581
1
Votes
Undo
I think Bavi_H nailed the reason!
It sounds very plausable that its because of the running status tactics! Thank you! I will investigate more on that! :)
9 months ago
·
#17721
0
Votes
Undo
This website forum doesnt work!
I have tried to post replyes several days now.. But it just keeps on turning around and the click on capcha keeps on turning red after some time, while the round symbol is still moving around for ever!

Aparently its if there is too much data, like 3 code blocks! It never saves and runs in endless loop!
9 months ago
·
#17722
0
Votes
Undo
LOL, its also not working with 1 codeblock!

So now I try post it without any block encodings!

Example 1:
Where it looses data:


248 1-1111000 COMMAND: Timing Clock
248 1-1111000 COMMAND: Timing Clock
248 1-1111000 COMMAND: Timing Clock
192 1-1000000 COMMAND: Program Change
76 0-1001100 DATA - SONG: 77 updateTFT()
tft.availableForWrite()==0

248 1-1111000 COMMAND: Timing Clock
240 1-1110000 COMMAND: SysEx begin
65 0-1000001 DATA
16 0-0010000 DATA
0 0-0000000 DATA
0 0-0000000 DATA
114 0-1110010 DATA
18 0-0010010 DATA
0 0-0000000 DATA
0 0-0000000 DATA
0 0-0000000 DATA
4 0-0000100 DATA
124 0-1111100 DATA
247 1-1110111 COMMAND: SysEx end
248 1-1111000 COMMAND: Timing Clock
248 1-1111000 COMMAND: Timing Clock
248 1-1111000 COMMAND: Timing Clock
248 1-1111000 COMMAND: Timing Clock
254 1-1111110 COMMAND: Active Sensing
248 1-1111000 COMMAND: Timing Clock
248 1-1111000 COMMAND: Timing Clock
248 1-1111000 COMMAND: Timing Clock
248 1-1111000 COMMAND: Timing Clock
248 1-1111000 COMMAND: Timing Clock
248 1-1111000 COMMAND: Timing Clock
248 1-1111000 COMMAND: Timing Clock


Problem: The last trace shown ProgramChange was 77, but on my source display the last was 85 (after the 77).

Here is example 2:


248 1-1111000 COMMAND: Timing Clock
248 1-1111000 COMMAND: Timing Clock
240 1-1110000 COMMAND: SysEx begin
65 0-1000001 DATA
16 0-0010000 DATA
0 0-0000000 DATA
0 0-0000000 DATA
114 0-1110010 DATA
248 1-1111000 COMMAND: Timing Clock
248 1-1111000 COMMAND: Timing Clock
248 1-1111000 COMMAND: Timing Clock
254 1-1111110 COMMAND: Active Sensing
248 1-1111000 COMMAND: Timing Clock
192 1-1000000 COMMAND: Program Change
17 0-0010001 DATA - SONG: 18 updateTFT()
tft.availableForWrite()==0

248 1-1111000 COMMAND: Timing Clock
248 1-1111000 COMMAND: Timing Clock
248 1-1111000 COMMAND: Timing Clock
248 1-1111000 COMMAND: Timing Clock
254 1-1111110 COMMAND: Active Sensing
192 1-1000000 COMMAND: Program Change
20 0-0010100 DATA - SONG: 21 updateTFT()
tft.availableForWrite()==0

248 1-1111000 COMMAND: Timing Clock
248 1-1111000 COMMAND: Timing Clock
248 1-1111000 COMMAND: Timing Clock
248 1-1111000 COMMAND: Timing Clock
248 1-1111000 COMMAND: Timing Clock
248 1-1111000 COMMAND: Timing Clock


Problems:

- It didnt get the last ProgramChange to 28, the last updated on TFT was 20 and
- It also lost a SysEx end code.

Any new suggestions?
9 months ago
·
#17723
0
Votes
Undo
How annoying it wont let me upload code at all.. not with or without code block tags.... So now I try as a zip file!
9 months ago
·
#17724
0
Votes
Undo
@Geoff, I answered you the other day, but apparently this forum is not working, because today my reply is gone and I have huge troubles of posting new replies at all. :(

Well.. My setup is as follows:

From my MIDI source device I send song changes via MIDI ProgramChange codes via 5pin MIDI cable to a MIDI shield boards MIDI IN and that board is connected to an Arduino Mega 2560 board via breadboard.

- I have tried to send MIDI data right trhu the MIDI THRU 5pin din on the MIDI shield board and further on to an identical MIDI-device b and it works fine without loosing the data.
- I have also tried the same setup with a simple Arduino code which only forwards the incoming MIDI data to the MIDI OUT on the MIDI shield board and further on to the identical MIDI device b and here it also works finde without loosing any data.

So my conclusion is that bothe my 2 midi devices work, and my midi cables work and the 3 5pin plugs on the MIDI shield also works and the MIDI shield board also works.

So that comes to the setup only looses data when the Arduino has several things to do and when it writes to the tft which slows the proces down. The writing to the serial trace output window doesnt seem to influence as it also looses data if I dont write to the trace window.

So
- Do I still interpret the MIDI data in a wrong way?
- Is the Arduino Mega 2560 not suitable for doing more than one litle test thing at a time? Like both midi AND tft writing?
- Do I have some bugs in my code?
- Is there something with the Arduino architecture I didnt catch abouty memories, flush, buffers, interrupts, timing or likewise?

Any suggestions would be appreciated.
Thanx.
9 months ago
·
#17730
0
Votes
Undo
Hello,

I'll try to look at your code, but a lot of what you're doing means nothing to me at all. Some of the devices you refer to also ???? I've heard of Arduino but I've never done anything with one.

Maybe you'll get a reply from someone here who does know something about these things.

As far as the forum is concerned, it works OK. We do get a lot of non-midi posts, often totally non-midi, and it's a constant battle to get rid of them. Your missing post might have been removed accidentally, or might have appeared to be non-midi. If it was in fact appropriate, but got deleted, we apologise. I note that your recent posts do appear. Regarding the code, I'm not sure about the rules, but I would always prefer that code be attached as a separate file so that it can be read/studies in comfort, and printed out, trying to make sense of large bodies of complex code on a small screen is not easy.

Given the seeming randomness of the lost code, the suggestions (from another, more specialised, forum) regarding interrupts sounds possible. I assume that you investigated this, and maybe tried to change your code to protect against this (more buffering?) What was the result of your checks regarding the earlier suggestions/

Geoff
9 months ago
·
#17731
0
Votes
Undo
Hello,

Just to confirm that I've got the code, which looks like C so I might be able to make sense of it.

I guess from the code that you are handling the data at a bit level - I assume that you are allowing for the fact that raw midi data contains extra bits, there is a 'stop' bit I think, and something else - this was discussed in a recent post regarding the quantity of midi data 'bits' that might be in a midi data stream, I had referred to there being 8 bits per byte, somone else corrected this as there was 10 bits in total for each data byte with the extra 'packing' bits. This could mean that there is more data than you expect, but the extra data would not be valid midi data and might generally confuse things so give the impression that data is 'lost'?

Just an initial thought.

Just found the prev thread. See

https://www.midi.org/forum/17325-midi-buffer-limits

reference to 10 bite, 1 start bit, 8 data bits, 1 stop bit

Geoff
0
Votes
Undo
I've never used Arduinos, but I've heard that software serial has problems like that, and you should use hardware serial.
Howver, the Mega 2560 appears to have four hardware ports, so I do not think that this is your problem.

Your parsing code still does not handle all MIDI correctly.
You should do it like this:

  • Bytes 0xF8..0xFF are one-byte real-time messages that can be sent inside other commands. You can handle/print them, but otherwise ignore them; do not set MIDI_Command. (Your "Reset MIDI_Command back" code is wrong; the last command might have been anything else.)
  • Bytes 0x80..0xF7 are normal command bytes. Set MIDI_Command only for those.
  • Bytes 0x00..0x7F are data bytes. How to handle them depends on the last command byte. In you case, you want to do something only for program changes. Your existing code for MIDI_Data is correct.


(You do not need to read the uppermost bit; it would be easier to just compare the byte values.)
9 months ago
·
#17733
0
Votes
Undo
@Geoff,
Hmm Im not sure my posts got deleted, more that its impossible to post them!
I might have thought it got posted, but there are SO many obsrtugles to post, that it might didnt get posted at all.
E.g. Now its impossible to post my code, even I posted code at my first post!
It just goes into endless turn-around-looping the mouse icon. And after a while the Im not a robot-thing goes red again and needs to re-click, lol. And after have been doing that for 5 minutes I loose interest in continuing.
SO.. if u are the admin or know him, pls tell to:
1) Fix the bug that its not possible to add the code inside the zip-file.
2) Tell them to fix the bug that Im not a robot goes into re-asking for click, even it was clicked before clicking the post/Send form button.
But its probably because someone just used a free 3rdpart capcha instead of coding its own simple code.
9 months ago
·
#17734
0
Votes
Undo
Yes, I think I've had a problem with posting recently.

I suspect that this has happened: I've ticked the Captcha box, then gone to the 'Post' icon and clocked that. BUT, the Captcha arrow was still circling, I've not given it time to stop. Sometimes, it takes longer than other times, I'm not sure what it's doing. So, Captcha decides I'm some sort of robot, and no matter how careful I am with further tries I still have a problem.

If I try again later, log in again, allow the arrow to stop, it works fine.

I don't know why you couldn't put something into a zip file. This is nothing to do with this forum? But, this forum accepts certain file types ONLY. .zip is OK. .mid is NOT!! There may also be a limit on size. You said you tried to do a pic - I've seen pics posted here, but again, the specific file type might have been a problem, again, the file size?

Geoff
9 months ago
·
#17735
0
Votes
Undo
Martin, as you know there is an Arduino MIDI library, and as I understand it, you were having some problems with it originally and decided to write code to handle the incoming MIDI messages yourself. However, I suspect your original problems might have been due to other problems in your code. It looks like you might have learned some things and made some improvements to your code since then, so perhaps if you try using the Arduino MIDI library again it might work better for you this time? I think the Arduino MIDI library will probably buffer incoming MIDI bytes and handle Running Status, so you wouldn't have to worry about programming those things yourself.


Bytes 0x80..0xF7 are normal command bytes. Set MIDI_Command only for those.

Clemens Ladisch: Remember that only Channel messages can use Running Status (see the references in my first post). As you said, System Realtime messages are always one-byte messages that can appear in-between the data of other messages and they don't change the remembered Running Status. But System Exclusive and System Common messages cause the Running Status to be forgotten. The next message after a System Exclusive or System Common message should always begin with a Status byte. (If it doesn't, then you just have to do nothing with the incoming bytes until you do see a Status byte.)

I'm finding it complicated to discuss without starting to write program snippets. When writing code to handle this, you might have to remember both what the current status byte is for the message you are currently building up, and what the "remembered Running Status byte" is for future data bytes that appear without an expected Status byte.
9 months ago
·
#17736
0
Votes
Undo
No, I didnt have problems posting a ZIP file. That was the ONLY solution way it succeeded me to upload the code file here.
Well enough about the forum here.. I will focus on solving my MIDI-problem now :)
9 months ago
·
#17737
0
Votes
Undo
@Clemens

I do use "hardware" serial, not software serial.

I would be so happy if its just bcs. I handle the MIDI incorrectly! Bcs. then its a simple problem, a bug 40 :) And then code CAN be stable... so I really hope tat.

When thats said...

do not set MIDI_Command. (Your "Reset MIDI_Command back" code is wrong; the last command might have been anything else.)


As I at the moment know exactly what codes are sent from the MIDI source..the method I have used with setting it back to 192 after getting sysEx End f.x. should work... in my head.
There is only ONE button I am touching and thats the song-changing turnable knob. And MIDI sends Sensing automatically and when the MIDI sync is set to ON it sends Timing CLock too.
HOWEVER... I still havent figured out WHY it sends SysEx data when I turn the knob fast!?

BUT I read u loud and clear.. better safe than sorry, and if it helps, it will be perfect, so I will try reconstruct my code, so it looks in byte intervals instead.
9 months ago
·
#17741
0
Votes
Undo
@Clemens:

Also now with changed code to ranges instead of bit-check, it looses data. E.g. this example should have ended on ProgramChange 27 (song 28) after the song 15. But again there comes a SysEx range of commands & data:


23:01:52.989 -> 248 = Real Time Message Byte Timing Clock
23:01:52.989 -> 248 = Real Time Message Byte Timing Clock
23:01:52.989 -> 248 = Real Time Message Byte Timing Clock
23:01:52.989 -> 248 = Real Time Message Byte Timing Clock
23:01:52.989 -> 248 = Real Time Message Byte Timing Clock
23:01:52.989 -> 248 = Real Time Message Byte Timing Clock
23:01:52.989 -> 248 = Real Time Message Byte Timing Clock
23:01:52.989 -> 248 = Real Time Message Byte Timing Clock
23:01:52.989 -> 248 = Real Time Message Byte Timing Clock
23:01:52.989 -> 254 = Real Time Message Byte Active Sensing
23:01:52.989 -> 192 = Command Byte : Program Change
23:01:52.989 -> 14 = Data Byte ~ SONG: 15 updateTFT()
23:01:52.989 -> tft.availableForWrite()==0
23:01:53.300 ->
23:01:53.300 -> 248 = Real Time Message Byte Timing Clock
23:01:53.300 -> 240 = Command Byte : SysEx begin
23:01:53.300 -> 65 = Data Byte
23:01:53.300 -> 16 = Data Byte
23:01:53.300 -> 0 = Data Byte
23:01:53.300 -> 0 = Data Byte
23:01:53.300 -> 114 = Data Byte
23:01:53.300 -> 18 = Data Byte
23:01:53.300 -> 0 = Data Byte
23:01:53.300 -> 0 = Data Byte
23:01:53.300 -> 0 = Data Byte
23:01:53.300 -> 8 = Data Byte
23:01:53.300 -> 120 = Data Byte
23:01:53.300 -> 247 = Command Byte : SysEx end
23:01:53.300 -> 248 = Real Time Message Byte Timing Clock
23:01:53.300 -> 248 = Real Time Message Byte Timing Clock
23:01:53.300 -> 248 = Real Time Message Byte Timing Clock
23:01:53.300 -> 248 = Real Time Message Byte Timing Clock
23:01:53.300 -> 248 = Real Time Message Byte Timing Clock
23:01:53.300 -> 248 = Real Time Message Byte Timing Clock
9 months ago
·
#17742
0
Votes
Undo
Latest code:
0
Votes
Undo
That SysEx looks valid.
Manufacturer ID (65) is Roland; device ID is 16 = default; model ID is 0 0 114 (Boss RC-505 ???); 18 looks like data set 1; 0 0 0 is the address; 8 is the data; 120 is the checksum (sum of address and data and checksum modulo 128 is zero).
I would guess that this message tells you that button nr. 8 was pressed (or that the value increased by 8, or something like that).

It's possible that some bytes get dropped without any error indication. A possible cause would be other processing (such as the output to the other serial port); try using much less logging.
9 months ago
·
#17744
0
Votes
Undo
Martin, your most recent log shows 311 milliseconds elapsed between these two lines:

23:01:52.989 -> tft.availableForWrite()==0
23:01:53.300 ->

That's enough time for up to 971 MIDI bytes to come in. According to one of the Arduino Serial documentation pages, it looks like the serial receive buffer is 64 bytes.

1. Perhaps you can try changing your updateTFT() function to send fewer TFT commands.

Instead of doing all of this every time in your updateTFT() function:

tft.fillScreen(ST77XX_RED);
tft.setTextColor(ST77XX_BLACK);
tft.setCursor(10, 10);
tft.setTextSize(3);
tft.print("SONG: ");
tft.setCursor(10+108, 10);
tft.setTextColor(ST77XX_BLACK);
tft.println(incomingMIDI_songNumber);

What happens if you just do this?:

tft.setCursor(118, 10);
tft.println(incomingMIDI_songNumber);

2. I couldn't find documentation about what the tft.availableForWrite() function does. Is it similar to the Ardunio Serial.availableForWrite() function? That seems return the number of free bytes in the write buffer. If the tft.availableForWrite() function is similar, then if you only send TFT commands when the tft.availableForWrite() function returns zero, maybe that means you will always have additional wait time until a write buffer has some free space?

What happens if you remove the if(tft.availableForWrite()==0) condition?
9 months ago
·
#17751
1
Votes
Undo
@Clemens and @Bavi_H thank you, I really appreciate your continuous posts. You all the time inspire me to try new things! :)

@Clemens.

- Yes its a RC-505 mkII. Have u read somewhere that the code stands for that?
- There were no button pressed, only turned the song knob forth & back fast. IF it should make sence somehow as a shortcut command to the last song when many song-data is sent, I would expect e.g. a distance/subtraction value from 14 to 27, so in this case if the value were 27-14=13 OR 27 then it would have made sence. But 65,16,114, 8 & 120 doesnt make any sence to me. But the definitions u have written above is that consequent rules for all SysEx?
- I have tried both with & without logging. Thats also why I made the easy logical setting "trace" in the beginning of the code, so I could test both with and without.
But I do have seen it fail also without the trace. But its a while ago and the code has changed since, so yes, would be smart to test it again.

@Bavi_H

- Ya I have noticed the jumps in milliseconds too. But Im not sure they are trustworthy! As it seems like all data are coming in chunks in that build in trace logging window of Arduino IDE. I have eralier experimented with timing also, both to log, but also to with purpose put in a wait until alle song changes were finish. I didnt have much success with that too. But it might make more sence now when the code is based on byte ranges! So I think first I need to program my own timer object again and post my own time in the log window, so we can check if it is a true long time the tftf wirting takes or if its just the IDE's chunks of data.
But of course the tft writing takes time no matter what. I have also bought some new & other types of tft's to test if they are faster.
- About the many commands and much writing to the tft, yes I have also simplified that a loot earlier. It helped a little, but still not 100% in all cases. But I will optimize that code again of course. BUT in fact I need to update 11 tft displays with different content! So I need a working base solution which doesnt get affected of how much is written, because else I will just have the problem again when adding 1 more or 2 or 5 or 11.
- About your last question in 1, what would happen would be for each writing the area on the screen would be more and more filled & blurred ending up just being a filled square.
- About your 2. question: tft.availableForWrite() isnt something I have found documented, but I also saw the serial.availableForWrite() and just thought that tft is also serial so it must be based on the same class, so I just tried it and it didnt fail. But I have also not seen it "go wrong" (not true) so I guess it doesnt make any difference if it is there or not. - But ya, I have tried MANY desperate things on my way to fix this. L
- I have also tried tft.flush() but it also didnt seem to solve it, also I have tried to disable other interrupts while writing to the tft with NoInterrupts() and interrupts() to reactivate, but this also didnt seem to fix it.

So ya, I will try my own timer and return to you.
I will also test without the trace and return.

But I really really would like to find the exact course of the problem! And not just "minimizing" by making things take a little longer and just reducing the propability of the lost datas. Becaus if we find the exact reaosn, we would probably also be able to dontrol it somehow.

I would prefer a solution with flush, buffer, ringbuffer, interrupts, better tft, better midi interpretation, pauses, or even using extra dedicated Arduinos or even other small computer devices as a solution where I can add so many tft displays and write so much as i want, without it looses data.
  • Page :
  • 1
  • 2
There are no replies made for this post yet.