From d901a440a7ee6feeda71cf507e52525c988b298d Mon Sep 17 00:00:00 2001
From: alivender <13898766233@163.com>
Date: Mon, 14 Jul 2025 17:15:35 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AE=8C=E5=96=84camera=E5=A4=8D?=
=?UTF-8?q?=E4=BD=8D=E9=80=BB=E8=BE=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
server/src/MsgBus.cs | 2 +-
server/src/Peripherals/CameraClient.cs | 67 ++++++++++---------
server/src/Services/HttpVideoStreamService.cs | 3 +-
3 files changed, 38 insertions(+), 34 deletions(-)
diff --git a/server/src/MsgBus.cs b/server/src/MsgBus.cs
index 0f653e8..573b074 100644
--- a/server/src/MsgBus.cs
+++ b/server/src/MsgBus.cs
@@ -3,7 +3,7 @@
///
public static class MsgBus
{
- private static readonly UDPServer udpServer = new UDPServer(1234, 11);
+ private static readonly UDPServer udpServer = new UDPServer(1234, 12);
///
/// 获取UDP服务器
///
diff --git a/server/src/Peripherals/CameraClient.cs b/server/src/Peripherals/CameraClient.cs
index d2e4408..2b1ff20 100644
--- a/server/src/Peripherals/CameraClient.cs
+++ b/server/src/Peripherals/CameraClient.cs
@@ -1,5 +1,6 @@
using System.Net;
using DotNext;
+using Peripherals.PowerClient;
namespace Peripherals.CameraClient;
@@ -27,7 +28,7 @@ class Camera
const uint CAM_I2C_ADDR = 0x3C;
const Peripherals.I2cClient.I2cProtocol CAM_PROTO = Peripherals.I2cClient.I2cProtocol.SCCB;
- const byte PLL_MUX = 60;
+ const byte PLL_MUX = 105;
const UInt32 FrameAddr = 0x00;
// 动态分辨率参数
@@ -54,6 +55,8 @@ class Camera
public async ValueTask> Init()
{
+ await PowerHardwareCamera(true);
+ await SleepHardwareCamera(false);
// 步骤1: 复位
var resetResult = await Reset();
if (!resetResult.IsSuccessful) return resetResult;
@@ -139,14 +142,16 @@ class Camera
var resolutionResult = await ConfigureResolution1280x720();
if (!resolutionResult.IsSuccessful) return resolutionResult;
- // 步骤22: 开始流
+ // // 步骤22: 开始流
var startResult = await StartStreaming();
if (!startResult.IsSuccessful) return startResult;
+ // var resetResult2 = await Reset();
+ // if (!resetResult2.IsSuccessful) return resetResult2;
return true;
}
- public async ValueTask> EnableCamera(bool isEnable)
+ public async ValueTask> EnableHardwareTrans(bool isEnable)
{
var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, CameraAddr.CAPTURE_ON, Convert.ToUInt32(isEnable));
if (!ret.IsSuccessful)
@@ -162,7 +167,7 @@ class Camera
return true;
}
- public async ValueTask> EnableCameraHardware(bool isEnable)
+ public async ValueTask> PowerHardwareCamera(bool isEnable)
{
{
var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, CameraAddr.CAMERA_POWER, (isEnable ? 0x00000001u : 0x00000000u));
@@ -180,7 +185,7 @@ class Camera
return true;
}
- public async ValueTask> SleepCameraHardware(bool isEnable)
+ public async ValueTask> SleepHardwareCamera(bool isEnable)
{
{
var ret = await UDPClientPool.WriteAddr(this.ep, this.taskID, CameraAddr.CAMERA_POWER, (isEnable ? 0x00000101u : 0x00000001u));
@@ -323,7 +328,7 @@ class Camera
}
else
{
- await Task.Delay(3); // 其他命令延时3ms
+ await Task.Delay(5); // 其他命令延时3ms
}
}
}
@@ -404,11 +409,6 @@ class Camera
// 2. 配置I2C寄存器
var resolutionRegisters = new UInt16[][]
{
- // H_OFFSET/V_OFFSET
- [0x3810, unchecked((byte)((hOffset >> 8) & 0xFF))],
- [0x3811, unchecked((byte)(hOffset & 0xFF))],
- [0x3812, unchecked((byte)((vOffset >> 8) & 0xFF))],
-
// H_START/V_START
[0x3800, unchecked((byte)((hStart >> 8) & 0xFF))],
[0x3801, unchecked((byte)(hStart & 0xFF))],
@@ -433,6 +433,10 @@ class Camera
[0x380E, unchecked((byte)((vts >> 8) & 0xFF))],
[0x380F, unchecked((byte)(vts & 0xFF))],
+ // H_OFFSET/V_OFFSET
+ [0x3810, unchecked((byte)((hOffset >> 8) & 0xFF))],
+ [0x3811, unchecked((byte)(hOffset & 0xFF))],
+ [0x3812, unchecked((byte)((vOffset >> 8) & 0xFF))],
// Timing Voffset
[0x3813, unchecked((byte)(vOffset & 0xFF))]
};
@@ -561,10 +565,11 @@ class Camera
{
var resetRegisters = new UInt16[][]
{
- [0x30, 0x08, 0x82] // 复位命令
+ [0x3103, 0x11],// system clock from pad, bit[1]
+ [0x3008, 0x82] // 复位命令
};
- return await ConfigureRegisters(resetRegisters, customDelayMs: 5); // 复位后等待5ms
+ return await ConfigureRegisters(resetRegisters, customDelayMs: 50); // 复位后等待5ms
}
///
@@ -589,7 +594,7 @@ class Camera
{
var basicRegisters = new UInt16[][]
{
- [0x3103, 0x02],
+ [0x3103, 0x02], // system clock from pad, bit[1]
[0x3017, 0xff],
[0x3018, 0xff],
[0x3037, 0x13],
@@ -646,9 +651,7 @@ class Camera
{
[0x3905, 0x02],
[0x3906, 0x10],
- [0x3901, 0x0a],
- [0x3035, 0x11], // 30fps
- [0x3036, PLL_MUX] // PLL倍频
+ [0x3901, 0x0a]
};
return await ConfigureRegisters(clockRegisters);
@@ -706,7 +709,6 @@ class Camera
[0x3c04, 0x28],
[0x3c05, 0x98],
[0x3c06, 0x00],
- [0x3c07, 0x08],
[0x3c08, 0x00],
[0x3c09, 0x1c],
[0x3c0a, 0x9c],
@@ -766,10 +768,6 @@ class Camera
[0x3a1e, 0x26], // AEC控制;stable range out low
[0x3a11, 0x60], // AEC控制; fast zone high
[0x3a1f, 0x14], // AEC控制; fast zone low
- [0x3a02, 0x17], // 60Hz max exposure
- [0x3a03, 0x10], // 60Hz max exposure
- [0x3a14, 0x17], // 50Hz max exposure
- [0x3a15, 0x10], // 50Hz max exposure
[0x3b07, 0x0a] // 帧曝光模式
};
@@ -913,14 +911,13 @@ class Camera
{
var timingRegisters = new UInt16[][]
{
- [0x3820, 0x46], // vflip
- [0x3821, 0x01], // mirror
- [0x3814, 0x31], // timing X inc
- [0x3815, 0x31], // timing Y inc
- [0x3618, 0x00],
- [0x3612, 0x29],
- [0x3709, 0x52],
- [0x370c, 0x03]
+ [0x3035, 0x11], // 60fps
+ [0x3036, PLL_MUX],// PLL倍频
+ [0x3c07, 0x08],
+ [0x3820, 0x41], // vflip
+ [0x3821, 0x00], // mirror
+ [0x3814, 0x11], // timing X inc
+ [0x3815, 0x11] // timing Y inc
};
return await ConfigureRegisters(timingRegisters);
@@ -934,14 +931,22 @@ class Camera
{
var testRegisters = new UInt16[][]
{
+ [0x3618, 0x00],
+ [0x3612, 0x29],
+ [0x3709, 0x52],
+ [0x370c, 0x03],
[0x4004, 0x02], // BLC(背光) 2 lines
[0x4713, 0x03], // JPEG mode 3
[0x4407, 0x04], // 量化标度
[0x460c, 0x20],
+ [0x3a02, 0x17], // 60Hz max exposure
+ [0x3a03, 0x10], // 60Hz max exposure
+ [0x3a14, 0x17], // 50Hz max exposure
+ [0x3a15, 0x10], // 50Hz max exposure
[0x4837, 0x22], // DVP CLK divider
[0x3824, 0x02], // DVP CLK divider
// 彩条测试禁用
- [0x503d, 0x00],
+ [0x503d, 0x80],
[0x4741, 0x00],
// 闪光灯配置
[0x3016, 0x02],
diff --git a/server/src/Services/HttpVideoStreamService.cs b/server/src/Services/HttpVideoStreamService.cs
index 442a654..e6209d2 100644
--- a/server/src/Services/HttpVideoStreamService.cs
+++ b/server/src/Services/HttpVideoStreamService.cs
@@ -156,8 +156,7 @@ public class HttpVideoStreamService : BackgroundService
throw new Exception("Please config camera first");
}
_cameraEnable = isEnabled;
- await _camera.EnableCamera(_cameraEnable);
- await _camera.SleepCameraHardware(!_cameraEnable);
+ await _camera.EnableHardwareTrans(_cameraEnable);
}
///