From 45887bd22fa1960a2941d177d9e8972bba082018 Mon Sep 17 00:00:00 2001 From: kujiro Date: Wed, 9 Oct 2024 18:59:45 +0900 Subject: [PATCH 1/4] add retries when grovepi returns invalid response --- src/devices/GrovePi/GrovePi.cs | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/devices/GrovePi/GrovePi.cs b/src/devices/GrovePi/GrovePi.cs index 467bdd05e1..dbd5087f89 100644 --- a/src/devices/GrovePi/GrovePi.cs +++ b/src/devices/GrovePi/GrovePi.cs @@ -7,6 +7,7 @@ using System.Device.I2c; using System.IO; using System.Threading; + using Iot.Device.GrovePiDevice.Models; namespace Iot.Device.GrovePiDevice @@ -100,7 +101,7 @@ public void WriteCommand(GrovePiCommand command, GrovePort pin, byte param1, byt return; } catch (IOException ex) - { + { innerEx = ex; tries++; Thread.Sleep(10); @@ -118,9 +119,10 @@ public void WriteCommand(GrovePiCommand command, GrovePort pin, byte param1, byt /// public byte[]? ReadCommand(GrovePiCommand command, GrovePort pin) { + const int dataNotAvailableCommand = 23; int numberBytesToRead = command switch { - GrovePiCommand.DigitalRead => 1, + GrovePiCommand.DigitalRead => 2, GrovePiCommand.AnalogRead or GrovePiCommand.UltrasonicRead or GrovePiCommand.LetBarGet => 3, GrovePiCommand.Version => 4, GrovePiCommand.DhtTemp => 9, @@ -143,7 +145,6 @@ public void WriteCommand(GrovePiCommand command, GrovePort pin, byte param1, byt try { _i2cDevice.Read(outArray); - return outArray; } catch (IOException ex) { @@ -151,7 +152,16 @@ public void WriteCommand(GrovePiCommand command, GrovePort pin, byte param1, byt innerEx = ex; tries++; Thread.Sleep(10); + continue; } + + if (outArray[0] != dataNotAvailableCommand && outArray[0] != 255) + { + return outArray; + } + + tries++; + Thread.Sleep(10); } throw new IOException($"{nameof(ReadCommand)}: Failed to write command {command}", innerEx); @@ -174,7 +184,13 @@ public PinValue DigitalRead(GrovePort pin) { try { - return (PinValue)_i2cDevice.ReadByte(); + var inArray = ReadCommand(GrovePiCommand.DigitalRead, pin); + if (inArray is null || inArray.Length < 2) + { + return (PinValue)(-1); + } + + return (PinValue)inArray[1]; } catch (IOException ex) { From 86db9a0cd3774abef30d60baab07cdf6f722eec6 Mon Sep 17 00:00:00 2001 From: kujiro Date: Thu, 10 Oct 2024 15:32:20 +0900 Subject: [PATCH 2/4] increase retry limit --- src/devices/GrovePi/GrovePi.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/devices/GrovePi/GrovePi.cs b/src/devices/GrovePi/GrovePi.cs index dbd5087f89..9e8afecad8 100644 --- a/src/devices/GrovePi/GrovePi.cs +++ b/src/devices/GrovePi/GrovePi.cs @@ -17,7 +17,7 @@ namespace Iot.Device.GrovePiDevice /// public class GrovePi : IDisposable { - private const byte MaxRetries = 4; + private const byte MaxRetries = 10; private readonly bool _shouldDispose; private I2cDevice _i2cDevice; From 8d258e4bb1a430019695de3c7762cbafc6dd8150 Mon Sep 17 00:00:00 2001 From: kujiro Date: Thu, 10 Oct 2024 15:36:47 +0900 Subject: [PATCH 3/4] fix DigitalRead method to call common ReadCommand method --- src/devices/GrovePi/GrovePi.cs | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/src/devices/GrovePi/GrovePi.cs b/src/devices/GrovePi/GrovePi.cs index 9e8afecad8..9ccfa8184e 100644 --- a/src/devices/GrovePi/GrovePi.cs +++ b/src/devices/GrovePi/GrovePi.cs @@ -175,33 +175,20 @@ public void WriteCommand(GrovePiCommand command, GrovePort pin, byte param1, byt public PinValue DigitalRead(GrovePort pin) { WriteCommand(GrovePiCommand.DigitalRead, pin, 0, 0); - byte tries = 0; - IOException? innerEx = null; - // When writing/reading to the I2C port, GrovePi doesn't respond on time in some cases - // So we wait a little bit before retrying - // In most cases, the I2C read/write can go thru without waiting - while (tries < MaxRetries) + try { - try + var data = ReadCommand(GrovePiCommand.DigitalRead, pin); + if (data is null || data.Length < 2) { - var inArray = ReadCommand(GrovePiCommand.DigitalRead, pin); - if (inArray is null || inArray.Length < 2) - { - return (PinValue)(-1); - } - - return (PinValue)inArray[1]; + return (PinValue)(-1); } - catch (IOException ex) - { - // Give it another try - innerEx = ex; - tries++; - Thread.Sleep(10); - } - } - throw new IOException($"{nameof(DigitalRead)}: Failed to read byte with command {GrovePiCommand.DigitalRead}", innerEx); + return (PinValue)data[1]; + } + catch (IOException) + { + return (PinValue)(-1); + } } /// From 93c630371654591b84a5d69241ad368607f2acaa Mon Sep 17 00:00:00 2001 From: hori Date: Mon, 28 Oct 2024 12:40:07 +0900 Subject: [PATCH 4/4] remove exception handling in DigitalRead method --- src/devices/GrovePi/GrovePi.cs | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/devices/GrovePi/GrovePi.cs b/src/devices/GrovePi/GrovePi.cs index 9ccfa8184e..b3d0175b93 100644 --- a/src/devices/GrovePi/GrovePi.cs +++ b/src/devices/GrovePi/GrovePi.cs @@ -175,20 +175,13 @@ public void WriteCommand(GrovePiCommand command, GrovePort pin, byte param1, byt public PinValue DigitalRead(GrovePort pin) { WriteCommand(GrovePiCommand.DigitalRead, pin, 0, 0); - try - { - var data = ReadCommand(GrovePiCommand.DigitalRead, pin); - if (data is null || data.Length < 2) - { - return (PinValue)(-1); - } - - return (PinValue)data[1]; - } - catch (IOException) + var data = ReadCommand(GrovePiCommand.DigitalRead, pin); + if (data is null || data.Length < 2) { return (PinValue)(-1); } + + return (PinValue)data[1]; } ///