first commit

This commit is contained in:
pandacraft 2025-03-21 16:04:17 +01:00
commit a5a0434432
1126 changed files with 439481 additions and 0 deletions

17
Software/CSharp/.gitattributes vendored Normal file
View file

@ -0,0 +1,17 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

49
Software/CSharp/.gitignore vendored Normal file
View file

@ -0,0 +1,49 @@
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msm
*.msp
# Windows shortcuts
*.lnk
# =========================
# Operating System Files
# =========================
# OSX
# =========================
.DS_Store
.AppleDouble
.LSOverride
# Thumbnails
._*
# Files that might appear on external disk
.Spotlight-V100
.Trashes
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
*.suo
Debug
bin
obj
Release
*.user

Binary file not shown.

After

Width:  |  Height:  |  Size: 801 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProjectGuid>{6D24EAD0-AF01-4870-B042-FC782A973C46}</ProjectGuid>
<OutputType>winmdobj</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Driver</RootNamespace>
<AssemblyName>Driver</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion>10.0.10240.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
<EnableDotNetNativeCompatibleProfile>true</EnableDotNetNativeCompatibleProfile>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<AllowCrossPlatformRetargeting>false</AllowCrossPlatformRetargeting>
<AppxPackage>true</AppxPackage>
<ContainsStartupTask>true</ContainsStartupTask>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\ARM\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>ARM</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
<OutputPath>bin\ARM\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>ARM</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<ItemGroup>
<!-- A reference to the entire .Net Framework and Windows SDK are automatically included -->
<None Include="project.json" />
</ItemGroup>
<ItemGroup>
<Compile Include="SimpleDriver.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Content Include="Properties\client.winU.rd.xml" />
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
</ItemGroup>
<ItemGroup>
<Content Include="Assets\Logo.scale-100.png" />
<Content Include="Assets\SmallLogo.scale-100.png" />
<Content Include="Assets\SplashScreen.scale-100.png" />
<Content Include="Assets\StoreLogo.scale-100.png" />
<Content Include="Assets\WideLogo.scale-100.png" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GrovePi\GrovePi.csproj">
<Project>{A667742A-B887-4B46-8EC1-C671E8BEC5E4}</Project>
<Name>GrovePi</Name>
</ProjectReference>
</ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
<VisualStudioVersion>14.0</VisualStudioVersion>
</PropertyGroup>
<PropertyGroup>
<SignAssembly>false</SignAssembly>
</PropertyGroup>
<PropertyGroup>
<DelaySign>false</DelaySign>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View file

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:iot="http://schemas.microsoft.com/appx/manifest/iot/windows10"
IgnorableNamespaces="uap mp iot">
<Identity
Name="GrovePi"
Publisher="CN=JonathanRobson/PaulBinder"
Version="1.0.0.0" />
<mp:PhoneIdentity PhoneProductId="ff75bed8-52f0-4a6c-bde0-ae9c4afb4f44" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<Properties>
<DisplayName>Driver</DisplayName>
<PublisherDisplayName>Jonathan Robson and Paul Binder</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.10069.0" MaxVersionTested="10.0.10069.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App">
<uap:VisualElements
DisplayName="Driver"
Square150x150Logo="Assets\Logo.png"
Square44x44Logo="Assets\SmallLogo.png"
Description="GrovePi Driver"
BackgroundColor="#464646"
AppListEntry="none">
<uap:SplashScreen Image="Assets\SplashScreen.png" />
</uap:VisualElements>
<Extensions>
<Extension Category="windows.backgroundTasks" EntryPoint="Driver.SimpleDriver">
<BackgroundTasks>
<iot:Task Type="startup" />
</BackgroundTasks>
</Extension>
</Extensions>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
</Capabilities>
</Package>

View file

@ -0,0 +1,30 @@
using System.Reflection;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("HelloWorld")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("HelloWorld")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: ComVisible(false)]

View file

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file contains Runtime Directives, specifications about types your application accesses
through reflection and other dynamic code patterns. Runtime Directives are used to control the
.NET Native optimizer and ensure that it does not remove code accessed by your library. If your
library does not do any reflection, then you generally do not need to edit this file. However,
if your library reflects over types, especially types passed to it or derived from its types,
then you should write Runtime Directives.
The most common use of reflection in libraries is to discover information about types passed
to the library. Runtime Directives have three ways to express requirements on types passed to
your library.
1. Parameter, GenericParameter, TypeParameter, TypeEnumerableParameter
Use these directives to reflect over types passed as a parameter.
2. SubTypes
Use a SubTypes directive to reflect over types derived from another type.
3. AttributeImplies
Use an AttributeImplies directive to indicate that your library needs to reflect over
types or methods decorated with an attribute.
For more information on writing Runtime Directives for libraries, please visit
http://go.microsoft.com/fwlink/?LinkId=613100
-->
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Library Name="driver">
<!-- add directives for your library here -->
</Library>
</Directives>

View file

@ -0,0 +1,34 @@
using System;
using System.Threading.Tasks;
using Windows.ApplicationModel.Background;
using GrovePi;
using GrovePi.Sensors;
namespace Driver
{
public sealed class SimpleDriver : IBackgroundTask
{
private readonly IBuildGroveDevices _deviceFactory = DeviceFactory.Build;
public void Run(IBackgroundTaskInstance taskInstance)
{
var led = _deviceFactory.Led(Pin.DigitalPin5);
var rotaryAngleSensor = _deviceFactory.RotaryAngleSensor(Pin.AnalogPin2);
var maxValue = 255;
while (true)
{
try
{
var sensorValue = rotaryAngleSensor.SensorValue();
led.AnalogWrite((byte)(sensorValue > maxValue ? maxValue : sensorValue));
Task.Delay(500).Wait();
}
catch (Exception)
{
throw;
}
}
}
}
}

View file

@ -0,0 +1,12 @@
{
"dependencies": {
"Microsoft.NETCore.UniversalWindowsPlatform": "5.3.3"
},
"frameworks": {
"uap10.0": {}
},
"runtimes": {
"win10-arm": {},
"win10-arm-aot": {}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,20 @@
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<package >
<metadata>
<id>GrovePi</id>
<version>1.0.10.0</version>
<title>GrovePi for Windows IoT</title>
<authors>Exadon, Ryan Pedersen</authors>
<owners>Jonathan Robson</owners>
<licenseUrl>http://opensource.org/licenses/MS-PL</licenseUrl>
<projectUrl>https://github.com/robsonj/GrovePi</projectUrl>
<requireLicenseAcceptance>true</requireLicenseAcceptance>
<description>GrovePi IoT C# library</description>
<summary>Windows IoT C# library to support GrovePi RaspberryPi 2 sensors</summary>
<releaseNotes>Added new sensors.</releaseNotes>
<language />
<tags>iot, grovepi, windows, arm, internet of things, grove, sensors</tags>
<dependencies />
</metadata>
</package>

View file

@ -0,0 +1,42 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26430.6
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrovePi", "GrovePi\GrovePi.csproj", "{A667742A-B887-4B46-8EC1-C671E8BEC5E4}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Driver", "Driver\Driver.csproj", "{6D24EAD0-AF01-4870-B042-FC782A973C46}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|ARM = Release|ARM
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A667742A-B887-4B46-8EC1-C671E8BEC5E4}.Debug|ARM.ActiveCfg = Debug|ARM
{A667742A-B887-4B46-8EC1-C671E8BEC5E4}.Debug|ARM.Build.0 = Debug|ARM
{A667742A-B887-4B46-8EC1-C671E8BEC5E4}.Debug|x64.ActiveCfg = Debug|ARM
{A667742A-B887-4B46-8EC1-C671E8BEC5E4}.Debug|x86.ActiveCfg = Debug|ARM
{A667742A-B887-4B46-8EC1-C671E8BEC5E4}.Release|ARM.ActiveCfg = Release|ARM
{A667742A-B887-4B46-8EC1-C671E8BEC5E4}.Release|ARM.Build.0 = Release|ARM
{A667742A-B887-4B46-8EC1-C671E8BEC5E4}.Release|x64.ActiveCfg = Release|ARM
{A667742A-B887-4B46-8EC1-C671E8BEC5E4}.Release|x86.ActiveCfg = Release|ARM
{6D24EAD0-AF01-4870-B042-FC782A973C46}.Debug|ARM.ActiveCfg = Debug|ARM
{6D24EAD0-AF01-4870-B042-FC782A973C46}.Debug|ARM.Build.0 = Debug|ARM
{6D24EAD0-AF01-4870-B042-FC782A973C46}.Debug|ARM.Deploy.0 = Debug|ARM
{6D24EAD0-AF01-4870-B042-FC782A973C46}.Debug|x64.ActiveCfg = Debug|ARM
{6D24EAD0-AF01-4870-B042-FC782A973C46}.Debug|x86.ActiveCfg = Debug|ARM
{6D24EAD0-AF01-4870-B042-FC782A973C46}.Release|ARM.ActiveCfg = Release|ARM
{6D24EAD0-AF01-4870-B042-FC782A973C46}.Release|ARM.Build.0 = Release|ARM
{6D24EAD0-AF01-4870-B042-FC782A973C46}.Release|ARM.Deploy.0 = Release|ARM
{6D24EAD0-AF01-4870-B042-FC782A973C46}.Release|x64.ActiveCfg = Release|ARM
{6D24EAD0-AF01-4870-B042-FC782A973C46}.Release|x86.ActiveCfg = Release|ARM
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,18 @@
using System;
using System.Threading.Tasks;
namespace GrovePi.Common
{
public static class Delay
{
public static void Milliseconds(int milliseconds)
{
Task.Delay(milliseconds).Wait();
}
public static void Microseconds(int microseconds)
{
Task.Delay(new TimeSpan(microseconds*10)).Wait();
}
}
}

View file

@ -0,0 +1,11 @@
namespace GrovePi
{
internal static class Constants
{
public const byte Unused = 0;
public const byte GroveVcc = 5;
public const byte AdcVoltage = 5;
public const int GroveRgpLcdMaxLength = 16;
public const int GroveRgpLcdRows = 2;
}
}

View file

@ -0,0 +1,430 @@
using GrovePi.I2CDevices;
using GrovePi.Sensors;
using System;
using System.Threading.Tasks;
using Windows.Devices.Enumeration;
using Windows.Devices.I2c;
namespace GrovePi
{
public static class DeviceFactory
{
public static IBuildGroveDevices Build = new DeviceBuilder();
}
public interface IBuildGroveDevices
{
IGrovePi GrovePi();
IGrovePi GrovePi(int address);
IRelay Relay(Pin pin);
ILed Led(Pin pin);
ITemperatureSensor TemperatureSensor(Pin pin);
ITemperatureAndHumiditySensor TemperatureAndHumiditySensor(Pin pin, Model model);
IDHTTemperatureAndHumiditySensor DHTTemperatureAndHumiditySensor(Pin pin, DHTModel model);
IUltrasonicRangerSensor UltraSonicSensor(Pin pin);
IAccelerometerSensor AccelerometerSensor(Pin pin);
IAirQualitySensor AirQualitySensor(Pin pin);
IRealTimeClock RealTimeClock(Pin pin);
ILedBar BuildLedBar(Pin pin);
IFourDigitDisplay FourDigitDisplay(Pin pin);
IChainableRgbLed ChainableRgbLed(Pin pin);
IRotaryAngleSensor RotaryAngleSensor(Pin pin);
IBuzzer Buzzer(Pin pin);
ISoundSensor SoundSensor(Pin pin);
ILightSensor LightSensor(Pin pin);
IButtonSensor ButtonSensor(Pin pin);
IRgbLcdDisplay RgbLcdDisplay();
IRgbLcdDisplay RgbLcdDisplay(int rgbAddress, int textAddress);
ISixAxisAccelerometerAndCompass SixAxisAccelerometerAndCompass();
IPIRMotionSensor PIRMotionSensor(Pin pin);
IGasSensorMQ2 GasSensorMQ2(Pin pin);
IMiniMotorDriver MiniMotorDriver();
IMiniMotorDriver MiniMotorDriver(int ch1Address1, int ch2Address2);
IOLEDDisplay9696 OLEDDisplay9696();
IOLEDDisplay128X64 OLEDDisplay128X64();
IThreeAxisAccelerometerADXL345 ThreeAxisAccelerometerADXL345();
IWaterAtomizer WaterAtomizer(Pin pin);
ISHTTemperatureAndHumiditySensor SHTTemperatureAndHumiditySensor();
}
internal class DeviceBuilder : IBuildGroveDevices
{
private const string I2CName = "I2C1"; /* For Raspberry Pi 2, use I2C1 */
private const byte GrovePiAddress = 0x04;
private const byte DisplayRgbI2CAddress = 0xC4;
private const byte DisplayTextI2CAddress = 0x7C;
private const byte SixAxisAccelerometerI2CAddress = 0x1e;
private const byte MiniMotorDriverCH1I2cAddress = 0xC4;
private const byte MiniMotorDriverCH2I2cAddress = 0xC0;
private const byte OLED96_96I2cAddress = 0x3C;
private const byte OLED128_64I2cAddress = 0x3C;
private const byte ThreeAxisAccelemeterADXL345I2cAddress = 0x53;
private const byte SHT31TemperatureAndHumidityI2CAddress = 0x44;
private GrovePi _device;
private RgbLcdDisplay _rgbLcdDisplay;
private SixAxisAccelerometerAndCompass _sixAxisAccelerometerAndCompass;
private MiniMotorDriver _miniMotorDriver;
private OLEDDisplay9696 _oledDisplay9696;
private OLEDDisplay128X64 _oledDisplay128X64;
private ThreeAxisAccelerometerADXL345 _ThreeAxisAccelerometerADXL345;
private SHTTemperatureAndHumiditySensor _shtTemperatureAndHumiditySensor;
public IGrovePi GrovePi()
{
return BuildGrovePiImpl(GrovePiAddress);
}
public IGrovePi GrovePi(int address)
{
return BuildGrovePiImpl(address);
}
public IRelay Relay(Pin pin)
{
return DoBuild(x => new Relay(x, pin));
}
public ILed Led(Pin pin)
{
return DoBuild(x => new Led(x, pin));
}
public ITemperatureSensor TemperatureSensor(Pin pin)
{
return DoBuild(x => new TemperatureSensor(x, pin));
}
public ITemperatureAndHumiditySensor TemperatureAndHumiditySensor(Pin pin, Model model)
{
return DoBuild(x => new TemperatureAndHumiditySensor(x, pin, model));
}
public IDHTTemperatureAndHumiditySensor DHTTemperatureAndHumiditySensor(Pin pin, DHTModel model)
{
return DoBuild(x => new DHTTemperatureAndHumiditySensor(x, pin, model));
}
public IAirQualitySensor AirQualitySensor(Pin pin)
{
return DoBuild(x => new AirQualitySensor(x, pin));
}
public IUltrasonicRangerSensor UltraSonicSensor(Pin pin)
{
return DoBuild(x => new UltrasonicRangerSensor(x, pin));
}
public IAccelerometerSensor AccelerometerSensor(Pin pin)
{
return DoBuild(x => new AccelerometerSensor(x, pin));
}
public IRealTimeClock RealTimeClock(Pin pin)
{
return DoBuild(x => new RealTimeClock(x, pin));
}
public IRotaryAngleSensor RotaryAngleSensor(Pin pin)
{
return DoBuild(x => new RotaryAngleSensor(x, pin));
}
public IBuzzer Buzzer(Pin pin)
{
return DoBuild(x => new Buzzer(x, pin));
}
public ISoundSensor SoundSensor(Pin pin)
{
return DoBuild(x => new SoundSensor(x, pin));
}
public ILedBar BuildLedBar(Pin pin)
{
return DoBuild(x => new LedBar(x, pin));
}
public IFourDigitDisplay FourDigitDisplay(Pin pin)
{
return DoBuild(x => new FourDigitDisplay(x, pin));
}
public IChainableRgbLed ChainableRgbLed(Pin pin)
{
return DoBuild(x => new ChainableRgbLed(x, pin));
}
public ILightSensor LightSensor(Pin pin)
{
return DoBuild(x => new LightSensor(x, pin));
}
public IRgbLcdDisplay RgbLcdDisplay(int rgbAddress, int textAddress)
{
return BuildRgbLcdDisplayImpl(rgbAddress, textAddress);
}
public IRgbLcdDisplay RgbLcdDisplay()
{
return BuildRgbLcdDisplayImpl(DisplayRgbI2CAddress, DisplayTextI2CAddress);
}
public ISixAxisAccelerometerAndCompass SixAxisAccelerometerAndCompass()
{
return BuildSixAxisAccelerometerAndCompassImpl();
}
public IMiniMotorDriver MiniMotorDriver()
{
return BuildMiniMotorDriverImpl(MiniMotorDriverCH1I2cAddress, MiniMotorDriverCH2I2cAddress);
}
public IMiniMotorDriver MiniMotorDriver(int ch1Address, int ch2Address)
{
return BuildMiniMotorDriverImpl(ch1Address, ch2Address);
}
public IOLEDDisplay9696 OLEDDisplay9696()
{
return BuildOLEDDisplayImpl();
}
public IOLEDDisplay128X64 OLEDDisplay128X64()
{
return BuildOLEDDisplay128X64Impl();
}
public IThreeAxisAccelerometerADXL345 ThreeAxisAccelerometerADXL345()
{
return BuildThreeAxisAccelerometerADXL345Impl();
}
public IButtonSensor ButtonSensor(Pin pin)
{
return DoBuild(x => new ButtonSensor(x, pin));
}
private TSensor DoBuild<TSensor>(Func<GrovePi, TSensor> factory)
{
var device = BuildGrovePiImpl(GrovePiAddress);
return factory(device);
}
private GrovePi BuildGrovePiImpl(int address)
{
if (_device != null)
{
return _device;
}
/* Initialize the I2C bus */
var settings = new I2cConnectionSettings(address)
{
BusSpeed = I2cBusSpeed.StandardMode
};
_device = Task.Run(async () =>
{
var dis = await GetDeviceInfo();
// Create an I2cDevice with our selected bus controller and I2C settings
var device = await I2cDevice.FromIdAsync(dis[0].Id, settings);
return new GrovePi(device);
}).Result;
return _device;
}
private RgbLcdDisplay BuildRgbLcdDisplayImpl(int rgbAddress, int textAddress)
{
if (null != _rgbLcdDisplay)
{
return _rgbLcdDisplay;
}
/* Initialize the I2C bus */
var rgbConnectionSettings = new I2cConnectionSettings(rgbAddress>>1)
{
BusSpeed = I2cBusSpeed.StandardMode
};
var textConnectionSettings = new I2cConnectionSettings(textAddress>>1)
{
BusSpeed = I2cBusSpeed.StandardMode
};
_rgbLcdDisplay = Task.Run(async () =>
{
var dis = await GetDeviceInfo();
// Create an I2cDevice with our selected bus controller and I2C settings
var rgbDevice = await I2cDevice.FromIdAsync(dis[0].Id, rgbConnectionSettings);
var textDevice = await I2cDevice.FromIdAsync(dis[0].Id, textConnectionSettings);
return new RgbLcdDisplay(rgbDevice, textDevice);
}).Result;
return _rgbLcdDisplay;
}
private SixAxisAccelerometerAndCompass BuildSixAxisAccelerometerAndCompassImpl()
{
if (_sixAxisAccelerometerAndCompass != null)
{
return _sixAxisAccelerometerAndCompass;
}
var settings = new I2cConnectionSettings(SixAxisAccelerometerI2CAddress)
{
BusSpeed = I2cBusSpeed.StandardMode
};
_sixAxisAccelerometerAndCompass = Task.Run(async () =>
{
var dis = await GetDeviceInfo();
var device = await I2cDevice.FromIdAsync(dis[0].Id, settings);
return new SixAxisAccelerometerAndCompass(device);
}).Result;
return _sixAxisAccelerometerAndCompass;
}
private MiniMotorDriver BuildMiniMotorDriverImpl(int ch1Address, int ch2Address)
{
if (_miniMotorDriver != null)
{
return _miniMotorDriver;
}
var motor1ConnectionSettings = new I2cConnectionSettings(ch1Address>>1)
{
BusSpeed = I2cBusSpeed.StandardMode
};
var motor2ConnectionSettings = new I2cConnectionSettings(ch2Address>>1)
{
BusSpeed = I2cBusSpeed.StandardMode
};
_miniMotorDriver = Task.Run(async () =>
{
var dis = await GetDeviceInfo();
var miniMotor1 = await I2cDevice.FromIdAsync(dis[0].Id, motor1ConnectionSettings);
var miniMotor2 = await I2cDevice.FromIdAsync(dis[0].Id, motor2ConnectionSettings);
return new MiniMotorDriver(miniMotor1, miniMotor2);
}).Result;
return _miniMotorDriver;
}
private OLEDDisplay9696 BuildOLEDDisplayImpl()
{
if(_oledDisplay9696 != null)
{
return _oledDisplay9696;
}
var connectionSettings = new I2cConnectionSettings(OLED96_96I2cAddress)
{
BusSpeed = I2cBusSpeed.StandardMode
};
_oledDisplay9696 = Task.Run(async () =>
{
var dis = await GetDeviceInfo();
var device = await I2cDevice.FromIdAsync(dis[0].Id, connectionSettings);
return new OLEDDisplay9696(device);
}).Result;
return _oledDisplay9696;
}
private OLEDDisplay128X64 BuildOLEDDisplay128X64Impl()
{
if (_oledDisplay128X64 != null)
{
return _oledDisplay128X64;
}
var connectionSettings = new I2cConnectionSettings(OLED128_64I2cAddress)
{
BusSpeed = I2cBusSpeed.StandardMode
};
_oledDisplay128X64 = Task.Run(async () =>
{
var dis = await GetDeviceInfo();
var device = await I2cDevice.FromIdAsync(dis[0].Id, connectionSettings);
return new OLEDDisplay128X64(device);
}).Result;
return _oledDisplay128X64;
}
private ThreeAxisAccelerometerADXL345 BuildThreeAxisAccelerometerADXL345Impl()
{
if (_ThreeAxisAccelerometerADXL345 != null)
{
return _ThreeAxisAccelerometerADXL345;
}
var connectionSettings = new I2cConnectionSettings(ThreeAxisAccelemeterADXL345I2cAddress)
{
BusSpeed = I2cBusSpeed.StandardMode
};
_ThreeAxisAccelerometerADXL345 = Task.Run(async () =>
{
var dis = await GetDeviceInfo();
var device = await I2cDevice.FromIdAsync(dis[0].Id, connectionSettings);
return new ThreeAxisAccelerometerADXL345(device);
}).Result;
return _ThreeAxisAccelerometerADXL345;
}
private SHTTemperatureAndHumiditySensor BuildSHTTemperatureAndHumiditySensorImpl()
{
if (_shtTemperatureAndHumiditySensor != null)
{
return _shtTemperatureAndHumiditySensor;
}
var _shtTemperatureAndHumiditySensorSettings = new I2cConnectionSettings(SHT31TemperatureAndHumidityI2CAddress)
{
BusSpeed = I2cBusSpeed.StandardMode,
SlaveAddress = SHT31TemperatureAndHumidityI2CAddress
};
_shtTemperatureAndHumiditySensor = Task.Run(async () => {
var dis = await GetDeviceInfo();
var shtSensor = await I2cDevice.FromIdAsync(dis[0].Id, _shtTemperatureAndHumiditySensorSettings);
return new SHTTemperatureAndHumiditySensor(shtSensor, SHTModel.Sht31, MeasurementMode.MediumRepeat);
}).Result;
return _shtTemperatureAndHumiditySensor;
}
private static async Task<DeviceInformationCollection> GetDeviceInfo()
{
//Find the selector string for the I2C bus controller
var aqs = I2cDevice.GetDeviceSelector(I2CName);
//Find the I2C bus controller device with our selector string
var dis = await DeviceInformation.FindAllAsync(aqs);
return dis;
}
public IPIRMotionSensor PIRMotionSensor(Pin pin)
{
return DoBuild(x => new PIRMotionSensor(x, pin));
}
public IGasSensorMQ2 GasSensorMQ2(Pin pin)
{
return DoBuild(x => new GasSensorMQ2(x, pin));
}
public IWaterAtomizer WaterAtomizer(Pin pin)
{
return DoBuild(x => new WaterAtomizer(x, pin));
}
public ISHTTemperatureAndHumiditySensor SHTTemperatureAndHumiditySensor()
{
return BuildSHTTemperatureAndHumiditySensorImpl();
}
}
}

View file

@ -0,0 +1,122 @@
using System;
using Windows.Devices.I2c;
using GrovePi.Common;
namespace GrovePi
{
public interface IGrovePi
{
string GetFirmwareVersion();
byte DigitalRead(Pin pin);
void DigitalWrite(Pin pin, byte value);
int AnalogRead(Pin pin);
void AnalogWrite(Pin pin, byte value);
void PinMode(Pin pin, PinMode mode);
void Flush();
}
internal sealed class GrovePi : IGrovePi
{
internal GrovePi(I2cDevice device)
{
if (device == null) throw new ArgumentNullException(nameof(device));
DirectAccess = device;
}
internal I2cDevice DirectAccess { get; }
public string GetFirmwareVersion()
{
var wbuffer = new byte[4] {(byte) Command.Version, Constants.Unused, Constants.Unused, Constants.Unused};
var rbuffer = new byte[4];
var i2cTransferResult = DirectAccess.WritePartial(wbuffer);
if (i2cTransferResult.Status != I2cTransferStatus.FullTransfer)
{
return "0.0.0";
}
i2cTransferResult = DirectAccess.ReadPartial(rbuffer);
if (i2cTransferResult.Status != I2cTransferStatus.FullTransfer)
{
return "0.0.0";
}
return $"{rbuffer[1]}.{rbuffer[2]}.{rbuffer[3]}";
}
public byte DigitalRead(Pin pin)
{
var wbuffer = new byte[4] {(byte) Command.DigitalRead, (byte) pin, Constants.Unused, Constants.Unused};
var rBuffer = new byte[1];
var i2cTransferResult = DirectAccess.WritePartial(wbuffer);
Delay.Milliseconds(10);
if (i2cTransferResult.Status != I2cTransferStatus.FullTransfer)
{
return 0;
}
i2cTransferResult = DirectAccess.ReadPartial(rBuffer);
if (i2cTransferResult.Status != I2cTransferStatus.FullTransfer)
{
return 0;
}
return rBuffer[0];
}
public void DigitalWrite(Pin pin, byte value)
{
var buffer = new byte[4] {(byte) Command.DigitalWrite, (byte) pin, value, Constants.Unused};
DirectAccess.WritePartial(buffer);
Delay.Milliseconds(10);
}
public int AnalogRead(Pin pin)
{
var wbuffer = new byte[4]{(byte) Command.AnalogRead, (byte) pin, Constants.Unused, Constants.Unused};
var rbuffer = new byte[3];
var i2cTransferResult = DirectAccess.WritePartial(wbuffer);
Delay.Milliseconds(10);
if (i2cTransferResult.Status != I2cTransferStatus.FullTransfer)
{
return 0;
}
i2cTransferResult = DirectAccess.ReadPartial(rbuffer);
if (i2cTransferResult.Status != I2cTransferStatus.FullTransfer)
{
return 0;
}
return rbuffer[1]*256 + rbuffer[2];
}
public void AnalogWrite(Pin pin, byte value)
{
var buffer = new byte[4] {(byte) Command.AnalogWrite, (byte) pin, value, Constants.Unused};
DirectAccess.WritePartial(buffer);
Delay.Milliseconds(10);
}
public void PinMode(Pin pin, PinMode mode)
{
var buffer = new byte[4] {(byte) Command.PinMode, (byte) pin, (byte) mode, Constants.Unused};
DirectAccess.WritePartial(buffer);
Delay.Milliseconds(10);
}
public void Flush()
{
var buffer = new byte[4] { Constants.Unused, Constants.Unused, Constants.Unused, Constants.Unused };
DirectAccess.WritePartial(buffer);
}
private enum Command
{
DigitalRead = 1,
DigitalWrite = 2,
AnalogRead = 3,
AnalogWrite = 4,
PinMode = 5,
Version = 8,
//DhtProSensorTemp = 40,
};
}
}

View file

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{A667742A-B887-4B46-8EC1-C671E8BEC5E4}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>GrovePi</RootNamespace>
<AssemblyName>GrovePi</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion>10.0.10240.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
<PlatformTarget>ARM</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\ARM\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>ARM</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<GenerateLibraryLayout>true</GenerateLibraryLayout>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
<PlatformTarget>ARM</PlatformTarget>
<OutputPath>bin\ARM\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>ARM</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<GenerateLibraryLayout>true</GenerateLibraryLayout>
</PropertyGroup>
<ItemGroup>
<!-- A reference to the entire .Net Framework and Windows SDK are automatically included -->
<None Include="GrovePi.nuspec" />
<None Include="project.json" />
</ItemGroup>
<ItemGroup>
<Compile Include="Common\Delay.cs" />
<Compile Include="Constants.cs" />
<Compile Include="DeviceFactory.cs" />
<Compile Include="GrovePi.cs" />
<Compile Include="I2CDevices\MiniMotorDriver.cs" />
<Compile Include="I2CDevices\OLEDDisplay128X64.cs" />
<Compile Include="I2CDevices\OLEDDisplay9696.cs" />
<Compile Include="I2CDevices\RgbLcdDisplay.cs" />
<Compile Include="I2CDevices\SixAxisAccelerometerAndCompass.cs" />
<Compile Include="I2CDevices\ThreeAxisAccelerometerADXL345.cs" />
<Compile Include="Sensors\AirQualitySensor.cs" />
<Compile Include="Sensors\ButtonSensor.cs" />
<Compile Include="Sensors\Buzzer.cs" />
<Compile Include="I2CDevices\SHTTemperatureAndHumiditySensor.cs" />
<Compile Include="Sensors\GasSensorMQ2.cs" />
<Compile Include="Sensors\Led.cs" />
<Compile Include="Pin.cs" />
<Compile Include="PinMode.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Sensors\AccelerometerSensor.cs" />
<Compile Include="Sensors\ChainableRgbLed.cs" />
<Compile Include="Sensors\FourDigitDisplay.cs" />
<Compile Include="Sensors\LedBar.cs" />
<Compile Include="Sensors\LightSensor.cs" />
<Compile Include="Sensors\PIRMotionSensor.cs" />
<Compile Include="Sensors\RealTimeClock.cs" />
<Compile Include="Sensors\Relay.cs" />
<Compile Include="Sensors\RotaryAngleSensor.cs" />
<Compile Include="Sensors\Sensor.cs" />
<Compile Include="Sensors\SensorStatus.cs" />
<Compile Include="Sensors\SoundSensor.cs" />
<Compile Include="Sensors\DHTTemperatureAndHumiditySensor .cs" />
<Compile Include="Sensors\TemperatureAndHumiditySensor.cs" />
<Compile Include="Sensors\TemperatureSensor.cs" />
<Compile Include="Sensors\UltrasonicRangerSensor.cs" />
<Compile Include="Sensors\WaterAtomizer.cs" />
<Content Include="Properties\client.winU.rd.xml" />
</ItemGroup>
<ItemGroup>
<SDKReference Include="WindowsIoT, Version=10.0.10240.0">
<Name>Windows IoT Extensions for the UWP</Name>
</SDKReference>
</ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
<VisualStudioVersion>14.0</VisualStudioVersion>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
-->
<Target Name="AfterBuild" Condition="'$(Configuration)' == 'Release'">
<Exec Command="nuget pack $(MSBuildProjectFile) -OutputDirectory $(OutDir) -Symbols -Prop Configuration=$(Configuration) -Prop TargetPath=$(OutDir)$(AssemblyName)$(TargetExt)" />
</Target>
</Project>

View file

@ -0,0 +1,20 @@
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<package >
<metadata>
<id>GrovePi</id>
<version>1.0.10.0</version>
<title>GrovePi for Windows IoT</title>
<authors>Exadon, Ryan Pedersen</authors>
<owners>Jonathan Robson</owners>
<licenseUrl>http://opensource.org/licenses/MS-PL</licenseUrl>
<projectUrl>https://github.com/robsonj/GrovePi</projectUrl>
<requireLicenseAcceptance>true</requireLicenseAcceptance>
<description>GrovePi IoT C# library</description>
<summary>Windows IoT C# library to support GrovePi RaspberryPi 2 sensors</summary>
<releaseNotes>Added new sensors.</releaseNotes>
<language />
<tags>iot, grovepi, windows, arm, internet of things, grove, sensors</tags>
<dependencies />
</metadata>
</package>

View file

@ -0,0 +1,61 @@
using System;
using Windows.Devices.I2c;
namespace GrovePi.I2CDevices
{
public interface IMiniMotorDriver
{
IMiniMotorDriver drive1(int Speed);
IMiniMotorDriver drive2(int Speed);
//IMiniMotorDriver getFault();
}
internal sealed class MiniMotorDriver : IMiniMotorDriver
{
internal MiniMotorDriver(I2cDevice Motor1Device, I2cDevice Motor2Device)
{
if (Motor1Device == null) throw new ArgumentNullException(nameof(Motor1Device));
motor1DirectAccess = Motor1Device;
if (Motor2Device == null) throw new ArgumentNullException(nameof(Motor2Device));
motor2DirectAccess = Motor2Device;
}
~MiniMotorDriver()
{
this.drive1(0);
this.drive2(0);
}
internal I2cDevice motor1DirectAccess { get; }
internal I2cDevice motor2DirectAccess { get; }
public IMiniMotorDriver drive1(int Speed)
{
byte regValue = 0x80;
motor1DirectAccess.Write(new byte[] { 0x1, regValue });
regValue = (byte)Math.Abs(Speed);
if (regValue > 63) regValue = 63;
regValue = (byte)(regValue * 4);
if (Speed < 0) regValue |= 0x01;
else regValue |= 0x02;
motor1DirectAccess.Write(new byte[] { 0x00, regValue});
return this;
}
public IMiniMotorDriver drive2(int Speed)
{
byte regValue = 0x80;
motor2DirectAccess.Write(new byte[] { 0x1, regValue });
regValue = (byte)Math.Abs(Speed);
if (regValue > 63) regValue = 63;
regValue = (byte)(regValue * 4);
if (Speed < 0) regValue |= 0x01;
else regValue |= 0x02;
motor2DirectAccess.Write(new byte[] { 0x00, regValue });
return this;
}
}
}

View file

@ -0,0 +1,440 @@
/*
* Ten Wong (wangtengoo7@gmail.com) 2017 Seeed technology inc.
* Refer to: https://github.com/Seeed-Studio/OLED_Display_128X64
* MIT License
*/
using System;
using Windows.Devices.I2c;
namespace GrovePi.I2CDevices
{
public interface IOLEDDisplay128X64
{
void init();
void setNormalDisplay();
void setInverseDisplay();
void sendCommand(byte command);
void sendData(byte data);
void setPageMode();
void setHorizontalMode();
void setTextXY(byte row, byte column);
void clearDisplay();
void setBrightness(byte brightness);
void putChar(char c);
void putString(string str);
int putNumber(long n);
int putFloat(float floatNumber, byte deci);
int putFloat(float floatNumber);
void drawBitmap(byte[] bitmaparray, int bytes);
void setHorizontalScrollProperties(byte direction, byte startPage, byte endPage, byte scrollSpeed);
void activateScroll();
void deactivateScroll();
}
internal sealed class OLEDDisplay128X64: IOLEDDisplay128X64
{
private const byte SeeedOLED_Max_X = 127; //128 Pixels
private const byte SeeedOLED_Max_Y = 63; //64 Pixels
private const byte PAGE_MODE = 01;
private const byte HORIZONTAL_MODE = 02;
private const byte SeeedOLED_Address = 0x3c;
private const byte SeeedOLED_Command_Mode = 0x80;
private const byte SeeedOLED_Data_Mode = 0x40;
private const byte SeeedOLED_Display_Off_Cmd = 0xAE;
private const byte SeeedOLED_Display_On_Cmd = 0xAF;
private const byte SeeedOLED_Normal_Display_Cmd = 0xA6;
private const byte SeeedOLED_Inverse_Display_Cmd = 0xA7;
private const byte SeeedOLED_Activate_Scroll_Cmd = 0x2F;
private const byte SeeedOLED_Dectivate_Scroll_Cmd = 0x2E;
private const byte SeeedOLED_Set_Brightness_Cmd = 0x81;
private const byte Scroll_Left = 0x00;
private const byte Scroll_Right = 0x01;
private const byte Scroll_2Frames = 0x7;
private const byte Scroll_3Frames = 0x4;
private const byte Scroll_4Frames = 0x5;
private const byte Scroll_5Frames = 0x0;
private const byte Scroll_25Frames = 0x6;
private const byte Scroll_64Frames = 0x1;
private const byte Scroll_128Frames = 0x2;
private const byte Scroll_256Frames = 0x3;
// This font be freely used without any restriction(It is placed in public domain)
private byte[,] BasicFont = new byte[,]
{
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x5F,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00},
{0x00,0x14,0x7F,0x14,0x7F,0x14,0x00,0x00},
{0x00,0x24,0x2A,0x7F,0x2A,0x12,0x00,0x00},
{0x00,0x23,0x13,0x08,0x64,0x62,0x00,0x00},
{0x00,0x36,0x49,0x55,0x22,0x50,0x00,0x00},
{0x00,0x00,0x05,0x03,0x00,0x00,0x00,0x00},
{0x00,0x1C,0x22,0x41,0x00,0x00,0x00,0x00},
{0x00,0x41,0x22,0x1C,0x00,0x00,0x00,0x00},
{0x00,0x08,0x2A,0x1C,0x2A,0x08,0x00,0x00},
{0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x00},
{0x00,0xA0,0x60,0x00,0x00,0x00,0x00,0x00},
{0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00},
{0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00},
{0x00,0x20,0x10,0x08,0x04,0x02,0x00,0x00},
{0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x00},
{0x00,0x00,0x42,0x7F,0x40,0x00,0x00,0x00},
{0x00,0x62,0x51,0x49,0x49,0x46,0x00,0x00},
{0x00,0x22,0x41,0x49,0x49,0x36,0x00,0x00},
{0x00,0x18,0x14,0x12,0x7F,0x10,0x00,0x00},
{0x00,0x27,0x45,0x45,0x45,0x39,0x00,0x00},
{0x00,0x3C,0x4A,0x49,0x49,0x30,0x00,0x00},
{0x00,0x01,0x71,0x09,0x05,0x03,0x00,0x00},
{0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00},
{0x00,0x06,0x49,0x49,0x29,0x1E,0x00,0x00},
{0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00},
{0x00,0x00,0xAC,0x6C,0x00,0x00,0x00,0x00},
{0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x00},
{0x00,0x14,0x14,0x14,0x14,0x14,0x00,0x00},
{0x00,0x41,0x22,0x14,0x08,0x00,0x00,0x00},
{0x00,0x02,0x01,0x51,0x09,0x06,0x00,0x00},
{0x00,0x32,0x49,0x79,0x41,0x3E,0x00,0x00},
{0x00,0x7E,0x09,0x09,0x09,0x7E,0x00,0x00},
{0x00,0x7F,0x49,0x49,0x49,0x36,0x00,0x00},
{0x00,0x3E,0x41,0x41,0x41,0x22,0x00,0x00},
{0x00,0x7F,0x41,0x41,0x22,0x1C,0x00,0x00},
{0x00,0x7F,0x49,0x49,0x49,0x41,0x00,0x00},
{0x00,0x7F,0x09,0x09,0x09,0x01,0x00,0x00},
{0x00,0x3E,0x41,0x41,0x51,0x72,0x00,0x00},
{0x00,0x7F,0x08,0x08,0x08,0x7F,0x00,0x00},
{0x00,0x41,0x7F,0x41,0x00,0x00,0x00,0x00},
{0x00,0x20,0x40,0x41,0x3F,0x01,0x00,0x00},
{0x00,0x7F,0x08,0x14,0x22,0x41,0x00,0x00},
{0x00,0x7F,0x40,0x40,0x40,0x40,0x00,0x00},
{0x00,0x7F,0x02,0x0C,0x02,0x7F,0x00,0x00},
{0x00,0x7F,0x04,0x08,0x10,0x7F,0x00,0x00},
{0x00,0x3E,0x41,0x41,0x41,0x3E,0x00,0x00},
{0x00,0x7F,0x09,0x09,0x09,0x06,0x00,0x00},
{0x00,0x3E,0x41,0x51,0x21,0x5E,0x00,0x00},
{0x00,0x7F,0x09,0x19,0x29,0x46,0x00,0x00},
{0x00,0x26,0x49,0x49,0x49,0x32,0x00,0x00},
{0x00,0x01,0x01,0x7F,0x01,0x01,0x00,0x00},
{0x00,0x3F,0x40,0x40,0x40,0x3F,0x00,0x00},
{0x00,0x1F,0x20,0x40,0x20,0x1F,0x00,0x00},
{0x00,0x3F,0x40,0x38,0x40,0x3F,0x00,0x00},
{0x00,0x63,0x14,0x08,0x14,0x63,0x00,0x00},
{0x00,0x03,0x04,0x78,0x04,0x03,0x00,0x00},
{0x00,0x61,0x51,0x49,0x45,0x43,0x00,0x00},
{0x00,0x7F,0x41,0x41,0x00,0x00,0x00,0x00},
{0x00,0x02,0x04,0x08,0x10,0x20,0x00,0x00},
{0x00,0x41,0x41,0x7F,0x00,0x00,0x00,0x00},
{0x00,0x04,0x02,0x01,0x02,0x04,0x00,0x00},
{0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00},
{0x00,0x01,0x02,0x04,0x00,0x00,0x00,0x00},
{0x00,0x20,0x54,0x54,0x54,0x78,0x00,0x00},
{0x00,0x7F,0x48,0x44,0x44,0x38,0x00,0x00},
{0x00,0x38,0x44,0x44,0x28,0x00,0x00,0x00},
{0x00,0x38,0x44,0x44,0x48,0x7F,0x00,0x00},
{0x00,0x38,0x54,0x54,0x54,0x18,0x00,0x00},
{0x00,0x08,0x7E,0x09,0x02,0x00,0x00,0x00},
{0x00,0x18,0xA4,0xA4,0xA4,0x7C,0x00,0x00},
{0x00,0x7F,0x08,0x04,0x04,0x78,0x00,0x00},
{0x00,0x00,0x7D,0x00,0x00,0x00,0x00,0x00},
{0x00,0x80,0x84,0x7D,0x00,0x00,0x00,0x00},
{0x00,0x7F,0x10,0x28,0x44,0x00,0x00,0x00},
{0x00,0x41,0x7F,0x40,0x00,0x00,0x00,0x00},
{0x00,0x7C,0x04,0x18,0x04,0x78,0x00,0x00},
{0x00,0x7C,0x08,0x04,0x7C,0x00,0x00,0x00},
{0x00,0x38,0x44,0x44,0x38,0x00,0x00,0x00},
{0x00,0xFC,0x24,0x24,0x18,0x00,0x00,0x00},
{0x00,0x18,0x24,0x24,0xFC,0x00,0x00,0x00},
{0x00,0x00,0x7C,0x08,0x04,0x00,0x00,0x00},
{0x00,0x48,0x54,0x54,0x24,0x00,0x00,0x00},
{0x00,0x04,0x7F,0x44,0x00,0x00,0x00,0x00},
{0x00,0x3C,0x40,0x40,0x7C,0x00,0x00,0x00},
{0x00,0x1C,0x20,0x40,0x20,0x1C,0x00,0x00},
{0x00,0x3C,0x40,0x30,0x40,0x3C,0x00,0x00},
{0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00},
{0x00,0x1C,0xA0,0xA0,0x7C,0x00,0x00,0x00},
{0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00},
{0x00,0x08,0x36,0x41,0x00,0x00,0x00,0x00},
{0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00},
{0x00,0x41,0x36,0x08,0x00,0x00,0x00,0x00},
{0x00,0x02,0x01,0x01,0x02,0x01,0x00,0x00},
{0x00,0x02,0x05,0x05,0x02,0x00,0x00,0x00}
};
internal I2cDevice DirectAccess { get; }
internal byte addressingMode;
internal OLEDDisplay128X64(I2cDevice Device)
{
if (Device == null) throw new ArgumentNullException(nameof(Device));
DirectAccess = Device;
}
public void init()
{
sendCommand(SeeedOLED_Display_Off_Cmd); //display off
//delay(5);
sendCommand(SeeedOLED_Display_On_Cmd); //display on
//delay(5);
sendCommand(SeeedOLED_Normal_Display_Cmd); //Set Normal Display (default)
}
public void setNormalDisplay()
{
sendCommand(SeeedOLED_Normal_Display_Cmd);
}
public void setInverseDisplay()
{
sendCommand(SeeedOLED_Inverse_Display_Cmd);
}
public void sendCommand(byte command)
{
DirectAccess.Write(new byte[] { SeeedOLED_Command_Mode, command });
}
public void sendData(byte data)
{
DirectAccess.Write(new byte[] { SeeedOLED_Data_Mode, data });
}
public void setPageMode()
{
addressingMode = PAGE_MODE;
sendCommand(0x20); //set addressing mode
sendCommand(0x02); //set page addressing mode
}
public void setHorizontalMode()
{
addressingMode = HORIZONTAL_MODE;
sendCommand(0x20); //set addressing mode
sendCommand(0x00); //set horizontal addressing mode
}
public void setTextXY(byte row, byte column)
{
sendCommand((byte)(0xB0 + row)); //set page address
sendCommand((byte)(0x00 + (8 * column & 0x0F))); //set column lower address
sendCommand((byte)(0x10 + ((8 * column >> 4) & 0x0F))); //set column higher address
}
public void clearDisplay()
{
byte i, j;
sendCommand(SeeedOLED_Display_Off_Cmd); //display off
for (j = 0; j < 8; j++)
{
setTextXY(j, 0);
{
for (i = 0; i < 16; i++) //clear all columns
{
putChar(' ');
}
}
}
sendCommand(SeeedOLED_Display_On_Cmd); //display on
setTextXY(0, 0);
}
public void setBrightness(byte brightness)
{
sendCommand(SeeedOLED_Set_Brightness_Cmd);
sendCommand(brightness);
}
public void putChar(char c)
{
if (c < 32 || c > 127) //Ignore non-printable ASCII characters. This can be modified for multilingual font.
{
c = ' '; //Space
}
byte i = 0;
for (i = 0; i < 8; i++)
{
//read bytes from code memory
sendData(BasicFont[c-32, i]); //font array starts at 0, ASCII starts at 32. Hence the translation
}
}
public void putString(string str)
{
foreach (var c in str)
{
putChar(c);
}
}
public int putNumber(long long_num)
{
char[] char_buffer = new char[10];
int i = 0;
int f = 0;
if (long_num < 0)
{
f = 1;
putChar('-');
long_num = -long_num;
}
else if (long_num == 0)
{
f = 1;
putChar('0');
return f;
}
while (long_num > 0)
{
char_buffer[i++] = (char)(long_num % 10);
long_num /= 10;
}
f = f + i;
for (; i > 0; i--)
{
putChar((char)('0' + (int)(char_buffer[i - 1])));
}
return f;
}
public int putFloat(float floatNumber, byte deci)
{
int temp = 0;
float decy = 0.0F;
float rounding = 0.5F;
int f = 0;
if (floatNumber < 0.0F)
{
putString("-");
floatNumber = -floatNumber;
f += 1;
}
for (int i = 0; i < deci; ++i)
{
rounding /= 10.0F;
}
floatNumber += rounding;
temp = (int)floatNumber;
f += putNumber(temp);
if (deci > 0)
{
putChar('.');
f += 1;
}
decy = floatNumber - temp;//decimal part,
for (int i = 0; i < deci; i++)//4
{
decy *= 10;// for the next decimal
temp = (int)decy;//get the decimal
putNumber(temp);
decy -= temp;
}
f += deci;
return f;
}
public int putFloat(float floatNumber)
{
int deci= 2;
int temp = 0;
float decy = 0.0F;
float rounding = 0.5F;
int f = 0;
if (floatNumber < 0.0)
{
putString("-");
floatNumber = -floatNumber;
f += 1;
}
for (int i = 0; i < deci; ++i)
{
rounding /= 10.0F;
}
floatNumber += rounding;
temp = (int)floatNumber;
f += putNumber(temp);
if (deci > 0)
{
putChar('.');
f += 1;
}
decy = floatNumber - temp;//decimal part,
for (int i = 0; i < deci; i++)//4
{
decy *= 10;// for the next decimal
temp = (int)decy;//get the decimal
putNumber(temp);
decy -= temp;
}
f += deci;
return f;
}
public void drawBitmap(byte[] bitmaparray, int bytes)
{
byte localAddressMode = addressingMode;
if (addressingMode != HORIZONTAL_MODE)
{
//Bitmap is drawn in horizontal mode
setHorizontalMode();
}
for (int i = 0; i < bytes; i++)
{
sendData(bitmaparray[i]);
}
if (localAddressMode == PAGE_MODE)
{
//If pageMode was used earlier, restore it.
setPageMode();
}
}
public void setHorizontalScrollProperties(byte direction, byte startPage, byte endPage, byte scrollSpeed)
{
if (Scroll_Right == direction)
{
//Scroll Right
sendCommand(0x26);
}
else
{
//Scroll Left
sendCommand(0x27);
}
sendCommand(0x00);
sendCommand(startPage);
sendCommand(scrollSpeed);
sendCommand(endPage);
sendCommand(0x00);
sendCommand(0xFF);
}
public void activateScroll()
{
sendCommand(SeeedOLED_Activate_Scroll_Cmd);
}
public void deactivateScroll()
{
sendCommand(SeeedOLED_Dectivate_Scroll_Cmd);
}
}
}

View file

@ -0,0 +1,450 @@
using System;
using Windows.Devices.I2c;
using GrovePi.Common;
using System.Diagnostics;
namespace GrovePi.I2CDevices
{
public interface IOLEDDisplay9696
{
IOLEDDisplay9696 initialize();
IOLEDDisplay9696 setNormalDisplay();
IOLEDDisplay9696 sendCommand(byte cmd);
IOLEDDisplay9696 sendData(byte Data);
IOLEDDisplay9696 setGrayLevel(byte grayLevel);
IOLEDDisplay9696 setVerticalMode();
IOLEDDisplay9696 setHorizontalMode();
IOLEDDisplay9696 setTextXY(byte Row, byte Column);
IOLEDDisplay9696 clearDisplay();
IOLEDDisplay9696 setContrastLevel(byte ContrastLevel);
IOLEDDisplay9696 putChar(char C);
IOLEDDisplay9696 putString(string text);
//IOLEDDisplay9696 putNumber();
//IOLEDDisplay9696 putFloat();
//IOLEDDisplay9696 putFloat();
IOLEDDisplay9696 drawBitmap(byte[] bitmaparray, int bytes);
IOLEDDisplay9696 setHorizontalScrollProperties(bool direction, byte startRow, byte endRow, byte startColumn, byte endColumn, byte scrollSpeed);
IOLEDDisplay9696 activateScroll();
IOLEDDisplay9696 deactivateScroll();
}
internal sealed class OLEDDisplay9696 : IOLEDDisplay9696
{
private const byte VERTICAL_MODE = 1;
private const byte HORIZONTAL_MODE = 2;
private const byte SeeedGrayOLED_Address = 0x3c;
private const byte SeeedGrayOLED_Command_Mode = 0x80;
private const byte SeeedGrayOLED_Data_Mode = 0x40;
private const byte SeeedGrayOLED_Display_Off_Cmd = 0xAE;
private const byte SeeedGrayOLED_Display_On_Cmd = 0xAF;
private const byte SeeedGrayOLED_Normal_Display_Cmd = 0xA4;
private const byte SeeedGrayOLED_Inverse_Display_Cmd = 0xA7;
private const byte SeeedGrayOLED_Activate_Scroll_Cmd = 0x2F;
private const byte SeeedGrayOLED_Dectivate_Scroll_Cmd = 0x2E;
private const byte SeeedGrayOLED_Set_ContrastLevel_Cmd = 0x81;
private const byte Scroll_Left = 0x00;
private const byte Scroll_Right = 0x01;
private const byte Scroll_2Frames = 0x7;
private const byte Scroll_3Frames = 0x4;
private const byte Scroll_4Frames = 0x5;
private const byte Scroll_5Frames = 0x0;
private const byte Scroll_25Frames = 0x6;
private const byte Scroll_64Frames = 0x1;
private const byte Scroll_128Frames = 0x2;
private const byte Scroll_256Frames = 0x3;
private byte grayH = 0;
private byte grayL = 0;
private byte addressingMode = 0;
private byte[,] BasicFont = new byte[,]
{
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x5F,0x00,0x00,0x00,0x00,0x00},
{0x00,0x00,0x07,0x00,0x07,0x00,0x00,0x00},
{0x00,0x14,0x7F,0x14,0x7F,0x14,0x00,0x00},
{0x00,0x24,0x2A,0x7F,0x2A,0x12,0x00,0x00},
{0x00,0x23,0x13,0x08,0x64,0x62,0x00,0x00},
{0x00,0x36,0x49,0x55,0x22,0x50,0x00,0x00},
{0x00,0x00,0x05,0x03,0x00,0x00,0x00,0x00},
{0x00,0x1C,0x22,0x41,0x00,0x00,0x00,0x00},
{0x00,0x41,0x22,0x1C,0x00,0x00,0x00,0x00},
{0x00,0x08,0x2A,0x1C,0x2A,0x08,0x00,0x00},
{0x00,0x08,0x08,0x3E,0x08,0x08,0x00,0x00},
{0x00,0xA0,0x60,0x00,0x00,0x00,0x00,0x00},
{0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00},
{0x00,0x60,0x60,0x00,0x00,0x00,0x00,0x00},
{0x00,0x20,0x10,0x08,0x04,0x02,0x00,0x00},
{0x00,0x3E,0x51,0x49,0x45,0x3E,0x00,0x00},
{0x00,0x00,0x42,0x7F,0x40,0x00,0x00,0x00},
{0x00,0x62,0x51,0x49,0x49,0x46,0x00,0x00},
{0x00,0x22,0x41,0x49,0x49,0x36,0x00,0x00},
{0x00,0x18,0x14,0x12,0x7F,0x10,0x00,0x00},
{0x00,0x27,0x45,0x45,0x45,0x39,0x00,0x00},
{0x00,0x3C,0x4A,0x49,0x49,0x30,0x00,0x00},
{0x00,0x01,0x71,0x09,0x05,0x03,0x00,0x00},
{0x00,0x36,0x49,0x49,0x49,0x36,0x00,0x00},
{0x00,0x06,0x49,0x49,0x29,0x1E,0x00,0x00},
{0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00},
{0x00,0x00,0xAC,0x6C,0x00,0x00,0x00,0x00},
{0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x00},
{0x00,0x14,0x14,0x14,0x14,0x14,0x00,0x00},
{0x00,0x41,0x22,0x14,0x08,0x00,0x00,0x00},
{0x00,0x02,0x01,0x51,0x09,0x06,0x00,0x00},
{0x00,0x32,0x49,0x79,0x41,0x3E,0x00,0x00},
{0x00,0x7E,0x09,0x09,0x09,0x7E,0x00,0x00},
{0x00,0x7F,0x49,0x49,0x49,0x36,0x00,0x00},
{0x00,0x3E,0x41,0x41,0x41,0x22,0x00,0x00},
{0x00,0x7F,0x41,0x41,0x22,0x1C,0x00,0x00},
{0x00,0x7F,0x49,0x49,0x49,0x41,0x00,0x00},
{0x00,0x7F,0x09,0x09,0x09,0x01,0x00,0x00},
{0x00,0x3E,0x41,0x41,0x51,0x72,0x00,0x00},
{0x00,0x7F,0x08,0x08,0x08,0x7F,0x00,0x00},
{0x00,0x41,0x7F,0x41,0x00,0x00,0x00,0x00},
{0x00,0x20,0x40,0x41,0x3F,0x01,0x00,0x00},
{0x00,0x7F,0x08,0x14,0x22,0x41,0x00,0x00},
{0x00,0x7F,0x40,0x40,0x40,0x40,0x00,0x00},
{0x00,0x7F,0x02,0x0C,0x02,0x7F,0x00,0x00},
{0x00,0x7F,0x04,0x08,0x10,0x7F,0x00,0x00},
{0x00,0x3E,0x41,0x41,0x41,0x3E,0x00,0x00},
{0x00,0x7F,0x09,0x09,0x09,0x06,0x00,0x00},
{0x00,0x3E,0x41,0x51,0x21,0x5E,0x00,0x00},
{0x00,0x7F,0x09,0x19,0x29,0x46,0x00,0x00},
{0x00,0x26,0x49,0x49,0x49,0x32,0x00,0x00},
{0x00,0x01,0x01,0x7F,0x01,0x01,0x00,0x00},
{0x00,0x3F,0x40,0x40,0x40,0x3F,0x00,0x00},
{0x00,0x1F,0x20,0x40,0x20,0x1F,0x00,0x00},
{0x00,0x3F,0x40,0x38,0x40,0x3F,0x00,0x00},
{0x00,0x63,0x14,0x08,0x14,0x63,0x00,0x00},
{0x00,0x03,0x04,0x78,0x04,0x03,0x00,0x00},
{0x00,0x61,0x51,0x49,0x45,0x43,0x00,0x00},
{0x00,0x7F,0x41,0x41,0x00,0x00,0x00,0x00},
{0x00,0x02,0x04,0x08,0x10,0x20,0x00,0x00},
{0x00,0x41,0x41,0x7F,0x00,0x00,0x00,0x00},
{0x00,0x04,0x02,0x01,0x02,0x04,0x00,0x00},
{0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00},
{0x00,0x01,0x02,0x04,0x00,0x00,0x00,0x00},
{0x00,0x20,0x54,0x54,0x54,0x78,0x00,0x00},
{0x00,0x7F,0x48,0x44,0x44,0x38,0x00,0x00},
{0x00,0x38,0x44,0x44,0x28,0x00,0x00,0x00},
{0x00,0x38,0x44,0x44,0x48,0x7F,0x00,0x00},
{0x00,0x38,0x54,0x54,0x54,0x18,0x00,0x00},
{0x00,0x08,0x7E,0x09,0x02,0x00,0x00,0x00},
{0x00,0x18,0xA4,0xA4,0xA4,0x7C,0x00,0x00},
{0x00,0x7F,0x08,0x04,0x04,0x78,0x00,0x00},
{0x00,0x00,0x7D,0x00,0x00,0x00,0x00,0x00},
{0x00,0x80,0x84,0x7D,0x00,0x00,0x00,0x00},
{0x00,0x7F,0x10,0x28,0x44,0x00,0x00,0x00},
{0x00,0x41,0x7F,0x40,0x00,0x00,0x00,0x00},
{0x00,0x7C,0x04,0x18,0x04,0x78,0x00,0x00},
{0x00,0x7C,0x08,0x04,0x7C,0x00,0x00,0x00},
{0x00,0x38,0x44,0x44,0x38,0x00,0x00,0x00},
{0x00,0xFC,0x24,0x24,0x18,0x00,0x00,0x00},
{0x00,0x18,0x24,0x24,0xFC,0x00,0x00,0x00},
{0x00,0x00,0x7C,0x08,0x04,0x00,0x00,0x00},
{0x00,0x48,0x54,0x54,0x24,0x00,0x00,0x00},
{0x00,0x04,0x7F,0x44,0x00,0x00,0x00,0x00},
{0x00,0x3C,0x40,0x40,0x7C,0x00,0x00,0x00},
{0x00,0x1C,0x20,0x40,0x20,0x1C,0x00,0x00},
{0x00,0x3C,0x40,0x30,0x40,0x3C,0x00,0x00},
{0x00,0x44,0x28,0x10,0x28,0x44,0x00,0x00},
{0x00,0x1C,0xA0,0xA0,0x7C,0x00,0x00,0x00},
{0x00,0x44,0x64,0x54,0x4C,0x44,0x00,0x00},
{0x00,0x08,0x36,0x41,0x00,0x00,0x00,0x00},
{0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00},
{0x00,0x41,0x36,0x08,0x00,0x00,0x00,0x00},
{0x00,0x02,0x01,0x01,0x02,0x01,0x00,0x00},
{0x00,0x02,0x05,0x05,0x02,0x00,0x00,0x00}
};
internal OLEDDisplay9696(I2cDevice Device)
{
if (Device == null) throw new ArgumentNullException(nameof(Device));
DirectAccess = Device;
}
public IOLEDDisplay9696 initialize()
{
this.sendCommand(0xFD); // unlock IC MCU from entering command.
this.sendCommand(0x12);
this.sendCommand(0xAE); // Set display off
this.sendCommand(0xA8); // set multiplex ratio
this.sendCommand(0x5F); // 96
this.sendCommand(0xA1); // set display start line
this.sendCommand(0x00);
this.sendCommand(0xA2); // set display offset
this.sendCommand(0x60);
this.sendCommand(0xA0); // set remap
this.sendCommand(0x46);
this.sendCommand(0xAB); // set vdd internal
this.sendCommand(0x01); //
this.sendCommand(0x81); // set contrasr
this.sendCommand(0x53); // 100 nit
this.sendCommand(0xB1); // Set Phase Length
this.sendCommand(0X51); //
this.sendCommand(0xB3); // Set Display Clock Divide Ratio/Oscillator Frequency
this.sendCommand(0x01);
this.sendCommand(0xB9); //
this.sendCommand(0xBC); // set pre_charge voltage/VCOMH
this.sendCommand(0x08); // (0x08);
this.sendCommand(0xBE); // set VCOMH
this.sendCommand(0X07); // (0x07);
this.sendCommand(0xB6); // Set second pre-charge period
this.sendCommand(0x01); //
this.sendCommand(0xD5); // enable second precharge and enternal vsl
this.sendCommand(0X62); // (0x62);
this.sendCommand(0xA4); // Set Normal Display Mode
this.sendCommand(0x2E); // Deactivate Scroll
this.sendCommand(0xAF); // Switch on display
Delay.Milliseconds(100);
// Row Address
this.sendCommand(0x75); // Set Row Address
this.sendCommand(0x00); // Start 0
this.sendCommand(0x5f); // End 95
// Column Address
this.sendCommand(0x15); // Set Column Address
this.sendCommand(0x08); // Start from 8th Column of driver IC. This is 0th Column for OLED
this.sendCommand(0x37); // End at (8 + 47)th column. Each Column has 2 pixels(segments)
// Init gray level for text. Default:Brightest White
grayH = 0xF0;
grayL = 0x0F;
return this;
}
internal I2cDevice DirectAccess { get; }
public IOLEDDisplay9696 sendCommand(byte cmd)
{
DirectAccess.Write(new byte[] { SeeedGrayOLED_Command_Mode, cmd });
return this;
}
public IOLEDDisplay9696 setContrastLevel(byte ContrastLevel)
{
this.sendCommand(SeeedGrayOLED_Set_ContrastLevel_Cmd);
this.sendCommand(ContrastLevel);
return this;
}
public IOLEDDisplay9696 setHorizontalMode()
{
this.sendCommand(0xA0); // remap to
this.sendCommand(0x42); // horizontal mode
// Row Address
this.sendCommand(0x75); // Set Row Address
this.sendCommand(0x00); // Start 0
this.sendCommand(0x5f); // End 95
// Column Address
this.sendCommand(0x15); // Set Column Address
this.sendCommand(0x08); // Start from 8th Column of driver IC. This is 0th Column for OLED
this.sendCommand(0x37); // End at (8 + 47)th column. Each Column has 2 pixels(or segments)
return this;
}
public IOLEDDisplay9696 setVerticalMode()
{
this.sendCommand(0xA0); // remap to
this.sendCommand(0x46); // Vertical mode
return this;
}
public IOLEDDisplay9696 setTextXY(byte Row, byte Column)
{
//Column Address
this.sendCommand(0x15); /* Set Column Address */
this.sendCommand((byte)(0x08 + (Column * 4))); /* Start Column: Start from 8 */
this.sendCommand(0x37); /* End Column */
// Row Address
this.sendCommand(0x75); /* Set Row Address */
this.sendCommand((byte)(0x00 + (Row * 8))); /* Start Row*/
this.sendCommand((byte)(0x07 + (Row * 8))); /* End Row*/
return this;
}
public IOLEDDisplay9696 clearDisplay()
{
byte i, j;
for (j = 0; j < 48; j++)
{
for (i = 0; i < 96; i++) //clear all columns
{
this.sendData(0x00);
}
}
return this;
}
public IOLEDDisplay9696 sendData(byte Data)
{
DirectAccess.Write(new byte[] { SeeedGrayOLED_Data_Mode, Data });
return this;
}
public IOLEDDisplay9696 setGrayLevel(byte grayLevel)
{
grayH = (byte)((grayLevel << 4) & 0xF0);
grayL = (byte)(grayLevel & 0x0F);
return this;
}
public IOLEDDisplay9696 putChar(char C)
{
if (C < 32 || C > 127) //Ignore non-printable ASCII characters. This can be modified for multilingual font.
{
C = ' '; //Space
}
for (int i = 0; i < 8; i = i + 2)
{
for (int j = 0; j < 8; j++)
{
// Character is constructed two pixel at a time using vertical mode from the default 8x8 font
byte c = 0x00;
byte bit1 = (byte)((BasicFont[C - 32, i] >> j) & 0x01);
byte bit2 = (byte)((BasicFont[C - 32, i + 1] >> j) & 0x01);
// Each bit is changed to a nibble
c |= (byte)((bit1.Equals(0x01)) ? grayH : 0x00);
c |= (byte)((bit2.Equals(0x01)) ? grayL : 0x00);
this.sendData(c);
}
}
return this;
}
public IOLEDDisplay9696 putString(string text)
{
foreach (var C in text)
{
this.putChar(C);
}
return this;
}
public IOLEDDisplay9696 drawBitmap(byte[] bitmaparray, int bytes)
{
byte localAddressMode = this.addressingMode;
if (addressingMode != HORIZONTAL_MODE)
{
//Bitmap is drawn in horizontal mode
this.setHorizontalMode();
}
//for (int i = 0; i < bytes; i++)
foreach (var Byte in bitmaparray)
{
for (int j = 0; j < 8; j = j + 2)
{
byte c = 0x00;
byte bit1 = (byte)(Byte << j & 0x80);
byte bit2 = (byte)(Byte << (j + 1) & 0x80);
// Each bit is changed to a nibble
c |= (byte)((bit1.Equals(0x80)) ? grayH : 0x00);
// Each bit is changed to a nibble
c |= (byte)((bit2.Equals(0x80)) ? grayL : 0x00);
this.sendData(c);
}
}
if (localAddressMode == VERTICAL_MODE)
{
//If Vertical Mode was used earlier, restore it.
this.setVerticalMode();
}
return this;
}
public IOLEDDisplay9696 setHorizontalScrollProperties(bool direction, byte startRow, byte endRow, byte startColumn, byte endColumn, byte scrollSpeed)
{
/*
Use the following defines for 'direction' :
Scroll_Left
Scroll_Right
Use the following defines for 'scrollSpeed' :
Scroll_2Frames
Scroll_3Frames
Scroll_4Frames
Scroll_5Frames
Scroll_25Frames
Scroll_64Frames
Scroll_128Frames
Scroll_256Frames
*/
if (Scroll_Right.Equals(direction))
{
//Scroll Right
this.sendCommand(0x27);
}
else
{
//Scroll Left
this.sendCommand(0x26);
}
this.sendCommand(0x00); //Dummmy byte
this.sendCommand(startRow);
this.sendCommand(scrollSpeed);
this.sendCommand(endRow);
this.sendCommand((byte)(startColumn + 8));
this.sendCommand((byte)(endColumn + 8));
this.sendCommand(0x00); //Dummmy byte
return this;
}
public IOLEDDisplay9696 activateScroll()
{
this.sendCommand(SeeedGrayOLED_Activate_Scroll_Cmd);
return this;
}
public IOLEDDisplay9696 deactivateScroll()
{
this.sendCommand(SeeedGrayOLED_Dectivate_Scroll_Cmd);
return this;
}
public IOLEDDisplay9696 setNormalDisplay()
{
this.sendCommand(SeeedGrayOLED_Normal_Display_Cmd);
return this;
}
public IOLEDDisplay9696 setInverseDisplay()
{
this.sendCommand(SeeedGrayOLED_Inverse_Display_Cmd);
return this;
}
}
}

View file

@ -0,0 +1,78 @@
using System;
using Windows.Devices.I2c;
using GrovePi.Common;
namespace GrovePi.I2CDevices
{
public interface IRgbLcdDisplay
{
IRgbLcdDisplay SetBacklightRgb(byte red, byte green, byte blue);
IRgbLcdDisplay SetText(string text);
}
internal sealed class RgbLcdDisplay : IRgbLcdDisplay
{
private const byte RedCommandAddress = 4;
private const byte GreenCommandAddress = 3;
private const byte BlueCommandAddress = 2;
private const byte TextCommandAddress = 0x80;
private const byte ClearDisplayCommandAddress = 0x01;
private const byte DisplayOnCommandAddress = 0x08;
private const byte NoCursorCommandAddress = 0x04;
private const byte TwoLinesCommandAddress = 0x28;
private const byte SetCharacterCommandAddress = 0x40;
internal RgbLcdDisplay(I2cDevice rgbDevice, I2cDevice textDevice)
{
if (rgbDevice == null) throw new ArgumentNullException(nameof(rgbDevice));
if (textDevice == null) throw new ArgumentNullException(nameof(textDevice));
RgbDirectAccess = rgbDevice;
TextDirectAccess = textDevice;
}
internal I2cDevice RgbDirectAccess { get; }
internal I2cDevice TextDirectAccess { get; }
public IRgbLcdDisplay SetBacklightRgb(byte red, byte green, byte blue)
{
//TODO: Find out what these addresses are for , set const.
RgbDirectAccess.Write(new byte[] {0, 0});
RgbDirectAccess.Write(new byte[] {1, 0});
RgbDirectAccess.Write(new byte[] { DisplayOnCommandAddress, 0xaa});
RgbDirectAccess.Write(new[] {RedCommandAddress, red});
RgbDirectAccess.Write(new[] {GreenCommandAddress, green});
RgbDirectAccess.Write(new[] {BlueCommandAddress, blue});
return this;
}
public IRgbLcdDisplay SetText(string text)
{
TextDirectAccess.Write(new[] {TextCommandAddress, ClearDisplayCommandAddress});
Delay.Milliseconds(50);
TextDirectAccess.Write(new[] {TextCommandAddress, (byte)(DisplayOnCommandAddress | NoCursorCommandAddress)});
TextDirectAccess.Write(new[] {TextCommandAddress, TwoLinesCommandAddress});
var count = 0;
var row = 0;
foreach (var c in text)
{
if (c.Equals('\n') || count == Constants.GroveRgpLcdMaxLength)
{
count = 0;
row += 1;
if (row == Constants.GroveRgpLcdRows)
break;
TextDirectAccess.Write(new byte[] {TextCommandAddress, 0xc0}); //TODO: find out what this address is
if (c.Equals('\n'))
continue;
}
count += 1;
TextDirectAccess.Write(new[] {SetCharacterCommandAddress, (byte) c});
}
return this;
}
}
}

View file

@ -0,0 +1,155 @@
using Windows.Devices.I2c;
namespace GrovePi.I2CDevices
{
/// <summary>
///
/// </summary>
public interface ISHTTemperatureAndHumiditySensor
{
double TemperatureInCelsius { get; }
double TemperatureInFahrenheit { get; }
double RelativeHumidity { get; }
void Measure();
}
/// <summary>
/// Specifies the model of sensor.
/// </summary>
public enum SHTModel
{
Sht31 = 0
}
/// <summary>
/// The repeatability setting influences the measurement duration and the current
/// consumption of the sensor.
/// </summary>
public enum MeasurementMode
{
HighRepeatClockStretch = 0,
MediumRepeatClockStretch,
LowRepeatClockStretch,
HighRepeat,
MediumRepeat,
LowRepeat
}
internal class SHTTemperatureAndHumiditySensor : ISHTTemperatureAndHumiditySensor
{
private readonly SHTModel _model;
internal I2cDevice _device;
private byte[] MeasureHighClockStretch = new byte[2] { 0x2C, 0x06 };
private byte[] MeasureMediumClockStretch = new byte[2] { 0x2C, 0x0D };
private byte[] MeasureLowClockStretch = new byte[2] { 0x2C, 0x10 };
private byte[] MeasureHigh = new byte[2] { 0x24, 0x00 };
private byte[] MeasureMedium = new byte[2] { 0x24, 0x0B };
private byte[] MeasureLow = new byte[2] { 0x24, 0x16 };
private byte[] ReadStatusRegisterCommandAddress = new byte[2] { 0xF3, 0x2D };
private byte[] ClearStatusRegisterCommandAddress = new byte[2] { 0x30, 0x41 };
private byte[] SoftResetCommandAddress = new byte[2] { 0x30, 0xA2 };
private byte[] EnableHeaterCommandAddress = new byte[2] { 0x30, 0x6D };
private byte[] DisableHeaderCommandAddress = new byte[2] { 0x30, 0x66 };
private byte[] BreakCommandAddress = new byte[2] { 0x30, 0x93 };
private byte[] _sensorData = new byte[6];
private byte[] _sensorCommand = new byte[4];
public double TemperatureInCelsius { get; set; }
public double TemperatureInFahrenheit { get; set; }
public double RelativeHumidity { get; set; }
internal SHTTemperatureAndHumiditySensor(I2cDevice sensorDevice, SHTModel model, MeasurementMode measureMode)
{
_device = sensorDevice;
_model = model;
switch (measureMode)
{
case MeasurementMode.HighRepeatClockStretch:
_sensorCommand = MeasureHighClockStretch;
break;
case MeasurementMode.MediumRepeatClockStretch:
_sensorCommand = MeasureMediumClockStretch;
break;
case MeasurementMode.LowRepeatClockStretch:
_sensorCommand = MeasureLowClockStretch;
break;
case MeasurementMode.HighRepeat:
_sensorCommand = MeasureHigh;
break;
case MeasurementMode.MediumRepeat:
_sensorCommand = MeasureMedium;
break;
case MeasurementMode.LowRepeat:
_sensorCommand = MeasureLow;
break;
default:
_sensorCommand = MeasureHigh;
break;
}
}
public void Measure()
{
_device.WriteRead(_sensorCommand, _sensorData);
TemperatureInCelsius = (((_sensorData[0] * 256) + _sensorData[1]) * 175.0) / 65535.0 - 45.0;
TemperatureInFahrenheit = (((_sensorData[0] * 256) + _sensorData[1]) * 315.0) / 65535.0 - 49.0;
RelativeHumidity = (((_sensorData[3] * 256) + _sensorData[4])) * 100.0 / 65535.0 - 6.0;
}
/// <summary>
/// This triggers the sensor to reset its system controller and reloads calibration data from the memory.
/// </summary>
public void Reset()
{
_device.Write(SoftResetCommandAddress);
}
/// <summary>
/// All flags (Bit 15, 11, 10, 4) in the status register can be cleared (set to zero)
/// </summary>
public void ClearStatusRegister()
{
_device.Write(ClearStatusRegisterCommandAddress);
}
/// <summary>
/// The status register contains information on the operational status of the heater, the alert mode and on
/// the execution status of the last command and the last write sequence.
/// </summary>
/// <returns>16bit status register response</returns>
public byte[] ReadStatusRegister()
{
var statusResponse = new byte[2];
_device.WriteReadPartial(ReadStatusRegisterCommandAddress, statusResponse);
return statusResponse;
}
/// <summary>
/// The heater can be switched on and off by command
/// </summary>
public void EnableHeater()
{
_device.Write(EnableHeaterCommandAddress);
}
public void DisableHeater()
{
_device.Write(DisableHeaderCommandAddress);
}
/// <summary>
/// It is rrecommended to stop the periodic data acquisition prior to sending another command using the break command.
/// Upon reception of the break command the sensor enters the single shot mode.
/// </summary>
internal void Break()
{
_device.Write(BreakCommandAddress);
}
}
}

View file

@ -0,0 +1,405 @@
using System;
using System.Linq;
using GrovePi.I2CDevices.Configuration;
using Windows.Devices.I2c;
using static System.Math;
namespace GrovePi.I2CDevices
{
public interface ISixAxisAccelerometerAndCompass
{
byte DeviceId();
double[] GetAcceleration();
double[] GetMagnetic();
double GetHeading();
double GetTiltHeading();
ISixAxisAccelerometerAndCompass Configure(Action<ISixAxisAccelerometerAndCompassConfiguration> configuration);
}
public interface ISixAxisAccelerometerAndCompassConfiguration
{
void AccelerationAxes(AccelerationAxes value);
void AccelerationDataRate(AccelerationDataRate value);
void AccelerationDataUpdateMode(AccelerationDataUpdateMode value);
void AccelerationScale(AccelerationScale value);
void MagneticDataRate(MagneticDataRate value);
void MagneticMode(MagneticMode value);
void MagneticResolution(MagneticResolution value);
void MagneticScale(MagneticScale value);
}
internal sealed class SixAxisAccelerometerAndCompass : ISixAxisAccelerometerAndCompass
{
private const int X = 0;
private const int Y = 1;
private const int Z = 2;
private const double Pow_2_15 = 32768;
private const byte WHO_AM_I = 0x0f;
private const byte CTRL_REG0 = 0x1F;
private const byte CTRL_REG1 = 0x20;
private const byte CTRL_REG2 = 0x21;
private const byte CTRL_REG3 = 0x22;
private const byte CTRL_REG4 = 0x23;
private const byte CTRL_REG5 = 0x24;
private const byte CTRL_REG6 = 0x25;
private const byte CTRL_REG7 = 0x26;
private const byte OUT_X_L_M = 0x08;
private const byte OUT_X_H_M = 0x09;
private const byte OUT_Y_L_M = 0x0A;
private const byte OUT_Y_H_M = 0x0B;
private const byte OUT_Z_L_M = 0x0C;
private const byte OUT_Z_H_M = 0x0D;
private const byte OUT_X_L_A = 0x28;
private const byte OUT_X_H_A = 0x29;
private const byte OUT_Y_L_A = 0x2A;
private const byte OUT_Y_H_A = 0x2B;
private const byte OUT_Z_L_A = 0x2C;
private const byte OUT_Z_H_A = 0x2D;
internal I2cDevice DirectAccess
{
get;
}
internal AccelerationAxes AccelerationAxes
{
get;
set;
} = AccelerationAxes.XYZ;
internal AccelerationDataRate AccelerationDataRate
{
get;
set;
} = AccelerationDataRate.Hz_50;
internal AccelerationDataUpdateMode AccelerationDataUpdateMode
{
get;
set;
} = AccelerationDataUpdateMode.Continuous;
internal AccelerationScale AccelerationScale
{
get
{
return accelerationScale;
}
set
{
accelerationScale = value;
switch (accelerationScale)
{
case AccelerationScale.G_2:
accelerationScaleFactor = 2.0;
break;
case AccelerationScale.G_4:
accelerationScaleFactor = 4.0;
break;
case AccelerationScale.G_6:
accelerationScaleFactor = 6.0;
break;
case AccelerationScale.G_8:
accelerationScaleFactor = 8.0;
break;
case AccelerationScale.G_16:
accelerationScaleFactor = 16.0;
break;
}
}
}
private AccelerationScale accelerationScale = AccelerationScale.G_2;
private double accelerationScaleFactor = 2.0;
internal MagneticDataRate MagneticDataRate
{
get;
set;
} = MagneticDataRate.Hz_50;
internal MagneticMode MagneticMode
{
get;
set;
} = MagneticMode.ContinousConversion;
internal MagneticResolution MagneticResolution
{
get;
set;
} = MagneticResolution.Low;
internal MagneticScale MagneticScale
{
get;
set;
} = MagneticScale.Gs_4;
internal SixAxisAccelerometerAndCompass(I2cDevice device)
{
if (device == null)
throw new ArgumentNullException(nameof(device));
DirectAccess = device;
Reconfigure();
}
public byte DeviceId() => ReadRegister(WHO_AM_I);
public double[] GetAcceleration()
{
// Windows is little-endian so read registers from low to high
var input = new[]
{
ReadRegister(OUT_X_L_A), ReadRegister(OUT_X_H_A),
ReadRegister(OUT_Y_L_A), ReadRegister(OUT_Y_H_A),
ReadRegister(OUT_Z_L_A), ReadRegister(OUT_Z_H_A)
};
// calculate two's complement value and scale by acceleration factor
var output = new[]
{
BitConverter.ToInt16(input, 0) / Pow_2_15 * accelerationScaleFactor,
BitConverter.ToInt16(input, 2) / Pow_2_15 * accelerationScaleFactor,
BitConverter.ToInt16(input, 4) / Pow_2_15 * accelerationScaleFactor
};
return output;
}
public double[] GetMagnetic()
{
// Windows is little-endian so read registers from low to high
var input = new[]
{
ReadRegister(OUT_X_L_M), ReadRegister(OUT_X_H_M),
ReadRegister(OUT_Y_L_M), ReadRegister(OUT_Y_H_M),
ReadRegister(OUT_Z_L_M), ReadRegister(OUT_Z_H_M)
};
// calculate two's complement value
var output = new[]
{
BitConverter.ToInt16(input, 0) / Pow_2_15,
BitConverter.ToInt16(input, 2) / Pow_2_15,
BitConverter.ToInt16(input, 4) / Pow_2_15
};
return output;
}
public double GetHeading()
{
var magnetic = GetMagnetic();
var heading = 180 * Atan2(magnetic[Y], magnetic[X]) / PI;
return (heading < 0) ? (heading + 360) : heading;
}
public double GetTiltHeading()
{
var acceleration = GetAcceleration();
var pitch = Asin(-acceleration[X]);
var roll = Asin(acceleration[Y] / Cos(pitch));
var magnetic = GetMagnetic();
var xh = magnetic[X] * Cos(pitch) + magnetic[Z] * Sin(pitch);
var yh = magnetic[X] * Sin(roll) * Sin(pitch) + magnetic[Y] * Cos(roll) - magnetic[Z] * Sin(roll) * Cos(pitch);
var heading = 180 * Atan2(yh, xh) / PI;
return (heading < 0) ? (heading + 360) : heading;
}
public ISixAxisAccelerometerAndCompass Configure(Action<ISixAxisAccelerometerAndCompassConfiguration> configuration)
{
if (configuration != null)
{
configuration(new SixAxisAccelerometerAndCompassConfiguration(this));
Reconfigure();
}
return this;
}
private byte ReadRegister(byte register)
{
var buffer = new byte[1];
DirectAccess.WriteRead(new[] { register }, buffer);
return buffer[0];
}
private void Reconfigure()
{
DirectAccess.Write(new[] { CTRL_REG0, (byte)0 }); // normal mode, FIFO disabled, high-pass filter disabled
DirectAccess.Write(new[] { CTRL_REG1, (byte)((byte)AccelerationDataRate | (byte)AccelerationDataUpdateMode | (byte)AccelerationAxes) });
DirectAccess.Write(new[] { CTRL_REG2, (byte)AccelerationScale });
DirectAccess.Write(new[] { CTRL_REG3, (byte)0 }); // interrupt 1 disabled
DirectAccess.Write(new[] { CTRL_REG4, (byte)0 }); // interrupt 2 disabled
DirectAccess.Write(new[] { CTRL_REG5, (byte)((byte)MagneticResolution | (byte)MagneticDataRate) });
DirectAccess.Write(new[] { CTRL_REG6, (byte)MagneticScale });
DirectAccess.Write(new[] { CTRL_REG7, (byte)MagneticMode });
}
}
internal sealed class SixAxisAccelerometerAndCompassConfiguration : ISixAxisAccelerometerAndCompassConfiguration
{
private readonly SixAxisAccelerometerAndCompass _sensor;
public SixAxisAccelerometerAndCompassConfiguration(SixAxisAccelerometerAndCompass sensor)
{
_sensor = sensor;
}
public void AccelerationAxes(AccelerationAxes value)
{
_sensor.AccelerationAxes = value;
}
public void AccelerationDataRate(AccelerationDataRate value)
{
_sensor.AccelerationDataRate = value;
}
public void AccelerationDataUpdateMode(AccelerationDataUpdateMode value)
{
_sensor.AccelerationDataUpdateMode = value;
}
public void AccelerationScale(AccelerationScale value)
{
_sensor.AccelerationScale = value;
}
public void MagneticDataRate(MagneticDataRate value)
{
if ((value == Configuration.MagneticDataRate.Hz_100) && (_sensor.AccelerationDataRate > Configuration.AccelerationDataRate.None) && (_sensor.AccelerationDataRate <= Configuration.AccelerationDataRate.Hz_50))
{
_sensor.AccelerationDataRate = Configuration.AccelerationDataRate.Hz_100;
}
_sensor.MagneticDataRate = value;
}
public void MagneticMode(MagneticMode value)
{
_sensor.MagneticMode = value;
}
public void MagneticResolution(MagneticResolution value)
{
_sensor.MagneticResolution = value;
}
public void MagneticScale(MagneticScale value)
{
_sensor.MagneticScale = value;
}
}
namespace Configuration
{
[Flags]
public enum AccelerationAxes : byte
{
None = 0,
X = 4,
Y = 2,
Z = 1,
XYZ = X | Y | Z
}
public enum AccelerationDataRate : byte
{
None = 0,
Hz_3_125 = 16,
Hz_6_25 = 32,
Hz_12_5 = 48,
Hz_25 = 64,
Hz_50 = 80,
Hz_100 = 96,
Hz_200 = 112,
Hz_400 = 128,
Hz_800 = 144,
Hz_1600 = 160
}
public enum AccelerationDataUpdateMode : byte
{
Continuous = 0,
OnRead = 8
}
public enum AccelerationScale : byte
{
G_2 = 0,
G_4 = 8,
G_6 = 16,
G_8 = 24,
G_16 = 32
}
public enum MagneticMode : byte
{
ContinousConversion = 0,
SingleConversion = 1,
PowerDown = 3
}
public enum MagneticDataRate : byte
{
Hz_3_125 = 0,
Hz_6_25 = 4,
Hz_12_5 = 8,
Hz_25 = 12,
Hz_50 = 16,
Hz_100 = 20
}
public enum MagneticResolution : byte
{
Low = 0,
High = 96
}
public enum MagneticScale : byte
{
Gs_2 = 0,
Gs_4 = 32,
Gs_8 = 64,
Gs_12 = 96
}
}
}

View file

@ -0,0 +1,91 @@
using System;
using GrovePi.I2CDevices.Configuration;
using Windows.Devices.I2c;
namespace GrovePi.I2CDevices
{
public interface IThreeAxisAccelerometerADXL345
{
IThreeAxisAccelerometerADXL345 Initialize();
double[] GetAcclXYZ();
}
internal sealed class ThreeAxisAccelerometerADXL345 : IThreeAxisAccelerometerADXL345
{
struct Acceleration
{
public double X;
public double Y;
public double Z;
};
private const byte ACCEL_I2C_ADDR = 0x53; /* 7-bit I2C address of the ADXL345 with SDO pulled low */
private const byte ACCEL_REG_POWER_CONTROL = 0x2D; /* Address of the Power Control register */
private const byte ACCEL_REG_DATA_FORMAT = 0x31; /* Address of the Data Format register */
private const byte ACCEL_REG_X = 0x32; /* Address of the X Axis data register */
private const byte ACCEL_REG_Y = 0x34; /* Address of the Y Axis data register */
private const byte ACCEL_REG_Z = 0x36; /* Address of the Z Axis data register */
internal I2cDevice DirectAccess { get; }
internal ThreeAxisAccelerometerADXL345(I2cDevice Device)
{
if (Device == null) throw new ArgumentNullException(nameof(Device));
DirectAccess = Device;
}
public IThreeAxisAccelerometerADXL345 Initialize()
{
/*
* Initialize the accelerometer:
*
* For this device, we create 2-byte write buffers:
* The first byte is the register address we want to write to.
* The second byte is the contents that we want to write to the register.
*/
byte[] WriteBuf_DataFormat = new byte[] { ACCEL_REG_DATA_FORMAT, 0x01 }; /* 0x01 sets range to +- 4Gs */
byte[] WriteBuf_PowerControl = new byte[] { ACCEL_REG_POWER_CONTROL, 0x08 }; /* 0x08 puts the accelerometer into measurement mode */
/* Write the register settings */
DirectAccess.Write(WriteBuf_DataFormat);
DirectAccess.Write(WriteBuf_PowerControl);
return this;
}
public double[] GetAcclXYZ()
{
const int ACCEL_RES = 1024; /* The ADXL345 has 10 bit resolution giving 1024 unique values */
const int ACCEL_DYN_RANGE_G = 8; /* The ADXL345 had a total dynamic range of 8G, since we're configuring it to +-4G */
const int UNITS_PER_G = ACCEL_RES / ACCEL_DYN_RANGE_G; /* Ratio of raw int values to G units */
byte[] RegAddrBuf = new byte[] { ACCEL_REG_X }; /* Register address we want to read from */
byte[] ReadBuf = new byte[6]; /* We read 6 bytes sequentially to get all 3 two-byte axes registers in one read */
/*
* Read from the accelerometer
* We call WriteRead() so we first write the address of the X-Axis I2C register, then read all 3 axes
*/
DirectAccess.WriteRead(RegAddrBuf, ReadBuf);
/*
* In order to get the raw 16-bit data values, we need to concatenate two 8-bit bytes from the I2C read for each axis.
* We accomplish this by using the BitConverter class.
*/
short AccelerationRawX = BitConverter.ToInt16(ReadBuf, 0);
short AccelerationRawY = BitConverter.ToInt16(ReadBuf, 2);
short AccelerationRawZ = BitConverter.ToInt16(ReadBuf, 4);
/* Convert raw values to G's */
double[] accel = new double[3];
accel[0] = (double)AccelerationRawX / UNITS_PER_G;
accel[1] = (double)AccelerationRawY / UNITS_PER_G;
accel[2] = (double)AccelerationRawZ / UNITS_PER_G;
return accel;
}
}
}

View file

@ -0,0 +1,16 @@
namespace GrovePi
{
public enum Pin
{
AnalogPin0 = 0,
AnalogPin1 = 1,
AnalogPin2 = 2,
DigitalPin2 = 2,
DigitalPin3 = 3,
DigitalPin4 = 4,
DigitalPin5 = 5,
DigitalPin6 = 6,
DigitalPin7 = 7,
DigitalPin8 = 8
}
}

View file

@ -0,0 +1,8 @@
namespace GrovePi
{
public enum PinMode
{
Input = 0,
Output = 1
}
}

View file

@ -0,0 +1,29 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("GrovePi")]
[assembly: AssemblyDescription("GrovePi library for Windows IoT")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Jonathan Robson")]
[assembly: AssemblyProduct("GrovePi")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.10")]
[assembly: AssemblyFileVersion("1.0.10")]
[assembly: ComVisible(false)]

View file

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file contains Runtime Directives, specifications about types your application accesses
through reflection and other dynamic code patterns. Runtime Directives are used to control the
.NET Native optimizer and ensure that it does not remove code accessed by your library. If your
library does not do any reflection, then you generally do not need to edit this file. However,
if your library reflects over types, especially types passed to it or derived from its types,
then you should write Runtime Directives.
The most common use of reflection in libraries is to discover information about types passed
to the library. Runtime Directives have three ways to express requirements on types passed to
your library.
1. Parameter, GenericParameter, TypeParameter, TypeEnumerableParameter
Use these directives to reflect over types passed as a parameter.
2. SubTypes
Use a SubTypes directive to reflect over types derived from another type.
3. AttributeImplies
Use an AttributeImplies directive to indicate that your library needs to reflect over
types or methods decorated with an attribute.
For more information on writing Runtime Directives for libraries, please visit
http://go.microsoft.com/fwlink/?LinkId=613100
-->
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Library Name="GrovePi">
<!-- add directives for your library here -->
</Library>
</Directives>

View file

@ -0,0 +1,41 @@
using System;
namespace GrovePi.Sensors
{
public interface IAccelerometerSensor
{
byte[] Read();
}
internal class AccelerometerSensor : IAccelerometerSensor
{
private const byte CommandAddress = 20;
private readonly GrovePi _device;
private readonly Pin _pin;
internal AccelerometerSensor(GrovePi device, Pin pin)
{
if (device == null) throw new ArgumentNullException(nameof(device));
_device = device;
_pin = pin;
}
public byte[] Read()
{
var buffer = new [] {CommandAddress, (byte) _pin, Constants.Unused, Constants.Unused};
_device.DirectAccess.Write(buffer);
var readBuffer = new byte[1];
_device.DirectAccess.Read(readBuffer);
if (readBuffer[1] > 32)
readBuffer[1] = (byte) -(readBuffer[1] - 224);
if (readBuffer[2] > 32)
readBuffer[2] = (byte) -(readBuffer[1] - 224);
if (readBuffer[3] > 32)
readBuffer[3] = (byte) -(readBuffer[1] - 224);
return readBuffer;
}
}
}

View file

@ -0,0 +1,27 @@
using System;
namespace GrovePi.Sensors
{
public interface IAirQualitySensor
{
int AirQuality();
}
internal class AirQualitySensor : IAirQualitySensor
{
private readonly GrovePi _device;
private readonly Pin _pin;
internal AirQualitySensor(GrovePi device, Pin pin)
{
if (device == null) throw new ArgumentNullException(nameof(device));
device.PinMode(_pin, PinMode.Input);
_device = device;
_pin = pin;
}
public int AirQuality()
{
return _device.AnalogRead(_pin);
}
}
}

View file

@ -0,0 +1,14 @@
namespace GrovePi.Sensors
{
public interface IButtonSensor
{
SensorStatus CurrentState { get; }
}
internal class ButtonSensor : Sensor<IButtonSensor>, IButtonSensor
{
internal ButtonSensor(IGrovePi device, Pin pin) : base(device, pin, PinMode.Input)
{
}
}
}

View file

@ -0,0 +1,15 @@
namespace GrovePi.Sensors
{
public interface IBuzzer
{
SensorStatus CurrentState { get; }
IBuzzer ChangeState(SensorStatus newState);
}
internal class Buzzer : Sensor<IBuzzer>, IBuzzer
{
internal Buzzer(IGrovePi device, Pin pin) : base(device, pin, PinMode.Output)
{
}
}
}

View file

@ -0,0 +1,75 @@
using System;
namespace GrovePi.Sensors
{
public interface IChainableRgbLed
{
IChainableRgbLed Initialise(byte numberOfLeds);
IChainableRgbLed StoreColor(byte red, byte green, byte blue);
IChainableRgbLed Test(byte numberOfLeds, byte testColor);
IChainableRgbLed SetPattern(byte pattern, byte led);
IChainableRgbLed Mudulo(byte offset, byte divisor);
IChainableRgbLed SetLevel(byte level, bool reverse);
}
internal class ChainableRgbLed : IChainableRgbLed
{
public const byte StoreColorCommandAddress = 90;
public const byte InitialiseCommandAddress = 91;
public const byte TestCommandAddress = 92;
public const byte SetPatternCommandAddress = 93;
public const byte SetModuloCommandAddress = 94;
public const byte SetLevelCommmandAddress = 95;
private readonly GrovePi _device;
private readonly Pin _pin;
internal ChainableRgbLed(GrovePi device, Pin pin)
{
if (device == null) throw new ArgumentNullException(nameof(device));
_device = device;
_pin = pin;
}
public IChainableRgbLed SetLevel(byte level, bool reverse)
{
var buffer = new[] {level, (byte) _pin, level, reverse ? (byte) 1 : (byte) 0};
_device.DirectAccess.Write(buffer);
return this;
}
public IChainableRgbLed Initialise(byte numberOfLeds)
{
var buffer = new[] {InitialiseCommandAddress, (byte) _pin, numberOfLeds, Constants.Unused};
_device.DirectAccess.Write(buffer);
return this;
}
public IChainableRgbLed StoreColor(byte red, byte green, byte blue)
{
var buffer = new[] {StoreColorCommandAddress, red, green, blue};
_device.DirectAccess.Write(buffer);
return this;
}
public IChainableRgbLed Test(byte numberOfLeds, byte testColor)
{
var buffer = new[] {TestCommandAddress, (byte) _pin, numberOfLeds, testColor};
_device.DirectAccess.Write(buffer);
return this;
}
public IChainableRgbLed SetPattern(byte pattern, byte led)
{
var buffer = new[] {SetPatternCommandAddress, (byte) _pin, pattern, led};
_device.DirectAccess.Write(buffer);
return this;
}
public IChainableRgbLed Mudulo(byte offset, byte divisor)
{
var buffer = new[] {SetModuloCommandAddress, (byte) _pin, offset, divisor};
_device.DirectAccess.Write(buffer);
return this;
}
}
}

View file

@ -0,0 +1,92 @@
using System;
using GrovePi.Common;
namespace GrovePi.Sensors
{
public interface IDHTTemperatureAndHumiditySensor
{
double TemperatureInCelsius { get; }
double TemperatureInFahrenheit { get; }
double Humidity { get; }
void Measure();
}
/// <summary>
/// Specifies the model of sensor.
/// DHT11 - blue one - comes with the GrovePi+ Starter Kit.
/// DHT22 - white one, aka DHT Pro or AM2302.
/// DHT21 - black one, aka AM2301.
/// </summary>
public enum DHTModel
{
/*
*/
Dht11 = 0,
Dht21 = 1,
Dht22 = 2
}
internal class DHTTemperatureAndHumiditySensor : IDHTTemperatureAndHumiditySensor
{
private readonly GrovePi _device;
private readonly DHTModel _model;
private readonly Pin _pin;
private const byte DHTCmd = 40;
private double t = 0;
private double h = 0;
internal DHTTemperatureAndHumiditySensor(GrovePi device, Pin pin, DHTModel model)
{
if (device == null) throw new ArgumentNullException(nameof(device));
_device = device;
_pin = pin;
_model = model;
}
public void Measure()
{
_device.DirectAccess.WritePartial(new byte[4] { DHTCmd, (byte)_pin, (byte)_model, Constants.Unused });
Delay.Milliseconds(600);
var readBuffer = new byte[9];
_device.DirectAccess.ReadPartial(readBuffer);
float t0 = BitConverter.ToSingle(readBuffer, 1);
float h0 = BitConverter.ToSingle(readBuffer, 5);
t = (double)t0;
h = (double)h0;
}
private double CtoF(double c)
{
return c * 9 / 5 + 32;
}
public double TemperatureInCelsius
{
get
{
return t;
}
}
public double TemperatureInFahrenheit
{
get
{
return CtoF(t);
}
}
public double Humidity
{
get
{
return h;
}
}
}
}

View file

@ -0,0 +1,88 @@
using System;
namespace GrovePi.Sensors
{
public interface IFourDigitDisplay
{
IFourDigitDisplay Initialise();
IFourDigitDisplay SetBrightness(byte brightness);
IFourDigitDisplay SetIndividualSegment(byte segment, byte value);
IFourDigitDisplay SetLedsOfSegment(byte segment, byte leds);
IFourDigitDisplay SetScore(byte left, byte right);
IFourDigitDisplay AllOn();
IFourDigitDisplay AllOff();
}
internal class FourDigitDisplay : IFourDigitDisplay
{
private const byte InitialiseCommandAddress = 70;
private const byte BrightnessCommandAddress = 71;
private const byte ValueCommandAddress = 72;
private const byte ValueZerosCommandAddress = 73;
private const byte IndividualDigitCommandAddress = 74;
private const byte IndividualLedsCommandAddress = 75;
private const byte ScoreCommandAddress = 76;
private const byte AnalogReadCommandAddress = 77;
private const byte AllOnCommandAddress = 78;
private const byte AllOffCommandAddress = 79;
private readonly GrovePi _device;
private readonly Pin _pin;
internal FourDigitDisplay(GrovePi device, Pin pin)
{
if (device == null) throw new ArgumentNullException(nameof(device));
_device = device;
_pin = pin;
}
public IFourDigitDisplay Initialise()
{
var buffer = new[] {InitialiseCommandAddress, (byte) _pin, Constants.Unused, Constants.Unused};
_device.DirectAccess.Write(buffer);
return this;
}
public IFourDigitDisplay SetBrightness(byte brightness)
{
brightness = Math.Min(brightness, (byte) 7);
var buffer = new[] { BrightnessCommandAddress, (byte) _pin, brightness, Constants.Unused};
_device.DirectAccess.Write(buffer);
return this;
}
public IFourDigitDisplay SetIndividualSegment(byte segment, byte value)
{
var buffer = new[] {IndividualDigitCommandAddress, (byte) _pin, segment, value};
_device.DirectAccess.Write(buffer);
return this;
}
public IFourDigitDisplay SetLedsOfSegment(byte segment, byte leds)
{
var buffer = new[] {IndividualLedsCommandAddress, (byte) _pin, segment, leds};
_device.DirectAccess.Write(buffer);
return this;
}
public IFourDigitDisplay SetScore(byte left, byte right)
{
var buffer = new[] {ScoreCommandAddress, (byte) _pin, left, right};
_device.DirectAccess.Write(buffer);
return this;
}
public IFourDigitDisplay AllOn()
{
var buffer = new[] {AllOnCommandAddress, (byte) _pin, Constants.Unused, Constants.Unused};
_device.DirectAccess.Write(buffer);
return this;
}
public IFourDigitDisplay AllOff()
{
var buffer = new[] {AllOffCommandAddress, (byte) _pin, Constants.Unused, Constants.Unused};
_device.DirectAccess.Write(buffer);
return this;
}
}
}

View file

@ -0,0 +1,22 @@
using System;
namespace GrovePi.Sensors
{
public interface IGasSensorMQ2
{
int SensorValue();
}
internal class GasSensorMQ2 : Sensor<IGasSensorMQ2>, IGasSensorMQ2
{
public GasSensorMQ2(GrovePi device, Pin pin) : base(device,pin,PinMode.Input)
{
}
public int SensorValue()
{
return Device.AnalogRead(Pin);
}
}
}

View file

@ -0,0 +1,16 @@
namespace GrovePi.Sensors
{
public interface ILed
{
SensorStatus CurrentState { get; }
ILed ChangeState(SensorStatus newState);
void AnalogWrite(byte value);
}
internal class Led : Sensor<ILed>, ILed
{
internal Led(IGrovePi device, Pin pin) : base(device, pin, PinMode.Output)
{
}
}
}

View file

@ -0,0 +1,76 @@
using System;
namespace GrovePi.Sensors
{
public interface ILedBar
{
ILedBar Initialize(Orientation orientation);
ILedBar SetOrientation(Orientation orientation);
ILedBar SetLevel(byte level);
ILedBar SetLed(byte level, byte led, SensorStatus state);
ILedBar ToggleLed(byte led);
}
internal class LedBar : ILedBar
{
private const byte InitialiseCommandAddress = 50;
private const byte OrientationCommandAddress = 51;
private const byte LevelCommandAddress = 52;
private const byte SetOneCommandAddress = 53;
private const byte ToggleOneCommandAddress = 54;
//private const byte SetCommandAddress = 55;
//private const byte GetCommandAddress = 56;
private readonly GrovePi _device;
private readonly Pin _pin;
internal LedBar(GrovePi device, Pin pin)
{
if (device == null) throw new ArgumentNullException(nameof(device));
_device = device;
_pin = pin;
}
public ILedBar Initialize(Orientation orientation)
{
var buffer = new[] {InitialiseCommandAddress, (byte) _pin, (byte) orientation, Constants.Unused};
_device.DirectAccess.WritePartial(buffer);
return this;
}
public ILedBar SetOrientation(Orientation orientation)
{
var buffer = new[] {OrientationCommandAddress, (byte) _pin, (byte) orientation, Constants.Unused};
_device.DirectAccess.WritePartial(buffer);
return this;
}
public ILedBar SetLevel(byte level)
{
level = Math.Min(level, (byte) 10);
var buffer = new[] {LevelCommandAddress, (byte) _pin, level, Constants.Unused};
_device.DirectAccess.WritePartial(buffer);
return this;
}
public ILedBar SetLed(byte level, byte led, SensorStatus state)
{
var buffer = new[] {SetOneCommandAddress, (byte) _pin, led, (byte) state};
_device.DirectAccess.WritePartial(buffer);
return this;
}
public ILedBar ToggleLed(byte led)
{
var buffer = new[] {ToggleOneCommandAddress, (byte) _pin, led, Constants.Unused};
_device.DirectAccess.WritePartial(buffer);
return this;
}
}
public enum Orientation
{
RedToGreen = 0,
GreenToRed = 1
}
}

View file

@ -0,0 +1,35 @@
using System;
namespace GrovePi.Sensors
{
public interface ILightSensor
{
int SensorValue();
double Resistance();
}
internal class LightSensor : ILightSensor
{
private readonly GrovePi _device;
private readonly Pin _pin;
internal LightSensor(GrovePi device, Pin pin)
{
if (device == null) throw new ArgumentNullException(nameof(device));
device.PinMode(_pin, PinMode.Input);
_device = device;
_pin = pin;
}
public int SensorValue()
{
return _device.AnalogRead(_pin);
}
public double Resistance()
{
var sensorValue = SensorValue();
return (double) (1023 - sensorValue)*10/sensorValue;
}
}
}

View file

@ -0,0 +1,28 @@
namespace GrovePi.Sensors
{
public interface IPIRMotionSensor
{
bool IsPeopleDetected();
}
internal class PIRMotionSensor:Sensor<IPIRMotionSensor>, IPIRMotionSensor
{
public PIRMotionSensor(GrovePi device, Pin pin):base(device, pin, PinMode.Input)
{
}
public bool IsPeopleDetected()
{
int sensorValue = Device.DigitalRead(Pin);
if (sensorValue == 0)
{
return false;
}
else
{
return true;
}
}
}
}

View file

@ -0,0 +1,31 @@
using System;
namespace GrovePi.Sensors
{
public interface IRealTimeClock
{
byte[] Read();
}
internal class RealTimeClock : IRealTimeClock
{
private const byte CommandAddress = 30;
private readonly GrovePi _device;
private readonly Pin _pin;
internal RealTimeClock(GrovePi device, Pin pin)
{
if (device == null) throw new ArgumentNullException(nameof(device));
_device = device;
_pin = pin;
}
public byte[] Read()
{
var buffer = new[] {CommandAddress, (byte) _pin, Constants.Unused, Constants.Unused};
_device.DirectAccess.Write(buffer);
_device.DirectAccess.Read(buffer);
return buffer;
}
}
}

View file

@ -0,0 +1,14 @@
namespace GrovePi.Sensors
{
public interface IRelay
{
SensorStatus CurrentState { get; }
IRelay ChangeState(SensorStatus newState);
}
internal class Relay : Sensor<IRelay>, IRelay
{
public Relay(IGrovePi device, Pin pin) : base(device, pin, PinMode.Output)
{
}
}
}

View file

@ -0,0 +1,46 @@
using System;
namespace GrovePi.Sensors
{
public interface IRotaryAngleSensor
{
int SensorValue();
double Voltage();
double Degrees();
}
public class RotaryAngleSensor : IRotaryAngleSensor
{
private const int FullAngle = 300;
private readonly GrovePi _device;
private readonly Pin _pin;
internal RotaryAngleSensor(GrovePi device, Pin pin)
{
if (device == null) throw new ArgumentNullException(nameof(device));
device.PinMode(_pin, PinMode.Input);
_device = device;
_pin = pin;
}
public int SensorValue()
{
return _device.AnalogRead(_pin);
}
public double Voltage()
{
return Math.Round(((float) SensorValue()*Constants.AdcVoltage/1023), 2);
}
public double Degrees()
{
return Math.Round((Voltage()*FullAngle)/Constants.GroveVcc, 2);
}
public int Brightness()
{
return (int) (Degrees()/FullAngle*255);
}
}
}

View file

@ -0,0 +1,38 @@
using System;
namespace GrovePi.Sensors
{
public abstract class Sensor<TSensorType> where TSensorType : class
{
protected readonly IGrovePi Device;
protected readonly Pin Pin;
internal Sensor(IGrovePi device, Pin pin, PinMode pinMode)
{
if (device == null) throw new ArgumentNullException(nameof(device));
Device = device;
Pin = pin;
device.PinMode(Pin, pinMode);
}
internal Sensor(IGrovePi device, Pin pin)
{
if (device == null) throw new ArgumentNullException(nameof(device));
Device = device;
Pin = pin;
}
public SensorStatus CurrentState => (SensorStatus) Device.DigitalRead(Pin);
public TSensorType ChangeState(SensorStatus newState)
{
Device.DigitalWrite(Pin, (byte) newState);
return this as TSensorType;
}
public void AnalogWrite(byte value)
{
Device.AnalogWrite(Pin,value);
}
}
}

View file

@ -0,0 +1,8 @@
namespace GrovePi.Sensors
{
public enum SensorStatus
{
Off = 0,
On = 1
}
}

View file

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GrovePi.Sensors
{
public interface ISoundSensor
{
int SensorValue();
}
internal class SoundSensor : Sensor<ISoundSensor>, ISoundSensor
{
public SoundSensor(IGrovePi device, Pin pin) : base(device, pin, PinMode.Input)
{
}
public int SensorValue()
{
return Device.AnalogRead(Pin);
}
}
}

View file

@ -0,0 +1,46 @@
using System;
namespace GrovePi.Sensors
{
public interface ITemperatureAndHumiditySensor
{
double TemperatureInCelsius();
}
/// <summary>
/// Specifies the model of sensor.
/// DHT11 - blue one - comes with the GrovePi+ Starter Kit.
/// DHT22 - white one, aka DHT Pro or AM2302.
/// DHT21 - black one, aka AM2301.
/// </summary>
public enum Model
{
/*
*/
Dht11 = 3975,
Dht21 = 4250,
Dht22 = 4250
}
internal class TemperatureAndHumiditySensor : ITemperatureAndHumiditySensor
{
private readonly IGrovePi _device;
private readonly Model _model;
private readonly Pin _pin;
internal TemperatureAndHumiditySensor(IGrovePi device, Pin pin, Model model)
{
if (device == null) throw new ArgumentNullException(nameof(device));
_device = device;
_pin = pin;
_model = model;
}
public double TemperatureInCelsius()
{
var result = (double) _device.AnalogRead(_pin);
var resistance = (1023 - result)*10000/result;
return 1/(Math.Log(resistance/10000)/(int) _model + 1/298.15) - 273.15;
}
}
}

View file

@ -0,0 +1,33 @@
using System;
namespace GrovePi.Sensors
{
public interface ITemperatureSensor
{
double TemperatureInCelsius();
}
/// <summary>
/// Temperature Sensor V1.1 & 1.2
/// ref: <http://wiki.seeed.cc/Grove-Temperature_Sensor_V1.2/>
/// </summary>
internal class TemperatureSensor : ITemperatureSensor
{
private readonly IGrovePi _device;
private readonly Pin _pin;
internal TemperatureSensor(IGrovePi device, Pin pin)
{
if (device == null) throw new ArgumentNullException(nameof(device));
_device = device;
_pin = pin;
}
public double TemperatureInCelsius()
{
var result = (double)_device.AnalogRead(_pin);
var resistance = (1023 - result) * 10000 / result;
return 1 / (Math.Log(resistance / 10000) / 4275 + 1 / 298.15) - 273.15;
}
}
}

View file

@ -0,0 +1,40 @@
using GrovePi.Common;
namespace GrovePi.Sensors
{
public interface IUltrasonicRangerSensor
{
int MeasureInCentimeters();
}
internal class UltrasonicRangerSensor : IUltrasonicRangerSensor
{
private const byte CommandAddress = 7;
private readonly GrovePi _device;
private readonly Pin _pin;
internal UltrasonicRangerSensor(GrovePi device, Pin pin)
{
_device = device;
_pin = pin;
}
public int MeasureInCentimeters()
{
var buffer = new byte[4] {CommandAddress, (byte) _pin, Constants.Unused, Constants.Unused};
var result = _device.DirectAccess.WritePartial(buffer);
if (result.Status != Windows.Devices.I2c.I2cTransferStatus.FullTransfer)
{
return -1;
}
Delay.Milliseconds(50);
buffer = new byte[3];
result = _device.DirectAccess.ReadPartial(buffer);
if (result.Status != Windows.Devices.I2c.I2cTransferStatus.FullTransfer)
{
return -1;
}
return buffer[1]*256 + buffer[2];
}
}
}

View file

@ -0,0 +1,14 @@
namespace GrovePi.Sensors
{
public interface IWaterAtomizer
{
SensorStatus CurrentState { get; }
IWaterAtomizer ChangeState(SensorStatus newState);
}
internal class WaterAtomizer : Sensor<IWaterAtomizer>, IWaterAtomizer
{
public WaterAtomizer(IGrovePi device, Pin pin) : base(device, pin, PinMode.Output)
{ }
}
}

View file

@ -0,0 +1,12 @@
{
"dependencies": {
"Microsoft.NETCore.UniversalWindowsPlatform": "5.3.3"
},
"frameworks": {
"uap10.0": {}
},
"runtimes": {
"win10-arm": {},
"win10-arm-aot": {}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,63 @@
![alt text](https://raw.githubusercontent.com/DexterInd/GrovePi/master/Software/CSharp/Windows_IOT_and_Dex-768x281.jpg "Logo WinIoT GrovePi")
# GrovePi in C#
Get the Packages:
* Windows 10 IoT C# driver library for [GrovePi](https://www.nuget.org/packages/GrovePi/).
* The NuGet package for the current release is available [here](https://www.nuget.org/packages/GrovePi/).
# Getting Started with WinIoT
If you are just starting with WinIoT, see our [tutorial for getting started with WinIoT and the GrovePi here](http://www.dexterindustries.com/GrovePi/programming/getting-started-with-windows-iot-and-the-grovepi-winiot/). There are three steps:
[Introduction to Getting Started with WinIoT and the GrovePi.](http://www.dexterindustries.com/GrovePi/programming/getting-started-with-windows-iot-and-the-grovepi-winiot/)
1. [Setting up your Computer and Raspberry Pi](http://www.dexterindustries.com/GrovePi/programming/getting-started-with-windows-iot-and-the-grovepi-winiot/getting-started-windows-iot-winiot-and-grovepi-setting-up-your-pc-and-pi/)
2. [Run Hello World in WinIoT](http://www.dexterindustries.com/GrovePi/programming/getting-started-with-windows-iot-and-the-grovepi-winiot/getting-started-windows-iot-winiot-and-grovepi-run-hello-world/)
3. [More WinIoT GrovePi Samples and Examples](http://www.dexterindustries.com/GrovePi/programming/getting-started-with-windows-iot-and-the-grovepi-winiot/getting-started-windows-iot-winiot-and-grovepi-more-winiot-grovepi-samples-and-examples/)
# Sample Programs in C#
Below are some simple examples of how to use the library.
######Sample Programs
* Button_Buzzer
* Example-Button
* Example-LCD_Display
* Example-LED
* Example-Light_Sensor
* Example-Relay
* Example-Sound_Sensor
* Example-Temp_and_Humidity
* Example-Ultrasonic
* HelloWorldBlinky
* LcdRgbDisplay
* LedFade
* Light_Sensor_LCDDisplay
#####Supported Samples
All supported sensors are available through the DeviceFactory class.
Supported sensors include:
- Relay
- Led
- TemperatureAndHumiditySensor
- UltraSonicSensor
- AccelerometerSensor
- RealTimeClock
- BuildLedBar
- FourDigitDisplay
- ChainableRgbLed
- RotaryAngleSensor
- Buzzer
- SoundSensor
- LightSensor
- ButtonSensor
- RgbLcdDisplay
### Getting Into It
Want to hack it open or make your own from scratch? With full hardware and software designs, you can remix and duplicate to your hearts content.
See more at the [GrovePi Site](http://dexterindustries.com/GrovePi/)

10
Software/CSharp/README.md Normal file
View file

@ -0,0 +1,10 @@
# GrovePi for C#
Multiple implantationss of GrovePi exist for C#:
- Universal Windows Platform for Windows IoT Core. You will find all details [here](./README-UWP.md)
- .NET Core IoT for Linux or Windows. You will find all details [here](https://github.com/dotnet/iot/tree/master/src/devices/GrovePi)
Universal Windows Platform for Windows IoT Core is a specific implementation of Windows IoT Core running on boards like Raspberry Pi. It's best if you love XAML and traditional Universal Windows Platform and if you need a UI.
.NET Core is open source. .NET Core is best thought of as 'agile .NET'. Generally speaking it is the same as the Desktop .NET Framework distributed as part of the Windows operating system, but it is a cross platform (Windows, Linux, macOS) and cross architecture (x86, x64, ARM) subset that can be deployed as part of the application (if desired), and thus can be updated quickly to fix bugs or add features. It is a perfect fit for boards like Raspberry running Raspbian. Check the [.NET Core IoT documentation](https://github.com/dotnet/iot/tree/master/Documentation) if you are not familiar with .NET Core.

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

@ -0,0 +1,160 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProjectGuid>{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}</ProjectGuid>
<OutputType>winmdobj</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ButtonBuzzer</RootNamespace>
<AssemblyName>ButtonBuzzer</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion>10.0.10586.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
<EnableDotNetNativeCompatibleProfile>true</EnableDotNetNativeCompatibleProfile>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<AllowCrossPlatformRetargeting>false</AllowCrossPlatformRetargeting>
<PackageCertificateKeyFile>ButtonBuzzer_TemporaryKey.pfx</PackageCertificateKeyFile>
<AppxPackage>true</AppxPackage>
<ContainsStartupTask>true</ContainsStartupTask>
<PackageCertificateThumbprint>E9BF24791F021240D5974379AE636319A5A29E21</PackageCertificateThumbprint>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\ARM\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>ARM</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
<OutputPath>bin\ARM\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>ARM</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<ItemGroup>
<!-- A reference to the entire .Net Framework and Windows SDK are automatically included -->
<None Include="ButtonBuzzer_TemporaryKey.pfx" />
<None Include="project.json" />
</ItemGroup>
<ItemGroup>
<Compile Include="StartupTask.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
</ItemGroup>
<ItemGroup>
<Content Include="Properties\Default.rd.xml" />
<Content Include="Assets\LockScreenLogo.scale-200.png">
<InProject>false</InProject>
</Content>
<Content Include="Assets\SplashScreen.scale-200.png">
<InProject>false</InProject>
</Content>
<Content Include="Assets\Square150x150Logo.scale-200.png">
<InProject>false</InProject>
</Content>
<Content Include="Assets\Square44x44Logo.scale-200.png">
<InProject>false</InProject>
</Content>
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png">
<InProject>false</InProject>
</Content>
<Content Include="Assets\StoreLogo.png">
<InProject>false</InProject>
</Content>
<Content Include="Assets\Wide310x150Logo.scale-200.png">
<InProject>false</InProject>
</Content>
</ItemGroup>
<ItemGroup>
<Reference Include="GrovePi, Version=1.0.7.0, Culture=neutral, processorArchitecture=ARM">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\GrovePi\bin\ARM\Debug\GrovePi.dll</HintPath>
</Reference>
</ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
<VisualStudioVersion>14.0</VisualStudioVersion>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<PropertyGroup>
<SignAssembly>false</SignAssembly>
</PropertyGroup>
<PropertyGroup>
<AssemblyOriginatorKeyFile>
</AssemblyOriginatorKeyFile>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View file

@ -0,0 +1,45 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ButtonBuzzer", "ButtonBuzzer.csproj", "{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{DC9CE5B0-5F88-4AFC-9F7A-CBCB69B6DFD7}"
ProjectSection(SolutionItems) = preProject
README.md = README.md
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|ARM = Release|ARM
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Debug|ARM.ActiveCfg = Debug|ARM
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Debug|ARM.Build.0 = Debug|ARM
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Debug|ARM.Deploy.0 = Debug|ARM
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Debug|x64.ActiveCfg = Debug|x64
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Debug|x64.Build.0 = Debug|x64
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Debug|x64.Deploy.0 = Debug|x64
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Debug|x86.ActiveCfg = Debug|x86
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Debug|x86.Build.0 = Debug|x86
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Debug|x86.Deploy.0 = Debug|x86
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Release|ARM.ActiveCfg = Release|ARM
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Release|ARM.Build.0 = Release|ARM
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Release|ARM.Deploy.0 = Release|ARM
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Release|x64.ActiveCfg = Release|x64
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Release|x64.Build.0 = Release|x64
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Release|x64.Deploy.0 = Release|x64
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Release|x86.ActiveCfg = Release|x86
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Release|x86.Build.0 = Release|x86
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Release|x86.Deploy.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:iot="http://schemas.microsoft.com/appx/manifest/iot/windows10" IgnorableNamespaces="uap mp iot">
<Identity Name="ButtonBuzzer-uwp" Publisher="CN=Dexter Industries Dev" Version="1.0.0.0" />
<mp:PhoneIdentity PhoneProductId="0e29ae6c-d965-4f75-9387-70a777ae7169" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
<Properties>
<DisplayName>ButtonBuzzer</DisplayName>
<PublisherDisplayName>Dexter Industries</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate" />
</Resources>
<Applications>
<Application Id="App">
<uap:VisualElements DisplayName="ButtonBuzzer" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="Demonstrate the Button and Buzzer with the GrovePi." BackgroundColor="transparent" AppListEntry="none">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png">
</uap:DefaultTile>
<uap:SplashScreen Image="Assets\SplashScreen.png" />
</uap:VisualElements>
<Extensions>
<Extension Category="windows.backgroundTasks" EntryPoint="ButtonBuzzer.StartupTask">
<BackgroundTasks>
<iot:Task Type="startup" />
</BackgroundTasks>
</Extension>
</Extensions>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
</Capabilities>
</Package>

View file

@ -0,0 +1,32 @@
using System.Resources;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ButtonBuzzer")]
[assembly: AssemblyDescription("Demonstrates Using the Button and Buzzer with the Dexter Industries GrovePi.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Dexter Industries")]
[assembly: AssemblyProduct("GrovePi")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("GrovePi")]
[assembly: AssemblyCulture("")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: ComVisible(false)]
[assembly: NeutralResourcesLanguage("")]

View file

@ -0,0 +1,31 @@
<!--
This file contains Runtime Directives used by .NET Native. The defaults here are suitable for most
developers. However, you can modify these parameters to modify the behavior of the .NET Native
optimizer.
Runtime Directives are documented at http://go.microsoft.com/fwlink/?LinkID=391919
To fully enable reflection for App1.MyClass and all of its public/private members
<Type Name="App1.MyClass" Dynamic="Required All"/>
To enable dynamic creation of the specific instantiation of AppClass<T> over System.Int32
<TypeInstantiation Name="App1.AppClass" Arguments="System.Int32" Activate="Required Public" />
Using the Namespace directive to apply reflection policy to all the types in a particular namespace
<Namespace Name="DataClasses.ViewModels" Seralize="All" />
-->
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Application>
<!--
An Assembly element with Name="*Application*" applies to all assemblies in
the application package. The asterisks are not wildcards.
-->
<Assembly Name="*Application*" Dynamic="Required All" />
<!-- Add your application specific runtime directives here. -->
</Application>
</Directives>

View file

@ -0,0 +1,87 @@
## **Button and Buzzer Example**
This example will demonstrate how to use the [Dexter Industries GrovePi](http://www.dexterindustries.com/grovepi-starter-kit/) with the [Grove Buzzer](http://www.dexterindustries.com/shop/grove-buzzer/) and the [Grove Button](http://www.dexterindustries.com/shop/grove-button/) to create a buzzer controlled by the touch sensor. This sample is designed to run on a Raspberry Pi 2 running Windows 10 IoT Core. The application is written as a Background Task and will run in Windows 10 IoT Core without any user interface.
### Requirements
You must have the following:
- [Windows 10](https://www.microsoft.com/windows/)
- [Visual Studio 2015 Community Edition](https://www.visualstudio.com/) or better
- [Raspberry Pi 2 running Windows 10 IoT Core](http://ms-iot.github.io/content/en-US/win10/RPI.htm)
- [GrovePi+ Starter Kit for Raspberry Pi](http://www.dexterindustries.com/grovepi-starter-kit/)
### Install a Visual Studio 2015
If you don't already have one installed, install Visual Studio 2015. You can use the free Community edition, or any other higher edition. When you are installing Visual Studio, you must do a __Custom__ install and select to install the __Universal Windows App Development Tools -> Tools and Windows SDK__.
After the installation is complete, install the Windows IoT Core Project Templates from [here](https://visualstudiogallery.msdn.microsoft.com/55b357e1-a533-43ad-82a5-a88ac4b01dec).
### Enable Developer Mode on your Windows 10 Development Device
When you are developing on Windows 10, you choose what tasks you want to enable on the device. This includes any devices - Windows 10 desktops, tablets and phones. You can enable a device for development, or just app side loading. To enable _Developer mode_ on your Windows 10 device:
1. Click the Windows icon (typically in the lower-left of the screen, on the left-most side of the toolbar).
2. Type __Update__ and select _Windows Update settings_ from the _Best match_ list. This will open the __UPDATE & SECURITY__ settings page.
3. Click on __For developers__ in the left sidebar.
4. Ensure the __Developer mode__ radio button is selected.
5. Save your changes and close the _Settings_ window.
### Build the Samples
Download the GrovePi repository to your development PC.
Each sample is its own solution. There are two ways to run the sample projects - within the GrovePi solution, or as individual solutions.
#### Samples as Part of GrovePi solution (recommended)
When you run the samples as part of the GrovePi solution you know that you are using the very latest build of GrovePi, however; the samples are not part of the GrovePi solution by default - you must add them.
1. Open __GrovePi\Software\CSharp\GrovePi.sln__ in Visual Studio
2. Right-click on the solution in the _Solution Explorer_
3. Select __Add__ > __ New Solution Folder__
4. Name the folder __Samples__
5. Right-click on the solution in the _Solution Explorer_
6. Select __Add__ > __ Existing Project__
7. Find the __ButtonBuzzer.csproj__ file - select it and click __Open__
This will add the _ButtonBuzzer_ project to you new _Samples_ directory.
In the _ButtonBuzzer_ project you need to update the reference to _GrovePi_.
1. In _Solution Explorer_ expand the _ButtonBuzzer_ project and the _References_ node.
2. Right-click on the __GrovePi__ reference and click __Remove_
3. Right-click on the __References__ node and choose __Add Reference__
4. Expand the __Projects__ node
5. Select (by checking the check box) the __GrovePi__ project.
6. Click __OK__
The project should now have all the updated references you need.
#### Samples as Independent Solutions
When you run the sampels as independent solutions, you need to ensure you are referencing a current version of the GrovePi assembly (likely more current than the one available as a NuGet package).
The following steps assume you have already opened _GrovePi\Software\CSharp\GrovePi.sln_ in Visual Studio and built the solution. To build the solution, open GrovePi.sln, and click on press CTRL + SHIFT + B. Then close GrovePi.sln.
After building the GrovePi solution:
1. Open __GrovePi\Software\CSharp\Samples\ButtonBuzzer.sln__ in Visual Studio
2. In _Solution Explorer_ expand the _ButtonBuzzer_ project and the _References_ node.
3. Right-click on the __GrovePi__ reference and click __Remove_
4. Right-click on "References" and click "Add Reference".
5. Select the __Browse__ tab and click the __Browse__ button.
6. Browse to __GrovePi\Software\CSharp\GrovePi\bin\ARM\Debug__ and select the __GrovePi.dll__ file
7. Click __OK__
The project should now have all the updated references you need.
### Setup the Hardware
For this example program, connect the following:
1. Buzzer to __D5__ (Digital Pin 5)
2. Button to __D2__ (Digital Pin 2)
### Run the Sample
To run the sample...
1. Right-click on the _ButtonBuzzer_ project in the _Solution Explorer_
2. Select __Set as Startup Project__
3. Right-click on the __Properties__ node under _ButtonBuzzer_ and select __Open__
4. Select the __Debug__ tab
5. Select __Remote Machine__ in the _Target device_ field
6. In the __Remote Machine__ field, Type in the name or IP Address of your Windows 10 IoT Core Raspberry Pi
7. Press __Ctrl__ + __S__ (this file will not be saved automatically, you must save it manually).
8. Press __F5__ to launch the debugger (it will take a minute or two to deploy your app onto the Raspberry Pi).

View file

@ -0,0 +1,104 @@
// Turn the Buzzer on and Off with A Button
// In this example, we turn a buzzer on and off with a button.
// The GrovePi connects the Raspberry Pi and Grove sensors.
// You can learn more about GrovePi here: http://www.dexterindustries.com/GrovePi
// This example combines the GrovePi + Button + Buzzer
// http://www.dexterindustries.com/shop/grovepi-board/
// http://www.dexterindustries.com/shop/grove-buzzer/
// http://www.dexterindustries.com/shop/grove-button/
// Hardware Setup:
// Connect the Button to digital port 2
// Connect the Buzzer to digital port 5
/*
The MIT License(MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2016 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System;
using Windows.ApplicationModel.Background;
// Add using statements to the GrovePi libraries
using GrovePi;
using GrovePi.Sensors;
namespace ButtonBuzzer
{
public sealed class StartupTask : IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
// Connect the Button to digital port 2
IButtonSensor button = DeviceFactory.Build.ButtonSensor(Pin.DigitalPin2);
// Connect the Buzzer to digital port 5
IBuzzer buzzer = DeviceFactory.Build.Buzzer(Pin.DigitalPin5);
// Loop endlessly
while (true)
{
try
{
// Check the value of the button.
string buttonon = button.CurrentState.ToString();
bool buttonison = buttonon.Equals("On", StringComparison.OrdinalIgnoreCase);
// Check the state of the buzzer. This is just to output to debug!
SensorStatus status = buzzer.CurrentState;
bool buzzeron = status.ToString().Equals("On", StringComparison.OrdinalIgnoreCase);
// Print out Diagnostics.
System.Diagnostics.Debug.WriteLine("Button is " + buttonon);
System.Diagnostics.Debug.WriteLine("Buzzer is " + status.ToString());
// If the Button is on . . . .
if (buttonison)
{
buzzer.ChangeState(GrovePi.Sensors.SensorStatus.On);
}
else
{
buzzer.ChangeState(GrovePi.Sensors.SensorStatus.Off);
}
}
catch (Exception ex)
{
// NOTE: There are frequent exceptions of the following:
// WinRT information: Unexpected number of bytes was transferred. Expected: '. Actual: '.
// This appears to be caused by the rapid frequency of writes to the GPIO
// These are being swallowed here/
// If you want to see the exceptions uncomment the following:
// System.Diagnostics.Debug.WriteLine(ex.ToString());
}
}
}
}
}

View file

@ -0,0 +1,16 @@
{
"dependencies": {
"Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0"
},
"frameworks": {
"uap10.0": {}
},
"runtimes": {
"win10-arm": {},
"win10-arm-aot": {},
"win10-x86": {},
"win10-x86-aot": {},
"win10-x64": {},
"win10-x64-aot": {}
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

@ -0,0 +1,160 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProjectGuid>{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}</ProjectGuid>
<OutputType>winmdobj</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Button</RootNamespace>
<AssemblyName>Button</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion>10.0.10586.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
<EnableDotNetNativeCompatibleProfile>true</EnableDotNetNativeCompatibleProfile>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<AllowCrossPlatformRetargeting>false</AllowCrossPlatformRetargeting>
<PackageCertificateKeyFile>Button_TemporaryKey.pfx</PackageCertificateKeyFile>
<AppxPackage>true</AppxPackage>
<ContainsStartupTask>true</ContainsStartupTask>
<PackageCertificateThumbprint>220B830742F2BA7DF0C18A3CCB48EC53EC262714</PackageCertificateThumbprint>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\ARM\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>ARM</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
<OutputPath>bin\ARM\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>ARM</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<ItemGroup>
<!-- A reference to the entire .Net Framework and Windows SDK are automatically included -->
<None Include="Button_TemporaryKey.pfx" />
<None Include="project.json" />
</ItemGroup>
<ItemGroup>
<Compile Include="StartupTask.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
</ItemGroup>
<ItemGroup>
<Content Include="Properties\Default.rd.xml" />
<Content Include="Assets\LockScreenLogo.scale-200.png">
<InProject>false</InProject>
</Content>
<Content Include="Assets\SplashScreen.scale-200.png">
<InProject>false</InProject>
</Content>
<Content Include="Assets\Square150x150Logo.scale-200.png">
<InProject>false</InProject>
</Content>
<Content Include="Assets\Square44x44Logo.scale-200.png">
<InProject>false</InProject>
</Content>
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png">
<InProject>false</InProject>
</Content>
<Content Include="Assets\StoreLogo.png">
<InProject>false</InProject>
</Content>
<Content Include="Assets\Wide310x150Logo.scale-200.png">
<InProject>false</InProject>
</Content>
</ItemGroup>
<ItemGroup>
<Reference Include="GrovePi, Version=1.0.7.0, Culture=neutral, processorArchitecture=ARM">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\GrovePi\bin\ARM\Debug\GrovePi.dll</HintPath>
</Reference>
</ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
<VisualStudioVersion>14.0</VisualStudioVersion>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<PropertyGroup>
<SignAssembly>false</SignAssembly>
</PropertyGroup>
<PropertyGroup>
<AssemblyOriginatorKeyFile>
</AssemblyOriginatorKeyFile>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View file

@ -0,0 +1,45 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Button", "Button.csproj", "{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{DC9CE5B0-5F88-4AFC-9F7A-CBCB69B6DFD7}"
ProjectSection(SolutionItems) = preProject
README.md = README.md
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|ARM = Release|ARM
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Debug|ARM.ActiveCfg = Debug|ARM
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Debug|ARM.Build.0 = Debug|ARM
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Debug|ARM.Deploy.0 = Debug|ARM
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Debug|x64.ActiveCfg = Debug|x64
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Debug|x64.Build.0 = Debug|x64
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Debug|x64.Deploy.0 = Debug|x64
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Debug|x86.ActiveCfg = Debug|x86
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Debug|x86.Build.0 = Debug|x86
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Debug|x86.Deploy.0 = Debug|x86
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Release|ARM.ActiveCfg = Release|ARM
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Release|ARM.Build.0 = Release|ARM
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Release|ARM.Deploy.0 = Release|ARM
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Release|x64.ActiveCfg = Release|x64
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Release|x64.Build.0 = Release|x64
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Release|x64.Deploy.0 = Release|x64
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Release|x86.ActiveCfg = Release|x86
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Release|x86.Build.0 = Release|x86
{1AAB0B0C-4AD6-49A7-9A1C-78ACE337A938}.Release|x86.Deploy.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:iot="http://schemas.microsoft.com/appx/manifest/iot/windows10" IgnorableNamespaces="uap mp iot">
<Identity Name="Button-uwp" Publisher="CN=Dexter Industries Dev" Version="1.0.0.0" />
<mp:PhoneIdentity PhoneProductId="0e29ae6c-d965-4f75-9387-70a777ae7169" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
<Properties>
<DisplayName>Button</DisplayName>
<PublisherDisplayName>DexterIndustries</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate" />
</Resources>
<Applications>
<Application Id="App">
<uap:VisualElements DisplayName="Button" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="Demonstrate using the button with GrovePi and WinIOT." BackgroundColor="transparent" AppListEntry="none">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png">
</uap:DefaultTile>
<uap:SplashScreen Image="Assets\SplashScreen.png" />
</uap:VisualElements>
<Extensions>
<Extension Category="windows.backgroundTasks" EntryPoint="Button.StartupTask">
<BackgroundTasks>
<iot:Task Type="startup" />
</BackgroundTasks>
</Extension>
</Extensions>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
</Capabilities>
</Package>

View file

@ -0,0 +1,32 @@
using System.Resources;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Button")]
[assembly: AssemblyDescription("Demonstrates using the Grove Button with the GrovePi.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Dexter Industries")]
[assembly: AssemblyProduct("GrovePi")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("GrovePi")]
[assembly: AssemblyCulture("Counter")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: ComVisible(false)]
[assembly: NeutralResourcesLanguage("")]

View file

@ -0,0 +1,31 @@
<!--
This file contains Runtime Directives used by .NET Native. The defaults here are suitable for most
developers. However, you can modify these parameters to modify the behavior of the .NET Native
optimizer.
Runtime Directives are documented at http://go.microsoft.com/fwlink/?LinkID=391919
To fully enable reflection for App1.MyClass and all of its public/private members
<Type Name="App1.MyClass" Dynamic="Required All"/>
To enable dynamic creation of the specific instantiation of AppClass<T> over System.Int32
<TypeInstantiation Name="App1.AppClass" Arguments="System.Int32" Activate="Required Public" />
Using the Namespace directive to apply reflection policy to all the types in a particular namespace
<Namespace Name="DataClasses.ViewModels" Seralize="All" />
-->
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Application>
<!--
An Assembly element with Name="*Application*" applies to all assemblies in
the application package. The asterisks are not wildcards.
-->
<Assembly Name="*Application*" Dynamic="Required All" />
<!-- Add your application specific runtime directives here. -->
</Application>
</Directives>

View file

@ -0,0 +1,87 @@
## **LED Fade Sample**
This sample will demonstrate how to use the Grove Button to Digital Port 2. This sample is designed to run on a Raspberry Pi 2 running Windows 10 IoT Core. The application is written as a Background Task and will run in Windows 10 IoT Core without any user interface.
### Requirements
You must have the following:
- [Windows 10](https://www.microsoft.com/windows/)
- [Visual Studio 2015 Community Edition](https://www.visualstudio.com/) or better
- [Raspberry Pi 2 running Windows 10 IoT Core](http://ms-iot.github.io/content/en-US/win10/RPI.htm)
- [GrovePi+ Starter Kit for Raspberry Pi](http://www.dexterindustries.com/grovepi-starter-kit/)
### Install a Visual Studio 2015
If you don't already have one installed, install Visual Studio 2015. You can use the free Community edition, or any other higher edition. When you are installing Visual Studio, you must do a __Custom__ install and select to install the __Universal Windows App Development Tools -> Tools and Windows SDK__.
After the installation is complete, install the Windows IoT Core Project Templates from [here](https://visualstudiogallery.msdn.microsoft.com/55b357e1-a533-43ad-82a5-a88ac4b01dec).
### Enable Developer Mode on your Windows 10 Development Device
When you are developing on Windows 10, you choose what tasks you want to enable on the device. This includes any devices - Windows 10 desktops, tablets and phones. You can enable a device for development, or just app side loading. To enable _Developer mode_ on your Windows 10 device:
1. Click the Windows icon (typically in the lower-left of the screen, on the left-most side of the toolbar).
2. Type __Update__ and select _Windows Update settings_ from the _Best match_ list. This will open the __UPDATE & SECURITY__ settings page.
3. Click on __For developers__ in the left sidebar.
4. Ensure the __Developer mode__ radio button is selected.
5. Save your changes and close the _Settings_ window.
### Build the Samples
Download the GrovePi repository to your development PC.
Each sample is its own solution. There are two ways to run the sample projects - within the GrovePi solution, or as individual solutions.
#### Samples as Part of GrovePi solution (recommended)
When you run the samples as part of the GrovePi solution you know that you are using the very latest build of GrovePi, however; the samples are not part of the GrovePi solution by default - you must add them.
1. Open __GrovePi\Software\CSharp\GrovePi.sln__ in Visual Studio
2. Right-click on the solution in the _Solution Explorer_
3. Select __Add__ > __ New Solution Folder__
4. Name the folder __Samples__
5. Right-click on the solution in the _Solution Explorer_
6. Select __Add__ > __ Existing Project__
7. Find the __Button.csproj__ file - select it and click __Open__
This will add the _Button_ project to you new _Samples_ directory.
In the _Button_ project you need to update the reference to _GrovePi_.
1. In _Solution Explorer_ expand the _Button_ project and the _References_ node.
2. Right-click on the __GrovePi__ reference and click __Remove_
3. Right-click on the __References__ node and choose __Add Reference__
4. Expand the __Projects__ node
5. Select (by checking the check box) the __GrovePi__ project.
6. Click __OK__
The project should now have all the updated references you need.
#### Samples as Independent Solutions
When you run the sampels as independent solutions, you need to ensure you are referencing a current version of the GrovePi assembly (likely more current than the one available as a NuGet package).
The following steps assume you have already opened _GrovePi\Software\CSharp\GrovePi.sln_ in Visual Studio and built the solution. To build the solution, open GrovePi.sln, and click on press CTRL + SHIFT + B. Then close GrovePi.sln.
After building the GrovePi solution:
1. Open __GrovePi\Software\CSharp\Samples\Button.sln__ in Visual Studio.
2. In _Solution Explorer_ expand the _Button_ project and the _References_ node.
3. Right-click on the __GrovePi__ reference and click __Remove_.
4. Right-click on "References" and click "Add Reference".
5. Select the __Browse__ tab and click the __Browse__ button.
6. Browse to __GrovePi\Software\CSharp\GrovePi\bin\ARM\Debug__ and select the __GrovePi.dll__ file
7. Click __OK__
The project should now have all the updated references you need.
### Setup the Hardware
For this sample, connect the following:
1. Connect the Button Sensor to __D2__ (Digital Pin 2)
### Run the Sample
To run the sample...
1. Right-click on the _Button_ project in the _Solution Explorer_
2. Select __Set as Startup Project__
3. Right-click on the __Properties__ node under _Button_ and select __Open__
4. Select the __Debug__ tab
5. Select __Remote Machine__ in the _Target device_ field
6. In the __Remote Machine__ field, Type in the name or IP Address of your Windows 10 IoT Core Raspberry Pi
7. Press __Ctrl__ + __S__ (this file will not be saved automatically, you must save it manually).
8. Press __F5__ to launch the debugger (it will take a minute or two to deploy your app onto the Raspberry Pi).

View file

@ -0,0 +1,73 @@
// Button Demonstration for the GrovePi.
// This example combines the GrovePi and the Grove Button using the Raspberry Pi and GrovePi.
// http://www.dexterindustries.com/shop/grovepi-board/
// http://www.dexterindustries.com/shop/grove-button/
/*
The MIT License(MIT)
GrovePi for the Raspberry Pi: an open source platform for connecting Grove Sensors to the Raspberry Pi.
Copyright (C) 2016 Dexter Industries
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
using System;
using Windows.ApplicationModel.Background;
// Add using statements to the GrovePi libraries
using GrovePi;
using GrovePi.Sensors;
namespace Button
{
public sealed class StartupTask : IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
// Connect the Button to digital port 2
IButtonSensor button = DeviceFactory.Build.ButtonSensor(Pin.DigitalPin2);
// Loop endlessly
while (true)
{
try
{
// Check the value of the button.
string buttonon = button.CurrentState.ToString();
// bool buttonison = buttonon.Equals("On", StringComparison.OrdinalIgnoreCase);
System.Diagnostics.Debug.WriteLine("Button is " + buttonon);
}
catch (Exception ex)
{
// NOTE: There are frequent exceptions of the following:
// WinRT information: Unexpected number of bytes was transferred. Expected: '. Actual: '.
// This appears to be caused by the rapid frequency of writes to the GPIO
// These are being swallowed here/
// If you want to see the exceptions uncomment the following:
// System.Diagnostics.Debug.WriteLine(ex.ToString());
}
}
}
}
}

View file

@ -0,0 +1,16 @@
{
"dependencies": {
"Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0"
},
"frameworks": {
"uap10.0": {}
},
"runtimes": {
"win10-arm": {},
"win10-arm-aot": {},
"win10-x86": {},
"win10-x86-aot": {},
"win10-x64": {},
"win10-x64-aot": {}
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Some files were not shown because too many files have changed in this diff Show more