新闻 – 软件开发_上位机开发_物联网开发_APP开发_深圳软件定制开发公司 https://www.unicrom.cn 由你创 Tue, 08 Jul 2025 06:47:11 +0000 zh-CN hourly 1 https://wordpress.org/?v=6.5.5 https://unicrom.oss-cn-hangzhou.aliyuncs.com/2024/11/官网网址-1.png 新闻 – 软件开发_上位机开发_物联网开发_APP开发_深圳软件定制开发公司 https://www.unicrom.cn 32 32 图像采集上位机系统开发 https://www.unicrom.cn/8705.html Tue, 08 Jul 2025 06:47:05 +0000 https://www.unicrom.cn/?p=8705 一、核心概念
  • 上位机: 指运行在主机(通常是PC或工控机)上,用于监控、控制下位机(如相机、图像采集卡、PLC等)并处理数据的软件系统。
  • 图像采集: 指通过特定的硬件(相机+镜头+光源+图像采集卡/接口)将光学图像转换为数字图像数据的过程。
  • 图像采集上位机系统: 运行在PC/工控机上的软件,负责:
    • 控制相机参数(曝光、增益、白平衡、触发模式等)。
    • 接收、缓存、处理和显示来自相机/采集卡的图像数据。
    • 提供用户界面进行交互(配置、预览、保存、分析)。
    • 可能包含图像处理、分析、测量、识别等功能。
    • 与其他系统(如PLC、数据库、MES)通信。

二、关键组成部分

  1. 硬件层:
    • 成像设备:
      • 工业相机: 面阵/线阵、CCD/CMOS、USB3 Vision/GigE Vision/Camera Link/CoaXPress 等接口、分辨率、帧率、色彩(黑白/彩色)。
      • 镜头: 焦距、光圈、接口(C/CS/F等)、视场角、景深。
      • 光源: LED光源(环形、条形、背光、同轴光等)、光源控制器(触发、亮度调节)。
    • 图像传输与采集:
      • 接口: USB3, GigE, Camera Link, CoaXPress 等。
      • 采集卡: 对于 Camera Link 和某些 CoaXPress 相机是必需的,负责高速数据接收和预处理(如DMA传输)。
    • 主机: PC 或工业控制计算机,需要足够的CPU、内存、GPU(如涉及GPU加速处理)、存储空间和稳定的操作系统。接口需匹配相机(USB端口、网卡、PCIe槽位)。
    • 触发与同步:
      • 硬件触发: 使用PLC、传感器(光电、编码器)等发出触发信号给相机或光源控制器。
      • 软件触发: 由上位机软件发出指令触发采集。
      • 同步: 确保相机曝光、光源点亮、机械运动(如传送带)精确同步。
  2. 驱动层:
    • 相机SDK: 相机厂商提供的软件开发包(如Basler Pylon, FLIR Spinnaker, Teledyne DALSA Sapera, Matrox Imaging Library (MIL), Allied Vision Vimba, Point Grey FlyCapture等)。这是与相机通信、控制参数、获取图像数据的基础。GenICam 标准使得不同厂商的相机可以通过统一的API(如Aravis, Harvester)访问。
    • 采集卡驱动/SDK: 如果使用采集卡,需要其厂商提供的驱动和开发库。
    • 操作系统驱动: USB、网卡等底层驱动。
  3. 软件层(上位机应用核心):
    • 用户界面:
      • 主窗口:图像显示区域(单/多视图)、控制面板、状态栏。
      • 相机/设备管理:枚举、连接/断开、选择。
      • 参数控制面板:实时调整曝光、增益、ROI、触发模式等。
      • 采集控制:开始/停止采集、单帧采集、连续采集、触发采集。
      • 图像处理/分析面板:调用处理算法,显示结果(如测量值、标记)。
      • 文件操作:保存图像(原始/处理后)、加载图像、录像。
      • 设置管理:保存/加载配置。
      • 日志与状态显示:运行日志、错误提示、帧率显示。
    • 图像采集引擎:
      • 相机/采集卡控制: 通过SDK API连接设备、设置参数、注册回调函数。
      • 图像获取: 高效接收图像数据(回调模式、轮询模式)。
      • 缓冲区管理: 设计高效的循环缓冲区(Ring Buffer)或队列,防止丢帧。尤其在高帧率下至关重要。
      • 图像转换与封装: 将SDK返回的原始数据(可能是特殊格式如Bayer Pattern)转换为标准图像格式(RGB, Mono8, Mono16等)并封装成易于处理的图像对象。
      • 时间戳与帧计数: 记录图像的时间信息和序列号。
    • 图像处理与分析模块:
      • 预处理: 去噪、滤波、二值化、形态学操作、几何变换(旋转、缩放)、色彩空间转换等。
      • 分析: 边缘检测、轮廓提取、Blob分析、尺寸测量、模板匹配(Pattern Matching)、OCR、缺陷检测等。
      • 库/框架: OpenCV (最常用,开源强大), Halcon (商业,功能强大,性能优异,价格高), VisionPro (商业,Cognex), MIL (商业,Matrox), AForge.NET (开源,.NET), Scikit-image (Python) 等。
    • 数据管理:
      • 图像存储:保存到本地文件(BMP, JPG, PNG, TIFF, RAW)或数据库。
      • 结果存储:将测量结果、分析报告保存到文件(CSV, TXT, Excel)或数据库(SQLite, MySQL, SQL Server, Oracle)。
      • 录像功能:保存为视频文件(AVI, MP4)。
    • 通信模块:
      • 与下位机通信: 通过串口(RS232/485)、以太网(TCP/UDP/Modbus TCP)、现场总线(Profinet, EtherCAT) 等与PLC、机器人或其他控制器交换指令(启动/停止、结果OK/NG)和状态信息。
      • 与数据库/MES通信: 将检测结果、生产数据上传到企业数据库或制造执行系统。
    • 辅助功能:
      • 日志记录(操作日志、错误日志)。
      • 用户权限管理。
      • 多语言支持(国际化)。
      • 自动更新。
      • 脚本支持(自动化任务)。
  4. 通信与集成层:
    • 网络协议栈(TCP/IP)。
    • 串口通信库。
    • 数据库连接库(ODBC, JDBC, ADO.NET, ORM)。
    • OPC UA/DA 客户端(用于工业自动化系统集成)。
    • Web Service/REST API(提供对外接口)。

三、开发流程建议

  1. 需求分析:
    • 明确应用场景(检测、测量、识别、定位、读码等)。
    • 确定核心指标:分辨率、帧率、精度、速度、稳定性要求。
    • 定义硬件规格:相机类型/接口、镜头、光源、是否需要采集卡、主机配置。
    • 定义软件功能:必须功能(采集、显示、保存、基本测量)、高级功能(复杂分析、通信)、UI需求、性能要求。
    • 确定通信接口和协议(与PLC、数据库等)。
    • 考虑未来扩展性。
  2. 硬件选型与搭建:
    • 根据需求选择相机、镜头、光源、采集卡、主机、线缆等。
    • 搭建光学成像系统,确保成像质量满足要求。
    • 连接并测试硬件触发/同步(如果使用)。
  3. 软件架构设计:
    • 选择技术栈:
      • 编程语言: C++ (性能最优,常用于工业级), C# (.NET平台,开发效率高,Windows首选), Python (开发快,生态好,性能需优化,或结合C++模块), Java (跨平台性好), LabVIEW (图形化,快速原型,性能有时受限)。
      • UI框架: Qt (C++/Python, 跨平台强大), WinForms/WPF (C#, Windows), PyQt/PySide (Python + Qt), JavaFX (Java)。
      • 图像处理库: OpenCV (首选开源), Halcon/VisionPro/MIL (商业高性能方案)。
      • 相机SDK: 根据所选相机确定 (Pylon, Vimba, Sapera, FlyCapture 等或 GenICam API)。
      • 数据库: SQLite (轻量级本地), MySQL/MariaDB/PostgreSQL (网络), SQL Server/Oracle (企业级)。
      • 通信库: 根据协议选择(如 .NET 的 SerialPort, Socket; C++ 的 Boost.Asio; Python 的 PySerial, socket)。
    • 设计模式:
      • MVVM/MVC: 分离UI逻辑与业务逻辑,提高可维护性。
      • 生产者-消费者: 核心模式!图像采集线程(生产者)将图像放入缓冲区,处理/显示线程(消费者)从中取出处理。使用线程安全队列(Qt的QQueue, C#的ConcurrentQueue, C++的std::queue+mutex/condition_variable)或环形缓冲区。
      • 事件驱动: 相机SDK通常基于回调(事件),驱动采集流程。
      • 插件架构: 如果算法多变,可考虑将处理模块设计为插件。
    • 模块划分: 清晰划分设备管理、采集引擎、图像处理、UI、通信、数据存储等模块。
  4. 核心模块开发:
    • 设备连接与初始化: 使用SDK枚举、连接相机/采集卡,获取设备信息。
    • 参数设置与控制: 实现UI控件与相机参数(曝光、增益、触发源/模式、ROI等)的绑定和设置。
    • 图像采集引擎:
      • 设置采集模式(连续、单帧、触发)。
      • 实现回调函数处理接收到的图像帧。
      • 高效缓冲区管理: 这是防止丢帧的关键。确保生产者(采集线程)不会覆盖消费者(处理/显示线程)还未处理完的帧。使用多缓冲策略。
      • 图像格式转换(如Bayer转RGB/Mono)。
    • 图像显示: 高效地将图像数据显示在UI控件上(注意跨线程UI更新问题)。
    • 基本图像处理与保存: 集成OpenCV等库,实现预览缩放、平移、伪彩、直方图、保存图像(不同格式)功能。
  5. 高级功能开发:
    • 图像分析算法: 根据需求实现或集成特定算法(如边缘检测、Blob分析、模板匹配、OCR)。
    • 通信模块: 实现与PLC的串口/网口通信,与数据库的连接和操作。
    • 结果记录与报告: 设计数据结构存储结果,实现报告生成(PDF, Excel)或数据库存储。
    • 用户管理、日志、配置管理。
  6. 测试与优化:
    • 单元测试: 测试核心模块功能。
    • 集成测试: 测试模块间协作,特别是图像流、处理流水线。
    • 性能测试:
      • 帧率稳定性: 长时间运行,统计实际帧率,检查是否有丢帧。
      • 资源占用: 监控CPU、内存、GPU使用率。
      • 处理延迟: 从触发到结果输出的时间。
    • 稳定性测试: 长时间运行(24/48小时),模拟异常情况(断线、错误输入)。
    • 优化:
      • 算法优化: 选择高效算法,利用多线程并行处理,利用GPU加速 (OpenCV CUDA, Halcon HDevEngine)。
      • 内存优化: 避免不必要的拷贝,及时释放资源,使用内存池。
      • I/O优化: 异步文件保存、数据库操作。
      • 缓冲区调优: 调整缓冲区大小以适应处理速度。
  7. 部署与维护:
    • 打包安装程序。
    • 编写用户手册、技术文档。
    • 现场部署、调试。
    • 提供持续维护和更新。

四、技术选型建议(常见组合)

  • 工业级高性能方案:
    • 语言: C++
    • UI框架: Qt
    • 图像库: Halcon / VisionPro / OpenCV
    • 相机SDK: 厂商原生SDK (Pylon, Sapera等) 或 GenICam (Aravis)
    • 优点: 性能最优,资源控制最精细,跨平台(Qt),稳定性高。
    • 缺点: C++开发周期相对长,开发门槛稍高。
  • Windows平台快速开发方案:
    • 语言: C#
    • UI框架: WPF (现代化) / WinForms (成熟)
    • 图像库: OpenCV (通过Emgu CV等封装库) / Halcon (.NET接口) / VisionPro (.NET接口) / AForge.NET
    • 相机SDK: 厂商提供的.NET SDK (如Pylon.NET, Vimba.NET) 或 GenICam (.NET封装)
    • 优点: .NET开发效率高,生态丰富,UI强大(WPF),Windows集成好。
    • 缺点: 主要限于Windows平台(.NET Core跨平台性在工业应用支持度待提升)。
  • 快速原型/科研/轻量级方案:
    • 语言: Python
    • UI框架: PyQt / PySide (基于Qt) / Tkinter (简单)
    • 图像库: OpenCV-Python / Scikit-image / SimpleITK (医学)
    • 相机SDK: PyPylon (Basler), Harvester (GenICam), 厂商Python SDK 或 OpenCV的VideoCapture(通常仅支持USB/普通网络摄像头)
    • 优点: 开发速度极快,库丰富,易于学习和测试。
    • 缺点: 运行效率相对C++/C#低(关键部分可用Cython或调用C++模块优化),打包部署稍复杂,线程管理和性能优化需要更小心,UI响应性和大型项目维护性可能不如前两者。

深圳市由你创科技有限公司是一家专业从事上位机开发的高新技术企业,公司深耕高端上位机技术开发服务,聚焦工业上位机软件开发发与实验室设备上位机软件开发,专业为客户提供上位机软件定制开发、非标自动化软件开发、PLC上位机软件开发、单片机上位机软件开发、工控上位机软件开发、医疗设备上位机软件开发、仪器仪表设备上位机软件开发、LabVIEW软件定制开发、BMS电池管理系统软件、C#上位机软件、上位机检测采集软件等。

我们的行业定位:深圳市由你创科技专注于提供高质量、可交付、长期持续的高端上位机开发技术服务。广泛服务于生物医药、汽车电子、高端装备、能源电力、材料化工、检验检测等行业。

服务优势:深圳市由你创科技拥有自主研发团队超过百名,70%以上是中高级研发人员,您可选择灵活的服务方式。自建2000平方米研发中心,37年实体企业,军工级研发背景,可提供长期稳定的上位机开发技术服务。与国内多个科研院所、高校、上市公司等行业标杆企业达成长期战略合作。

深圳市由你创专业服务队,整合先进的项目管理方案和前沿的软件技术。为企业和科研单位的产品应用落地和科学研究提供强有力的支持,帮助客户实现可衡量的商业价值。

]]>
工控采集板卡定制开发 https://www.unicrom.cn/8695.html Tue, 08 Jul 2025 06:22:48 +0000 https://www.unicrom.cn/?p=8695 一、 明确需求

信号类型与数量:

  • 模拟输入:电压范围 (mV? V?)、电流 (4-20mA? 0-20mA?)、通道数、分辨率 (12位? 16位? 24位?)、采样率、精度要求、是否需要隔离?单端/差分?
  • 模拟输出:电压/电流范围、通道数、分辨率、刷新率、精度、驱动能力、隔离?
  • 数字输入:电压电平 (TTL? 5V? 24V?)、通道数、干接点/湿接点?采样率/响应速度?隔离?计数器需求 (编码器?)?
  • 数字输出:电压电平、通道数、驱动能力 (继电器? 晶体管? 开漏?)、开关频率?隔离?
  • 特殊接口:RS232/RS485/RS422? CAN? EtherCAT? Profibus? 以太网? USB? PCIe? PCI? 其他工业总线?
  • 其他传感器接口:热电偶 (T/C)? RTD? 应变片 (桥路)? IEPE? 加速度计? 特定传感器协议?

性能指标:

  • 采样率/吞吐量:数据采集和传输的最大速率。
  • 精度:ADC/DAC 的 INL/DNL,整体系统误差。
  • 稳定性:温漂、时漂。
  • 实时性:确定性延迟要求?(对运动控制、高速采集尤为重要)。
  • 同步性:多通道间是否需要严格同步?板卡间同步?

环境要求:

  • 工作温度范围:工业级 (0~70°C)? 宽温 (-40~85°C)?
  • 湿度、振动、冲击、EMC (电磁兼容性):需要满足哪些标准 (如 IEC 61000-4-x)? 防护等级?
  • 电源:输入电压范围?功耗预算?

机械与电气接口:

  • 板卡尺寸:标准尺寸 (如 PCI, PCIe, PXI, PXIe, CompactPCI, VPX) 还是自定义尺寸?
  • 连接器类型:螺丝端子? DBxx? D-Sub? DIN? 航空插头? 欧式连接器? 板对板连接器? 位置和数量。
  • 安装方式:导轨? 面板? 机箱内插卡?

软件与驱动:

  • 操作系统支持:Windows? Linux (RT-Preempt? Xenomai?)? VxWorks? QNX? 其他RTOS?
  • 驱动程序:需要提供标准的驱动接口 (如 NI-DAQmx, COMEDI, LabVIEW)? 自定义API (DLL, .so)? 底层寄存器访问?
  • 开发库/示例:提供何种语言 (C/C++, C#, Python, LabVIEW, MATLAB) 的库和示例代码?
  • 配置工具:是否需要图形化配置软件?

可靠性与维护:

  • MTBF (平均无故障时间) 要求?
  • 诊断功能:板卡状态自检? LED 指示?
  • 固件升级:是否支持现场升级 (如通过 USB/以太网)?

成本与数量:

  • 目标成本:单板成本? 开发成本预算?
  • 预期生产数量:小批量? 中批量? 大批量? (直接影响元器件选型和设计策略)

认证与标准:

  • 需要满足哪些行业或地区认证? (CE, FCC, UL, RoHS, REACH, 特定行业如医疗、轨道交通等)

    二、 开发流程

    需求分析与规格书定义: 与客户深入沟通,将需求转化为详细的、可量化的、双方确认的硬件规格说明书软件功能说明书。这是后续所有工作的基础和验收依据。

    系统架构设计:

    • 选择合适的处理器/控制器:MCU? FPGA? DSP? SoC (如 Xilinx Zynq, Intel Cyclone V SoC)? 基于性能、成本、灵活性考量。
    • 选择核心器件:ADC, DAC, 信号调理芯片 (放大器、滤波器、隔离器、保护电路)、数字 I/O 芯片、通信接口芯片、电源管理芯片等。
    • 总线接口选择:PCIe? USB? Ethernet? 定制背板?
    • 硬件框图设计。

    原理图设计: 根据选定的器件和架构,绘制详细的电路原理图。重点考虑信号完整性、电源完整性、噪声抑制、隔离设计、保护电路。

    PCB 设计与 Layout:

    • 元器件布局:考虑散热、信号流向、干扰隔离。
    • 布线:高速数字信号 (阻抗控制、差分对、长度匹配)、模拟信号 (避免数字噪声干扰、地线设计)、电源分配 (低阻抗路径、去耦电容放置)。
    • 层叠设计。
    • 严格遵循 EMC/EMI 设计规范。

    硬件原型制作与调试:

    • PCB 打样、SMT 贴片/手工焊接。
    • 硬件功能调试:电源、时钟、复位、基本接口通信。
    • 信号链调试:逐级测试信号调理、ADC/DAC 性能、数字 I/O 功能。
    • 环境测试 (初步):温漂、基本稳定性。

    嵌入式软件开发 (Firmware):

    • 处理器/FPGA 初始化、外设驱动开发 (ADC, DAC, GPIO, UART, SPI, I2C, Ethernet, USB 等)。
    • 数据采集控制逻辑、数据传输逻辑 (DMA, FIFO)。
    • 通信协议栈实现 (如 Modbus TCP, EtherCAT Slave Stack)。
    • 实时任务处理 (如果要求实时性)。
    • 固件升级机制。
    • 板载诊断与状态监控。

    驱动与 API 开发 (Host Software):

    • 开发操作系统下的设备驱动程序 (内核驱动或用户态驱动)。
    • 设计并实现用户友好的 API (如 DLL, .so, ActiveX)。
    • 开发配置工具或库。
    • 提供多种语言的示例程序。

    系统集成与测试:

    • 软硬件联合调试。
    • 全面功能测试: 覆盖所有需求规格。
    • 性能测试: 采样率、精度、稳定性、实时性、吞吐量。
    • 环境测试: 高低温、湿热、振动、冲击。
    • EMC 测试: 传导发射、辐射发射、静电放电、浪涌、快速瞬变脉冲群等 (根据目标标准)。
    • 可靠性测试: 长时间运行老化测试。
    • 兼容性测试: 在不同主机、操作系统版本上的测试。

    设计优化与定型: 根据测试结果进行设计迭代和优化。

    小批量试产 (NPI): 验证生产工艺、供应链稳定性。

    文档交付: 提供完整的文档,包括:

    • 硬件原理图、PCB Gerber 文件、BOM 表。
    • 软件源代码 (或库/驱动)、API 文档、用户手册。
    • 测试报告 (功能、性能、环境、EMC)。
    • 生产测试规范。

    量产与持续支持: 批量生产、质量管控、售后技术支持、可能的固件/软件更新。

      三、 如何选择靠谱的工控采集板开发服务商

      1. 专业经验: 在工控、数据采集、特定信号处理 (如高速、高精度、振动分析)、嵌入式系统、FPGA、相关总线协议 (EtherCAT, CAN) 方面有丰富经验。查看成功案例。
      2. 技术能力: 拥有硬件设计、高速PCB设计、EMC设计、嵌入式软件开发、驱动开发、测试验证的完整团队和能力。
      3. 质量体系: 遵循规范的开发流程 (如 ISO 9001),有严格的质量控制和测试手段。
      4. 供应链与生产管理: 具备元器件采购、PCBA 加工、测试、组装能力或可靠的合作伙伴。
      5. 沟通与服务: 沟通顺畅、响应及时、能提供良好的项目管理和技术支持。
      6. 成本与周期: 报价合理,能按承诺的周期交付。

      深圳市由你创科技有限公司是一家专业从事工控采集板定制开发的高新技术企业,公司深耕高端fpga开发服务,聚焦工业fpga开发与实验室fpga开发服务,专业为客户提供fpga定制开发、fpga电路设计开发、fpga硬件开发、fpga软件开发、医疗设备fpga板卡开发、仪器仪表设备fpga设计开发、嵌入式DSP开发、图像处理卡定制开发、esp32项目开发、采集板定制开发、国产化板卡定制、嵌入式板卡定制、集成电路板卡定制等。

      我们的行业定位:深圳市由你创科技专注于提供高质量、可交付、长期持续的高端fpga开发定制服务。广泛服务于通信、医疗、汽车电子、高端装备、能源电力、材料化工、检验检测等行业。

      服务优势:深圳市由你创科技拥有自主研发团队超过百名,70%以上是中高级研发人员,您可选择灵活的服务方式。自建2000平方米研发中心,37年实体企业,军工级研发背景,深圳市由你创科技可为客户提供长期稳定的fpga开发定制服务。与国内多个科研院所、高校、上市公司等行业标杆企业达成长期战略合作。

      深圳市由你创科技专业服务队,整合先进的项目管理方案和前沿的软件技术。为企业和科研单位的产品应用落地和科学研究提供强有力的支持,帮助客户实现可衡量的商业价值。

      ]]>
      下位机开发公司哪家好? https://www.unicrom.cn/8664.html Sat, 28 Jun 2025 09:55:54 +0000 https://www.unicrom.cn/?p=8664 在工业自动化、智能设备、物联网终端等领域的核心战场,下位机如同设备的“大脑”,其性能与稳定性直接决定了整个系统的成败。选择一家技术实力雄厚、经验丰富、服务到位的下位机开发公司,是您项目成功的关键一步。面对市场上众多的选择,哪家公司真正值得信赖?深圳市由你创科技有限公司,正是您寻找的专业下位机开发合作伙伴。

      为什么选择由你创?

      • 技术为本,实力铸就: 由你创科技的核心团队拥有深厚的嵌入式系统开发功底,精通 ARM Cortex-M系列、ESP32、RISC-V等主流平台,熟练掌握 C/C++、RTOS(如FreeRTOS、RT-Thread)、Linux嵌入式开发,并对各类通信协议(如UART, SPI, I2C, CAN, Modbus, Ethernet, 4G/5G, LoRa, Bluetooth, WiFi)有深刻理解和丰富实践经验。我们紧跟技术前沿,确保为您打造性能卓越、稳定可靠的下位机系统。
      • 经验丰富,行业深耕: 我们不是纸上谈兵的理论派。由你创科技在工业控制、智能家居、医疗设备、物联网终端、消费电子等多个领域成功交付了众多复杂下位机项目。无论是高精度数据采集、实时运动控制、低功耗无线连接,还是复杂的多任务调度,我们都积累了宝贵的实战经验和成熟的解决方案库,能快速理解您的需求,规避潜在风险。
      • 需求导向,量身定制: 我们深知,没有放之四海皆准的方案。由你创科技坚持深度需求分析,从您的具体应用场景、功能要求、性能指标、成本预算出发,提供高度定制化的下位机软硬件开发服务。我们不仅仅是写代码,更是为您打造解决实际问题的核心引擎
      • 流程规范,质量保障: 从需求确认、方案设计、硬件选型(或设计)、软件编码、单元测试、系统集成测试到严格的老化测试、压力测试、EMC测试,我们遵循严谨的开发流程和质量控制体系。确保交付给您的产品性能稳定、运行可靠、符合行业标准,经得起市场和时间的考验。
      • 响应迅捷,服务无忧: 选择由你创科技,您获得的不仅仅是一个开发团队,更是一个值得信赖的技术后盾。我们提供及时高效的沟通快速响应的技术支持,无论是开发过程中的需求微调,还是产品上市后的维护升级,我们都将全力以赴,确保您的项目顺利推进和产品长期稳定运行。
      • 立足深圳,辐射全国: 深圳作为中国电子信息和硬件创新的高地,拥有最完善的产业链和人才资源。由你创科技扎根于此,能够快速整合优质资源,为您提供高性价比的解决方案,并高效服务全国客户。

      成功案例印证实力

      • 某智能工厂产线控制系统: 为其开发了基于STM32和CAN总线的多节点实时PLC控制器,实现高精度运动控制和设备联动,提升生产效率25%,故障率显著降低。
      • 某高端医疗检测设备主控板: 完成了核心下位机软硬件开发,确保高速数据采集(精度达0.01%)多传感器同步以及符合严格医疗法规的稳定性和安全性,助力设备成功通过认证并上市。
      • 某物联网环境监测终端: 设计了超低功耗的LoRaWAN终端节点,集成多类传感器,实现野外环境数据的长周期、远距离、可靠传输,电池寿命超过3年。

      选择由你创科技,您将获得:

      • 强大的专业技术团队支撑
      • 经过验证的成熟行业解决方案
      • 稳定可靠的高质量产品交付
      • 灵活高效的定制开发服务
      • 省心无忧的全流程项目管理和技术支持
      • 极具竞争力的成本效益

      下位机开发流程

      ]]>
      Unity+nodejs简单实现webscoket聊天室 https://www.unicrom.cn/8646.html Sat, 28 Jun 2025 09:37:06 +0000 https://www.unicrom.cn/?p=8646 一、前言

      在这个互联网时代,几乎每个人都有微信或QQ这类实时通讯工具,现在很多网络游戏也带有实时聊天功能,那这样一个很常见的功能需要怎么实现呢?接下来我们就通过Unity+Nodejs来实现一个简单的聊天室吧!

      二、首先我们用unity搭建一个简单聊天室的页面:

      将左右两边的消息对象做成预制体方便后面创建;

      接着我们来实现C#代码:

      基础变量信息定义:

      接收消息方法定义,nodejs会转发json字符串到客户端,客户端再对消息进行解析处理

      接着,我们就可以开始编写连接websocket的代码,要记得和nodejs定义和通讯地址和端口,否则会连接不上哦!

      写好连接代码和接收消息的方法,我们还缺少一个发送消息的方法:

      将发送消息方法和发送按钮绑定

      这样,客户端的代码我们就写好了,只需要将脚本挂载到场景上了

      三、实现node代码

      nodejs代码的实现也不复杂,nodejs引入ws,就可以实现webscoket连接了,代码实现如下:

      接着就打开我们的cmd窗口,运行我们的nodejs脚本

      如果你没有安装ws模块,就会遇到下面这个报错

      我们需要用npm安装下ws模块

      安装成功后就可以再次执行node server.js命令了

      四、聊天室启动

      将应用打包后,我们打开两个窗口,一个为昵称A同学,一个昵称为B同学,他们两个就可以进行对话了

      在运行nodejs的cmd窗口我们也打印了客户端传过来的消息

      一个unity+nodejs的聊天室就这么搞定了,除了可以通过webscoket实现聊天室实时通讯以外,我们也可以实现游戏的多人实时联机,但这比聊天室复杂多了,因为要考虑到游戏的环境信息同步,玩家操作同步,这就留着下次有机会再讲吧!

      ]]>
      AI驱动的机器视觉技术 https://www.unicrom.cn/8642.html Sat, 28 Jun 2025 09:23:33 +0000 https://www.unicrom.cn/?p=8642  工业视觉算法,AI视觉模型这些都是老生常谈了,本期要讲的是升级版. ‌自进化检测系统.

         目前大多数据视觉检测算法,都是在某些固定场景,通过流水线或者多轴机械臂,来自动化检测目标状态,常见缺陷检测,或者目标计数等, 大多都能满足使用场景.

         随着越来越多的场景使用视觉自动化之后,有些场景对于固定的视觉算法,或者模型不能满足同场景下,目标环境多变的情况. 下发分享我们的一个实战案例.

         显微镜(3轴)自动识别玻片上的活体细胞,通过不通项目的玻片识别出活体细胞用于病变分析.  起初始项目给人类使用.  项目采用python+yolo算法+3轴PLC对玻片进行切片分析.

         随着客户的业务发展,客户将该产品应用到宠物上. 但是由于不同生物的情况不一样.导致识别率下降. 客户希望这个识别算法能自动升级.

         最终我们在这个基础上做出升级, 把一台算力好的电脑做为增量训练的服务器(云端的成本贵), 让所有显微镜,通过MQTT服务(云端)把数据传到本地服务器上.  由于在识别的时候,增加了把图像和识别目标信息打包成可用于增量训练的格式.   

         服务器每天把采集到的数据保存在本地,等训练结束之后. 立马开始新一轮增量训练.

         当训练出来的新模型文件,通过验证之后,识别率增加2%,就提示所有客户端,有新的更新.  用户 可以点击更新,或者稍后更新.  客户端(显微镜)通过下载新的模型文件,然后算法重新初始化,可以做在线热更新算法.  

      ‌   自进化检测系统,支持数据清洗与模型自训练,适应产线实时变化。这是一套低成本的实现方式.

      ]]>
      PXI高速采集卡定制开发 https://www.unicrom.cn/8637.html Tue, 08 Jul 2025 06:31:27 +0000 https://www.unicrom.cn/?p=8637 一、明确定制需求
      1. 性能参数
        • 采样率:≥1GS/s?需明确单通道/多通道同步能力
        • 分辨率:12/14/16位ADC选择(影响信噪比)
        • 输入范围:±1V至±10V可编程?是否需要硬件衰减器
        • 带宽:DC~500MHz(前端模拟电路设计关键)
        • 存储深度:板载DDR4容量(如8GB)决定连续采集时长
      2. 特殊功能
        • 实时信号处理:需集成FPGA实现FIR滤波/FFT加速
        • 多卡同步:PXI触发总线+星型触发精度(<100ps抖动)
        • 协议解析:如自定义工业总线解码(CAN FD、EtherCAT)
      3. 机械与环境
        • 3U/6U PXIe尺寸选择
        • 军工级温度范围(-40°C~+85°C)
        • 抗振动设计(MIL-STD-810G)

      二、硬件开发关键技术

      模块设计要点
      模拟前端– 多级保护电路(TVS+限幅器)
      – 低噪声运放(如ADI ADA4896)
      – 抗混叠滤波器自动切换
      ADC选型TI ADC12DJ5200RF(12位,5.2GS/s)或ADI AD9208(双通道,3GS/s)
      时钟架构– 低抖动时钟源(<50fs RMS)
      – 多通道相位同步设计
      – 支持外部时钟参考输入
      FPGA处理Xilinx Kintex UltraScale KU115(实现实时数据压缩/数字下变频)
      接口设计PXIe x8 Gen3接口(>6GB/s带宽),支持DMA零拷贝传输

      三、固件开发(FPGA逻辑核心)

      vhdl

      -- 示例:JESD204B接口数据接收模块
      entity jesd_rx is
        port(
          sysref : in std_logic;   -- 系统参考时钟
          adc_data : in serdes_array; -- 高速串行数据
          ...
        );
      end entity;
      
      architecture rtl of jesd_rx is
      begin
        -- 多通道数据对齐逻辑
        lane_alignment: process(sysref)
        begin
          if rising_edge(sysref) then
            -- 实现确定性延迟补偿
          end if;
        end process;
      end architecture;

      关键算法实现

      • 实时FFT(使用Xilinx DSP Slice优化)
      • 数字触发(支持窗口触发、欠幅触发)
      • 数据流压缩(如μ-law压缩降低50%带宽)

      四、软件栈开发

      1. 驱动程序
        • 符合IVI-COM标准架构
        • 支持Windows/Linux实时系统(如NI Linux Real-Time)
      2. API设计python# Python调用示例(基于C封装DLL) import ctypes pxi_dll = ctypes.WinDLL(“pxi_hsaq.dll”) pxi_dll.init_board(0) # 初始化槽位0设备 pxi_dll.set_sampling_rate(1e9) # 设置1GS/s采样 buffer = ctypes.create_string_buffer(1024*1024) pxi_dll.acquire_data(buffer, 1024*1024)
      3. 上位机软件
        • LabVIEW模块化架构(推荐用于快速原型开发)
        • 可选Qt/C#开发定制化界面

      五、验证与合规性

      1. 电气测试
        • 使用高精度信号源验证INL/DNL(如Keysight N6705C)
        • 眼图测试(≥8dB信噪比裕量)
      2. 系统集成测试
        • 多卡同步精度测量(需PXIe-6674T定时模块)
        • 持续72小时压力测试
      3. 认证要求
        • CE/FCC电磁兼容认证
        • PXI Systems Alliance硬件兼容性认证

      深圳市由你创科技有限公司是一家专业从事工控采集板定制开发的高新技术企业,公司深耕高端fpga开发服务,聚焦工业fpga开发与实验室fpga开发服务,专业为客户提供fpga定制开发、fpga电路设计开发、fpga硬件开发、fpga软件开发、医疗设备fpga板卡开发、仪器仪表设备fpga设计开发、嵌入式DSP开发、图像处理卡定制开发、esp32项目开发、采集板定制开发、国产化板卡定制、嵌入式板卡定制、集成电路板卡定制等。

      我们的行业定位:深圳市由你创科技专注于提供高质量、可交付、长期持续的高端fpga开发定制服务。广泛服务于通信、医疗、汽车电子、高端装备、能源电力、材料化工、检验检测等行业。

      服务优势:深圳市由你创科技拥有自主研发团队超过百名,70%以上是中高级研发人员,您可选择灵活的服务方式。自建2000平方米研发中心,37年实体企业,军工级研发背景,深圳市由你创科技可为客户提供长期稳定的fpga开发定制服务。与国内多个科研院所、高校、上市公司等行业标杆企业达成长期战略合作。

      深圳市由你创科技专业服务队,整合先进的项目管理方案和前沿的软件技术。为企业和科研单位的产品应用落地和科学研究提供强有力的支持,帮助客户实现可衡量的商业价值。

      ]]>
      如何选择一家靠谱的上位机软件开发服务商?  https://www.unicrom.cn/8450.html Wed, 16 Apr 2025 01:44:06 +0000 https://www.unicrom.cn/?p=8450 引言:上位机软件开发——企业智能化的核心引擎

      在工业4.0与数字化转型的浪潮下,上位机软件作为连接设备、数据与用户的“核心引擎”,其开发质量直接影响企业的生产效率与竞争力。然而,面对技术门槛高、需求多变、交付周期不可控等难题,如何选择一家技术过硬、服务可靠的上位机开发服务商?

      深圳市由你创科技有限公司全栈技术能力、行业深耕经验与准时交付承诺,成为众多企业做上位机开发的长期合作伙伴。本文从选择标准出发,深度解析由你创科技如何以技术赋能企业,助力智能化升级。

      一、选择上位机开发服务商的五大核心标准

      1. 技术实力:全栈开发与软硬协同能力

      • 编程语言与框架:精通C#(WPF/WinForms)、Python、C++(Qt)、Electron等主流技术栈,支持跨平台开发(Windows/Linux/Web/移动端)。
      • 硬件协议支持:深度适配Modbus、OPC UA、CAN、MQTT等工业与物联网协议,支持私有协议定制化开发。
      • 软硬件协同能力:与FPGA、嵌入式系统联合调试经验,确保数据链路低延迟、高可靠。

      深圳由你创科技优势

      • 自研通信中间件:优化FPGA与上位机数据传输,延迟降低35%;
      • 微服务架构:支持高并发数据处理,实测10万+设备同时在线无压力。

      2. 行业经验:垂直领域的场景化落地

      • 行业理解深度:服务商需熟悉目标行业标准(如医疗DICOM、工业ISA-95)与法规要求(FDA/ISO认证)。
      • 成功案例验证:需验证服务商是否具备复杂场景(如多设备协同、高精度控制)的落地能力。

      由你创科技实践

      • 工业自动化:为某汽车制造厂开发MES监控系统,集成300+台设备,实现生产异常秒级报警;
      • 医疗设备:设计符合FDA认证的超声影像工作站,支持AI辅助诊断与DICOM云端传输。

      3. 服务流程:标准化与透明化

      • 需求分析:提供交互式原型设计(Demo),确保需求精准对齐;
      • 项目管理:明确开发周期、测试节点(单元测试/压力测试)与交付物清单,支持客户全程参与。

      由你创科技流程

      • 阶段一:需求调研与架构设计(5-7个工作日);
      • 阶段二:核心功能开发与多设备联调(6-10周);
      • 阶段三:用户培训与交付(1-2周),确保“零障碍”交接。

      4. 交付准时性:从承诺到落地的保障

      • 敏捷开发模式:采用Scrum框架,分阶段交付可验证版本,降低项目延期风险;
      • 供应链支持:与硬件厂商深度合作,确保FPGA、传感器等外设调试资源充足。

      由你创科技承诺

      • 合同签订后严格按里程碑交付,历史项目准时交付率超95%;
      • 2023年某智慧物流项目中,提前10天完成500台AGV调度系统上线。

      5. 售后服务:长期价值守护

      • 代码可维护性:提供规范代码注释、API文档及Git版本管理;
      • 升级支持:支持功能扩展、跨平台迁移及第三方系统对接。

      由你创科技服务保障

      • 交付后1年内免费维护,7×12小时技术响应;
      • 提供源码托管与知识产权保护,确保客户资产安全。

      二、由你创科技的核心优势——技术+服务双驱动

      1. 技术实力:软硬一体,性能卓越

      • 全栈开发能力:覆盖FPGA逻辑设计、上位机软件开发、云端数据平台集成,提供一站式解决方案。案例:为某半导体厂商开发“晶圆检测系统”,FPGA实现图像预处理,上位机集成AI缺陷分类,检测效率提升3倍。
      • 高性能架构设计:采用分布式微服务架构,支持10万+设备高并发接入,数据吞吐量达百万条/秒。

      2. 行业深耕:技术复用与快速交付

      • 工业领域:开发SCADA系统、设备健康管理(PHM)平台,客户覆盖大金、镭晨、源控、利元亨等知名企业;
      • 新能源领域:设计BMS上位机软件,支持ISO 26262功能安全认证,客户量产交付超50万套。

      3. 服务口碑:以客户为中心

      • 交付准时:2023年某智能工厂项目中,75天完成上位机系统开发,支持200台机器人协同作业;
      • 成本优化:“标准化模块+定制开发”模式,节省客户30%以上开发成本。

      三、成功案例:由你创科技如何助力企业降本增效?

      案例1:生物工艺罐体系统

      • 客户需求: 缓冲液配置、存储、分配 。
      • 解决方案:实现设备控制、设备状态监测、设备数据管理、配方管理、异常报警等功能。
      • 成果:质量保证的同时解决了工艺工程、电气工程和软件工程之间80%的协调工作。。

      案例2:高端医疗影像处理平台

      • 客户痛点:原有系统数据处理慢,无法满足实时超声成像需求。
      • 由你创方案:FPGA端:部署实时滤波与图像增强算法;上位机端:开发DICOM标准接口,支持云端存储与AI诊断。
      • 成果:图像处理延时从50ms降至8ms,通过CFDA认证并批量投产。

      四、合作流程:四步实现高效落地

      1. 需求沟通:提交功能清单、性能指标及硬件环境说明;
      2. 方案设计:5个工作日内获取技术方案与报价;
      3. 开发实施:敏捷开发模式,支持分阶段验收;
      4. 交付培训:提供操作手册、技术培训与售后支持。

      结语:选择由你创科技,让智能升级更省心

      选择一家靠谱的上位机开发服务商,既要看技术实力,也要看服务沉淀与交付保障。深圳市由你创科技有限公司“技术领先、服务贴心、交付准时”为核心竞争力,通过全栈开发能力行业化解决方案,为企业提供高效、可靠的数字化转型支持。

      深圳市由你创科技有限公司是一家专业从事上位机开发的国家高新企业。技术团队有十年以上的项目研发经验。精通c++,c#,PYTHON,labview,java,matlab等多种冷门技术栈。业务覆盖生物医药、汽车电子、高端装备、机器人、材料化工、检验检测等前沿高科技行业。为行业领军企业、科研机构提供长期研发技术服务。做上位机开发,选由你创,研发服务的源头工厂。

      #上位机开发# #上位机软件开发# #上位机开发哪家好# #靠谱的上位机开发服务商#

      ]]>
      DeepSeek本地化部署 | AI应用开发  https://www.unicrom.cn/8077.html Tue, 18 Feb 2025 05:47:30 +0000 https://www.unicrom.cn/?p=8077 一、deepseek简介

      在数字化转型的浪潮中,AI 技术已成为企业提升竞争力的关键。DeepSeek是一款开源AI平台,通过全栈开源架构实现技术共享。其核心能力涵盖多模态交互、垂直领域优化及轻量化部署,支持企业快速定制AI助手,应用于智能客服、数据分析等场景,提升业务流程效率,灵活适配金融、制造等行业需求,推动AI技术从实验室到产业的高效转化,为各行各业赋能。

      二、参数选择

      deepseek-R1不同参数体量的模型综合表现评分如下,综合官网的评分以及网上的实机评测, 大致性能分为三个档次, 1.5b, 7b, 8b 三个一档, 对硬件性能要求最低, 逻辑思维能力较差的基础类型, 14b和32b一档, 对硬件性能要求中等, 有一定的逻辑思维能力, 在处理例如 复杂代码, 文章生成, 重点总结等复杂任务中也有不错的表现, 70b, 671b一档, 对硬件要求较高, 需要专业的高性能显卡或者显卡集群来执行, 处理能力优秀, 70b参数的性能和GPT-4的综合表现相当, 671b参数的deepseek-R1综合表现接近 OpenAI-o1。

      想要本地部署, 需要根据自己的设备的性能来部署, 以下是硬件和参数体量对应的大致关系, 不绝对准确, 仅供参考。

      我这里用的是12G显存的RTX4080显卡+13thi9CPU +32GRAM主机, 选择的是14b的模型(根据实际使用经验, 显存是比较关键的硬件参数,其他硬件参数可以利用各种优化技术来适配, 但是尽量保证显存符合要求,不然严重影响本地部署的使用体验)。

      三、部署流程

      整体部署流程分为两部分:

      后端: 根据本地设备的性能选择合适参数体量的DeepSeek-R1模型, 配置本地环境并下载模型数据,。

      前端: 安装浏览器插件, 优化与Ai交互的UI界面, 并在必要的情况下搭建网页服务器, 确保局域网内成员可用。

       ①后端部署

      Ollama是一个专为在本地环境中运行和定制大型语言模型而设计的工具。它提供了一个简单而高效的接口,用于创建、运行和管理这些模型,

      Ollama支持多种操作系统,包括但不限于:

      macOS:适用于所有现代版本的macOS。

      Windows:支持Windows 10及更高版本。

      Linux:支持多种Linux发行版,如Ubuntu、Fedora等。

      Docker:通过Docker容器,Ollama可以在几乎任何支持Docker的环境中运行。

      windows环境下下载ollamaSetup.exe, 执行安装程序安装完成后, 命令行中执行命令:

      ollama --version

      如果安装成功则会显示ollama的版本信息如下格式:

      ollama几乎支持目前所有主流的开源大语言模型, 当然也包括如今大火的deepseek。

      官网程序下载, 本地安装好ollama后, 执行命令:

      ollama run deepseek-r1:14b

      开始下载模型,过程如图所示:

      下载完成后, 后端部署完成。

      ②前端部署

      为提升交互体验, 可以安装浏览器插件, 以聊天框的UI界面和AI进行问答(默认只能从命令行聊天)

      浏览器插件如下, google浏览器和edge浏览器均可以安装。

      安装好之后前端界面如下:

      以上就是本地部署deepseek的基本流程。

      四、使用体验

      输出速度:

      deepseek-r1提供了 1.5b/7b/8b/14b/32b/70b/671b一共七个参数体量的模型, 参数体量也是最直观的可以看出模型性能的参数, 由上面的图片可以看到, 模型运行时, GPU和显存几乎都是满负荷的状态, 正常情况下, 14b的模型运行起来大约需要20G左右的显存, ollama利用多种优化技术使得其在显存更小的设备上也可以运行。

      Ollama优化特性(包括但不限于):

      • 智能量化:支持2-8bit动态量化(精度损失<3%)
      • 内存压缩:采用Huffman编码压缩权重(压缩率40-60%)
      • 层卸载:自动将非活跃层转存至系统内存/SSD
      • 即时编译:针对不同GPU架构自动生成优化内核

      如图所示, 左侧为设备型号及参数, 根据网上的资料显示, 14b体量的模型需要RTX3090以及至少14G的显存, 实际测试使用效果, RTX4080Laptop +12G显存也是可以正常运行14b的deepseek-r1的, (原理上ollama会利用多种技术来减低大语言模型的本地化部署对于硬件的性能要求, 常用的就是量化技术, 简单地说就是降低模型参数精度, 使得模型可以在不太影响输出效果的前提下, 一定程度的减少硬件参数要求) 实机使用, deepseek-r1 14b版本的输出速度在25~40token/s区间, 可以说输出速度非常快, 使用起来比较流畅。

      输出效果

      输出效果相对于输出速度, 更加主观, 我们召集了多位同事和本地部署的deepseek-r1:14b进行对话并反馈使用体验, 并做如下总结:

      • 相较于deepseek-r1 1.5b/7b/8b 版本, 14b版本明显在 对话/梳理/思考/总结 等方面有较大的提升, 逻辑完整性较高
      • 仅4080显卡的笔记本上就可以运行deepseek-r1:14b, 真正的实现了AI大语言模型走进生活各处
      • 可以给模型定向投喂数据, 增强模型对特定领域的问题的理解及回复精准度, 且不担心重要数据的泄露
      • 比如联网采集数据后, 由deepseek来分辨,过滤, 总结结论的能力上, 由于网络上信息量大, 无效信息占比较高, 14b体量的deepseek无法有效分辨来源及准确性, 满血版(671b参数)的deepseek-R1, 对关键数据的敏感程度, 以及总结有效数据的能力明显更强
      • 对于复杂问题的处理能力上, 稍显不足, 编程, 数学题, 以及特定专精领域的专业知识, 由于训练的资源有限, 回答的准确率有待提升.

      (图示中deepseek-r1:14b虽然理解了题目, 但是给出的答案并不符合题目要求)

      (图示中deepseek-r1:14b一度思维混乱, 反复否定自己之前的分析, 最后艰难的得出正确结果)

      五、输出调优

      给deepseek喂特定数据, 强化deepseek在需要的特定领域强化回答能力. 

      ①下载并加载量化工具(如nomic-embed-text),在命令行中执行以下命令:

      ollama pull nomic-embed-text

      在Page Assist的设置中,找到RAG设置,将文本嵌入模型设置为nomic-embed-text。

      ②添加知识到知识库:

      回到Page Assist的首页,选择添加知识库。

      通过Page Assist的界面,投喂数据(如pdf、文本等)到DeepSeek模型中(因为很多数据涉及到公司内部资料或者商业机密, 不适合在公开的AI 接口中直接投放, 本地部署deepseek, 可以规避这类问题)

      通过知识库添加本地数据, 进而增强模型的回答和理解能力。

      ]]>
      MCU驱动TF-card具体实现 https://www.unicrom.cn/7949.html Wed, 25 Dec 2024 02:36:11 +0000 https://www.unicrom.cn/?p=7949 嵌入式开发中, 经常会有主控板识别TF卡+读取数据+写入数据的 需求, 下面尽量用简介的描述详细说明一下, 相关驱动的实现细节,

      实现TF-card的驱动需要配置的东西比较多, 基本流程就是:

      ①配置芯片的相关引脚  ②引用FatFS文件系统的三方库 ③根据具体需求配置相关引脚的参数 ④在main函数中调用相关功能的初始化函数初始化对应的硬件⑤实际跑通并测试相关功能(识别+读取+写入)⑥实际应用TF-card驱动功能

      ①配置相关引脚

      这一步相对简单, 如图所示配置 数据线SDIO_D0~SDIO_D3,时钟线SDIO_CLK以及SDIO_CMD

      这里我们配置了 四位的数据通讯(除非是引脚不够, 或者数据较少, 才会用一位的)

       ②引用FatFS文件系统的三方库 

      这个是必要的文件系统配置, 想要和 TF-card交互数据, 卡必须有文件系统, 通常情况下使用FatFS

      配置较多, 扇区大小, 编码方式等, 相关配置如图所示

      ③+④基本参数配置好之看一下初始化代码, SDIO的相关参数配置需要在使用前初始化, 代码比较清晰, 不多加赘述

      void HAL_SD_MspInit(SD_HandleTypeDef* sdHandle)
      {
      
        GPIO_InitTypeDef GPIO_InitStruct = {0};
        if(sdHandle->Instance==SDIO)
        {
        /* USER CODE BEGIN SDIO_MspInit 0 */
      
        /* USER CODE END SDIO_MspInit 0 */
          /* SDIO clock enable */
          __HAL_RCC_SDIO_CLK_ENABLE();
        
          __HAL_RCC_GPIOC_CLK_ENABLE();
          __HAL_RCC_GPIOD_CLK_ENABLE();
          /**SDIO GPIO Configuration    
          PC8     ------> SDIO_D0
          PC9     ------> SDIO_D1
          PC10     ------> SDIO_D2
          PC11     ------> SDIO_D3
          PC12     ------> SDIO_CK
          PD2     ------> SDIO_CMD 
          */
          GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11 
                                |GPIO_PIN_12;
          GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
          GPIO_InitStruct.Pull = GPIO_NOPULL;
          GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
          GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
          HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
      
          GPIO_InitStruct.Pin = GPIO_PIN_2;
          GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
          GPIO_InitStruct.Pull = GPIO_NOPULL;
          GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
          GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
          HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
      
        /* USER CODE BEGIN SDIO_MspInit 1 */
      
        /* USER CODE END SDIO_MspInit 1 */
        }
      }
      
      void HAL_SD_MspDeInit(SD_HandleTypeDef* sdHandle)
      {
      
        if(sdHandle->Instance==SDIO)
        {
        /* USER CODE BEGIN SDIO_MspDeInit 0 */
      
        /* USER CODE END SDIO_MspDeInit 0 */
          /* Peripheral clock disable */
          __HAL_RCC_SDIO_CLK_DISABLE();
        
          /**SDIO GPIO Configuration    
          PC8     ------> SDIO_D0
          PC9     ------> SDIO_D1
          PC10     ------> SDIO_D2
          PC11     ------> SDIO_D3
          PC12     ------> SDIO_CK
          PD2     ------> SDIO_CMD 
          */
          HAL_GPIO_DeInit(GPIOC, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11 
                                |GPIO_PIN_12);
      
          HAL_GPIO_DeInit(GPIOD, GPIO_PIN_2);
      
        /* USER CODE BEGIN SDIO_MspDeInit 1 */
      
        /* USER CODE END SDIO_MspDeInit 1 */
        }
      } 

      ⑤这里基本就配置完了, 验证一下功能, (验证功能仅适用一位数据的交互方式)基本逻辑就是通过串口打印一下函数执行的结果

      void SD_Test(void)
      {
        FRESULT res; /* FatFs function common result code */
        uint32_t byteswritten, bytesread; /* File write/read counts */
        uint8_t wtext[] = "This is STM32 working with FatFs.\n"; /* File write buffer */
        uint8_t rtext[100]; /* File read buffer */
      
        /* Register the file system object to the FatFs module */
        if (f_mount(&SDFatFS, (TCHAR const*)PATH, 0) != FR_OK)
        {
          printf("Failed to mount SD card\r\n");
          return;
        }
      
        /* Create/open a file, name is specified by Path with FileName */
        res = f_open(&SDFile, "STM32.TXT", FA_CREATE_ALWAYS | FA_WRITE);
        if (res != FR_OK)
        {
          printf("Failed to open/create file (error code: %d)\r\n", res);
          return;
        }
      
        /* Write data to the file */
        res = f_write(&SDFile, wtext, sizeof(wtext), (void *)&byteswritten);
        if ((byteswritten < sizeof(wtext)) || (res != FR_OK))
        {
          printf("Failed to write file (error code: %d)\r\n", res);
          return;
        }
      
        /* Close the file */
        res = f_close(&SDFile);
        if (res != FR_OK)
        {
          printf("Failed to close file (error code: %d)\r\n", res);
          return;
        }
      
        printf("File written successfully: %s\r\n", wtext);
      
        /* Open the file, name is specified by Path with FileName */
        res = f_open(&SDFile, "STM32.TXT", FA_READ);
        if (res != FR_OK)
        {
          printf("Failed to open file (error code: %d)\r\n", res);
          return;
        }
      
        /* Read string from the file */
        res = f_read(&SDFile, rtext, sizeof(rtext), (void *)&bytesread);
        if ((bytesread == 0) || (res != FR_OK))
        {
          printf("Failed to read file (error code: %d)\r\n", res);
          return;
        }
      
        /* Close the file */
        res = f_close(&SDFile);
        if (res != FR_OK)
        {
          printf("Failed to close file (error code: %d)\r\n", res);
          return;
        }
      
        printf("Read from file: %s\r\n", rtext);
      }

      最终执行结果是,  407通过串口打印了相关测试函数的执行结果信息,显示识别并写入成功, 将SD接到电脑上, 可以看到一个 名为STM32.TXT的文件, 说明SD卡驱动已经成功跑通.

      当然这里仅作为说明驱动使能, 简化了很多细节没有说明.

      比如说 正常情况下, SD卡是有第九个引脚需要通过电位高低来识别SD-card存在, 以此来实现SD卡热插拔的功能,或者软件方式通过定时器定时轮询检测也可以实现, 

      又比如说,FatFS只是比较常见的文件系统, 如果 设备作为某个体系中的一部分, 需要用和整体一样的系统, 可能就无法通过cubeMX直接引用 FatFS的文件系统 的三方库, 那么相关的文件系统的配置 就需要一系列繁琐的配置.

      ]]>
      关于WPF如何连接SQLite或MySQL数据库进行简单增删改查 https://www.unicrom.cn/7941.html Thu, 19 Dec 2024 08:10:16 +0000 https://www.unicrom.cn/?p=7941 以下是使用 Visual Studio WPF 项目来连接数据库操作人物角色数据的完整教程,使用 SQLite 和 MySQL 两种数据库的实现方案。你可以选择其中一种,根据你的需求实施。


      步骤 1:环境准备

      1. 安装 Visual Studio
        确保已安装 Visual Studio,并选择支持 WPF 的 .NET 框架 开发功能。
      2. 创建 WPF 项目
        • 启动 Visual Studio,选择 新建项目 > WPF 应用程序
        • 选择目标框架(如 .NET 6 或 .NET Framework)。
      3. 安装数据库驱动程序
        • 如果使用 SQLite
          打开 NuGet 包管理器,搜索并安装 System.Data.SQLite
        • 如果使用 MySQL
          搜索并安装 MySql.Data 或 MySqlConnector
      4. 安装数据库管理工具,例如Navicat等,以及安装对应版本MySQL。
      5. 创建数据库和表
        准备一个数据库文件或者数据库实例,创建存储角色数据的表。

      步骤 2:SQLite 实现

      1. 创建数据库和表

      创建一个 SQLite 数据库文件(如 genshin.db),并用工具或代码创建表 Characters

      SQL 示例:

      CREATE TABLE Characters (
          Id INT AUTO_INCREMENT PRIMARY KEY,
          Name VARCHAR(255) NOT NULL,
          Element VARCHAR(255) NOT NULL,
          Rarity INT NOT NULL
      ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
      

      2. 设计 WPF 界面

      在 MainWindow.xaml 中设计界面,允许用户输入角色数据并执行增删改查操作。

      <Window x:Class="GenshinDatabaseApp.MainWindow"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              Title="角色管理" Height="450" Width="800">
          <Grid Margin="10">
              <StackPanel Orientation="Vertical" HorizontalAlignment="Center">
                  <TextBox x:Name="NameBox" Width="200" PlaceholderText="角色名" Margin="5"/>
                  <TextBox x:Name="ElementBox" Width="200" PlaceholderText="元素" Margin="5"/>
                  <TextBox x:Name="RarityBox" Width="200" PlaceholderText="稀有度 (1-5)" Margin="5"/>
                  <Button Content="添加角色" Width="200" Click="AddCharacter_Click" Margin="5"/>
                  <Button Content="更新角色" Width="200" Click="UpdateCharacter_Click" Margin="5"/>
                  <Button Content="删除角色" Width="200" Click="DeleteCharacter_Click" Margin="5"/>
                  <Button Content="查询角色" Width="200" Click="SearchCharacter_Click" Margin="5"/>
              </StackPanel>
              <DataGrid x:Name="CharacterGrid" AutoGenerateColumns="True" Margin="10,200,10,10" />
          </Grid>
      </Window>
      

      3. 后端代码

      在 MainWindow.xaml.cs 中实现增删改查逻辑。

      using System;
      using System.Collections.ObjectModel;
      using System.Data.SQLite;
      using System.Windows;
      
      namespace GenshinDatabaseApp
      {
          public partial class MainWindow : Window
          {
              private string connectionString = "Data Source=genshin.db";
      
              public ObservableCollection<Character> Characters { get; set; }
      
              public MainWindow()
              {
                  InitializeComponent();
                  Characters = new ObservableCollection<Character>();
                  CharacterGrid.ItemsSource = Characters;
                  LoadCharacters();
              }
      
              private void LoadCharacters()
              {
                  Characters.Clear();
                  using (var connection = new SQLiteConnection(connectionString))
                  {
                      connection.Open();
                      string query = "SELECT * FROM Characters";
                      using (var command = new SQLiteCommand(query, connection))
                      using (var reader = command.ExecuteReader())
                      {
                          while (reader.Read())
                          {
                              Characters.Add(new Character
                              {
                                  Id = reader.GetInt32(0),
                                  Name = reader.GetString(1),
                                  Element = reader.GetString(2),
                                  Rarity = reader.GetInt32(3)
                              });
                          }
                      }
                  }
              }
      
              private void AddCharacter_Click(object sender, RoutedEventArgs e)
              {
                  using (var connection = new SQLiteConnection(connectionString))
                  {
                      connection.Open();
                      string query = "INSERT INTO Characters (Name, Element, Rarity) VALUES (@Name, @Element, @Rarity)";
                      using (var command = new SQLiteCommand(query, connection))
                      {
                          command.Parameters.AddWithValue("@Name", NameBox.Text);
                          command.Parameters.AddWithValue("@Element", ElementBox.Text);
                          command.Parameters.AddWithValue("@Rarity", int.Parse(RarityBox.Text));
                          command.ExecuteNonQuery();
                      }
                  }
                  LoadCharacters();
              }
      
              private void UpdateCharacter_Click(object sender, RoutedEventArgs e)
              {
                  if (CharacterGrid.SelectedItem is Character selectedCharacter)
                  {
                      using (var connection = new SQLiteConnection(connectionString))
                      {
                          connection.Open();
                          string query = "UPDATE Characters SET Name=@Name, Element=@Element, Rarity=@Rarity WHERE Id=@Id";
                          using (var command = new SQLiteCommand(query, connection))
                          {
                              command.Parameters.AddWithValue("@Name", NameBox.Text);
                              command.Parameters.AddWithValue("@Element", ElementBox.Text);
                              command.Parameters.AddWithValue("@Rarity", int.Parse(RarityBox.Text));
                              command.Parameters.AddWithValue("@Id", selectedCharacter.Id);
                              command.ExecuteNonQuery();
                          }
                      }
                      LoadCharacters();
                  }
              }
      
              private void DeleteCharacter_Click(object sender, RoutedEventArgs e)
              {
                  if (CharacterGrid.SelectedItem is Character selectedCharacter)
                  {
                      using (var connection = new SQLiteConnection(connectionString))
                      {
                          connection.Open();
                          string query = "DELETE FROM Characters WHERE Id=@Id";
                          using (var command = new SQLiteCommand(query, connection))
                          {
                              command.Parameters.AddWithValue("@Id", selectedCharacter.Id);
                              command.ExecuteNonQuery();
                          }
                      }
                      LoadCharacters();
                  }
              }
      
              private void SearchCharacter_Click(object sender, RoutedEventArgs e)
              {
                  Characters.Clear();
                  using (var connection = new SQLiteConnection(connectionString))
                  {
                      connection.Open();
                      string query = "SELECT * FROM Characters WHERE Name LIKE @Name";
                      using (var command = new SQLiteCommand(query, connection))
                      {
                          command.Parameters.AddWithValue("@Name", $"%{NameBox.Text}%");
                          using (var reader = command.ExecuteReader())
                          {
                              while (reader.Read())
                              {
                                  Characters.Add(new Character
                                  {
                                      Id = reader.GetInt32(0),
                                      Name = reader.GetString(1),
                                      Element = reader.GetString(2),
                                      Rarity = reader.GetInt32(3)
                                  });
                              }
                          }
                      }
                  }
              }
          }
      
          public class Character
          {
              public int Id { get; set; }
              public string Name { get; set; }
              public string Element { get; set; }
              public int Rarity { get; set; }
          }
      }
      

      步骤 3:运行程序

      1. 确保 genshin.db 文件存在于项目根目录中,并已包含 Characters 表。
      2. 运行 WPF 应用程序,可以通过界面添加、修改、删除和查询角色信息。

      MySQL 实现

      如果需要使用 MySQL,将 SQLiteConnection 替换为 MySqlConnection,并调整连接字符串为:

      string connectionString = "Server=your_server;Database=genshin.sql;User=your_user;Password=your_password;";
      

      其余逻辑与 SQLite 类似。

      推荐字符集和排序规则

      1. 字符集utf8mb4
        • utf8mb4 是 MySQL 8.0 推荐的字符集,它支持 Unicode 完整字符集,包括多字节字符和表情符号(Emoji)。
      2. 排序规则:根据需求选择以下之一:
        • 通用排序规则utf8mb4_general_ci
          适合大部分普通应用,排序和比较效率较高。
        • 准确排序规则utf8mb4_unicode_ci
          遵循 Unicode 排序规则,支持多语言排序,但性能略逊于 utf8mb4_general_ci
        • 区分大小写utf8mb4_bin
          精确比较,区分大小写,适用于需要精确匹配的场景。

      创建数据库的 SQL 示例

      CREATE DATABASE genshin_db
      CHARACTER SET utf8mb4
      COLLATE utf8mb4_unicode_ci;
      

      选用排序规则的考虑

      • utf8mb4_general_ci
        • 不区分大小写(Case Insensitive)。
        • 性能较好,适合通用性需求。
        • 不完全遵循 Unicode 标准,排序结果可能略有偏差。
      • utf8mb4_unicode_ci
        • 不区分大小写(Case Insensitive)。
        • 完全遵循 Unicode 排序规则,支持更准确的多语言排序。
        • 性能略低于 utf8mb4_general_ci
      • utf8mb4_bin
        • 区分大小写(Case Sensitive)。
        • 精确比较,适合密码存储、唯一标识符等场景。

      希望这篇文章能帮助你快速上手开发,顺利实现 WPF 程序对数据库的增删改查管理角色数据!

      ]]>