44 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			44 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # pig-house-controller
 | ||
| 
 | ||
| ## LoRa通信协议约定
 | ||
| 
 | ||
| 本项目中的LoRa通信采用自定义的帧格式,以支持精确寻址和大数据包的自动分片与重组。所有数据包均由主控节点主动发起。
 | ||
| 
 | ||
| ### 1. 物理帧结构
 | ||
| 
 | ||
| 每个通过LoRa UART模块发送的物理数据包都遵循以下结构:
 | ||
| 
 | ||
| | 字段                       | 长度 (字节) | 值 (Hex)          | 描述                            |
 | ||
| |:-------------------------| :------------ | :---------------- |:------------------------------|
 | ||
| | **帧头 (Header)**          | 1             | `0xED`            | 固定值,表示一个数据包的开始。               |
 | ||
| | **数据长度 (Length)**        | 1             | `0x00`-`0xFF`     | 从`总包数`字段到`数据块`末尾的总字节数,不包含源地址。 |
 | ||
| | **目标地址 (DestAddr)**      | 2             | `0x0000`-`0xFFFF` | 接收该数据包的设备地址。                  |
 | ||
| | **总包数 (TotalChunks)**    | 1             | `0x01`-`0xFF`     | 表示当前消息被分成了几个包。`0x01`代表这是唯一的包。 |
 | ||
| | **当前包序号 (CurrentChunk)** | 1             | `0x00`-`0xFE`     | 当前是第几个数据包(从0开始计数)。            |
 | ||
| | **数据块 (ChunkData)**      | N             | -                 | 实际传输的数据片段。                    |
 | ||
| | **源地址 (SourceAddr)**      | 2             | `0x0000`-`0xFFFF` | 发送该数据包的设备地址,由硬件自动拼接。          |
 | ||
| 
 | ||
| **示例:**
 | ||
| 
 | ||
| 发送一个数据为 `[0x01, 0x02, 0x03]` 的单包消息到地址 `0x1234`,发送方地址为 `0x5678`:
 | ||
| `ED 05 12 34 01 00 01 02 03 56 78`
 | ||
| - `ED`: 帧头
 | ||
| - `05`: 后续长度 (1+1+3 = 5)
 | ||
| - `12 34`: 目标地址
 | ||
| - `01`: 总包数 (共1包)
 | ||
| - `00`: 当前包序号 (第0包)
 | ||
| - `01 02 03`: 数据块
 | ||
| - `56 78`: 源地址
 | ||
| 
 | ||
| ### 2. 数据分片 (Fragmentation)
 | ||
| 
 | ||
| - LoRa模块的物理层限制单次发送的数据部分**最大为240字节**。
 | ||
| - 根据项目约定,为自定义协议头(总包数、当前包序号)预留2字节,地址由模块处理。
 | ||
| - 因此,每个物理包中 **`数据块 (ChunkData)` 的最大长度为 `238` 字节**。
 | ||
| - `send_packet` 方法会自动处理分片逻辑。
 | ||
| 
 | ||
| ### 3. 数据重组 (Reassembly)
 | ||
| 
 | ||
| - `receive_packet` 方法会缓存收到的分片。
 | ||
| - 当一个设备的所有分片都接收完毕后,`receive_packet` 会将它们自动重组成一个完整的消息,并向上层返回。
 | ||
| - 由于通信是单向的(仅主控发送),接收端无需管理多个源地址的重组缓冲区。 |