Skip to content

Commit

Permalink
Add TinyCodeReader driver + general cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
adrianstevens committed Jan 14, 2024
1 parent fe1654d commit a4efc7b
Show file tree
Hide file tree
Showing 10 changed files with 370 additions and 18 deletions.
30 changes: 30 additions & 0 deletions Source/CompositeDevices.sln
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sample", "Sample", "{1B4743
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PersonSensor_Sample", "Sensors.Motion.UsefulSensors.PersonSensor\Samples\PersonSensor_Sample\PersonSensor_Sample.csproj", "{6046728F-EFF4-4B77-8C15-7CB87B145395}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Cameras", "Cameras", "{EFA4C1B3-5257-451E-908F-AF9EDA45F224}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UsefulSensors", "UsefulSensors", "{72A32E4E-7492-4F7C-BF42-9CF2E664338B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TinyCodeReader", "TinyCodeReader", "{FCD85A86-0779-4AC3-A12C-91F3C0C5D161}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sensors.UsefulSensors.TinyCodeReader", "Sensors.UsefulSensors.TinyCodeReader\Driver\Sensors.UsefulSensors.TinyCodeReader.csproj", "{956151FF-9CF1-4D48-A150-21A8B8A5DB89}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sample", "Sample", "{B155FD13-EEE6-40B3-9C3A-A0FEADCBE24F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TinyCodeReader_Sample", "Sensors.UsefulSensors.TinyCodeReader\Samples\TinyCodeReader_Sample\TinyCodeReader_Sample.csproj", "{8A554253-ECCF-45A4-8054-DFA5108B0616}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -119,6 +131,18 @@ Global
{6046728F-EFF4-4B77-8C15-7CB87B145395}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6046728F-EFF4-4B77-8C15-7CB87B145395}.Release|Any CPU.Build.0 = Release|Any CPU
{6046728F-EFF4-4B77-8C15-7CB87B145395}.Release|Any CPU.Deploy.0 = Release|Any CPU
{956151FF-9CF1-4D48-A150-21A8B8A5DB89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{956151FF-9CF1-4D48-A150-21A8B8A5DB89}.Debug|Any CPU.Build.0 = Debug|Any CPU
{956151FF-9CF1-4D48-A150-21A8B8A5DB89}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{956151FF-9CF1-4D48-A150-21A8B8A5DB89}.Release|Any CPU.ActiveCfg = Release|Any CPU
{956151FF-9CF1-4D48-A150-21A8B8A5DB89}.Release|Any CPU.Build.0 = Release|Any CPU
{956151FF-9CF1-4D48-A150-21A8B8A5DB89}.Release|Any CPU.Deploy.0 = Release|Any CPU
{8A554253-ECCF-45A4-8054-DFA5108B0616}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8A554253-ECCF-45A4-8054-DFA5108B0616}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8A554253-ECCF-45A4-8054-DFA5108B0616}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{8A554253-ECCF-45A4-8054-DFA5108B0616}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8A554253-ECCF-45A4-8054-DFA5108B0616}.Release|Any CPU.Build.0 = Release|Any CPU
{8A554253-ECCF-45A4-8054-DFA5108B0616}.Release|Any CPU.Deploy.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -142,6 +166,12 @@ Global
{773E12FF-A4F0-4835-9BAA-34454DB42E6B} = {4A6B7EF6-7730-4570-A72F-6E4506227668}
{1B4743D8-E3B7-4466-9A66-266B91AB3676} = {4A6B7EF6-7730-4570-A72F-6E4506227668}
{6046728F-EFF4-4B77-8C15-7CB87B145395} = {1B4743D8-E3B7-4466-9A66-266B91AB3676}
{EFA4C1B3-5257-451E-908F-AF9EDA45F224} = {78203E26-CBDE-48BC-B8CF-617F8A863D65}
{72A32E4E-7492-4F7C-BF42-9CF2E664338B} = {EFA4C1B3-5257-451E-908F-AF9EDA45F224}
{FCD85A86-0779-4AC3-A12C-91F3C0C5D161} = {72A32E4E-7492-4F7C-BF42-9CF2E664338B}
{956151FF-9CF1-4D48-A150-21A8B8A5DB89} = {FCD85A86-0779-4AC3-A12C-91F3C0C5D161}
{B155FD13-EEE6-40B3-9C3A-A0FEADCBE24F} = {FCD85A86-0779-4AC3-A12C-91F3C0C5D161}
{8A554253-ECCF-45A4-8054-DFA5108B0616} = {B155FD13-EEE6-40B3-9C3A-A0FEADCBE24F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BF2FC8CE-57C6-468C-B82D-D8204E6D9360}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using Meadow.Devices;
using Meadow.Foundation.Relays;
using Meadow.Peripherals.Relays;
using System;
using System.Threading;
using System.Threading.Tasks;
using static Meadow.Foundation.Relays.ElectromagneticRelayModule;
Expand All @@ -17,7 +16,7 @@ public class MeadowApp : App<F7FeatherV2>

public override Task Initialize()
{
Console.WriteLine("Initialize...");
Resolver.Log.Info("Initialize...");

module = new ElectromagneticRelayModule(Device.CreateI2cBus(), ElectromagneticRelayModule.GetAddressFromPins(false, false, false));

Expand All @@ -28,26 +27,26 @@ public override Task Run()
{
for (int i = 0; i < 5; i++)
{
Console.Write("All on (closed)");
Resolver.Log.Info("All on (closed)");
module.SetAllOn();

Thread.Sleep(1000);

Console.Write("All off (open)");
Resolver.Log.Info("All off (open)");
module.SetAllOff();

Thread.Sleep(1000);

for (int j = 0; j < (int)RelayIndex.Relay4; j++)
{
Console.Write($"{(RelayIndex)j} on (closed)");
Resolver.Log.Info($"{(RelayIndex)j} on (closed)");
module.Relays[j].State = RelayState.Closed;
Thread.Sleep(1000);
}

for (int j = 0; j < (int)RelayIndex.Relay4; j++)
{
Console.Write($"{(RelayIndex)j} off (open)");
Resolver.Log.Info($"{(RelayIndex)j} off (open)");
module.Relays[j].State = RelayState.Open;
Thread.Sleep(1000);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,12 @@ public partial class PersonSensor : II2cPeripheral


/// <summary>
/// Initializes a new instance of the ElectroMagneticRelayModule device
/// Initializes a new instance of the Useful Sensor's Person Sensor device
/// </summary>
/// <param name="i2cBus">The I2C bus the peripheral is connected to</param>
/// <param name="address">The bus address of the peripheral</param>
public PersonSensor(II2cBus i2cBus, byte address = 0x62)
public PersonSensor(II2cBus i2cBus)
{
i2cComms = new I2cCommunications(i2cBus, address, DATA_LENGTH);
i2cComms = new I2cCommunications(i2cBus, DefaultI2cAddress, DATA_LENGTH);
readBuffer = new byte[DATA_LENGTH];
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using Meadow;
using Meadow.Devices;
using Meadow.Foundation.Sensors;
using System;
using System.Threading;
using System.Threading.Tasks;

Expand All @@ -15,7 +14,7 @@ public class MeadowApp : App<F7CoreComputeV2>

public override Task Initialize()
{
Console.WriteLine("Initialize...");
Resolver.Log.Info("Initialize...");

personSensor = new PersonSensor(Device.CreateI2cBus());

Expand All @@ -38,18 +37,14 @@ private void DisplaySensorData(PersonSensorResults sensorData)
{
if (sensorData.NumberOfFaces == 0)
{
Console.WriteLine("No faces found");
Resolver.Log.Info("No faces found");
return;
}

for (int i = 0; i < sensorData.NumberOfFaces; ++i)
{
var face = sensorData.FaceData[i];
Console.Write($"Face #{i}: ");
Console.Write($"{face.BoxConfidence} confidence, ");
Console.Write($"({face.BoxLeft}, {face.BoxTop}), ");
Console.Write($"({face.BoxRight}, {face.BoxBottom}), ");
Console.WriteLine(face.IsFacing == 1 ? "facing" : "not facing");
Resolver.Log.Info($"Face #{i}: {face.BoxConfidence} confidence, ({face.BoxLeft}, {face.BoxTop}), ({face.BoxRight}, {face.BoxBottom}), facing: {face.IsFacing}");
}
}

Expand Down
67 changes: 67 additions & 0 deletions Source/Sensors.UsefulSensors.TinyCodeReader/Driver/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Meadow.Foundation.Sensors.PersonSensor

**Useful Sensor's I2C optical person sensor**

The **UsefulSensorsPersonSensor** library is designed for the [Wilderness Labs](www.wildernesslabs.co) Meadow .NET IoT platform and is part of [Meadow.Foundation](https://developer.wildernesslabs.co/Meadow/Meadow.Foundation/).

The **Meadow.Foundation** peripherals library is an open-source repository of drivers and libraries that streamline and simplify adding hardware to your C# .NET Meadow IoT application.

For more information on developing for Meadow, visit [developer.wildernesslabs.co](http://developer.wildernesslabs.co/).

To view all Wilderness Labs open-source projects, including samples, visit [github.com/wildernesslabs](https://github.com/wildernesslabs/).

## Usage

```csharp
PersonSensor personSensor;

public override Task Initialize()
{
Console.WriteLine("Initialize...");

personSensor = new PersonSensor(Device.CreateI2cBus());

return Task.CompletedTask;
}

public override Task Run()
{
while (true)
{
var sensorData = personSensor.GetSensorData();
DisplaySensorData(sensorData);

Thread.Sleep(1500);
}
}

private void DisplaySensorData(PersonSensorResults sensorData)
{
if (sensorData.NumberOfFaces == 0)
{
Console.WriteLine("No faces found");
return;
}

for (int i = 0; i < sensorData.NumberOfFaces; ++i)
{
var face = sensorData.FaceData[i];
Console.Write($"Face #{i}: ");
Console.Write($"{face.BoxConfidence} confidence, ");
Console.Write($"({face.BoxLeft}, {face.BoxTop}), ");
Console.Write($"({face.BoxRight}, {face.BoxBottom}), ");
Console.WriteLine(face.IsFacing == 1 ? "facing" : "not facing");
}
}

```
## How to Contribute

- **Found a bug?** [Report an issue](https://github.com/WildernessLabs/Meadow_Issues/issues)
- Have a **feature idea or driver request?** [Open a new feature request](https://github.com/WildernessLabs/Meadow_Issues/issues)
- Want to **contribute code?** Fork the [Meadow.Foundation.CompositeDevices](https://github.com/WildernessLabs/Meadow.Foundation.CompositeDevices) repository and submit a pull request against the `develop` branch


## Need Help?

If you have questions or need assistance, please join the Wilderness Labs [community on Slack](http://slackinvite.wildernesslabs.co/).
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<Project Sdk="Meadow.Sdk/1.1.0">
<PropertyGroup>
<PackageReadmeFile>Readme.md</PackageReadmeFile>
<LangVersion>10.0</LangVersion>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageIcon>icon.png</PackageIcon>
<Authors>Wilderness Labs, Inc</Authors>
<TargetFramework>netstandard2.1</TargetFramework>
<OutputType>Library</OutputType>
<AssemblyName>UsefulSensorsPersonSensor</AssemblyName>
<Company>Wilderness Labs, Inc</Company>
<PackageProjectUrl>http://developer.wildernesslabs.co/Meadow/Meadow.Foundation/</PackageProjectUrl>
<PackageId>Meadow.Foundation.Sensors.PersonSensor</PackageId>
<RepositoryUrl>https://github.com/WildernessLabs/Meadow.Foundation</RepositoryUrl>
<PackageTags>Meadow.Foundation,Meadow,camera,person,sensor,AI</PackageTags>
<Version>1.7.0</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Description>Useful Sensor's I2C optical person sensor</Description>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<None Include=".\Readme.md" Pack="true" PackagePath="" />
<None Include="..\..\icon.png" Pack="true" PackagePath="" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\Meadow.Foundation\Source\Meadow.Foundation.Core\Meadow.Foundation.Core.csproj" />
</ItemGroup>
</Project>
113 changes: 113 additions & 0 deletions Source/Sensors.UsefulSensors.TinyCodeReader/Driver/TinyCodeReader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
using Meadow.Hardware;
using System;
using System.Threading.Tasks;

namespace Meadow.Foundation.Sensors;

/// <summary>
/// Represents a Useful Sensor's Tiny Code Reader
/// </summary>
public class TinyCodeReader : II2cPeripheral
{
/// <summary>
/// Event raised when a QR code is read
/// </summary>
public event EventHandler<string> CodeRead = default!;

/// <summary>
/// Gets a value indicating whether the sensor is sampling/running
/// </summary>
public bool IsRunning { get; private set; }

/// <summary>
/// The sample period of the sensor (default 200ms)
/// </summary>
public TimeSpan SamplePeriod { get; set; } = TimeSpan.FromMilliseconds(200);

/// <inheritdoc/>
public byte DefaultI2cAddress => 0x0C;

private readonly int CONTENT_BYTE_COUNT = 254;
private readonly int CONTENT_BYTE_LENGTH_COUNT = 2;
private readonly int LED_REGISTER = 0x01;

private readonly byte[] readBuffer;
private readonly II2cCommunications i2cComms;

/// <summary>
/// Initializes a new instance of the ElectroMagneticRelayModule device
/// </summary>
/// <param name="i2cBus">The I2C bus the peripheral is connected to</param>
public TinyCodeReader(II2cBus i2cBus)
{
i2cComms = new I2cCommunications(i2cBus, DefaultI2cAddress, CONTENT_BYTE_COUNT + CONTENT_BYTE_LENGTH_COUNT);
readBuffer = new byte[CONTENT_BYTE_COUNT + CONTENT_BYTE_LENGTH_COUNT];
}

/// <summary>
/// Sets the LED on the Tiny Code Reader
/// </summary>
/// <param name="enable">enable if true, disable if false</param>
public void SetLed(bool enable)
{
i2cComms.WriteRegister((byte)LED_REGISTER, (byte)(enable ? 0x01 : 0x00));
}

/// <summary>
/// Reads the string value of the QR code from the Tiny Code Reader
/// </summary>
/// <returns>the code as a string if avaliable, null if no code found</returns>
public string? ReadCode()
{
i2cComms.ReadRegister(0x00, readBuffer);

if (readBuffer[0] == 0)
{
return null;
}
else
{
return System.Text.Encoding.UTF8.GetString(readBuffer, 2, readBuffer[0]);
}
}

/// <summary>
/// Start sampling the sensor
/// </summary>
public void StartUpdating(TimeSpan? samplePeriod = null)
{
if (IsRunning)
{
return;
}

IsRunning = true;

if (samplePeriod != null)
{
SamplePeriod = samplePeriod.Value;
}

Task.Run(async () =>
{
while (IsRunning)
{
var code = ReadCode();
if (code != null)
{
CodeRead?.Invoke(this, code);
}
await Task.Delay(SamplePeriod);
}
});
}

/// <summary>
/// Stop sampling the sensor
/// </summary>
public void StopUpdating()
{
IsRunning = false;
}
}
Loading

0 comments on commit a4efc7b

Please sign in to comment.