edit proshivka

This commit is contained in:
Dana Markova
2025-04-30 12:16:18 +03:00
parent 1f97891439
commit 27a120fc7f
12 changed files with 707 additions and 4 deletions

137
DroneClientCpp/joypad.h Normal file
View File

@ -0,0 +1,137 @@
// joypad.h ───────────────────────────────────────────────────────────
#pragma once
#include <iostream>
#include <iomanip>
#include <Windows.h> // <- для AllocConsole
#using <System.dll>
using namespace System;
using namespace System::IO::Ports;
using namespace System::Threading;
/*---------------------------------------------------------------------
Joypad (i-Bus → COM-порт)
---------------------------------------------------------------------*/
public ref class Joypad
{
public:
/* событие е подписывайтесь_ ➜ ничего в форме не вызовется */
delegate void TickHandler(array<UInt16>^ ch);
event TickHandler^ TickEvent;
Joypad()
{
// -------- открываем консоль один раз ----------------------
static bool consoleReady = false;
if (!consoleReady && ::AllocConsole())
{
FILE* fp;
freopen_s(&fp, "CONOUT$", "w", stdout);
std::cout << " CH1 CH2 CH3 CH4 CH5 CH6\n";
consoleReady = true;
}
// ----------------------------------------------------------
_sp = gcnew SerialPort();
_sp->ReadTimeout = 200;
_sp->ReadBufferSize = 256;
}
/* ---------- запуск ------------------------------------------- */
bool Start(String^ port, int baud )
{
if (_run) return true;
try
{
_sp->PortName = port;
_sp->BaudRate = baud;
_sp->Parity = Parity::None;
_sp->DataBits = 8;
_sp->StopBits = StopBits::One;
_sp->Open();
}
catch (Exception^ ex)
{
System::Diagnostics::Debug::WriteLine("Serial error: " + ex->Message);
return false;
}
_run = true;
_thr = gcnew Thread(gcnew ThreadStart(this, &Joypad::RxLoop));
_thr->IsBackground = true;
_thr->Start();
return true;
}
/* ---------- остановка ---------------------------------------- */
void Stop()
{
_run = false;
if (_thr && _thr->IsAlive) _thr->Join();
if (_sp->IsOpen) _sp->Close();
}
property array<UInt16>^ Channels { array<UInt16>^ get() { return _ch; } }
private:
// ----------- поток приёма i-Bus ---------------------------------
void RxLoop()
{
array<Byte>^ buf = gcnew array<Byte>(64);
array<Byte>^ pkt = gcnew array<Byte>(32);
while (_run)
{
int read = 0;
try { read = _sp->Read(buf, 0, buf->Length); }
catch (TimeoutException^) { continue; }
for (int i = 0; i < read; ++i)
{
_fifo[_head++] = buf[i];
if (_head >= _fifo->Length) _head = 0;
if (_fifo[_head] == 0x20 && _fifo[(_head + 1) & 0x7F] == 0x40)
{
for (int j = 0; j < 32; ++j)
pkt[j] = _fifo[(_head + j) & 0x7F];
if (!CheckPkt(pkt)) continue;
ParseChannels(pkt);
// -------- 1) печать в консоль ----------------
std::cout << '\r';
for (int k = 0; k < 6; ++k)
std::cout << std::setw(6) << _ch[k] << ' ';
std::cout << std::flush;
// ---------------------------------------------
// -------- 2) необязательный вызов события ----
TickEvent(_ch); // raise
}
}
}
}
bool CheckPkt(array<Byte>^ p)
{
UInt16 sum = 0; for (int i = 0; i < 30; ++i) sum += p[i];
sum = 0xFFFF - sum;
return sum == (p[30] | p[31] << 8);
}
void ParseChannels(array<Byte>^ p)
{
for (int i = 0; i < 14; ++i)
_ch[i] = (UInt16)(p[2 + i * 2] | p[3 + i * 2] << 8);
}
/* ---------- поля --------------------------------------------- */
SerialPort^ _sp;
Thread^ _thr;
bool _run = false;
array<UInt16>^ _ch = gcnew array<UInt16>(14);
array<Byte>^ _fifo = gcnew array<Byte>(128);
int _head = 0;
};