You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
696 lines
24 KiB
696 lines
24 KiB
using System; |
|
using System.Collections.Generic; |
|
using System.Linq; |
|
using System.Reflection; |
|
using System.Text; |
|
using System.Runtime.InteropServices; |
|
using System.Drawing; |
|
using System.Windows.Forms; |
|
using System.Windows.Forms.VisualStyles; |
|
using System.ComponentModel; |
|
using System.Drawing.Imaging; |
|
using System.Globalization; |
|
using static System.Net.Mime.MediaTypeNames; |
|
|
|
namespace UTIL |
|
{ |
|
public static class ASMBL |
|
{ |
|
#region Методы доступа к атрибутам сборки |
|
|
|
public static string AssemblyTitle |
|
{ |
|
get |
|
{ |
|
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false); |
|
if (attributes.Length > 0) |
|
{ |
|
AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0]; |
|
if (titleAttribute.Title != "") |
|
{ |
|
return titleAttribute.Title; |
|
} |
|
} |
|
return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase); |
|
} |
|
} |
|
|
|
public static string AssemblyVersion |
|
{ |
|
get |
|
{ |
|
return Assembly.GetExecutingAssembly().GetName().Version.ToString(); |
|
} |
|
} |
|
|
|
public static string AssemblyDescription |
|
{ |
|
get |
|
{ |
|
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false); |
|
if (attributes.Length == 0) |
|
{ |
|
return ""; |
|
} |
|
return ((AssemblyDescriptionAttribute)attributes[0]).Description; |
|
} |
|
} |
|
|
|
public static string AssemblyProduct |
|
{ |
|
get |
|
{ |
|
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false); |
|
if (attributes.Length == 0) |
|
{ |
|
return ""; |
|
} |
|
#if DEBUG |
|
return ((AssemblyProductAttribute)attributes[0]).Product + " Debug version"; |
|
#else |
|
return ((AssemblyProductAttribute)attributes[0]).Product + " Release version"; |
|
#endif |
|
} |
|
} |
|
|
|
public static string AssemblyCopyright |
|
{ |
|
get |
|
{ |
|
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false); |
|
if (attributes.Length == 0) |
|
{ |
|
return ""; |
|
} |
|
return ((AssemblyCopyrightAttribute)attributes[0]).Copyright; |
|
} |
|
} |
|
|
|
public static string AssemblyCompany |
|
{ |
|
get |
|
{ |
|
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false); |
|
if (attributes.Length == 0) |
|
{ |
|
return ""; |
|
} |
|
return ((AssemblyCompanyAttribute)attributes[0]).Company; |
|
} |
|
} |
|
public static string AssemblyConfiguration |
|
{ |
|
get |
|
{ |
|
#if DEBUG |
|
return "Debug version"; |
|
#else |
|
return "Release version"; |
|
#endif |
|
} |
|
} |
|
public static string[] AssemblyConf |
|
{ |
|
get |
|
{ |
|
string[] s = new string[11]; |
|
|
|
object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyConfigurationAttribute), false); |
|
#if DEBUG |
|
s[0] = "Debug version"; |
|
#else |
|
s[0] = "Release version"; |
|
#endif |
|
attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyAlgorithmIdAttribute), false); |
|
if (attributes.Length == 0) |
|
s[1] = "AssemblyAlgorithmId = "; |
|
else |
|
s[1] = "AssemblyAlgorithmId = " + ((AssemblyAlgorithmIdAttribute)attributes[0]).AlgorithmId; |
|
|
|
attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false); |
|
if (attributes.Length == 0) |
|
s[2] = "AssemblyCompany = "; |
|
else |
|
s[2] = "AssemblyCompany = " + ((AssemblyCompanyAttribute)attributes[0]).Company; |
|
|
|
attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false); |
|
if (attributes.Length == 0) |
|
s[3] = "AssemblyCopyright = "; |
|
else |
|
s[3] = "AssemblyCopyright = " + ((AssemblyCopyrightAttribute)attributes[0]).Copyright; |
|
|
|
attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false); |
|
if (attributes.Length == 0) |
|
s[4] = "AssemblyDescription = "; |
|
else |
|
s[4] = "AssemblyDescription = " + ((AssemblyDescriptionAttribute)attributes[0]).Description; |
|
|
|
attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyFileVersionAttribute), false); |
|
if (attributes.Length == 0) |
|
s[5] = "AssemblyFileVersion = "; |
|
else |
|
s[5] = "AssemblyFileVersion = " + ((AssemblyFileVersionAttribute)attributes[0]).Version; |
|
|
|
attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false); |
|
if (attributes.Length == 0) |
|
s[6] = "AssemblyInformationalVersion = "; |
|
else |
|
s[6] = "AssemblyInformationalVersion = " + ((AssemblyInformationalVersionAttribute)attributes[0]).InformationalVersion; |
|
|
|
attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false); |
|
if (attributes.Length == 0) |
|
s[7] = "AssemblyProduct = "; |
|
else |
|
s[7] = "AssemblyProduct = " + ((AssemblyProductAttribute)attributes[0]).Product; |
|
|
|
attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false); |
|
if (attributes.Length == 0) |
|
s[8] = "AssemblyTitle = "; |
|
else |
|
s[8] = "AssemblyTitle = " + ((AssemblyTitleAttribute)attributes[0]).Title; |
|
|
|
attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTrademarkAttribute), false); |
|
if (attributes.Length == 0) |
|
s[9] = "AssemblyTrademark = "; |
|
else |
|
s[9] = "AssemblyTrademark = " + ((AssemblyTrademarkAttribute)attributes[0]).Trademark; |
|
|
|
attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyVersionAttribute), false); |
|
if (attributes.Length == 0) |
|
s[10] = "AssemblyVersion = "; |
|
else |
|
s[10] = "AssemblyVersion = " + ((AssemblyVersionAttribute)attributes[0]).Version; |
|
|
|
return s; |
|
} |
|
} |
|
#endregion |
|
} |
|
|
|
public class IniFile |
|
{ |
|
[DllImport("kernel32.dll")] |
|
private extern static int GetPrivateProfileString(String AppName, String KeyName, String Default, StringBuilder ReturnedString, UInt32 Size, String FileName); |
|
[DllImport("kernel32.dll")] |
|
private extern static int WritePrivateProfileString(String AppName, String KeyName, String Str, String FileName); |
|
public IniFile(string filename) |
|
{ |
|
IniFileName = filename; |
|
} |
|
public String IniFileName |
|
{ |
|
get; |
|
set; |
|
} |
|
public String _GetString(String section, String key) |
|
{ |
|
StringBuilder s1 = new StringBuilder(128); |
|
GetPrivateProfileString(section, key, "", s1, 128, IniFileName); |
|
return s1.ToString(); |
|
} |
|
public Int64 _GetInt(String section, String key) |
|
{ |
|
StringBuilder s1 = new StringBuilder(100); |
|
GetPrivateProfileString(section, key, "", s1, 100, IniFileName); |
|
return Int64.Parse(s1.ToString()); |
|
} |
|
public Boolean _GetBool(String section, String key) |
|
{ |
|
StringBuilder s1 = new StringBuilder(100); |
|
GetPrivateProfileString(section, key, "", s1, 100, IniFileName); |
|
return Boolean.Parse(s1.ToString()); |
|
} |
|
public Double _GetDouble(String section, String key) |
|
{ |
|
StringBuilder s1 = new StringBuilder(100); |
|
GetPrivateProfileString(section, key, "", s1, 100, IniFileName); |
|
return Double.Parse(s1.ToString()); |
|
} |
|
public void _SetString(String section, String key, String val) |
|
{ |
|
WritePrivateProfileString(section, key, val, IniFileName); |
|
} |
|
public void _SetInt(String section, String key, Int64 val) |
|
{ |
|
WritePrivateProfileString(section, key, val.ToString(), IniFileName); |
|
} |
|
public void _SetDouble(String section, String key, Double val) |
|
{ |
|
WritePrivateProfileString(section, key, val.ToString(), IniFileName); |
|
} |
|
public void _SetBool(String section, String key, Boolean val) |
|
{ |
|
WritePrivateProfileString(section, key, val.ToString(), IniFileName); |
|
} |
|
} |
|
|
|
public static class S2B |
|
{ |
|
#region Загрузка/выгрузка данных в структуру |
|
public static T BuffToStruct<T>(byte[] arr) |
|
{ |
|
GCHandle gch = GCHandle.Alloc(arr, GCHandleType.Pinned); |
|
IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(arr, 0); |
|
T ret = (T)Marshal.PtrToStructure(ptr, typeof(T)); |
|
gch.Free(); |
|
return default(T); |
|
} |
|
public static T BuffToClass<T>(byte[] arr) |
|
{ |
|
GCHandle gch = GCHandle.Alloc(arr, GCHandleType.Pinned); |
|
IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(arr, 0); |
|
T ret = (T)Marshal.PtrToStructure(ptr, typeof(T)); |
|
gch.Free(); |
|
return default(T); |
|
} |
|
public static byte[] StructToBuff<T>(T value) where T : struct |
|
{ |
|
byte[] arr = new byte[Marshal.SizeOf(value)]; // создать массив |
|
GCHandle gch = GCHandle.Alloc(arr, GCHandleType.Pinned); // зафиксировать в памяти |
|
IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(arr, 0); // и взять его адрес |
|
Marshal.StructureToPtr(value, ptr, true); // копировать в массив |
|
gch.Free(); // снять фиксацию |
|
return arr; |
|
} |
|
public static byte[] ClassToBuff<T>(T value) where T : class |
|
{ |
|
byte[] arr = new byte[Marshal.SizeOf(value)]; // создать массив |
|
GCHandle gch = GCHandle.Alloc(arr, GCHandleType.Pinned); // зафиксировать в памяти |
|
IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(arr, 0); // и взять его адрес |
|
Marshal.StructureToPtr(value, ptr, true); // копировать в массив |
|
gch.Free(); // снять фиксацию |
|
return arr; |
|
} |
|
#endregion |
|
} |
|
|
|
public static class RichTextBoxExtensions |
|
{ |
|
public static void AppendText(this RichTextBox box, string text, Color color) |
|
{ |
|
if (box.InvokeRequired) |
|
{ |
|
box.Invoke((MethodInvoker)(delegate |
|
{ |
|
box.SelectionStart = box.TextLength; |
|
box.SelectionLength = 0; |
|
box.SelectionColor = color; |
|
box.AppendText(text); |
|
box.SelectionColor = box.ForeColor; |
|
box.ScrollToCaret(); |
|
})); |
|
} |
|
else |
|
{ |
|
box.SelectionStart = box.TextLength; |
|
box.SelectionLength = 0; |
|
box.SelectionColor = color; |
|
box.AppendText(text); |
|
box.SelectionColor = box.ForeColor; |
|
box.ScrollToCaret(); |
|
} |
|
} |
|
public static void AppendText(this RichTextBox box, string text, Color bgcolor, Color fgcolor) |
|
{ |
|
if (box.InvokeRequired) |
|
{ |
|
box.Invoke((MethodInvoker)(delegate |
|
{ |
|
box.SelectionStart = box.TextLength; |
|
box.SelectionLength = 0; |
|
box.SelectionColor = fgcolor; |
|
box.SelectionBackColor = bgcolor; |
|
box.AppendText(text); |
|
box.SelectionColor = box.ForeColor; |
|
box.SelectionBackColor = box.BackColor; |
|
box.ScrollToCaret(); |
|
})); |
|
} |
|
else |
|
{ |
|
box.SelectionStart = box.TextLength; |
|
box.SelectionLength = 0; |
|
box.SelectionColor = fgcolor; |
|
box.SelectionBackColor = bgcolor; |
|
box.AppendText(text); |
|
box.SelectionColor = box.ForeColor; |
|
box.SelectionBackColor = box.BackColor; |
|
box.ScrollToCaret(); |
|
} |
|
} |
|
} |
|
|
|
public class GKalman |
|
{ |
|
double _err_measure = 0.0F; |
|
double _err_estimate = 0.0F; |
|
double _q = 0.0F; |
|
double _last_estimate = 0.0F; |
|
public GKalman(double mea_e, double est_e, double q) |
|
{ |
|
setParameters(mea_e, est_e, q); |
|
} |
|
|
|
// разброс измерения, скорость изменения значений (разброс измерения принимается равным разбросу оценки) |
|
public GKalman(double mea_e, double q) |
|
{ |
|
setParameters(mea_e, mea_e, q); |
|
} |
|
|
|
// разброс измерения, разброс оценки, скорость изменения значений |
|
public void setParameters(double mea_e, double est_e, double q) |
|
{ |
|
_err_measure = mea_e; |
|
_err_estimate = est_e; |
|
_q = q; |
|
} |
|
|
|
// разброс измерения, скорость изменения значений (разброс измерения принимается равным разбросу оценки) |
|
public void setParameters(double mea_e, double q) |
|
{ |
|
setParameters(mea_e, mea_e, q); |
|
} |
|
|
|
// возвращает фильтрованное значение |
|
public double filtered(double value) |
|
{ |
|
double _kalman_gain, _current_estimate; |
|
_kalman_gain = _err_estimate / (_err_estimate + _err_measure); |
|
_current_estimate = _last_estimate + _kalman_gain * (value - _last_estimate); |
|
_err_estimate = (1.0 - _kalman_gain) * _err_estimate + Math.Abs(_last_estimate - _current_estimate) * _q; |
|
_last_estimate = _current_estimate; |
|
return (double)_current_estimate; |
|
} |
|
} |
|
|
|
public unsafe class UnsafeBitmap |
|
{ |
|
Bitmap bitmap; |
|
// three elements used for MakeGreyUnsafe |
|
int width; |
|
BitmapData bitmapData = null; |
|
Byte* pBase = null; |
|
public UnsafeBitmap(Bitmap bitmap) |
|
{ |
|
this.bitmap = new Bitmap(bitmap); |
|
} |
|
public UnsafeBitmap(int width, int height) |
|
{ |
|
this.bitmap = new Bitmap(width, height, PixelFormat.Format24bppRgb); |
|
} |
|
public void Dispose() |
|
{ |
|
bitmap.Dispose(); |
|
} |
|
public Bitmap Bitmap |
|
{ |
|
get |
|
{ |
|
return (bitmap); |
|
} |
|
} |
|
private Point PixelSize |
|
{ |
|
get |
|
{ |
|
GraphicsUnit unit = GraphicsUnit.Pixel; |
|
RectangleF bounds = bitmap.GetBounds(ref unit); |
|
|
|
return new Point((int)bounds.Width, (int)bounds.Height); |
|
} |
|
} |
|
public void LockBitmap() |
|
{ |
|
GraphicsUnit unit = GraphicsUnit.Pixel; |
|
RectangleF boundsF = bitmap.GetBounds(ref unit); |
|
Rectangle bounds = new Rectangle((int)boundsF.X, |
|
(int)boundsF.Y, |
|
(int)boundsF.Width, |
|
(int)boundsF.Height); |
|
|
|
// Figure out the number of bytes in a row |
|
// This is rounded up to be a multiple of 4 |
|
// bytes, since a scan line in an image must always be a multiple of 4 bytes |
|
// in length. |
|
width = (int)boundsF.Width * sizeof(PixelData); |
|
if (width % 4 != 0) |
|
{ |
|
width = 4 * (width / 4 + 1); |
|
} |
|
bitmapData = |
|
bitmap.LockBits(bounds, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); |
|
pBase = (Byte*)bitmapData.Scan0.ToPointer(); |
|
} |
|
public PixelData GetPixel(int x, int y) |
|
{ |
|
PixelData returnValue = *PixelAt(x, y); |
|
return returnValue; |
|
} |
|
public void SetPixel(int x, int y, PixelData colour) |
|
{ |
|
PixelData* pixel = PixelAt(x, y); |
|
*pixel = colour; |
|
} |
|
public void UnlockBitmap() |
|
{ |
|
bitmap.UnlockBits(bitmapData); |
|
bitmapData = null; |
|
pBase = null; |
|
} |
|
public PixelData* PixelAt(int x, int y) |
|
{ |
|
return (PixelData*)(pBase + y * width + x * sizeof(PixelData)); |
|
} |
|
} |
|
|
|
public struct PixelData |
|
{ |
|
public byte blue; |
|
public byte green; |
|
public byte red; |
|
} |
|
public static class Util |
|
{ |
|
public static String Val(Object value) |
|
{ |
|
// Console.WriteLine(value.GetType()); |
|
// String tmp = value.GetType().ToString().Split(new Char[] { '.' })[1]; |
|
String tmp; |
|
tmp = value.GetType().ToString(); |
|
Console.WriteLine(tmp); |
|
tmp = value.GetType().ToString().Split(new Char[] { '.' })[1]; |
|
Console.WriteLine(tmp); |
|
switch (tmp) |
|
{ |
|
case "Double": |
|
case "Single": |
|
case "Decimal": |
|
// return Math.Round(Convert.ToDouble(value), 2).ToString("+0.00;-0.00;+0.00"); |
|
case "UInt64": |
|
case "UInt32": |
|
case "UInt16": |
|
case "Byte": |
|
// return value.ToString(); |
|
// return $"{value:+0;+0;+0}"; |
|
case "Int64": |
|
case "Int32": |
|
case "Int16": |
|
case "SByte": |
|
// return $"{value:+0;-0;+0}"; |
|
// return value.ToString(); |
|
case "String": |
|
// return $"{value}"; |
|
// return value.ToString(); |
|
case "Hex": |
|
// return $"{value}"; |
|
// return value.ToString(); |
|
default: |
|
break; |
|
} |
|
return ""; |
|
} |
|
public static T minmax<T>(T min, T max, T val) |
|
{ |
|
dynamic dmin = min; |
|
dynamic dmax = max; |
|
dynamic dval = val; |
|
if (dval <= dmin) |
|
return dmin; |
|
if (dval > dmax) |
|
return dmax; |
|
return dval; |
|
} |
|
public struct Hex<T> |
|
{ |
|
private T _Value; |
|
public static implicit operator Hex<T>(T value) |
|
{ |
|
return new Hex<T> { _Value = value }; |
|
} |
|
public static implicit operator T(Hex<T> value) |
|
{ |
|
return value._Value; |
|
} |
|
public override string ToString() |
|
{ |
|
if (_Value.GetType() == typeof(UInt64)) |
|
return $"{_Value:X016}"; |
|
if (_Value.GetType() == typeof(UInt32)) |
|
return $"{_Value:X08}"; |
|
if (_Value.GetType() == typeof(UInt16)) |
|
return $"{_Value:X04}"; |
|
if (_Value.GetType() == typeof(Byte)) |
|
return $"{_Value:X02}"; |
|
return _Value.ToString(); |
|
} |
|
} |
|
public struct Hex0x<T> |
|
{ |
|
private T _Value; |
|
private CultureInfo ci;// = new CultureInfo("ru-Ru"); |
|
public static implicit operator Hex0x<T>(T value) |
|
{ |
|
return new Hex0x<T> { _Value = value }; |
|
} |
|
public static implicit operator T(Hex0x<T> value) |
|
{ |
|
return value._Value; |
|
} |
|
public override string ToString() |
|
{ |
|
if (_Value.GetType() == typeof(UInt64)) |
|
return $"0x{_Value:X016}"; |
|
if (_Value.GetType() == typeof(UInt32)) |
|
return $"0x{_Value:X08}"; |
|
if (_Value.GetType() == typeof(UInt16)) |
|
return $"0x{_Value:X04}"; |
|
if (_Value.GetType() == typeof(Byte)) |
|
return $"0x{_Value:X02}"; |
|
return _Value.ToString(); |
|
} |
|
} |
|
public static String printtime(Boolean ms) |
|
{ |
|
if (ms == true) |
|
return DateTime.Now.ToString("HH:mm:ss:fff"); |
|
else |
|
return DateTime.Now.ToString("HH:mm:ss"); |
|
} |
|
private const int EM_SETTABSTOPS = 0x00CB; |
|
|
|
[DllImport("User32.dll", CharSet = CharSet.Auto)] |
|
public static extern IntPtr SendMessage(IntPtr h, int msg, int wParam, int[] lParam); |
|
|
|
public static void SetTabWidth(TextBox textbox, int tabWidth) |
|
{ |
|
Graphics graphics = textbox.CreateGraphics(); |
|
var characterWidth = (int)graphics.MeasureString("M", textbox.Font).Width; |
|
SendMessage |
|
(textbox.Handle |
|
, EM_SETTABSTOPS |
|
, 1 |
|
, new int[] { tabWidth * characterWidth } |
|
); |
|
} |
|
} |
|
public class CircularBuffer<T> |
|
{ |
|
T[] _buffer; |
|
Int32 _head; |
|
Int32 _tail; |
|
Int32 _length; |
|
Int32 _bufferSize; |
|
Object _lock = new object(); |
|
public CircularBuffer(Int32 bufferSize) |
|
{ |
|
_buffer = new T[bufferSize]; |
|
_bufferSize = bufferSize; |
|
_head = bufferSize - 1; |
|
} |
|
public bool IsEmpty |
|
{ |
|
get { return _length == 0; } |
|
} |
|
public bool IsFull |
|
{ |
|
get { return _length == _bufferSize; } |
|
} |
|
public T Dequeue() |
|
{ |
|
lock (_lock) |
|
{ |
|
if (IsEmpty) throw new InvalidOperationException("Queue exhausted"); |
|
|
|
T dequeued = _buffer[_tail]; |
|
_tail = NextPosition(_tail); |
|
_length--; |
|
return dequeued; |
|
} |
|
} |
|
private int NextPosition(int position) |
|
{ |
|
return (position + 1) % _bufferSize; |
|
} |
|
public void Enqueue(T toAdd) |
|
{ |
|
lock (_lock) |
|
{ |
|
_head = NextPosition(_head); |
|
_buffer[_head] = toAdd; |
|
if (IsFull) |
|
_tail = NextPosition(_tail); |
|
else |
|
_length++; |
|
} |
|
} |
|
} |
|
public class GFilterRA |
|
{ |
|
public GFilterRA() |
|
{ } |
|
public GFilterRA(double coef, UInt16 interval) |
|
{ |
|
_coef = coef; |
|
_prd = interval; |
|
} |
|
public GFilterRA(double coef) |
|
{ |
|
_coef = coef; |
|
} |
|
UInt32 millis() |
|
{ |
|
return (UInt32)DateTimeOffset.Now.ToUnixTimeMilliseconds(); |
|
} |
|
public void setCoef(double coef) |
|
{ |
|
_coef = coef; |
|
} |
|
public void setPeriod(UInt16 interval) |
|
{ |
|
_prd = interval; |
|
} |
|
public double filteredTime(double value) |
|
{ |
|
if (millis() - _tmr >= _prd) |
|
{ |
|
_tmr += _prd; |
|
filtered(value); |
|
} |
|
return _fil; |
|
} |
|
double filtered(double value) |
|
{ |
|
return _fil += (value - _fil) * _coef; |
|
} |
|
void setStep(UInt16 interval) |
|
{ |
|
_prd = interval; |
|
} |
|
|
|
double _coef = 0.0F, _fil = 0.0F; |
|
UInt32 _tmr = 0; |
|
UInt32 _prd = 0; |
|
}; |
|
|
|
|
|
}
|
|
|