ptmir:
Hello everybody , i have a question about the buffer , i found information on the Internet
So if i send a 264 bytes to RX serial port , only the first 64 bytes stays on the buffer...
Max. 63 bytes stay in the buffer.
Though the size of the buffer is 64, it can keep 63 bytes only at the same time, due to its internal organization as a FIFO ringbuffer.
ptmir:
how do you handle this limit so it can read all 264 bytes , when you can not
divide the incoming data ( only sends 264 bytes at once..to RX port ) ?
"Serial" is one of the slowest things you can run on an Arduino. You will never receive "264 bytes at once". Even with 115200 baud you receive only 11520 bytes per second, which means that every 86 microseconds one byte arrives. So it goes like this:
byte #1 arrives
86 microseconds ==> nothing happens
byte #2 arrives
86 microseconds ==> nothing happens
byte #3 arrives
86 microseconds ==> nothing happens
byte #4 arrives
86 microseconds ==> nothing happens
byte #5 arrives
86 microseconds ==> nothing happens
You can always use the "nothing happens" time to read the bytes from the Serial input buffer and save them in another buffer of the size you actually want.
With clever programming, your Serial input buffer will hardly contain more than 1 byte at any time, even when receiving all the time. So most likely, clever Arduino programs will never use more than 1 byte of the Serial input buffer, although up to max. 63 bytes could be in the Serial input buffer with some less clever programming.
Only dumb programs using dumb commands like "delay()" will lead to an overflow of the serial input puffer. So just avoid using dumb commands like "delay()" and all the "Serial.parseBullshit()" or other silly commands, and you get what you want: A clever program that handles all Serial input quickly.
Then it's just a question of what you do with the packet data you're reading. One simple solution would be to read it into a buffer of your own - an array of 264 chars. RAM is in short supply on most arduinos though, so if possible, it would likely be preferable to parse the data as you receive it.
You've ignored the advice above: Wikipedia tells me that MIDI runs at 31250 baud or ~3125 characters a second. Which means that delay(100) you're using is more than enough to overflow the serial buffer.
i did not have initially a delay there but without it i did not get any data .. so i implement a delay(100)
i will try now a delayMicroseconds(258) instead , lets see
The real problem is that once you see the start byte, your code executes the while loop assuming that all of your data will be there. It won't - serial data transmission is slow as mentioned above. You need to structure your code so that it can read the data as and when it arrives.
When you do post your code again, better to post (or attach) the whole thing.
//========================================================================================
//== VOID SYSEX receive from Synth !!
//========================================================================================
void receiveSysex() {
Serial.end() ; //desliga o serial output
delay(200);
Serial.begin(31250); // para trabalhar no MIDI
Serial.flush();
digitalWrite(8, LOW);
delay(50);
digitalWrite(8, HIGH);
//F0 Start of SysX
//44 00 00 Casio Manufacturer ID
//70 MIDI Channel 1 (70..7F = channel 1..16)
//must be the same channel als the CZ-5000 MIDI channel number
//10 Command "Dump Request"
//xx [00..1F] = PRESET Timbre numbers A1-D8
//[20..3F] = MEMORY Timbre numbers A1-D8
//[40..5F] = CARTRIDGE Timbres A1-D8
//[60] = Timbre in the Edit Buffer
//70 31 End of request (so not the usual F7 sysx terminator)
//F0 44 00 00 70 10 60 70 31 F7 request patch from CURRENT SOUND area
//byte casioRe[]={0xF0, 0x44, 0x00, 0x00, 0x70, 0x10, 0x60 , 0x70, 0x31 , 0xF7} ;
byte casioRe[]={0xF0, 0x44, 0x00, 0x00, 0x70, 0x10, 0x60 , 0x70, 0x31} ;
Serial.write(casioRe, sizeof(casioRe)); // request CURRENT SOUND casio cz-1000
Serial.flush();
delayMicroseconds(2200);
byte one = 0;
int index=0;
byte datax [264];
int doit=0;
if (Serial.available() > 0)
{
one = Serial.read();
if (one == 0xF0)
{ datax[0]= 0xF0;
index++;
while (Serial.available()>0)
{
datax[index] = Serial.read();
index++;
}
datax[263]=0xf7;
doit=1;
}
}
delay(2000);
if (doit==1)
{
//------------------------------------------
//GRAVAR em FICHEIRO
//nome do file a gravar é o maximo + 1
//----------------------------------------
char sysexName [3];
File sysexFile;
int nmax;
nmax=maximo+1;
sprintf(sysexName,"%i",nmax);
//Serial.print(maximo,DEC); // DEBUGUING MAXIMO FILES .. OK FOR F16 FORMAT SD CARD ...
sysexFile.setTimeout(0); // sets the maximum milliseconds to wait for serial data
sysexFile = SD.open(sysexName, FILE_WRITE); //This creates a file !!! cool :)
delay(500);
// if the file is available, write to it:
if (sysexFile) {
for (int n=0; n< sizeof(datax) ; n++)
{ sysexFile.write(datax [n]); }
sysexFile.close();
maximo=maximo+1; // entao se foi gravado um novo file o maximo incrementa 1
putINITXTinc() ;
}
delay(1000); // para que evite o user de estar a pressionar este botao sem parar.... ,like crazy lol
digitalWrite(8, LOW);
delay(50);
digitalWrite(8, HIGH);
}
}
//========================================================================================
//== END !!! VOID SYSEX receive from Synth !!
//========================================================================================
The function call "delay(100);" means something like:
Prevent my program to execute for a very, very long time.
The time shall be 100 milliseconds = 1.6 million controller cycles,
Do nothing until the Serial input buffer is flooded several times.
If ready with blocking everything, then continue.
Blocking all the program execution for millions of controller cycles until the input buffer is flooded several time is NOT a good programming logic.