合并面板按键类
This commit is contained in:
parent
4ef42d15a4
commit
a259dafbca
|
@ -1,7 +1,5 @@
|
|||
#include "Button.h"
|
||||
|
||||
InputPort Button::ACZero;
|
||||
int Button::ACZeroAdjTime = 2300;
|
||||
#include "ACZero.h"
|
||||
|
||||
Button::Button()
|
||||
{
|
||||
|
@ -9,8 +7,7 @@ Button::Button()
|
|||
Index = 0;
|
||||
_Value = false;
|
||||
|
||||
//_Handler = nullptr;
|
||||
//_Param = nullptr;
|
||||
Zero = nullptr;
|
||||
}
|
||||
|
||||
Button::~Button()
|
||||
|
@ -25,11 +22,8 @@ void Button::Set(Pin key, Pin led, Pin relay)
|
|||
void Button::Set(Pin key, Pin led, bool ledInvert, Pin relay, bool relayInvert)
|
||||
{
|
||||
Key.Set(key);
|
||||
//Key.Register(OnPress, this);
|
||||
//Key.Press = OnPress;
|
||||
Key.Press.Bind(&Button::OnPress, this);
|
||||
Key.UsePress();
|
||||
//Key.Register(Delegate2<InputPort&, bool>(&Button::OnPress, this))
|
||||
Key.Open();
|
||||
|
||||
if (led != P0)
|
||||
|
@ -44,12 +38,6 @@ void Button::Set(Pin key, Pin led, bool ledInvert, Pin relay, bool relayInvert)
|
|||
}
|
||||
}
|
||||
|
||||
/*void Button::OnPress(InputPort* port, bool down, void* param)
|
||||
{
|
||||
Button* btn = (Button*)param;
|
||||
if(btn) btn->OnPress(port->_Pin, down);
|
||||
}*/
|
||||
|
||||
void Button::OnPress(InputPort& port, bool down)
|
||||
{
|
||||
// 每次按下弹起,都取反状态
|
||||
|
@ -57,25 +45,10 @@ void Button::OnPress(InputPort& port, bool down)
|
|||
{
|
||||
SetValue(!_Value);
|
||||
|
||||
//if(_Handler) _Handler(this, _Param);
|
||||
Press(*this);
|
||||
}
|
||||
}
|
||||
|
||||
/*void Button::Register(EventHandler handler, void* param)
|
||||
{
|
||||
if(handler)
|
||||
{
|
||||
_Handler = handler;
|
||||
_Param = param;
|
||||
}
|
||||
else
|
||||
{
|
||||
_Handler = nullptr;
|
||||
_Param = nullptr;
|
||||
}
|
||||
}*/
|
||||
|
||||
bool Button::GetValue() { return _Value; }
|
||||
|
||||
int Button::OnWrite(byte data)
|
||||
|
@ -98,24 +71,11 @@ String Button::ToString() const
|
|||
return str;
|
||||
}
|
||||
|
||||
bool CheckZero(const InputPort& port)
|
||||
{
|
||||
int retry = 200;
|
||||
while (!port.Read() && retry-- > 0) Sys.Delay(100); // 检测下降沿 先去掉低电平 while(io==false)
|
||||
if (retry <= 0) return false;
|
||||
|
||||
retry = 200;
|
||||
while (port.Read() && retry-- > 0) Sys.Delay(100); // 当检测到 高电平结束 就是下降沿的到来
|
||||
if (retry <= 0) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Button::SetValue(bool value)
|
||||
{
|
||||
if (!ACZero.Empty())
|
||||
if (Zero)
|
||||
{
|
||||
if (CheckZero(ACZero)) Sys.Delay(ACZeroAdjTime);
|
||||
Sys.Sleep(Zero->Time);
|
||||
|
||||
// 经检测 过零检测电路的信号是 高电平12ms 低电平7ms 即下降沿后8.5ms 是下一个过零点
|
||||
// 从给出信号到继电器吸合 测量得到的时间是 6.4ms 继电器抖动 1ms左右 即 平均在7ms上下
|
||||
|
@ -127,21 +87,3 @@ void Button::SetValue(bool value)
|
|||
|
||||
_Value = value;
|
||||
}
|
||||
|
||||
bool Button::SetACZeroPin(Pin aczero)
|
||||
{
|
||||
auto& port = ACZero;
|
||||
|
||||
// 该方法可能被初级工程师多次调用,需要检查并释放旧的,避免内存泄漏
|
||||
if (!port.Empty()) port.Close();
|
||||
|
||||
port.Set(aczero).Open();
|
||||
|
||||
// 需要检测是否有交流电,否则关闭
|
||||
if (CheckZero(port)) return true;
|
||||
|
||||
port.Close();
|
||||
port.Clear();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
24
App/Button.h
24
App/Button.h
|
@ -5,14 +5,13 @@
|
|||
#include "Device\Port.h"
|
||||
#include "Message\DataStore.h"
|
||||
|
||||
class ACZero;
|
||||
|
||||
// 面板按钮
|
||||
class Button : public ByteDataPort
|
||||
{
|
||||
private:
|
||||
void OnPress(InputPort& port, bool down);
|
||||
|
||||
public:
|
||||
cstring Name; // 按钮名称
|
||||
cstring Name; // 按钮名称
|
||||
int Index; // 索引号,方便在众多按钮中标识按钮
|
||||
|
||||
InputPort Key; // 输入按键
|
||||
|
@ -21,7 +20,8 @@ public:
|
|||
|
||||
Delegate<Button&> Press; // 按下事件
|
||||
|
||||
public:
|
||||
ACZero* Zero; // 交流电过零检测
|
||||
|
||||
// 构造函数。指示灯和继电器一般开漏输出,需要倒置
|
||||
Button();
|
||||
virtual ~Button();
|
||||
|
@ -29,25 +29,17 @@ public:
|
|||
void Set(Pin key, Pin led = P0, bool ledInvert = true, Pin relay = P0, bool relayInvert = true);
|
||||
void Set(Pin key, Pin led, Pin relay);
|
||||
bool GetValue();
|
||||
void SetValue(bool value);
|
||||
virtual void SetValue(bool value);
|
||||
|
||||
virtual int OnWrite(byte data);
|
||||
virtual byte OnRead();
|
||||
|
||||
String ToString() const;
|
||||
|
||||
// 过零检测
|
||||
private:
|
||||
static int ACZeroAdjTime; // 过零检测时间补偿 默认 2300us
|
||||
|
||||
public:
|
||||
static InputPort ACZero; // 交流过零检测引脚
|
||||
|
||||
static bool SetACZeroPin(Pin aczero); // 设置过零检测引脚
|
||||
static void SetACZeroAdjTime(int us){ ACZeroAdjTime = us; }; // 设置 过零检测补偿时间
|
||||
|
||||
private:
|
||||
bool _Value; // 状态
|
||||
|
||||
virtual void OnPress(InputPort& port, bool down);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -30,50 +30,16 @@ Button_GrayLevelConfig::Button_GrayLevelConfig()
|
|||
OffGrayLevel = 20;
|
||||
}
|
||||
|
||||
InputPort* Button_GrayLevel::ACZero = nullptr;
|
||||
int Button_GrayLevel::ACZeroAdjTime = 2300;
|
||||
|
||||
Button_GrayLevel::Button_GrayLevel() : ByteDataPort()
|
||||
Button_GrayLevel::Button_GrayLevel() : Button()
|
||||
{
|
||||
#if DEBUG
|
||||
Name = nullptr;
|
||||
#endif
|
||||
Index = 0;
|
||||
_Value = false;
|
||||
|
||||
_Pwm = nullptr;
|
||||
_Channel = 0;
|
||||
|
||||
//_Handler = nullptr;
|
||||
//_Param = nullptr;
|
||||
EnableDelayClose = true;
|
||||
_tid = 0;
|
||||
Next = 0xFF;
|
||||
}
|
||||
|
||||
void Button_GrayLevel::Set(Pin key, Pin relay, bool relayInvert)
|
||||
{
|
||||
Key.Set(key);
|
||||
|
||||
// 中断过滤模式
|
||||
//Key.Mode = InputPort::Both;
|
||||
|
||||
Key.ShakeTime = 20;
|
||||
//Key.Register(OnPress, this);
|
||||
Key.Press.Bind(&Button_GrayLevel::OnPress, this);
|
||||
Key.HardEvent = true;
|
||||
|
||||
Key.UsePress();
|
||||
Key.Open();
|
||||
|
||||
//面板事件
|
||||
if (!_task3)
|
||||
{
|
||||
_task3 = Sys.AddTask(&Button_GrayLevel::ReportPress, this, -1, -1, "面板事件");
|
||||
}
|
||||
if (relay != P0) Relay.Init(relay, relayInvert).Open();
|
||||
}
|
||||
|
||||
void Button_GrayLevel::Set(Pwm* drive, byte pulseIndex)
|
||||
{
|
||||
if (drive && pulseIndex < 4)
|
||||
|
@ -84,6 +50,11 @@ void Button_GrayLevel::Set(Pwm* drive, byte pulseIndex)
|
|||
// 刷新输出
|
||||
RenewGrayLevel();
|
||||
}
|
||||
//面板事件
|
||||
if (!_task3)
|
||||
{
|
||||
_task3 = Sys.AddTask(&Button_GrayLevel::ReportPress, this, -1, -1, "面板事件");
|
||||
}
|
||||
}
|
||||
|
||||
void Button_GrayLevel::RenewGrayLevel()
|
||||
|
@ -118,12 +89,6 @@ void Button_GrayLevel::GrayLevelDown()
|
|||
}
|
||||
}
|
||||
|
||||
/*void Button_GrayLevel::OnPress(InputPort* port, bool down, void* param)
|
||||
{
|
||||
Button_GrayLevel* btn = (Button_GrayLevel*)param;
|
||||
if (btn) btn->OnPress(port, down);
|
||||
}*/
|
||||
|
||||
void Button_GrayLevel::OnPress(InputPort& port, bool down)
|
||||
{
|
||||
//只有弹起才能执行业务动作
|
||||
|
@ -174,9 +139,9 @@ void Button_GrayLevel::ReportPress()
|
|||
Press(*this);
|
||||
}
|
||||
|
||||
void Close2Task(void * param)
|
||||
void Button_GrayLevel::OnDelayClose()
|
||||
{
|
||||
auto bt = (Button_GrayLevel *)param;
|
||||
auto bt = this;
|
||||
bt->GrayLevelUp();
|
||||
if (bt->delaytime > 1000)
|
||||
{
|
||||
|
@ -186,9 +151,10 @@ void Close2Task(void * param)
|
|||
else
|
||||
{
|
||||
bt->delaytime = 0;
|
||||
|
||||
debug_printf("延时关闭已完成 删除任务 %p\r\n", bt->_task2);
|
||||
Sys.RemoveTask(bt->_task2);
|
||||
bt->_task2 = 0;
|
||||
Sys.SetTask(bt->_task2, false);
|
||||
|
||||
bt->SetValue(false);
|
||||
bt->Key.PressTime = 0;
|
||||
bt->Press(*bt); // 维护数据区状态
|
||||
|
@ -199,81 +165,22 @@ void Close2Task(void * param)
|
|||
|
||||
void Button_GrayLevel::DelayClose2(int ms)
|
||||
{
|
||||
if (!_task2 && ms)
|
||||
{
|
||||
_task2 = Sys.AddTask(Close2Task, this, 0, 1000, "延时关闭");
|
||||
}
|
||||
if (ms == 0)return;
|
||||
|
||||
if (!_task2) _task2 = Sys.AddTask(&Button_GrayLevel::OnDelayClose, this, -1, -1, "延时关闭");
|
||||
|
||||
Sys.SetTask(_task2, true, 0);
|
||||
|
||||
delaytime = ms;
|
||||
}
|
||||
|
||||
int Button_GrayLevel::OnWrite(byte data)
|
||||
{
|
||||
SetValue(data > 0);
|
||||
|
||||
return OnRead();
|
||||
}
|
||||
|
||||
byte Button_GrayLevel::OnRead()
|
||||
{
|
||||
return _Value ? 1 : 0;
|
||||
}
|
||||
|
||||
bool Button_GrayLevel::GetValue() { return _Value; }
|
||||
|
||||
bool CheckZero(InputPort* port)
|
||||
{
|
||||
// 过零检测代码有风险 强制执行喂狗任务确保不出问题
|
||||
//auto dog = Task::Scheduler()->FindTask(WatchDog::FeedDogTask);
|
||||
//if(dog) dog->Execute(Sys.Ms());
|
||||
|
||||
// 检测下降沿 先去掉低电平 while(io==false)
|
||||
int retry = 200;
|
||||
while (*port == false && retry-- > 0) Sys.Delay(100);
|
||||
if (retry <= 0) return false;
|
||||
|
||||
// 喂狗
|
||||
Sys.Sleep(1);
|
||||
|
||||
// 当检测到 高电平结束 就是下降沿的到来
|
||||
retry = 200;
|
||||
while (*port == true && retry-- > 0) Sys.Delay(100);
|
||||
if (retry <= 0) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Button_GrayLevel::SetValue(bool value)
|
||||
{
|
||||
_Value = value;
|
||||
|
||||
if (ACZero && ACZero->Opened)
|
||||
{
|
||||
if (CheckZero(ACZero)) Sys.Delay(ACZeroAdjTime);
|
||||
// 经检测 过零检测电路的信号是 高电平12ms 低电平7ms 即下降沿后8.5ms 是下一个过零点
|
||||
// 从给出信号到继电器吸合 测量得到的时间是 6.4ms 继电器抖动 1ms左右 即 平均在7ms上下
|
||||
// 故这里添加1ms延时
|
||||
// 这里有个不是问题的问题 一旦过零检测电路烧了 开关将不能正常工作
|
||||
}
|
||||
|
||||
Relay = value;
|
||||
Button::SetValue(value);
|
||||
|
||||
RenewGrayLevel();
|
||||
}
|
||||
|
||||
bool Button_GrayLevel::SetACZeroPin(Pin aczero)
|
||||
{
|
||||
// 该方法需要检查并释放旧的,避免内存泄漏
|
||||
if (!ACZero) ACZero = new InputPort(aczero);
|
||||
|
||||
// 需要检测是否有交流电,否则关闭
|
||||
if (CheckZero(ACZero)) return true;
|
||||
|
||||
ACZero->Close();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Button_GrayLevel::Init(TIMER tim, byte count, Button_GrayLevel* btns, TAction onpress, const ButtonPin* pins, byte* level, const byte* state)
|
||||
{
|
||||
debug_printf("\r\n初始化开关按钮 \r\n");
|
||||
|
@ -311,7 +218,7 @@ void Button_GrayLevel::Init(TIMER tim, byte count, Button_GrayLevel* btns, TActi
|
|||
// 配置 Button 主体
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
btns[i].Set(pins[i].Key, pins[i].Relay, pins[i].Invert);
|
||||
btns[i].Set(pins[i].Key, P0, false, pins[i].Relay, pins[i].Invert);
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
|
@ -335,38 +242,6 @@ void Button_GrayLevel::Init(TIMER tim, byte count, Button_GrayLevel* btns, TActi
|
|||
}
|
||||
}
|
||||
|
||||
void ACZeroReset(void *param)
|
||||
{
|
||||
InputPort* port = Button_GrayLevel::ACZero;
|
||||
if (port)
|
||||
{
|
||||
//Sys.Reboot();
|
||||
debug_printf("定时检查过零检测\r\n");
|
||||
|
||||
// 需要检测是否有交流电,否则关闭
|
||||
if (CheckZero(port)) return;
|
||||
|
||||
port->Close();
|
||||
}
|
||||
}
|
||||
|
||||
void Button_GrayLevel::InitZero(Pin zero, int us)
|
||||
{
|
||||
if (zero == P0) return;
|
||||
|
||||
debug_printf("\r\n过零检测引脚PB12探测\r\n");
|
||||
Button_GrayLevel::SetACZeroAdjTime(us);
|
||||
|
||||
if (Button_GrayLevel::SetACZeroPin(zero))
|
||||
debug_printf("已连接交流电!\r\n");
|
||||
else
|
||||
debug_printf("未连接交流电或没有使用过零检测电路\r\n");
|
||||
|
||||
debug_printf("所有开关按钮准备就绪!\r\n\r\n");
|
||||
|
||||
Sys.AddTask(ACZeroReset, nullptr, 60000, 60000, "定时过零");
|
||||
}
|
||||
|
||||
Button_GrayLevelConfig Button_GrayLevel::InitGrayConfig()
|
||||
{
|
||||
static Button_GrayLevelConfig cfg;
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
#define __BUTTON_GRAY_LEVEL_H__
|
||||
|
||||
#include "Config.h"
|
||||
#include "Device\Port.h"
|
||||
#include "Device\Pwm.h"
|
||||
#include "Message\DataStore.h"
|
||||
|
||||
#include "Button.h"
|
||||
|
||||
struct ButtonPin
|
||||
{
|
||||
|
@ -25,7 +25,7 @@ public:
|
|||
};
|
||||
|
||||
class Button_GrayLevel;
|
||||
using TAction = Delegate<Button_GrayLevel&>::TAction;
|
||||
using TAction = Delegate<Button&>::TAction;
|
||||
|
||||
// 面板按钮
|
||||
// 这里必须使用_packed关键字,生成对齐的代码,否则_Value只占一个字节,导致后面的成员进行内存操作时错乱
|
||||
|
@ -33,41 +33,27 @@ using TAction = Delegate<Button_GrayLevel&>::TAction;
|
|||
// 干脆把_Value挪到最后解决问题
|
||||
extern Button_GrayLevelConfig* ButtonConfig;
|
||||
|
||||
class Button_GrayLevel : public ByteDataPort
|
||||
class Button_GrayLevel : public Button
|
||||
{
|
||||
public:
|
||||
int Index; // 索引号,方便在众多按钮中标识按钮
|
||||
#if DEBUG
|
||||
cstring Name; // 按钮名称
|
||||
#endif
|
||||
|
||||
InputPort Key; // 输入按键
|
||||
OutputPort Relay; // 继电器
|
||||
|
||||
// 外部设置模式调用
|
||||
typedef bool(*IOHandler)(Button_GrayLevel* bt, bool down, void * param);
|
||||
IOHandler ExterSet = nullptr;
|
||||
void * ExterSetParam = nullptr;
|
||||
|
||||
public:
|
||||
bool EnableDelayClose; // 标识是否启用延时关闭功能,默认启用
|
||||
Delegate<Button_GrayLevel&> Press;
|
||||
|
||||
// 构造函数。指示灯和继电器一般开漏输出,需要倒置
|
||||
Button_GrayLevel();
|
||||
|
||||
static Button_GrayLevelConfig InitGrayConfig();
|
||||
void Set(Pin key, Pin relay = P0, bool relayInvert = true);
|
||||
|
||||
using Button::Set;
|
||||
|
||||
// led 驱动器设置
|
||||
void Set(Pwm* drive, byte pulseIndex);
|
||||
bool GetValue();
|
||||
void SetValue(bool value);
|
||||
|
||||
virtual void SetValue(bool value);
|
||||
void RenewGrayLevel();
|
||||
|
||||
//virtual int Write(byte* pcmd); // 重载 ByteDataPort 的函数 自定义 Delay Flush Open Close
|
||||
//virtual int Read(byte* cmd);
|
||||
|
||||
virtual int OnWrite(byte data);
|
||||
virtual byte OnRead();
|
||||
public:
|
||||
static void Init(TIMER tim, byte count, Button_GrayLevel* btns, TAction onpress, const ButtonPin* pins, byte* level, const byte* state);
|
||||
static void UpdateLevel(byte* level, Button_GrayLevel* btns, byte count);
|
||||
|
||||
private:
|
||||
// 指示灯灰度驱动器 Pwm;
|
||||
|
@ -77,33 +63,19 @@ private:
|
|||
bool _Value; // 状态
|
||||
ushort Reserved; // 补足对齐问题
|
||||
|
||||
//static void OnPress(InputPort* port, bool down, void* param);
|
||||
void OnPress(InputPort& port, bool down);
|
||||
|
||||
public:
|
||||
static void Init(TIMER tim, byte count, Button_GrayLevel* btns, TAction onpress, const ButtonPin* pins, byte* level, const byte* state);
|
||||
static void InitZero(Pin zero, int us = 2300);
|
||||
static void UpdateLevel(byte* level, Button_GrayLevel* btns, byte count);
|
||||
virtual void OnPress(InputPort& port, bool down);
|
||||
|
||||
void GrayLevelDown();
|
||||
void GrayLevelUp();
|
||||
void DelayClose2(int ms); // 自定义延时关闭
|
||||
int delaytime = 0;
|
||||
uint _task2 = 0;
|
||||
void OnDelayClose();
|
||||
|
||||
//上报状态变化
|
||||
uint _task3 = 0;
|
||||
|
||||
void ReportPress();
|
||||
// 过零检测
|
||||
private:
|
||||
static int ACZeroAdjTime; // 过零检测时间补偿 默认 2300us
|
||||
|
||||
public:
|
||||
static InputPort* ACZero; // 交流过零检测引脚
|
||||
|
||||
static bool SetACZeroPin(Pin aczero); // 设置过零检测引脚
|
||||
static void SetACZeroAdjTime(int us) { ACZeroAdjTime = us; }; // 设置 过零检测补偿时间
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -234,7 +234,7 @@ bool CheckUserPress(InputPort* port, bool down, void* param)
|
|||
return false;
|
||||
}
|
||||
|
||||
void CheckUserPress3(Button_GrayLevel& btn)
|
||||
void CheckUserPress3(Button& btn)
|
||||
{
|
||||
CheckUserPress(&btn.Key, btn.Key.Read(), nullptr);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue