Compare commits

...
5 Commits
17 changed files with 457 additions and 89 deletions
+1
View File
@@ -1,3 +1,4 @@
charger-gui/.vs/
charger-gui/bin/
charger-gui/obj/
charger-gui/publish/
+29 -15
View File
@@ -36,31 +36,45 @@
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" FontSize="20" Text="I_acc"/>
<TextBlock Grid.Row="0" Grid.Column="1" FontSize="20" Text="{Binding Path=IAcc,Mode=OneWay,StringFormat=F4}" />
<TextBlock Grid.Row="1" Grid.Column="0" FontSize="20" Text="U1_acc"/>
<TextBlock Grid.Row="1" Grid.Column="1" FontSize="20" Text="{Binding Path=U1Acc,Mode=OneWay,StringFormat=F4}" />
<TextBlock Grid.Row="2" Grid.Column="0" FontSize="20" Text="U2_acc"/>
<TextBlock Grid.Row="2" Grid.Column="1" FontSize="20" Text="{Binding Path=U2Acc,Mode=OneWay,StringFormat=F4}" />
<TextBlock Grid.Row="3" Grid.Column="0" FontSize="20" Text="I_lamp"/>
<TextBlock Grid.Row="3" Grid.Column="1" FontSize="20" Text="{Binding Path=ILamp,Mode=OneWay,StringFormat=F4}" />
<TextBlock Grid.Row="4" Grid.Column="0" FontSize="20" Text="U1_lamp"/>
<TextBlock Grid.Row="4" Grid.Column="1" FontSize="20" Text="{Binding Path=U1Lamp,Mode=OneWay,StringFormat=F4}" />
<TextBlock Grid.Row="5" Grid.Column="0" FontSize="20" Text="U2_lamp"/>
<TextBlock Grid.Row="5" Grid.Column="1" FontSize="20" Text="{Binding Path=U2Lamp,Mode=OneWay,StringFormat=F4}" />
<TextBlock Grid.Row="6" Grid.Column="0" FontSize="20" Text="CHARGE"/>
<Ellipse Grid.Row="6" Grid.Column="1" Width="20" Height="20" Fill="{Binding Path=ChargeStatus,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Grid.Row="7" Grid.Column="0" FontSize="20" Text="LAMP"/>
<Ellipse Grid.Row="7" Grid.Column="1" Width="20" Height="20" Fill="{Binding Path=LampStatus,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Grid.Row="0" Grid.Column="1" FontSize="20" Text="{Binding Path=IReal,Mode=OneWay,StringFormat=F4}" />
<TextBlock Grid.Row="1" Grid.Column="0" FontSize="20" Text="U_acc"/>
<TextBlock Grid.Row="1" Grid.Column="1" FontSize="20" Text="{Binding Path=UAcc,Mode=OneWay,StringFormat=F4}" />
<TextBlock Grid.Row="2" Grid.Column="0" FontSize="20" Text="I_raw"/>
<TextBlock Grid.Row="2" Grid.Column="1" FontSize="20" Text="{Binding Path=IRaw,Mode=OneWay,StringFormat=F4}" />
<TextBlock Grid.Row="3" Grid.Column="0" FontSize="20" Text="U2"/>
<TextBlock Grid.Row="3" Grid.Column="1" FontSize="20" Text="{Binding Path=U2,Mode=OneWay,StringFormat=F4}" />
<TextBlock Grid.Row="4" Grid.Column="0" FontSize="20" Text="U3"/>
<TextBlock Grid.Row="4" Grid.Column="1" FontSize="20" Text="{Binding Path=U3,Mode=OneWay,StringFormat=F4}" />
<TextBlock Grid.Row="5" Grid.Column="0" FontSize="20" Text="U4"/>
<TextBlock Grid.Row="5" Grid.Column="1" FontSize="20" Text="{Binding Path=U4,Mode=OneWay,StringFormat=F4}" />
<TextBlock Grid.Row="6" Grid.Column="0" FontSize="20" Text="U5"/>
<TextBlock Grid.Row="6" Grid.Column="1" FontSize="20" Text="{Binding Path=U5,Mode=OneWay,StringFormat=F4}" />
<TextBlock Grid.Row="7" Grid.Column="0" FontSize="20" Text="CHARGE"/>
<Ellipse Grid.Row="7" Grid.Column="1" Width="20" Height="20" Fill="{Binding Path=ChargeStatus,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}" />
<TextBlock Grid.Row="8" Grid.Column="0" FontSize="20" Text="LAMP"/>
<Ellipse Grid.Row="8" Grid.Column="1" Width="20" Height="20" Fill="{Binding Path=LampStatus,Mode=OneWay,UpdateSourceTrigger=PropertyChanged}" />
</Grid>
<StackPanel Grid.Row="1" Grid.Column="1">
<TextBlock FontSize="24" Text="MANUAL"/>
<Button Content="Flip Lamp" Height="40" Click="LampButton_Click"/>
<Button Content="Flip Charge" Height="40" Click="FlipChargeButton_Click"/>
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="2">
<TextBlock FontSize="24" Text="AUTO"/>
<Button Content="Discharge" Height="40" Click="DischargeButton_Click"/>
<Button Content="Сharge" Height="40" Click="ChargeButton_Click"/>
<Button Content="Calibrate I" Height="40" Click="CalibrateButton_Click"/>
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="3">
<TextBlock FontSize="24" Text="TRAIN"/>
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="20" Text="Duration (s)" Height="40"/>
<TextBox Text="{Binding Path=TrainDuration}" FontSize="20" MinWidth="60"/>
</StackPanel>
<Button Content="GO" Height="40" Click="TrainButton_Click"/>
</StackPanel>
<TextBlock Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="4" Text="{Binding Path=OperationStatus,Mode=OneWay}" />
</Grid>
+25
View File
@@ -60,6 +60,16 @@ namespace charger_gui
model.IsCharging = !model.IsCharging;
}
private void CalibrateButton_Click(object sender, RoutedEventArgs e)
{
if (model.CurrentOperation != null)
{
model.CurrentOperation.Cancel();
}
model.CurrentOperation = new CalibrateOperation(log, model);
model.CurrentOperation.Start();
}
private void DischargeButton_Click(object sender, RoutedEventArgs e)
{
if (model.CurrentOperation != null)
@@ -79,5 +89,20 @@ namespace charger_gui
model.CurrentOperation = new ChargeOperation(log, model);
model.CurrentOperation.Start();
}
private void TrainButton_Click(object sender, RoutedEventArgs e)
{
if (model.CurrentOperation != null)
{
model.CurrentOperation.Cancel();
}
model.CurrentOperation = new TrainOperation(log, model, model.TrainDuration);
model.CurrentOperation.Start();
}
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
Environment.Exit(0);
}
}
}
+45 -37
View File
@@ -1,10 +1,7 @@
using charger_gui.operations;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Windows.Media;
namespace charger_gui
@@ -24,87 +21,93 @@ namespace charger_gui
}
}
private float iAcc;
public float IAcc
private float iRaw;
public float IRaw
{
get
{
return iAcc;
return iRaw;
}
set
{
iAcc = value;
OnPropertyChanged("IAcc");
iRaw = value;
OnPropertyChanged("IRaw");
OnPropertyChanged("IReal");
}
}
public float IZero { get; internal set; }
public float IReal
{
get
{
return IRaw - IZero;
}
}
private float u1Acc;
public float U1Acc
private float u2;
public float U2
{
get
{
return u1Acc;
return u2;
}
set
{
u1Acc = value;
OnPropertyChanged("U1Acc");
u2 = value;
OnPropertyChanged("U2");
}
}
private float u2Acc;
public float U2Acc
private float u3;
public float U3
{
get
{
return u2Acc;
return u3;
}
set
{
u2Acc = value;
OnPropertyChanged("U2Acc");
u3 = value;
OnPropertyChanged("U3");
OnPropertyChanged("UAcc");
}
}
private float iLamp;
public float ILamp
private float u4;
public float U4
{
get
{
return iLamp;
return u4;
}
set
{
iLamp = value;
OnPropertyChanged("ILamp");
u4 = value;
OnPropertyChanged("U4");
}
}
private float u1Lamp;
public float U1Lamp
private float u5;
public float U5
{
get
{
return u1Lamp;
return u5;
}
set
{
u1Lamp = value;
OnPropertyChanged("U1Lamp");
u5 = value;
OnPropertyChanged("U5");
OnPropertyChanged("UAcc");
}
}
private float u2Lamp;
public float U2Lamp
public float UAcc
{
get
{
return u2Lamp;
}
set
{
u2Lamp = value;
OnPropertyChanged("U2Lamp");
return U3 - U5;
}
}
@@ -190,7 +193,10 @@ namespace charger_gui
currentOperation.StatusChanged -= OnCurrentOperationStatusChanged;
}
currentOperation = value;
currentOperation.StatusChanged += OnCurrentOperationStatusChanged;
if (currentOperation != null)
{
currentOperation.StatusChanged += OnCurrentOperationStatusChanged;
}
OnPropertyChanged("OperationStatus");
}
}
@@ -209,6 +215,8 @@ namespace charger_gui
}
}
public int TrainDuration { get; set; }
private void FillPorts()
{
ports = new List<string>(SerialPort.GetPortNames());
+73
View File
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app" />
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- Параметры манифеста UAC
Если вы хотите изменить уровень контроля учетных записей Windows, замените узел
requestedExecutionLevel на один из следующих.
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
При указании элемента requestedExecutionLevel будет отключена виртуализация файлов и реестра.
Удалите этот элемент, если виртуализация требуется приложению для обратной
совместимости.
-->
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
<applicationRequestMinimum>
<defaultAssemblyRequest permissionSetReference="Custom" />
<PermissionSet class="System.Security.PermissionSet" version="1" Unrestricted="true" ID="Custom" SameSite="site" />
</applicationRequestMinimum>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Список версий Windows, на которых это приложение было протестировано
и будет работать. Раскомментируйте соответствующие элементы, чтобы ОС Windows
автоматически выбрала наиболее совместимое окружение. -->
<!-- Windows Vista -->
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
<!-- Windows 7 -->
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->
<!-- Windows 8 -->
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->
<!-- Windows 8.1 -->
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->
<!-- Windows 10 -->
<!--<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />-->
</application>
</compatibility>
<!-- Указывает, что приложение поддерживает определение DPI и не будет автоматически масштабироваться Windows при более высоких
значениях DPI. Приложения Windows Presentation Foundation (WPF) по умолчанию поддерживают определение DPI, им не нужно
специально включать параметр для этого. Для приложений Windows Forms на платформе .NET Framework 4.6, для которых задан этот параметр, необходимо
также задать для "EnableWindowsFormsHighDpiAutoResizing" значение "true" в файле app.config.
При этом приложение начинает учитывать длинные пути. Дополнительные сведения см. на странице https://docs.microsoft.com/windows/win32/fileio/maximum-file-path-limitation.-->
<!--
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
</windowsSettings>
</application>
-->
<!-- Включите темы для общих элементов управления и диалоговых окон Windows (Windows XP и более поздние версии) -->
<!--
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
-->
</assembly>
+6 -7
View File
@@ -67,14 +67,13 @@ namespace charger_gui
IModbusSerialMaster master = ModbusSerialMaster.CreateRtu(serialPort);
while (!shouldRestart)
{
var r1 = master.ReadHoldingRegisters(SLAVE_ADDRESS, 0, 4);
model.IAcc = ToFloat(r1[0], r1[1]);
model.ILamp = ToFloat(r1[2], r1[3]);
var r1 = master.ReadHoldingRegisters(SLAVE_ADDRESS, 0, 2);
model.IRaw = ToFloat(r1[0], r1[1]);
var r2 = master.ReadHoldingRegisters(SLAVE_ADDRESS, 6, 8);
model.U1Acc = ToFloat(r2[0], r2[1]);
model.U2Acc = ToFloat(r2[2], r2[3]);
model.U1Lamp = ToFloat(r2[4], r2[5]);
model.U2Lamp = ToFloat(r2[6], r2[7]);
model.U2 = ToFloat(r2[0], r2[1]);
model.U3 = ToFloat(r2[2], r2[3]);
model.U4 = ToFloat(r2[4], r2[5]);
model.U5 = ToFloat(r2[6], r2[7]);
master.WriteSingleRegister(SLAVE_ADDRESS, CHARGE_REGISTER, (ushort)(model.IsCharging ? 1 : 0));
master.WriteSingleRegister(SLAVE_ADDRESS, LAMP_REGISTER, (ushort)(model.IsLampOn ? 1 : 0));
// ничего не упало, коннект есть значит
+45
View File
@@ -13,6 +13,22 @@
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<Deterministic>true</Deterministic>
<IsWebBootstrapper>false</IsWebBootstrapper>
<PublishUrl>W:\temp\charger-gui\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>4</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<PublishWizardCompleted>true</PublishWizardCompleted>
<BootstrapperEnabled>false</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@@ -33,6 +49,24 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ManifestCertificateThumbprint>BEEA544097F13D7DCC301EAB82DAD11595FA2626</ManifestCertificateThumbprint>
</PropertyGroup>
<PropertyGroup>
<ManifestKeyFile>charger-gui_TemporaryKey.pfx</ManifestKeyFile>
</PropertyGroup>
<PropertyGroup>
<GenerateManifests>true</GenerateManifests>
</PropertyGroup>
<PropertyGroup>
<SignManifests>false</SignManifests>
</PropertyGroup>
<PropertyGroup>
<TargetZone>LocalIntranet</TargetZone>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>Properties\app.manifest</ApplicationManifest>
</PropertyGroup>
<ItemGroup>
<Reference Include="NModbus4, Version=2.1.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>packages\NModbus4.2.1.0\lib\net40\NModbus4.dll</HintPath>
@@ -58,6 +92,8 @@
</ApplicationDefinition>
<Compile Include="Logger.cs" />
<Compile Include="operations\AutomaticOperation.cs" />
<Compile Include="operations\CalibrateOperation.cs" />
<Compile Include="operations\TrainOperation.cs" />
<Compile Include="operations\ChargeOperation.cs" />
<Compile Include="operations\DischargeOperation.cs" />
<Compile Include="UpdateWorker.cs" />
@@ -93,11 +129,20 @@
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="charger-gui_TemporaryKey.pfx" />
<None Include="packages.config" />
<None Include="Properties\app.manifest" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
+16
View File
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishUrlHistory>W:\temp\charger-gui\|C:\Work\charger\charger-gui\publish\</PublishUrlHistory>
<InstallUrlHistory />
<SupportUrlHistory />
<UpdateUrlHistory />
<BootstrapperUrlHistory />
<ErrorReportUrlHistory />
<FallbackCulture>ru-RU</FallbackCulture>
<VerifyUploadedFiles>false</VerifyUploadedFiles>
</PropertyGroup>
<PropertyGroup>
<EnableSecurityDebugging>false</EnableSecurityDebugging>
</PropertyGroup>
</Project>
Binary file not shown.
@@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace charger_gui.operations
{
class CalibrateOperation : AutomaticOperation
{
const float SECONDS_TO_PASS = 10f;
private int passed;
private bool isComplete = false;
public override string Status
{
get
{
if (isComplete) return "Calibrating complete in " + passed + " seconds";
else return "Calibrating, passed " + passed + " seconds";
}
}
public CalibrateOperation(Logger log, MainWindowViewModel model) : base(log, model)
{
}
protected override void Work()
{
log.Log("Calibrating started");
var start = DateTime.Now;
model.IsCharging = false;
model.IsLampOn = false;
Thread.Sleep(500);
float sum = 0;
int cnt = 0;
while (passed < SECONDS_TO_PASS)
{
Thread.Sleep(20);
sum += model.IRaw;
cnt++;
passed = (int)((DateTime.Now - start).TotalSeconds);
OnStatusChanged();
}
model.IZero = sum / cnt;
log.Log("Calibrating complete in " + passed + " seconds");
model.IsLampOn = false;
isComplete = true;
OnStatusChanged();
}
}
}
+5 -4
View File
@@ -32,18 +32,19 @@ namespace charger_gui.operations
model.IsCharging = true;
model.IsLampOn = false;
Thread.Sleep(500);
while (model.U2Acc < MAX_VOLTAGE)
while (model.UAcc < MAX_VOLTAGE)
{
Thread.Sleep(1000);
passed = (int)((DateTime.Now - start).TotalSeconds);
OnStatusChanged();
log.Log("Charging " + passed + "s " + model.U2Acc.ToString("F4"));
if (model.U1Acc < 10f)
log.Log("Charging " + passed + "s " + model.UAcc.ToString("F4"));
if (model.U2 < 10f)
{
log.Log("Charging error: NO POWER. " + model.U1Acc.ToString("F4"));
log.Log("Charging error: NO POWER. " + model.U2.ToString("F4"));
}
}
log.Log("Charging complete in " + passed + " seconds");
model.IsCharging = false;
isComplete = true;
OnStatusChanged();
}
+3 -2
View File
@@ -32,14 +32,15 @@ namespace charger_gui.operations
model.IsCharging = false;
model.IsLampOn = true;
Thread.Sleep(500);
while (model.U2Acc > MIN_VOLTAGE)
while (model.UAcc > MIN_VOLTAGE)
{
Thread.Sleep(1000);
passed = (int)((DateTime.Now - start).TotalSeconds);
OnStatusChanged();
log.Log("Discharging " + passed + "s " + model.U2Acc.ToString("F4"));
log.Log("Discharging " + passed + "s " + model.U3.ToString("F4"));
}
log.Log("Discharging complete in " + passed + " seconds");
model.IsLampOn = false;
isComplete = true;
OnStatusChanged();
}
+63
View File
@@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace charger_gui.operations
{
class TrainOperation : AutomaticOperation
{
const float MAX_VOLTAGE = 14.5f;
private int passed;
private bool isComplete = false;
private int duration;
public override string Status
{
get
{
if (isComplete) return "Training complete in " + passed + " seconds";
else return "Training, passed " + passed + " seconds (of " + duration + ")";
}
}
public TrainOperation(Logger log, MainWindowViewModel model, int duration) : base(log, model)
{
this.duration = duration;
}
protected override void Work()
{
log.Log("Training started");
var start = DateTime.Now;
while (passed < duration)
{
model.IsCharging = true;
model.IsLampOn = false;
Thread.Sleep(1000);
model.IsCharging = false;
model.IsLampOn = false;
Thread.Sleep(50);
model.IsCharging = false;
model.IsLampOn = true;
Thread.Sleep(1000);
model.IsCharging = false;
model.IsLampOn = false;
Thread.Sleep(50);
passed = (int)((DateTime.Now - start).TotalSeconds);
OnStatusChanged();
log.Log("Training" + passed + "s " + model.UAcc.ToString("F4"));
if (model.U2 < 10f)
{
log.Log("Training error: NO POWER. " + model.U2.ToString("F4"));
}
}
log.Log("Training complete in " + passed + " seconds");
model.IsCharging = false;
model.IsLampOn = false;
isComplete = true;
OnStatusChanged();
}
}
}
BIN
View File
Binary file not shown.
+94 -24
View File
@@ -1,13 +1,69 @@
#include <ModbusRTU.h>
class Reader
{
const static int AMOUNT = 20;
const static int FILTER_SIZE = 5;
int pin;
int reads[AMOUNT];
int current_read;
public:
Reader(int pin)
{
this->pin = pin;
current_read = 0;
for (int i = 0; i < AMOUNT; i++) reads[i] = 0;
}
void Read()
{
reads[current_read] = analogRead(pin);
current_read++;
if (current_read >= AMOUNT) current_read -= AMOUNT;
}
int sorted_reads[AMOUNT];
int Get()
{
for (int i = 0; i < AMOUNT; i++)
{
sorted_reads[i] = reads[i];
}
bool f = true;
while (f)
{
f = false;
for (int i = 0; i < AMOUNT - 1; i++)
{
if (sorted_reads[i] > sorted_reads[i + 1])
{
int t = sorted_reads[i];
sorted_reads[i] = sorted_reads[i + 1];
sorted_reads[i + 1] = t;
f = true;
}
}
}/*
float sum = 0;
int cnt = 0;
for (int i = FILTER_SIZE; i < AMOUNT - FILTER_SIZE; i++)
{
sum += reads[i];
cnt++;
}
return (int)(sum / cnt + 0.5);*/
return sorted_reads[AMOUNT / 2];
}
};
ModbusRTU mb;
#define MODBUS_ADDRESS 1
#define I_ACC_LOW_REGISTER 0
#define I_ACC_HIGH_REGISTER 1
#define I_LAMP_LOW_REGISTER 2
#define I_LAMP_HIGH_REGISTER 3
#define ACC_STATE_REGISTER 4
#define LAMP_STATE_REGISTER 5
#define U_ACC_LOW_REGISTER 6
@@ -28,6 +84,7 @@ float R_lamp;
void setup()
{
Serial.begin(115200);
pinMode(A7, INPUT);
pinMode(A4, INPUT);
pinMode(A5, INPUT);
pinMode(A2, INPUT);
@@ -39,8 +96,6 @@ void setup()
mb.slave(MODBUS_ADDRESS);
mb.addHreg(I_ACC_LOW_REGISTER);
mb.addHreg(I_ACC_HIGH_REGISTER);
mb.addHreg(I_LAMP_LOW_REGISTER);
mb.addHreg(I_LAMP_HIGH_REGISTER);
mb.addHreg(ACC_STATE_REGISTER);
mb.addHreg(LAMP_STATE_REGISTER);
for (int i = 0; i < 4; i++)
@@ -50,33 +105,43 @@ void setup()
}
}
float I_lamp;
Reader R2(A2);
Reader R3(A3);
Reader R4(A4);
Reader R5(A5);
Reader R7(A7);
float I_acc;
float U1_lamp;
float U2_lamp;
float U1_acc;
float U2_acc;
float U4;
float U5;
float U2;
float U3;
void ReadLamp()
{
int a4 = analogRead(A4);
int a5 = analogRead(A5);
int a4 = R4.Get();
int a5 = R5.Get();
// multiply by 5 as reference current,
// multiply by 3 because of the divider
U1_lamp = a4 / 1023.0 * 5 * 3;
U2_lamp = a5 / 1023.0 * 5 * 3;
I_lamp = (U1_lamp - U2_lamp) / R_lamp;
U4 = a4 / 1023.0 * 5 * 3;
U5 = a5 / 1023.0 * 5 * 3;
}
void ReadAcc()
{
int a2 = analogRead(A2);
int a3 = analogRead(A3);
int a2 = R2.Get();
int a3 = R3.Get();
// multiply by 5 as reference current,
// multiply by 3 because of the divider
U1_acc = a2 / 1023.0 * 5 * 3;
U2_acc = a3 / 1023.0 * 5 * 3;
I_acc = (U1_acc - U2_acc) / R_LIMITER;
U2 = a2 / 1023.0 * 5 * 3;
U3 = a3 / 1023.0 * 5 * 3;
}
const float CURRENT_SENSOR_MAX = 5;
void ReadI()
{
I_acc = ((R7.Get() + 0.0) / 1023.0 - 0.5) * CURRENT_SENSOR_MAX;
}
void WriteFloatReg(int start, float val)
@@ -91,14 +156,19 @@ uint16_t lamp_state = 0;
void loop()
{
R2.Read();
R3.Read();
R4.Read();
R5.Read();
R7.Read();
ReadLamp();
ReadAcc();
ReadI();
WriteFloatReg(I_ACC_LOW_REGISTER, I_acc);
WriteFloatReg(U_ACC_LOW_REGISTER, U1_acc);
WriteFloatReg(U_ACC_LOW_REGISTER + 2, U2_acc);
WriteFloatReg(I_LAMP_LOW_REGISTER, I_lamp);
WriteFloatReg(U_LAMP_LOW_REGISTER, U1_lamp);
WriteFloatReg(U_LAMP_LOW_REGISTER + 2, U2_lamp);
WriteFloatReg(U_ACC_LOW_REGISTER, U2);
WriteFloatReg(U_ACC_LOW_REGISTER + 2, U3);
WriteFloatReg(U_LAMP_LOW_REGISTER, U4);
WriteFloatReg(U_LAMP_LOW_REGISTER + 2, U5);
mb.task();
lamp_state = mb.Hreg(LAMP_STATE_REGISTER);
acc_state = mb.Hreg(ACC_STATE_REGISTER);
Binary file not shown.
Binary file not shown.