Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

added voltaic v10x driver and sample #1065

Merged
merged 1 commit into from
Aug 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<Project Sdk="Meadow.Sdk/1.1.0">
<PropertyGroup>
<Version>1.11.0</Version>
<Nullable>enable</Nullable>
<LangVersion>10.0</LangVersion>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageIcon>icon.png</PackageIcon>
<Authors>Wilderness Labs, Inc</Authors>
<TargetFramework>netstandard2.1</TargetFramework>
<OutputType>Library</OutputType>
<AssemblyName>V10x</AssemblyName>
<Company>Wilderness Labs, Inc</Company>
<PackageProjectUrl>http://developer.wildernesslabs.co/Meadow/Meadow.Foundation/</PackageProjectUrl>
<PackageId>Meadow.Foundation.Batteries.Voltaic.V10x</PackageId>
<RepositoryUrl>https://github.com/WildernessLabs/Meadow.Foundation</RepositoryUrl>
<PackageTags>Meadow,Meadow.Foundation,Battery,Solar Battery,Voltaic,V10x,V107</PackageTags>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Description>Voltaix V10x-series RS485 Modbus solar battery with charge controller</Description>
</PropertyGroup>
<ItemGroup>
<None Include="..\..\..\icon.png" Pack="true" PackagePath="" />
<ProjectReference Include="..\..\..\Meadow.Foundation.Core\Meadow.Foundation.Core.csproj" />
<ProjectReference Include="..\..\..\..\..\Meadow.Modbus\src\Meadow.Modbus\Meadow.Modbus.csproj" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
using Meadow.Modbus;
using Meadow.Units;
using System;

namespace Meadow.Foundation.Batteries.Voltaic;

/// <summary>
/// Represents a Voltaic Systems V10x solar charge controller and battery
/// </summary>
public class V10x : ModbusPolledDevice
{
private double _rawBatteryVoltage;
private double _rawInputVoltage;
private double _rawInputCurrent;
private double _rawLoadVoltage;
private double _rawLoadCurrent;
private double _rawEnvironmentTemp;
private double _rawControllerTemp;

private const ushort BatteryOutputSwitchRegister = 0;

/// <summary>
/// The default Modbus address for the V10x device.
/// </summary>
public const int DefaultModbusAddress = 1;

/// <summary>
/// The default baud rate for communication with the V10x device.
/// </summary>
public const int DefaultBaudRate = 9600;

/// <summary>
/// Gets the battery voltage.
/// </summary>
public Voltage BatteryVoltage => new Voltage(_rawBatteryVoltage, Voltage.UnitType.Volts);

/// <summary>
/// Gets the input voltage.
/// </summary>
public Voltage InputVoltage => new Voltage(_rawInputVoltage, Voltage.UnitType.Volts);

/// <summary>
/// Gets the input current.
/// </summary>
public Current InputCurrent => new Current(_rawInputCurrent, Current.UnitType.Amps);

/// <summary>
/// Gets the load voltage.
/// </summary>
public Voltage LoadVoltage => new Voltage(_rawLoadVoltage, Voltage.UnitType.Volts);

/// <summary>
/// Gets the load current.
/// </summary>
public Current LoadCurrent => new Current(_rawLoadCurrent, Current.UnitType.Amps);

/// <summary>
/// Gets the environment temperature.
/// </summary>
public Temperature EnvironmentTemp => new Temperature(_rawEnvironmentTemp, Temperature.UnitType.Celsius);

/// <summary>
/// Gets the controller temperature.
/// </summary>
public Temperature ControllerTemp => new Temperature(_rawControllerTemp, Temperature.UnitType.Celsius);

public V10x(
ModbusClientBase client,
byte modbusAddress = DefaultModbusAddress,
TimeSpan? refreshPeriod = null)
: base(client, modbusAddress, refreshPeriod)
{
MapInputRegistersToField(
startRegister: 0x30a0,
registerCount: 1,
fieldName: nameof(_rawBatteryVoltage),
conversionFunction: ConvertRegisterToRawValue
);

MapInputRegistersToField(
startRegister: 0x304e,
registerCount: 1,
fieldName: nameof(_rawInputVoltage),
conversionFunction: ConvertRegisterToRawValue
);

MapInputRegistersToField(
startRegister: 0x304f,
registerCount: 1,
fieldName: nameof(_rawInputCurrent),
conversionFunction: ConvertRegisterToRawValue
);

MapInputRegistersToField(
startRegister: 0x304a,
registerCount: 1,
fieldName: nameof(_rawLoadVoltage),
conversionFunction: ConvertRegisterToRawValue
);

MapInputRegistersToField(
startRegister: 0x304b,
registerCount: 1,
fieldName: nameof(_rawLoadCurrent),
conversionFunction: ConvertRegisterToRawValue
);

MapInputRegistersToField(
startRegister: 0x30a2,
registerCount: 1,
fieldName: nameof(_rawEnvironmentTemp),
conversionFunction: ConvertRegisterToRawValue
);

MapInputRegistersToField(
startRegister: 0x3037,
registerCount: 1,
fieldName: nameof(_rawControllerTemp),
conversionFunction: ConvertRegisterToRawValue
);
}

/// <summary>
/// Sets the battery output switch state.
/// </summary>
public bool BatteryOutput
{
set => _ = WriteCoil(BatteryOutputSwitchRegister, value);
}

private object ConvertRegisterToRawValue(ushort[] registers)
{
// value is one register in 1/100 of a unit
return registers[0] / 100d;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using Meadow;
using Meadow.Devices;
using Meadow.Foundation.Batteries.Voltaic;
using Meadow.Hardware;
using Meadow.Modbus;
using System;
using System.Diagnostics;
using System.Threading.Tasks;

namespace Batteries.Voltaic.V10x_Sample
{
public class MeadowApp : App<F7FeatherV2>
{
//<!=SNIP=>

public override async Task Run()
{
Resolver.Log.Info("Run...");

using (var port = new SerialPortShim("COM5", V10x.DefaultBaudRate, Parity.None, 8, StopBits.One))
{
port.ReadTimeout = TimeSpan.FromSeconds(15);
port.Open();

var client = new ModbusRtuClient(port);
var controller = new V10x(client);

controller.CommTimeout += (s, e) => Debug.WriteLine("Read Timeout");
controller.CommError += (s, e) => Debug.WriteLine($"Error: {e.Message}");

controller.StartPolling();

var i = 0;

while (true)
{
await Task.Delay(2000);
Debug.WriteLine($"---------------");
Debug.WriteLine($"Battery voltage: {controller.BatteryVoltage.Volts:N2} V");
Debug.WriteLine($"Input voltage: {controller.InputVoltage.Volts:N2} V");
Debug.WriteLine($"Input current: {controller.InputCurrent.Amps:N2} A");
Debug.WriteLine($"Load voltage: {controller.LoadVoltage.Volts:N2} V");
Debug.WriteLine($"Load current: {controller.LoadCurrent.Amps:N2} A");
Debug.WriteLine($"Environ temp: {controller.EnvironmentTemp.Fahrenheit:N2} F");
Debug.WriteLine($"Controller temp: {controller.ControllerTemp.Fahrenheit:N2} F");

controller.BatteryOutput = (i++ % 2 == 0);
}
}
}

//<!=SNOP=>
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Meadow.Sdk/1.1.0">
<PropertyGroup>
<RepositoryUrl>https://github.com/WildernessLabs/Meadow.Foundation</RepositoryUrl>
<Company>Wilderness Labs, Inc</Company>
<Authors>Wilderness Labs, Inc</Authors>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<TargetFramework>netstandard2.1</TargetFramework>
<OutputType>Library</OutputType>
<AssemblyName>App</AssemblyName>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\..\..\Meadow.Core\Source\implementations\f7\Meadow.F7\Meadow.F7.csproj" />
<ProjectReference Include="..\..\Driver\Batteries.Voltaic.V10x.csproj" />
</ItemGroup>
</Project>
51 changes: 51 additions & 0 deletions Source/Meadow.Foundation.sln
Original file line number Diff line number Diff line change
Expand Up @@ -1603,6 +1603,24 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PCanBasic_Sample", "Meadow.
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{97463BD7-A424-4720-B737-CB1D9A9C6AEF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RTCs.Pcf8523", "Meadow.Foundation.Peripherals\RTCs.Pcf8523\Driver\RTCs.Pcf8523.csproj", "{947BDDE4-3F2D-4521-AC9E-CF6DF9D6935D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Pcf8523", "Pcf8523", "{DA1B8F44-071F-492F-A1CA-66D656B9142E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{4BEF29DB-2912-4879-A010-D83AD2DF7D74}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Pcf8523_Sample", "Meadow.Foundation.Peripherals\RTCs.Pcf8523\Samples\Pcf8523_Sample\Pcf8523_Sample.csproj", "{35119A3C-8C47-47C9-A265-D5ACA418A68F}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Batteries", "Batteries", "{331683A5-17B3-429E-A74A-664BDF9F97B1}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "V10x", "V10x", "{D0A6D7E9-A1F0-4776-BA5B-202CFDBBB608}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Batteries.Voltaic.V10x", "Meadow.Foundation.Peripherals\Batteries.Voltaic.V10x\Driver\Batteries.Voltaic.V10x.csproj", "{56ADF95A-2ABC-4229-A13B-67CDA6DD1942}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{50BE5E08-199B-4D10-9B56-340C799B0E81}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "V10x_Sample", "Meadow.Foundation.Peripherals\Batteries.Voltaic.V10x\Samples\V10x_Sample\V10x_Sample.csproj", "{154268C0-1BC6-4A3E-A6CF-13E0FC4721F4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -3875,6 +3893,30 @@ Global
{506044BB-BEC1-42D1-AF84-CD28D4E2911A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{506044BB-BEC1-42D1-AF84-CD28D4E2911A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{506044BB-BEC1-42D1-AF84-CD28D4E2911A}.Release|Any CPU.Build.0 = Release|Any CPU
{947BDDE4-3F2D-4521-AC9E-CF6DF9D6935D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{947BDDE4-3F2D-4521-AC9E-CF6DF9D6935D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{947BDDE4-3F2D-4521-AC9E-CF6DF9D6935D}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{947BDDE4-3F2D-4521-AC9E-CF6DF9D6935D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{947BDDE4-3F2D-4521-AC9E-CF6DF9D6935D}.Release|Any CPU.Build.0 = Release|Any CPU
{947BDDE4-3F2D-4521-AC9E-CF6DF9D6935D}.Release|Any CPU.Deploy.0 = Release|Any CPU
{35119A3C-8C47-47C9-A265-D5ACA418A68F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{35119A3C-8C47-47C9-A265-D5ACA418A68F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{35119A3C-8C47-47C9-A265-D5ACA418A68F}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{35119A3C-8C47-47C9-A265-D5ACA418A68F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{35119A3C-8C47-47C9-A265-D5ACA418A68F}.Release|Any CPU.Build.0 = Release|Any CPU
{35119A3C-8C47-47C9-A265-D5ACA418A68F}.Release|Any CPU.Deploy.0 = Release|Any CPU
{56ADF95A-2ABC-4229-A13B-67CDA6DD1942}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{56ADF95A-2ABC-4229-A13B-67CDA6DD1942}.Debug|Any CPU.Build.0 = Debug|Any CPU
{56ADF95A-2ABC-4229-A13B-67CDA6DD1942}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{56ADF95A-2ABC-4229-A13B-67CDA6DD1942}.Release|Any CPU.ActiveCfg = Release|Any CPU
{56ADF95A-2ABC-4229-A13B-67CDA6DD1942}.Release|Any CPU.Build.0 = Release|Any CPU
{56ADF95A-2ABC-4229-A13B-67CDA6DD1942}.Release|Any CPU.Deploy.0 = Release|Any CPU
{154268C0-1BC6-4A3E-A6CF-13E0FC4721F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{154268C0-1BC6-4A3E-A6CF-13E0FC4721F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{154268C0-1BC6-4A3E-A6CF-13E0FC4721F4}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{154268C0-1BC6-4A3E-A6CF-13E0FC4721F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{154268C0-1BC6-4A3E-A6CF-13E0FC4721F4}.Release|Any CPU.Build.0 = Release|Any CPU
{154268C0-1BC6-4A3E-A6CF-13E0FC4721F4}.Release|Any CPU.Deploy.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -4673,6 +4715,15 @@ Global
{3D40446F-F902-4C89-93B9-2BE094BDE136} = {48CA0124-A227-4F35-BEFB-FF07F1CE6D20}
{506044BB-BEC1-42D1-AF84-CD28D4E2911A} = {3D40446F-F902-4C89-93B9-2BE094BDE136}
{97463BD7-A424-4720-B737-CB1D9A9C6AEF} = {066DBCFD-A21D-4FD2-87A5-B88363158149}
{947BDDE4-3F2D-4521-AC9E-CF6DF9D6935D} = {DA1B8F44-071F-492F-A1CA-66D656B9142E}
{DA1B8F44-071F-492F-A1CA-66D656B9142E} = {15C7A398-35B0-4035-AE4B-FE84026D0D9E}
{4BEF29DB-2912-4879-A010-D83AD2DF7D74} = {DA1B8F44-071F-492F-A1CA-66D656B9142E}
{35119A3C-8C47-47C9-A265-D5ACA418A68F} = {4BEF29DB-2912-4879-A010-D83AD2DF7D74}
{331683A5-17B3-429E-A74A-664BDF9F97B1} = {64623FCA-6086-4F0A-A59D-2BF372EA38AA}
{D0A6D7E9-A1F0-4776-BA5B-202CFDBBB608} = {331683A5-17B3-429E-A74A-664BDF9F97B1}
{56ADF95A-2ABC-4229-A13B-67CDA6DD1942} = {D0A6D7E9-A1F0-4776-BA5B-202CFDBBB608}
{50BE5E08-199B-4D10-9B56-340C799B0E81} = {D0A6D7E9-A1F0-4776-BA5B-202CFDBBB608}
{154268C0-1BC6-4A3E-A6CF-13E0FC4721F4} = {50BE5E08-199B-4D10-9B56-340C799B0E81}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {AF7CA16F-8C38-4546-87A2-5DAAF58A1520}
Expand Down
Loading