Skip to content

Commit b108f00

Browse files
NaglfarioEllerbach
andauthored
Driver DRV8825 for stepper motor was added (#1407)
Co-authored-by: Laurent Ellerbach <laurelle@microsoft.com>
1 parent a66a3ac commit b108f00

19 files changed

+964
-0
lines changed

devices/Drv8825/Direction.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
namespace Iot.Device.Drv8825
5+
{
6+
/// <summary>
7+
/// Motor rotation direction.
8+
/// </summary>
9+
public enum Direction
10+
{
11+
/// <summary>
12+
/// Rotation in the same direction as a clock's hands.
13+
/// </summary>
14+
Clockwise,
15+
16+
/// <summary>
17+
/// Rotation in the opposite direction to the movement of the hands of a clock.
18+
/// </summary>
19+
Counterclockwise
20+
}
21+
}

devices/Drv8825/Drv8825.cs

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Device;
6+
using System.Device.Gpio;
7+
using System.Threading;
8+
using UnitsNet;
9+
10+
namespace Iot.Device.Drv8825
11+
{
12+
/// <summary>
13+
/// Class for controlling Drv8825 stepper motor driver.
14+
/// </summary>
15+
public class Drv8825 : IDisposable
16+
{
17+
private readonly ushort _fullStepsPerRotation;
18+
private readonly GpioPin _stepPin;
19+
private readonly GpioPin _dirPin;
20+
private readonly GpioPin? _sleepPin;
21+
private readonly bool _shouldDisposeGpioController;
22+
private readonly MicrostepsController _microstepsController;
23+
24+
private GpioController? _gpioController;
25+
26+
/// <summary>
27+
/// Gets or sets the delay that allows the driver to recognize a step. By default, it is 5 microseconds.
28+
/// It is not recommended to set this delay less than 2 microseconds,
29+
/// otherwise the motor will "miss"(skip) some steps.
30+
/// And it is not recommended to set this delay more than 50 microseconds,
31+
/// otherwise the morot will stop recognize steps.
32+
/// </summary>
33+
public TimeSpan StepDelay { get; set; } = TimeSpan.FromTicks(5 * 10L);
34+
35+
/// <summary>
36+
/// Gets or sets delay between each step (or microstep).
37+
/// </summary>
38+
public TimeSpan DelayBetweenSteps { get; set; } = TimeSpan.Zero;
39+
40+
/// <summary>
41+
/// Initializes a new instance of the <see cref="Drv8825" /> class.
42+
/// </summary>
43+
/// <param name="stepPin">Microcontroller pin connected to STEP driver pin. Used to set steps count.</param>
44+
/// <param name="dirPin">Microcontroller pin connected to DIR driver pin. Used to set rotation direction.</param>
45+
/// <param name="sleepPin">Microcontroller pin connected to SLP driver pin. Used to wake up and put the driver to sleep. Usually SLP need to connect with RST pin.</param>
46+
/// <param name="fullStepsPerRotation">How many steps your motor need to make full rotation. For example, Nema 17 takes 200 full steps to complete full rotation.</param>
47+
/// <param name="gpioController">GPIO controller. If it not passed, then it be created here.</param>
48+
/// <param name="shouldDisposeGpioController">True to dispose the Gpio Controller when this class wiill be disposed.</param>
49+
/// <param name="m0Pin">Microcontroller pin connected to M0 driver pin. Can be used to microsteps control. 0 if not connected.</param>
50+
/// <param name="m1Pin">Microcontroller pin connected to M1 driver pin. Can be used to microsteps control. 0 if not connected.</param>
51+
/// <param name="m2Pin">Microcontroller pin connected to M2 driver pin. Can be used to microsteps control. 0 if not connected.</param>
52+
public Drv8825(
53+
byte stepPin,
54+
byte dirPin,
55+
byte sleepPin = 0,
56+
ushort fullStepsPerRotation = 200,
57+
GpioController? gpioController = null,
58+
bool shouldDisposeGpioController = true,
59+
byte m0Pin = 0,
60+
byte m1Pin = 0,
61+
byte m2Pin = 0)
62+
{
63+
_fullStepsPerRotation = fullStepsPerRotation;
64+
_gpioController = gpioController ?? new GpioController();
65+
_shouldDisposeGpioController = shouldDisposeGpioController || gpioController is null;
66+
_stepPin = _gpioController.OpenPin(stepPin, PinMode.Output);
67+
_dirPin = _gpioController.OpenPin(dirPin, PinMode.Output);
68+
69+
if (sleepPin > 0)
70+
{
71+
_sleepPin = _gpioController.OpenPin(sleepPin, PinMode.Output);
72+
}
73+
74+
_microstepsController = new MicrostepsController(_gpioController, m0Pin, m1Pin, m2Pin);
75+
}
76+
77+
/// <summary>
78+
/// Switch driver to working mode.
79+
/// </summary>
80+
/// <exception cref="InvalidOperationException">Throws when sleep pin doesn't passed.</exception>
81+
public void WakeUp()
82+
{
83+
if (_sleepPin == null)
84+
{
85+
throw new InvalidOperationException("Sleep pin does not passed. Try to create driver class with sleepPin param");
86+
}
87+
88+
_sleepPin.Write(PinValue.High);
89+
}
90+
91+
/// <summary>
92+
/// Switch driver to sleep mode.
93+
/// </summary>
94+
/// <param name="millisecondsDelay">The number of milliseconds to wait before going to sleep. Use if you want give to driver time to process all previously sent steps.</param>
95+
/// <exception cref="InvalidOperationException">Throws when sleep pin doesn't passed.</exception>
96+
public void Sleep(int millisecondsDelay = 0)
97+
{
98+
if (_sleepPin == null)
99+
{
100+
throw new InvalidOperationException("Sleep pin does not passed. Try to create driver class with sleepPin param");
101+
}
102+
103+
if (millisecondsDelay > 0)
104+
{
105+
Thread.Sleep(millisecondsDelay);
106+
}
107+
108+
_sleepPin.Write(PinValue.Low);
109+
}
110+
111+
/// <summary>
112+
/// Rotates a stepper motor.
113+
/// </summary>
114+
/// <param name="angle">Angle to rotate.</param>
115+
/// <param name="stepSize">Step size.</param>
116+
public void Rotate(Angle angle, StepSize stepSize = StepSize.FullStep)
117+
{
118+
if (angle.Degrees == 0)
119+
{
120+
return;
121+
}
122+
123+
_dirPin.Write(angle.Degrees > 0 ? PinValue.High : PinValue.Low);
124+
var degreeForStepsCalculation = angle.Degrees < 0 ? -angle.Degrees : angle.Degrees;
125+
var pulses = degreeForStepsCalculation / 360 * _fullStepsPerRotation * (byte)stepSize;
126+
127+
_microstepsController.Set(stepSize);
128+
Rotate((int)pulses);
129+
}
130+
131+
/// <summary>
132+
/// Rotates a stepper motor.
133+
/// </summary>
134+
/// <param name="steps">Steps count.</param>
135+
/// <param name="direction">True to go forward, false to go back(or vice versa if you connect the motor in the opposite direction).</param>
136+
/// <param name="size">Step size.</param>
137+
public virtual void Rotate(
138+
int steps,
139+
Direction direction = Direction.Clockwise,
140+
StepSize size = StepSize.FullStep)
141+
{
142+
if (steps == 0)
143+
{
144+
return;
145+
}
146+
147+
_microstepsController.Set(size);
148+
_dirPin.Write(direction == Direction.Clockwise ? PinValue.High : PinValue.Low);
149+
150+
Rotate(steps);
151+
}
152+
153+
/// <summary>
154+
/// <inheritdoc/>
155+
/// </summary>
156+
public void Dispose()
157+
{
158+
if (_shouldDisposeGpioController)
159+
{
160+
_gpioController?.Dispose();
161+
}
162+
163+
_gpioController = null;
164+
}
165+
166+
/// <summary>
167+
/// Controls the speed of rotation.
168+
/// </summary>
169+
private void SleepBetweenSteps()
170+
{
171+
if (DelayBetweenSteps == TimeSpan.Zero)
172+
{
173+
return;
174+
}
175+
176+
Thread.Sleep(DelayBetweenSteps);
177+
}
178+
179+
/// <summary>
180+
/// Rotates a stepper motor.
181+
/// </summary>
182+
/// <param name="steps">Steps count.</param>
183+
private void Rotate(int steps)
184+
{
185+
for (var i = 0; i < steps; i++)
186+
{
187+
_stepPin.Write(PinValue.High);
188+
Thread.Sleep(StepDelay);
189+
_stepPin.Write(PinValue.Low);
190+
SleepBetweenSteps();
191+
}
192+
}
193+
}
194+
}

devices/Drv8825/Drv8825.nfproj

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="Current" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<Import Project="packages\Nerdbank.GitVersioning.3.7.115\build\Nerdbank.GitVersioning.props" Condition="Exists('packages\Nerdbank.GitVersioning.3.7.115\build\Nerdbank.GitVersioning.props')" />
4+
<PropertyGroup Label="Globals">
5+
<NanoFrameworkProjectSystemPath>$(MSBuildExtensionsPath)\nanoFramework\v1.0\</NanoFrameworkProjectSystemPath>
6+
<Nullable>enable</Nullable>
7+
</PropertyGroup>
8+
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.Default.props" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.Default.props')" />
9+
<PropertyGroup>
10+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
11+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
12+
<ProjectTypeGuids>{11A8DD76-328B-46DF-9F39-F559912D0360};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
13+
<ProjectGuid>5aae94ba-29f0-4004-8404-1a5095698531</ProjectGuid>
14+
<OutputType>Library</OutputType>
15+
<AppDesignerFolder>Properties</AppDesignerFolder>
16+
<FileAlignment>512</FileAlignment>
17+
<RootNamespace>Iot.Device.Drv8825</RootNamespace>
18+
<AssemblyName>Iot.Device.Drv8825</AssemblyName>
19+
<TargetFrameworkVersion>v1.0</TargetFrameworkVersion>
20+
<DocumentationFile>bin\$(Configuration)\Iot.Device.Drv8825.xml</DocumentationFile>
21+
<LangVersion>9.0</LangVersion>
22+
<StyleCopTreatErrorsAsWarnings>false</StyleCopTreatErrorsAsWarnings>
23+
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
24+
<RestoreLockedMode Condition="'$(TF_BUILD)' == 'True' or '$(ContinuousIntegrationBuild)' == 'True'">true</RestoreLockedMode>
25+
<SignAssembly>true</SignAssembly>
26+
<AssemblyOriginatorKeyFile>..\key.snk</AssemblyOriginatorKeyFile>
27+
<DelaySign>false</DelaySign>
28+
</PropertyGroup>
29+
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.props" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.props')" />
30+
<ItemGroup>
31+
<Reference Include="mscorlib, Version=1.17.11.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
32+
<HintPath>packages\nanoFramework.CoreLibrary.1.17.11\lib\mscorlib.dll</HintPath>
33+
</Reference>
34+
<Reference Include="nanoFramework.Runtime.Events, Version=1.11.32.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
35+
<HintPath>packages\nanoFramework.Runtime.Events.1.11.32\lib\nanoFramework.Runtime.Events.dll</HintPath>
36+
</Reference>
37+
<Reference Include="System.Device.Gpio, Version=1.1.57.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
38+
<HintPath>packages\nanoFramework.System.Device.Gpio.1.1.57\lib\System.Device.Gpio.dll</HintPath>
39+
</Reference>
40+
<Reference Include="System.Math, Version=1.5.116.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
41+
<HintPath>packages\nanoFramework.System.Math.1.5.116\lib\System.Math.dll</HintPath>
42+
</Reference>
43+
<Reference Include="UnitsNet.Angle, Version=5.75.0.0, Culture=neutral, PublicKeyToken=null">
44+
<HintPath>packages\UnitsNet.nanoFramework.Angle.5.75.0\lib\UnitsNet.Angle.dll</HintPath>
45+
</Reference>
46+
</ItemGroup>
47+
<ItemGroup>
48+
<None Include="packages.config" />
49+
<Compile Include="Direction.cs" />
50+
<Compile Include="Drv8825.cs" />
51+
<Compile Include="StepSize.cs" />
52+
<Compile Include="MicrostepsController.cs" />
53+
<None Include="README.md" />
54+
<Compile Include="Properties\AssemblyInfo.cs" />
55+
</ItemGroup>
56+
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.CSharp.targets" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.CSharp.targets')" />
57+
<ProjectExtensions>
58+
<ProjectCapabilities>
59+
<ProjectConfigurationsDeclaredAsItems />
60+
</ProjectCapabilities>
61+
</ProjectExtensions>
62+
<Import Project="packages\StyleCop.MSBuild.6.2.0\build\StyleCop.MSBuild.targets" Condition="Exists('packages\StyleCop.MSBuild.6.2.0\build\StyleCop.MSBuild.targets')" />
63+
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
64+
<PropertyGroup>
65+
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
66+
</PropertyGroup>
67+
<Error Condition="!Exists('packages\StyleCop.MSBuild.6.2.0\build\StyleCop.MSBuild.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\StyleCop.MSBuild.6.2.0\build\StyleCop.MSBuild.targets'))" />
68+
<Error Condition="!Exists('packages\Nerdbank.GitVersioning.3.7.115\build\Nerdbank.GitVersioning.props')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Nerdbank.GitVersioning.3.7.115\build\Nerdbank.GitVersioning.props'))" />
69+
<Error Condition="!Exists('packages\Nerdbank.GitVersioning.3.7.115\build\Nerdbank.GitVersioning.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Nerdbank.GitVersioning.3.7.115\build\Nerdbank.GitVersioning.targets'))" />
70+
</Target>
71+
<Import Project="packages\Nerdbank.GitVersioning.3.7.115\build\Nerdbank.GitVersioning.targets" Condition="Exists('packages\Nerdbank.GitVersioning.3.7.115\build\Nerdbank.GitVersioning.targets')" />
72+
</Project>

devices/Drv8825/Drv8825.nuspec

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
3+
<metadata>
4+
<id>nanoFramework.Iot.Device.Drv8825</id>
5+
<version>$version$</version>
6+
<title>nanoFramework.Iot.Device.Drv8825</title>
7+
<authors>nanoframework</authors>
8+
<requireLicenseAcceptance>false</requireLicenseAcceptance>
9+
<license type="file">LICENSE.md</license>
10+
<releaseNotes>
11+
</releaseNotes>
12+
<readme>docs\README.md</readme>
13+
<developmentDependency>false</developmentDependency>
14+
<projectUrl>https://github.com/nanoframework/nanoFramework.IoT.Device</projectUrl>
15+
<icon>images\nf-logo.png</icon>
16+
<repository type="git" url="https://github.com/nanoframework/nanoFramework.IoT.Device" commit="$commit$" />
17+
<copyright>Copyright (c) .NET Foundation and Contributors</copyright>
18+
<description>This package includes the .NET IoT Core binding Iot.Device.Drv8825 for .NET nanoFramework C# projects.</description>
19+
<summary>Iot.Device.Drv8825 assembly for .NET nanoFramework C# projects</summary>
20+
<tags>nanoFramework C# csharp netmf netnf Iot.Device.Drv8825 Drv8825</tags>
21+
<dependencies>
22+
<dependency id="nanoFramework.CoreLibrary" version="1.17.11" />
23+
<dependency id="nanoFramework.Runtime.Events" version="1.11.32" />
24+
<dependency id="nanoFramework.System.Device.Gpio" version="1.1.57" />
25+
<dependency id="nanoFramework.System.Math" version="1.5.116" />
26+
<dependency id="UnitsNet.nanoFramework.Angle" version="5.75.0" />
27+
</dependencies>
28+
</metadata>
29+
<files>
30+
<file src="bin\Release\Iot.Device.Drv8825.dll" target="lib\Iot.Device.Drv8825.dll" />
31+
<file src="bin\Release\Iot.Device.Drv8825.pdb" target="lib\Iot.Device.Drv8825.pdb" />
32+
<file src="bin\Release\Iot.Device.Drv8825.pdbx" target="lib\Iot.Device.Drv8825.pdbx" />
33+
<file src="bin\Release\Iot.Device.Drv8825.pe" target="lib\Iot.Device.Drv8825.pe" />
34+
<file src="bin\Release\Iot.Device.Drv8825.xml" target="lib\Iot.Device.Drv8825.xml" />
35+
<file src="README.md" target="docs\" />
36+
<file src="..\..\assets\nf-logo.png" target="images" />
37+
<file src="..\..\LICENSE.md" target="" />
38+
</files>
39+
</package>

devices/Drv8825/Drv8825.sln

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.14.36203.30
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{11A8DD76-328B-46DF-9F39-F559912D0360}") = "Drv8825", "Drv8825.nfproj", "{5AAE94BA-29F0-4004-8404-1A5095698531}"
7+
EndProject
8+
Project("{11A8DD76-328B-46DF-9F39-F559912D0360}") = "Drv8825.samples", "samples\Drv8825.samples.nfproj", "{E8798205-E0D7-443F-B96A-8F752B7EF454}"
9+
EndProject
10+
Global
11+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
12+
Debug|Any CPU = Debug|Any CPU
13+
Release|Any CPU = Release|Any CPU
14+
EndGlobalSection
15+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
16+
{5AAE94BA-29F0-4004-8404-1A5095698531}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17+
{5AAE94BA-29F0-4004-8404-1A5095698531}.Debug|Any CPU.Build.0 = Debug|Any CPU
18+
{5AAE94BA-29F0-4004-8404-1A5095698531}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
19+
{5AAE94BA-29F0-4004-8404-1A5095698531}.Release|Any CPU.ActiveCfg = Release|Any CPU
20+
{5AAE94BA-29F0-4004-8404-1A5095698531}.Release|Any CPU.Build.0 = Release|Any CPU
21+
{5AAE94BA-29F0-4004-8404-1A5095698531}.Release|Any CPU.Deploy.0 = Release|Any CPU
22+
{E8798205-E0D7-443F-B96A-8F752B7EF454}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23+
{E8798205-E0D7-443F-B96A-8F752B7EF454}.Debug|Any CPU.Build.0 = Debug|Any CPU
24+
{E8798205-E0D7-443F-B96A-8F752B7EF454}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
25+
{E8798205-E0D7-443F-B96A-8F752B7EF454}.Release|Any CPU.ActiveCfg = Release|Any CPU
26+
{E8798205-E0D7-443F-B96A-8F752B7EF454}.Release|Any CPU.Build.0 = Release|Any CPU
27+
{E8798205-E0D7-443F-B96A-8F752B7EF454}.Release|Any CPU.Deploy.0 = Release|Any CPU
28+
EndGlobalSection
29+
GlobalSection(SolutionProperties) = preSolution
30+
HideSolutionNode = FALSE
31+
EndGlobalSection
32+
GlobalSection(ExtensibilityGlobals) = postSolution
33+
SolutionGuid = {724AA4FB-36FD-46CB-ADB0-63E6CA4C322F}
34+
EndGlobalSection
35+
EndGlobal
68.8 KB
Loading

0 commit comments

Comments
 (0)