Skip to content

Commit

Permalink
Fixes to I2C device support
Browse files Browse the repository at this point in the history
Note: i2cdetect requires the very latest Firmata version
  • Loading branch information
pgrawehr committed Apr 27, 2020
1 parent 11c8527 commit ffca3cc
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/devices/Arduino/ArduinoI2cDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public ArduinoI2cDevice(ArduinoBoard board, I2cConnectionSettings connectionSett
pinsFound++;
}

_board.Firmata.SendI2cConfigCommand();

if (pinsFound < 2)
{
throw new NotSupportedException("Need at least two I2C capable pins. Is I2C support disabled in Firmata?");
Expand Down
14 changes: 14 additions & 0 deletions src/devices/Arduino/FirmataDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,20 @@ public void WriteDigitalPin(int pin, PinValue value)
}
}

public void SendI2cConfigCommand()
{
lock (_synchronisationLock)
{
// The command is mandatory, even if the argument is typically ignored
_firmataStream.WriteByte((byte)FirmataCommand.START_SYSEX);
_firmataStream.WriteByte((byte)FirmataSysexCommand.I2C_CONFIG);
_firmataStream.WriteByte(0);
_firmataStream.WriteByte(0);
_firmataStream.WriteByte((byte)FirmataCommand.END_SYSEX);
_firmataStream.Flush();
}
}

public void WriteReadI2cData(int slaveAddress, ReadOnlySpan<byte> writeData, Span<byte> replyData)
{
// See documentation at https://github.com/firmata/protocol/blob/master/i2c.md
Expand Down
55 changes: 53 additions & 2 deletions src/devices/Arduino/samples/Arduino.sample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@
using System.Device.I2c;
using System.Device.Spi;
using System.IO.Ports;
using System.Text;
using System.Threading;
using Iot.Device.Arduino;
using Iot.Device.Bmxx80;
using Iot.Device.Bmxx80.PowerMode;

namespace Ft4222.Samples
namespace Arduino.Samples
{
/// <summary>
/// Sample application for Ft4222
/// Sample application for Arduino control over firmata
/// </summary>
internal class Program
{
Expand Down Expand Up @@ -87,6 +89,7 @@ private static bool Menu(ArduinoBoard board)
Console.WriteLine(" 6 Run PWM test with a simple led dimming on GPIO6 port");
Console.WriteLine(" 7 Dim the LED according to the input on A1");
Console.WriteLine(" 8 Read analog channel as fast as possible");
Console.WriteLine(" 0 Detect all devices on the I2C bus");
Console.WriteLine(" X Exit");
var key = Console.ReadKey();
Console.WriteLine();
Expand Down Expand Up @@ -117,6 +120,9 @@ private static bool Menu(ArduinoBoard board)
case '8':
TestAnalogCallback(board);
break;
case '0':
ScanDeviceAddressesOnI2cBus(board);
break;
case 'x':
case 'X':
return false;
Expand Down Expand Up @@ -163,6 +169,8 @@ private static void TestI2c(ArduinoBoard board)
var device = board.CreateI2cDevice(new I2cConnectionSettings(0, Bmp280.DefaultI2cAddress));

var bmp = new Bmp280(device);
bmp.StandbyTime = StandbyTime.Ms250;
bmp.SetPowerMode(Bmx280PowerMode.Normal);
Console.WriteLine("Device open");
while (!Console.KeyAvailable)
{
Expand All @@ -178,6 +186,49 @@ private static void TestI2c(ArduinoBoard board)
Console.WriteLine();
}

private static void ScanDeviceAddressesOnI2cBus(ArduinoBoard board)
{
StringBuilder stringBuilder = new StringBuilder();

stringBuilder.Append(" 0 1 2 3 4 5 6 7 8 9 a b c d e f");
stringBuilder.Append(Environment.NewLine);

for (int startingRowAddress = 0; startingRowAddress < 128; startingRowAddress += 16)
{
stringBuilder.Append($"{startingRowAddress:x2}: "); // Beginning of row.

for (int rowAddress = 0; rowAddress < 16; rowAddress++)
{
int deviceAddress = startingRowAddress + rowAddress;

// Skip the unwanted addresses.
if (deviceAddress < 0x3 || deviceAddress > 0x77)
{
stringBuilder.Append(" ");
continue;
}

var connectionSettings = new I2cConnectionSettings(0, deviceAddress);
using (var i2cDevice = board.CreateI2cDevice(connectionSettings))
{
try
{
i2cDevice.ReadByte(); // Only checking if device is present.
stringBuilder.Append($"{deviceAddress:x2} ");
}
catch
{
stringBuilder.Append("-- ");
}
}
}

stringBuilder.Append(Environment.NewLine);
}

Console.WriteLine(stringBuilder.ToString());
}

public static void TestGpio(ArduinoBoard board)
{
// Use Pin 6
Expand Down

0 comments on commit ffca3cc

Please sign in to comment.