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); } ///