Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mma7660fc driver #275

Merged
merged 3 commits into from
Mar 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace Meadow.Foundation.Sensors.Motion
{
public partial class Mma7660fc
{
/// <summary>
/// Valid addresses for the sensor.
/// </summary>
public enum Addresses : byte
{
/// <summary>
/// Bus address 0x4C
/// </summary>
Address_0x4c = 0x4C,
/// <summary>
/// Bus address 0x4C
/// </summary>
Default = Address_0x4c
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
namespace Meadow.Foundation.Sensors.Motion
{
public partial class Mma7660fc
{
/// <summary>
/// Sensor power mode
/// </summary>
public enum SensorPowerMode : byte
{
/// <summary>
/// Device is in standby mode
/// </summary>
Standby = 0,
/// <summary>
/// Device is active
/// </summary>
Active = 1,
}

/// <summary>
/// Represents the number samples per second
/// </summary>
public enum SampleRate : byte
{
/// <summary>
/// 120 samples per second
/// </summary>
_120 = 0,
/// <summary>
/// 64 sample per second
/// </summary>
_64 = 1,
/// <summary>
/// 32 samples per second
/// </summary>
_32 =2,
/// <summary>
/// 16 samples per second
/// </summary>
_16 = 3,
/// <summary>
/// 8 samples per second
/// </summary>
_8 = 4,
/// <summary>
/// 4 samples per second
/// </summary>
_4 = 5,
/// <summary>
/// 2 samples per second
/// </summary>
_2 = 6,
/// <summary>
/// 1 samples per second
/// </summary>
_1 = 7,
}

/// <summary>
/// Direction/orientation of the device
/// UP/DOWN/LEFT/RIGHT
/// </summary>
public enum DirectionType : byte
{
/// <summary>
/// Direction unknown
/// </summary>
Unknown = 0,
/// <summary>
/// Device oriented up
/// </summary>
Up = 0b00011000,
/// <summary>
/// Device oriented down
/// </summary>
Down = 0b00010100,
/// <summary>
/// Device oriented right
/// </summary>
Right = 0b00001000,
/// <summary>
/// Device oriented left
/// </summary>
Left = 0b00000100,
}

/// <summary>
/// Is device face down or face up
/// </summary>
public enum OrientationType : byte
{
/// <summary>
/// Orientation unknown
/// </summary>
Unknown = 0,
/// <summary>
/// Device is face up (on back)
/// </summary>
Back = 0b00000010,
/// <summary>
/// Device is face down (on front)
/// </summary>
Front = 0b00000001,
}

/// <summary>
/// Device Tilt status
/// </summary>
public enum Tilt : byte
{
/// <summary>
/// Has the device been shaken
/// </summary>
Shake = 0b10000000,
/// <summary>
/// Has the device been tapped
/// </summary>
Tap = 0b00100000,
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Meadow.Foundation.Sensors.Motion
{
public partial class Mma7660fc
{
public enum Registers : byte
{
XOUT = 0x00,
YOUT = 0x01,
ZOUT = 0x02,
TILT = 0x03,
Mode = 0x07,
SleepRate = 0x08
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
using System;
using System.Threading.Tasks;
using Meadow.Hardware;
using Meadow.Peripherals.Sensors.Motion;
using Meadow.Units;

namespace Meadow.Foundation.Sensors.Motion
{
/// <summary>
/// Represents Mma7660fc 3-axis acclerometer
/// </summary>
public partial class Mma7660fc : ByteCommsSensorBase<Acceleration3D>, IAccelerometer
{
/// <summary>
/// Raised when new acceleration data is processed
/// </summary>
public event EventHandler<IChangeResult<Acceleration3D>> Acceleration3DUpdated = delegate { };

/// <summary>
/// Current Acceleration3d value
/// </summary>
public Acceleration3D? Acceleration3D => Conditions;

public DirectionType Direction { get; set; } = DirectionType.Unknown;
public OrientationType Orientation { get; set; } = OrientationType.Unknown;

/// <summary>
/// Create a new instance of the Mma7660fc communicating over the I2C interface.
/// </summary>
/// <param name="address">Address of the I2C sensor</param>
/// <param name="i2cBus">I2C bus</param>
public Mma7660fc(II2cBus i2cBus, Addresses address = Addresses.Default)
: this(i2cBus, (byte)address)
{
}

/// <summary>
/// Create a new instance of the Mma7660fc communicating over the I2C interface.
/// </summary>
/// <param name="address">Address of the I2C sensor</param>
/// <param name="i2cBus">I2C bus</param>
public Mma7660fc(II2cBus i2cBus, byte address)
: base(i2cBus, address)
{
Initialize();
}

void Initialize()
{
SetMode(SensorPowerMode.Standby);
SetSampleRate(SampleRate._32);
SetMode(SensorPowerMode.Active);
}

void SetMode(SensorPowerMode mode)
{
Peripheral.WriteRegister((byte)Registers.Mode, (byte)mode);
}

/// <summary>
/// Set sample rate in samples per second
/// </summary>
/// <param name="rate">sample rate</param>
public void SetSampleRate(SampleRate rate)
{
Peripheral.WriteRegister((byte)Registers.SleepRate, (byte)rate);
}

/// <summary>
/// Read sensor data from registers
/// </summary>
/// <returns></returns>
protected override Task<Acceleration3D> ReadSensor()
{
return Task.Run(() =>
{
Direction = (DirectionType)(Peripheral.ReadRegister((byte)Registers.TILT) & 0x1C);

Orientation = (OrientationType)(Peripheral.ReadRegister((byte)Registers.TILT) & 0x03);

int xAccel, yAccel, zAccel;
byte x, y, z;

//Signed byte 6-bit 2’s complement data with allowable range of +31 to -32
//[5] is 0 if the g direction is positive, 1 if the g direction is negative.
do
{
x = Peripheral.ReadRegister((byte)Registers.XOUT);
}
//ensure bit 6 isn't set - if so, it means there was a read/write collision ... try again
while (x >= 64);

//check bit 5 and flip to negative
if ((x & (1 << 5)) != 0) xAccel = x - 64;
else xAccel = x;

do
{
y = Peripheral.ReadRegister((byte)Registers.YOUT);
}
//ensure bit 6 isn't set - if so, it means there was a read/write collision ... try again
while (y >= 64);

if ((y & (1 << 5)) != 0) yAccel = y - 64;
else yAccel = y;

do
{
z = Peripheral.ReadRegister((byte)Registers.ZOUT);
}
//ensure bit 6 isn't set - if so, it means there was a read/write collision ... try again
while (y >= 64);

if ((z & (1 << 5)) != 0) zAccel = z - 64;
else zAccel = z;

return new Acceleration3D(
new Acceleration(xAccel * 3.0 / 64.0, Acceleration.UnitType.Gravity),
new Acceleration(yAccel * 3.0 / 64.0, Acceleration.UnitType.Gravity),
new Acceleration(zAccel * 3.0 / 64.0, Acceleration.UnitType.Gravity)
);
});
}

/// <summary>
/// Raise event and notify subscribers
/// </summary>
/// <param name="changeResult">Acceleration3d data</param>
protected override void RaiseEventsAndNotify(IChangeResult<Acceleration3D> changeResult)
{
Acceleration3DUpdated?.Invoke(this, changeResult);
base.RaiseEventsAndNotify(changeResult);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Meadow.Sdk/1.1.0">
<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageIcon>icon.png</PackageIcon>
<Authors>Wilderness Labs, Inc</Authors>
<TargetFramework>netstandard2.1</TargetFramework>
<OutputType>Library</OutputType>
<AssemblyName>Mma7660fc</AssemblyName>
<Company>Wilderness Labs, Inc</Company>
<PackageProjectUrl>http://developer.wildernesslabs.co/Meadow/Meadow.Foundation/</PackageProjectUrl>
<PackageId>Meadow.Foundation.Sensors.Motion.Mma7660fc</PackageId>
<RepositoryUrl>https://github.com/WildernessLabs/Meadow.Foundation</RepositoryUrl>
<PackageTags>Meadow.Foundation, Mma7660fc, Accelerometer, Motion</PackageTags>
<Version>0.1.0</Version>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Description>Mma7660fc I2C 3-axis accelerometer</Description>
</PropertyGroup>
<ItemGroup>
<None Include="..\..\..\..\icon.png" Pack="true" PackagePath="" />
<ProjectReference Include="..\..\..\..\Meadow.Foundation.Core\Meadow.Foundation.Core.csproj" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using System;
using System.Threading.Tasks;
using Meadow;
using Meadow.Devices;
using Meadow.Foundation.Sensors.Motion;
using Meadow.Units;
using AU = Meadow.Units.Acceleration.UnitType;

namespace Sensors.Motion.Mma7660fc_Sample
{
public class MeadowApp : App<F7MicroV2, MeadowApp>
{
//<!—SNIP—>

Mma7660fc sensor;

public MeadowApp()
{
Console.WriteLine("Initializing");

// create the sensor driver
sensor = new Mma7660fc(Device.CreateI2cBus());

// classical .NET events can also be used:
sensor.Updated += (sender, result) => {
Console.WriteLine($"Accel: [X:{result.New.X.MetersPerSecondSquared:N2}," +
$"Y:{result.New.Y.MetersPerSecondSquared:N2}," +
$"Z:{result.New.Z.MetersPerSecondSquared:N2} (m/s^2)]" +
$" Direction: {sensor.Direction}" +
$" Orientation: {sensor.Orientation}");
};

// Example that uses an IObersvable subscription to only be notified when the filter is satisfied
var consumer = Mma7660fc.CreateObserver(
handler: result => Console.WriteLine($"Observer: [x] changed by threshold; new [x]: X:{result.New.X:N2}, old: X:{result.Old?.X:N2}"),
// only notify if there's a greater than 0.5G change in the Z direction
filter: result => {
if (result.Old is { } old) { //c# 8 pattern match syntax. checks for !null and assigns var.
return ((result.New - old).Z > new Acceleration(0.5, AU.Gravity));
}
return false;
});
sensor.Subscribe(consumer);

//==== one-off read
ReadConditions().Wait();

// start updating
sensor.StartUpdating(TimeSpan.FromMilliseconds(1000));
}

protected async Task ReadConditions()
{
var result = await sensor.Read();
Console.WriteLine("Initial Readings:");
Console.WriteLine($"Accel: [X:{result.X.MetersPerSecondSquared:N2}," +
$"Y:{result.Y.MetersPerSecondSquared:N2}," +
$"Z:{result.Z.MetersPerSecondSquared:N2} (m/s^2)]");
}

//<!—SNOP—>
}
}
Loading