Advertisement
Ilya_Bykonya

Untitled

Mar 17th, 2024
471
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Arduino 6.89 KB | Source Code | 0 0
  1. enum ReceiveMessageState {
  2.   WaitHeader = 0x1,
  3.   WaitBody = 0x2,
  4.   WaitCRC = 0x3
  5. };
  6.  
  7. template<
  8.   typename ReceiveBufferType, size_t receive_buffer_size,
  9.   typename SendBufferType, size_t send_buffer_size,
  10.   size_t receive_header_size, const uint8_t receive_header_bytes[receive_header_size],
  11.   size_t send_header_size, const uint8_t send_header_bytes[send_header_size]
  12. >
  13. class ComPortReadWriteController: public Printable {
  14. public:
  15.   typedef uint8_t (*CrcCalculateFunction)(uint8_t*, size_t);
  16. private:
  17.   //stream
  18.   Stream& m_stream{};
  19.   // receive
  20.   ReceiveBufferType m_receive_buffer[receive_buffer_size]{};
  21.   ReceiveMessageState m_receive_state = ReceiveMessageState::WaitHeader;
  22.   CrcCalculateFunction m_receive_crc_calculator{};
  23.   // send
  24.   SendBufferType m_send_buffer[send_buffer_size]{};
  25.   CrcCalculateFunction m_send_crc_calculator{};
  26. public:
  27.   ComPortReadWriteController(Stream& stream, CrcCalculateFunction receive_crc_calculator, CrcCalculateFunction send_crc_calculator)
  28.     :m_stream{ stream }, m_receive_crc_calculator{ receive_crc_calculator }, m_send_crc_calculator{ send_crc_calculator } {}
  29. public:
  30.   // receive
  31.   const ReceiveBufferType* receive_data() const { return m_receive_buffer; }
  32.   ReceiveBufferType* receive_data() { return m_receive_buffer; }
  33.   size_t receive_size() const { return receive_buffer_size; }
  34.   // send
  35.   const SendBufferType* send_data() const { return m_send_buffer; }
  36.   SendBufferType* send_data() { return m_send_buffer; }
  37.   size_t send_size() const { return send_buffer_size; }
  38. private:
  39.   // receive
  40.   constexpr size_t receive_bytes_count() const { return receive_buffer_size * sizeof(ReceiveBufferType); }
  41.   const uint8_t* receive_raw_data() const { return reinterpret_cast<const uint8_t*>(m_receive_buffer); }
  42.   uint8_t* receive_raw_data() { return reinterpret_cast<const uint8_t*>(m_receive_buffer); }
  43.   // send
  44.   constexpr size_t send_bytes_count() const { return send_buffer_size * sizeof(SendBufferType); }
  45.   const uint8_t* send_raw_data() const { return reinterpret_cast<const uint8_t*>(m_send_buffer); }
  46.   uint8_t* send_raw_data() { return reinterpret_cast<const uint8_t*>(m_send_buffer); }
  47. public:
  48.   size_t printToInternalStream() const { return printTo(m_stream); }
  49.   virtual size_t printTo(Print& p) const override final {
  50.     return (p.write(send_header_bytes, send_header_size) + p.write(send_raw_data(), send_bytes_count()) +
  51.       p.write(m_send_crc_calculator(send_raw_data(), send_bytes_count())));
  52.   }
  53.   bool handle_read_process() {
  54.     switch (m_receive_state) {
  55.       case ReceiveMessageState::WaitHeader: {
  56.         return handle_wait_header();
  57.       }
  58.       case ReceiveMessageState::WaitBody: {
  59.         return handle_wait_body();
  60.       }
  61.       case ReceiveMessageState::WaitCRC: {
  62.         return handle_wait_crc();
  63.       }
  64.       default: {
  65.         m_receive_state = ReceiveMessageState::WaitHeader;
  66.         return false;
  67.       }
  68.     }
  69.   }
  70.   ReceiveMessageState state() const {
  71.     return m_receive_state;
  72.   }
  73. private:
  74.   bool handle_wait_header() {
  75.     if(m_stream.available() < receive_header_size)
  76.       return false;
  77.  
  78.     for(size_t index = 0; index < receive_header_size; ++index)
  79.     {
  80.       const auto header_byte = static_cast<uint8_t>(m_stream.read());
  81.       // Serial.print("Receive header byte: ");
  82.       // Serial.print(header_byte);Serial.print(":");
  83.       // Serial.print(receive_header_bytes[index]);Serial.print(":");
  84.       // Serial.print(index);Serial.print(":");
  85.       // Serial.println(receive_header_size);
  86.       if(header_byte != receive_header_bytes[index])
  87.         return false;
  88.     }
  89.  
  90.     m_receive_state = ReceiveMessageState::WaitBody;
  91.     return handle_wait_body();
  92.   }
  93.   bool handle_wait_body() {
  94.     if(m_stream.available() < receive_bytes_count())
  95.       return false;
  96.  
  97.     // Serial.println("Receive body: ");
  98.     m_stream.readBytes(receive_raw_data(), receive_bytes_count());
  99.     m_receive_state = ReceiveMessageState::WaitCRC;
  100.     return handle_wait_crc();
  101.   }
  102.   bool handle_wait_crc() {
  103.     if(m_stream.available() < 1)
  104.       return false;
  105.  
  106.     const auto crc_byte = static_cast<uint8_t>(m_stream.read());
  107.     // Serial.print("Receive CRC: "); Serial.println(crc_byte);
  108.     m_receive_state = ReceiveMessageState::WaitHeader;
  109.     return m_receive_crc_calculator(receive_raw_data(), receive_bytes_count()) == crc_byte;
  110.   }
  111. };
  112.  
  113. template<
  114.   typename BufferType, size_t receive_buffer_size, size_t send_buffer_size,
  115.   size_t header_size, const uint8_t header_bytes[header_size]
  116. >
  117. class ComPortSymmetricReadWriteController: public ComPortReadWriteController<
  118.   BufferType, receive_buffer_size,
  119.   BufferType, send_buffer_size,
  120.   header_size, header_bytes,
  121.   header_size, header_bytes
  122. > {
  123. public:
  124.     ComPortSymmetricReadWriteController(Stream& stream, typename ComPortSymmetricReadWriteController::CrcCalculateFunction crc_calculator)
  125.       :ComPortReadWriteController<
  126.         BufferType, receive_buffer_size, BufferType, send_buffer_size,
  127.         header_size, header_bytes, header_size, header_bytes
  128.       >{ stream, crc_calculator, crc_calculator } {}
  129. };
  130.  
  131.  
  132.  
  133. constexpr const uint8_t header_controller[2]{ 0x2B, 0x20 };
  134. uint8_t calculate_crc_function(uint8_t* bytes, size_t length) {
  135.   uint16_t data_sum{ 0 };
  136.   for (size_t index = 0; index < length; ++index)
  137.     data_sum += bytes[index];
  138.  
  139.   return static_cast<uint8_t>(256 - static_cast<uint8_t>(data_sum));
  140. }
  141. ComPortSymmetricReadWriteController<uint16_t, 3, 5, 2, header_controller> com_port_buffer {
  142.   Serial, calculate_crc_function
  143. };
  144.  
  145.  
  146. void setup() {
  147.   Serial.begin(9600);
  148. }
  149. void loop() {
  150.   // Controller handing
  151.   com_port_buffer.send_data()[1] = static_cast<uint16_t>(com_port_buffer.state());
  152.  
  153.   static uint64_t last_send_receive_state_time{ 0 };
  154.   if(const auto current_time = millis(); last_send_receive_state_time + 1000 < current_time)
  155.   {
  156.     last_send_receive_state_time = current_time;
  157.     // Serial.print("Current receive state: "); Serial.println(static_cast<uint16_t>(com_port_buffer.state()));
  158.   }
  159.  
  160.  
  161.  
  162.  
  163.   static uint64_t last_controller_receive_time{ 0 };
  164.   if(const auto current_time = millis(); last_controller_receive_time + 500 < current_time)
  165.   {
  166.     last_controller_receive_time = current_time;
  167.     com_port_buffer.send_data()[0] += 1;
  168.   }
  169.   // ==================
  170.   // Send data to arrow
  171.   static uint64_t last_send_message_to_serial_millis{ 0 };
  172.   if(const auto current_time = millis(); last_send_message_to_serial_millis + 500 < current_time) {
  173.     last_send_message_to_serial_millis = current_time;
  174.     Serial.print(com_port_buffer);
  175.   }
  176.   // ==================
  177.  
  178.   // Receive data from arrow
  179.   if(com_port_buffer.handle_read_process()) {
  180.     com_port_buffer.send_data()[0] = 0;
  181.     for(size_t index = 0; index < com_port_buffer.receive_size(); ++index) {
  182.       com_port_buffer.send_data()[2 + index] = 2 * com_port_buffer.receive_data()[index];
  183.     }
  184.   }
  185.   // =======================
  186. }
  187.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement