SmartOS/App/Raster.cpp

228 lines
4.0 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "Device\Port.h"
#include "App\PulsePort.h"
#include "Raster.h"
static Stream* _Cache = nullptr; //实际送的数据
static uint _RasterTask = 0;
static int _Ras = 0;
static PulsePort* Create(Pin pin)
{
auto pp = new PulsePort();
pp->Port = new InputPort();
pp->Port->Set(pin);
pp->Port->Floating = false;
pp->Port->Pull = InputPort::UP;
pp->Port->HardEvent = true;
return pp;
}
Raster::Raster(Pin pinA, Pin pinB)
{
OnInit();
RasterA = Create(pinA);
RasterB = Create(pinB);
_Ras++;
}
Raster::~Raster()
{
delete RasterA->Port;
delete RasterA;
delete RasterB->Port;
delete RasterB;
if (--_Ras == 0)
{
//delete _Cache;
Sys.RemoveTask(_task);
}
}
void Raster::Init()
{
if (RasterA != nullptr)
{
RasterA->Min = Min;
RasterA->Max = Max;
RasterA->Filter = Filter;
}
if (RasterB != nullptr)
{
RasterB->Min = Min;
RasterB->Max = Max;
RasterB->Filter = Filter;
}
}
void Raster::OnInit()
{
RasterA = nullptr;
RasterB = nullptr;
Opened = false;
FlagB.Start = 0;
FlagB.Time = 0;
FlagB.Count = 0;
FlagA.Start = 0;
FlagA.Time = 0;
FlagA.Count = 0;
Min = 100; // 最小时间间隔 单位 ms
Max = 3000; // 最大时间间隔 单位 ms
Filter = false;
Count = 0;
Count2 = 0;
}
bool Raster::Open()
{
if (Opened) return true;
if (RasterA != nullptr)
{
RasterA->Press.Bind(&Raster::OnHandlerA, this);
RasterA->Open();
}
if (RasterB != nullptr)
{
RasterB->Press.Bind(&Raster::OnHandlerB, this);
RasterB->Open();
}
if (!_Cache)
{
_Cache = new MemoryStream();
_Cache->SetCapacity(512);
}
// 光栅一直在轮训是否有数据要发送
if (!_RasterTask) _RasterTask = Sys.AddTask(&Raster::Report, this, 3000, 2500, "光栅发送");
Opened = true;
return true;
}
// 检查配对
static bool CheckMatch(FlagData& flag, UInt64 now)
{
if (flag.Count == 0)
{
debug_printf("等待配对\r\n");
return false;
}
// 超过3秒无效
if (flag.Start + 3000 < now)
{
debug_printf("过期清零\r\n");
flag.Count = 0;
return false;
}
return true;
}
void Raster::OnHandlerA(PulsePort& raster)
{
//Buzzer.Blink(2, 500);
debug_printf("A路触发波长%d \r\n", raster.Time);
FlagA.Start = raster.Start;
FlagA.Time = raster.Time;
FlagA.Count++;
if (CheckMatch(FlagB, FlagA.Start))
{
LineReport();
debug_printf("A配对\r\n");
}
}
void Raster::OnHandlerB(PulsePort& raster)
{
//Buzzer.Blink(2, 500);
debug_printf("B路触发波长%d \r\n", raster.Time);
FlagB.Start = raster.Start;
FlagB.Time = raster.Time;
debug_printf("获得波长%d\r\n", FlagB.Time);
FlagB.Count++;
if (CheckMatch(FlagA, FlagB.Start))
{
LineReport();
debug_printf("B配对\r\n");
}
}
// 已经匹配一对通过事件
void Raster::LineReport()
{
auto size = sizeof(RasTriData);
Stop = true;
// 构造当前数据
RasTriData data;
data.Index = Index;
data.Start = DateTime::Now().TotalMs();
data.TimeA = FlagA.Time;
data.TimeB = FlagB.Time;
debug_printf("data获得波长%d\r\n", data.TimeB);
// 时间差加方向
if (FlagA.Start > FlagB.Start)
{
data.Direction = 0x00;
data.Time = (ushort)(FlagA.Start - FlagB.Start);
Count++;
data.Count = Count;
}
else
{
data.Direction = 0x01;
data.Time = (ushort)(FlagB.Start - FlagA.Start);
Count2++;
data.Count = Count2;
}
Buffer bs(&data, size);
// 如果满了,马上发送
if (bs.Length() > 256 - (int)_Cache->Position())
Report();
_Cache->Write(bs);
debug_printf("写入%d\r\n", data.Count);
//写完数据后标致清零
FlagA.Count = FlagB.Count = 0;
Stop = false;
}
void Raster::Report()
{
// 没数据或者客户端未登录
if (_Cache->Length == 0 || Stop) return;
//先把数据复制一下
Buffer bs(_Cache->GetBuffer(), _Cache->Position());
MemoryStream cache;
cache.Write(bs);
_Cache->SetPosition(0);
_Cache->Length = 0;
//委托执行时间太久了
OnReport(cache);
}