diff --git a/Arduino/ReceiveCart/ReceiveCart.ino b/Arduino/ReceiveCart/ReceiveCart.ino index b1a41d8..4534669 100644 --- a/Arduino/ReceiveCart/ReceiveCart.ino +++ b/Arduino/ReceiveCart/ReceiveCart.ino @@ -45,6 +45,7 @@ void setup() { Serial.begin(115200); pinMode(LED_BUILTIN, OUTPUT); Wire.begin(); + Wire.setClock(400000); } void loop() { diff --git a/Arduino/SendCart/SendCart.ino b/Arduino/SendCart/SendCart.ino index 54de478..6bb0292 100644 --- a/Arduino/SendCart/SendCart.ino +++ b/Arduino/SendCart/SendCart.ino @@ -33,6 +33,7 @@ void setup() { Serial.begin(115200); pinMode(LED_BUILTIN, OUTPUT); Wire.begin(); + Wire.setClock(400000); } /* diff --git a/Assets/Scripts/Arduino_Com.cs b/Assets/Scripts/Arduino_Com.cs index c5f1bad..bf7a9a3 100644 --- a/Assets/Scripts/Arduino_Com.cs +++ b/Assets/Scripts/Arduino_Com.cs @@ -14,6 +14,7 @@ public class Arduino_Com : MonoBehaviour { Déconnecté, Connecté, + Connexion, Lecture, Écriture, Invalide @@ -68,16 +69,26 @@ public class Arduino_Com : MonoBehaviour return sum; } + // Core communication function. + // Receives all the data from the cartridge and writes it out to the png file. + // As the computer will probably read the serial data faster than the Arduino + // /and/ the transfer is quite slow (lots of bits, low baudrate), make this a + // coroutine. + // This prevents the whole application freezing up why waiting for data and + // allow presenting visual feedback. private IEnumerator ReceiveSerialData() { do { + // We could use an event instead but as Unity is lagging behind .NET versions, + // it wouldn't be cross-platform. yield return new WaitUntil(() => _serial.BytesToRead >= 1); + // Read all available data, up to the PageSize. _readBytes += _serial.Read(_pageBuffer, _readBytes, PageSize - _readBytes); // Full page received, check checksum and ACK/NAK, write received page. - if (_readBytes >= 128) + if (_readBytes >= PageSize) { Byte[] checksum = new byte[2]; // There might be less than the two characters of the checksum available, loop until complete. @@ -88,7 +99,8 @@ public class Arduino_Com : MonoBehaviour } while (checksumRead < 2); // Implicit type of the sum is 4 bytes, so the overflow doesn't occur. Compute manually. - if (65536 - (BitConverter.ToUInt16(checksum) + ComputeChecksum(_pageBuffer)) == 0) + if ((UInt16.MaxValue + 1) - + (BitConverter.ToUInt16(checksum) + ComputeChecksum(_pageBuffer)) == 0) { // Checksum valid, write it out to the cart. _cart.Write(_pageBuffer); @@ -104,6 +116,7 @@ public class Arduino_Com : MonoBehaviour _readBytes = 0; } } while (_currentPage < PageCount); + // We are done receiving the cart, we don't expect more data to be received so the coroutine can return. _currentPage = 0; _state = ArduinoState.Connecté; @@ -222,14 +235,7 @@ public class Arduino_Com : MonoBehaviour return; } - // TODO: Wait ~2s for Arduino startup - _arduinoControlButton.text = "Déconnecter"; - - _cartLoadButton.SetEnabled(true); - // _cartWriteButton.SetEnabled(true); TODO: Not implemented - _arduinoSerialPort.SetEnabled(false); - - _state = ArduinoState.Connecté; + StartCoroutine(DoSerialConnection()); } } @@ -244,4 +250,24 @@ public class Arduino_Com : MonoBehaviour _state = SerialPort.GetPortNames().Contains(newPort.newValue) ? ArduinoState.Déconnecté : ArduinoState.Invalide; _arduinoControlButton.SetEnabled(_state != ArduinoState.Invalide); } + + // Update UI during connection and when ready, prevent interacting too quickly. + IEnumerator DoSerialConnection() + { + _arduinoControlButton.text = "Connexion..."; + _arduinoControlButton.SetEnabled(false); + _arduinoSerialPort.SetEnabled(false); + _state = ArduinoState.Connexion; + + // Delay enabling transfers because the Arduino is slow to set-up the serial. + yield return new WaitForSeconds(1.5f); + + _arduinoControlButton.text = "Déconnecter"; + _arduinoControlButton.SetEnabled(true); + + _cartLoadButton.SetEnabled(true); + // _cartWriteButton.SetEnabled(true); TODO: Not implemented + + _state = ArduinoState.Connecté; + } }