Serial read from software  always lost

I’m trying to use two arduino to simulate an ignition convert system,
something like ECU
the concepted circuit like below…

The right arduino is simulated as a signal to send RPM pulse from digital pin 2,
and use a pot VR to change the pulse speed.
The left arduino is simulated as a ignition system to read the pulse as interupt from the right arduino ,then calculate the RPM and map RPM to ten blocks of range from RPM 0~9999-> EEPROM address 0~9, then output pulse X times as ignition, which X is read from the EEPROM . etc as below.
RPM 0~999 will output ignition 3 times . 3 read from EEPROM address 0
RPM 1000~1999 will output ignition 3 times . 3 read from EEPROM address 1
RPM 2000~2999 will output ignition 3 times. 3 read from EEPROM address 2
RPM 3000~3999 will output ignition 2 times. 2 read from EEPROM address 3

RPM 9000~9999 will output ignition 1 time. 1 read from EEPROM address 9

Then I use the C++ to write an interface to monitor the current RPM and ignition times which send from the ignition arduino(left arduino), the arduino will consecutively send the protocol as “~RPM!Ignition times@” ,and software decode the protocol to display the values of RPM and ignition times.

look on the snapshot of the software, the echo message of the protocol “~RPM!Ignition times@” seems always lost in the transmission of serial port, and even when the RPM is up to several thousands , the echo frequency up, and the protocol lost more…i dont know how to solve this problem , is there any solution to not lost so much serial transmited data???
Then sometimes i write the EEPROM value of an specific address, the left arduino sometimes fail to read the command of “write EEPROM protocol”, it is also the transmission lost in the arduino end.
or the send echo process is conflited with the interupt signal from the right arduino??Or does anyone have better way to monitor the specific value form the arduino then print on the software??

We can't see your code. Specifically, we can not see what baud rate you are using to communicate between the two boards.

Serial data takes time to be sent. The higher the baud rate, the less time is taken.

You may be sending data faster than it can be processed. You might want to look at the protocol. Sending "~RPM!Ignition times@" may seem like a good idea, but that is 20 characters. Sending "~R!IT@" is as easily interpreted by the Arduino, and is only 6 characters, meaning that it takes only 30% of the time to send.

Thanks , ~RPM!Ignition Times@, RPM and Ignition Times is variable, for example, when RPM is 1000 and Ignition times is 3, arduino send echo as "~1000!3@" to software , for while i took another test to monitor the echo protocol from default Serial Monitor of Arduino IDE instead of my software , i found it didnt lost the transmited data as the software does , snapshot below. so now i can know maybe the problem is not the transmission lost, it is the software received serial data error for each transmission, maybe is the timeout problem??? btw, the baudrate of two boards are some as 9600

the soucecode like below…;
send the echo using Streaming.h to send the RPM and ignition times info.
another problem, snapshot

when the RPM up, the serial receive lots of ~RPM!Ignition times@ at single transmission.

The serial transmission rate of 9600 is pretty slow. It can be increased up to 115200. Might help.

Otherwise, post all the code for both the sender and receiver.

One thing to consider is that EEPROM reads are not all that fast. Perhaps you should read the values once in setup, and store them in an array. Then, reference that array in loop.

I put some source code relating to the serial interaction between my c++ software and arduino.
This is the C++ write EEPROM request function.
This is based on Qt GUI interface,and using one of the opensource serial communication library,QextSerialPort
writeAddressLineEdit is a text area to type the EEPROM address which will be written.
writeDataLineEdit is also a text area to type the data which will be written into above address.
QTextStream(&text)<<’@’<<address<<’#’<<data<<’$’; will coporate above two text to construct a writing EEPROM request protocol to send into arduino.
port->write(text.toAscii(),text.length()); to send the protocol to arduino through serial port.

void ArduinoComm::writeEEPROM()
QString address,data,text;
QString msg;
QTextStream(&msg)<<"EEPROM Write Address: “<<address<<” Data: "<<data;
emit print(msg);

The second stage , arduino received the protocol like below sourcecode, to decode the “@Address#Data$” protocol to know which address and what data wants to be written. use the state relation to control the decode flow logic, and i also take arduino connected with an LCD to display the message after EEPROM writing action is sucessful.

else if(readByte==’#’&&state==1)
else if(readByte==’$’&&state==2)
lcd.print(" ");
else if(state==1)
else if(state==2)


The new probelm, sometimes the request is fail when i send a EEPROM writing request to arduino, sometimes its ok.
fail: arduino could always decode the request , but sometimes decode the wrong address or data,this is weird. For example, i send @9#13$ means i want to write integer 13 into EEPROM address 9 of arduino, but sometimes fail like arduino display another address or data on the LCD, means it didnt write the correct address of data which software requested.
I think it was not the transmission lost problem , because somehow it can display the message on the LCD, means arduino received the completed protocol totally containing @…#…$, so how it will still the wrong address and data???

If you send "@9#13$" and the Arduino receives "@#13$" or "@9#1$" or "@9#3$", the behavior of the program will be incorrect.

For fully robust packet handling, you'd need to send the length of the packet and some sort of checksum, too. Then, after receiving a "complete" packet, you'd need to make sure that the received packet length matched the sent packet length and that the received packet checksum matched the sent checksum.

In the readbyte=='@' block, you should set add_digits and data_digits to 0, too. Or, get rid of them, and set address and data to 0.