如何从零编写自己的.NET IoT设备驱动

360影视 日韩动漫 2025-03-14 09:21 2

摘要:本文将以 NV3030B LCD 设备驱动为例详细介绍如何从零开始一个.NET IoT设备编写驱动。这里我们使用树莓派作为硬件平台,并参考.NET IOT 官方的 Ili934x TFT LCD 驱动库。

本文将以 NV3030B LCD 设备驱动为例详细介绍如何从零开始一个.NET IoT设备编写驱动。这里我们使用树莓派作为硬件平台,并参考.NET IOT 官方的 Ili934x TFT LCD 驱动库。

在前面的 《使用.NET玩转IOT的入门建议》 文章中,我们提到.NET IOT 开发驱动的方法,借力打力跨界学习,可以先按照这些示例代码操作一遍,然后再用 .NET 重写。这里我们就以 NV3030B LCD 设备驱动为例,详细介绍如何从零开始一个.NET IoT设备编写驱动。

在开始编写驱动之前,我们需要确保以下内容:

•树莓派(本文以 Raspberry Pi Zero 2 W 为例)•微雪 1.5寸 LCD 屏幕,NV3030B驱动芯片•SPI 接线•.NET 8.0 或更高版本•微雪官方的 Python 驱动示例代码

树莓派的 40 pin 接线基本一致,可以参考 树莓派 Gpio 接口图[1]

40 Pin

显示屏和树莓派的接线如下:

接线效果示意图

在编写.NET驱动之前,我们首先需要验证SPI接线和设备是否正常工作。我们可以使用微雪显示屏提供的示例 Python 代码进行测试,里面包含了 Python 版本的驱动代码。

需要注意的是:如果之前没有安装 numpy 和 pillow 库,需要先安装:

sudo apt install python3-numpy python3-pillow

然后运行示例代码,观察显示屏是否正常,如果屏幕亮起并显示内容,则说明接线和设备正常,我们可以进入下一步。

前面的文章我们提到过,想接设备先看官方驱动库的支持情况。能用支持的设备就买支持的,没有支持的,可以参考官方的驱动库,或者参考其他人的开源项目。再不行我们找官方的类似的驱动,改巴改巴,也能用。这里我就找到了官方的 Ili934x TFT LCD 驱动库[2],我们可以参考这个库的设计思路,来编写 NV3030B LCD 的驱动。

这个库的大部分代码都是可以拿来直接用的,我们只需要修改一些初始化和一些细节代码就可以了。这里我们就以这个库为基础,来编写 NV3030B LCD 的驱动。

4.1 使用 Github Copilot 快速进行项目搭建当然,大模型时代,谁还自己写代码呢?写是不可能写的,这些脏活累活,都是交给 AI 去做。我们只需要告诉 AI 我们要做什么,AI 就会帮我们生成代码。现在,我们直接祭出 Github Copilot 大法,当他参考 Python 驱动按照Ili934x库的实现,帮我们完成 NV3030B 驱动:Github Copilot

当然,AI 生成的代码不是百分百准确的,我们还是需要自己进行逐个审核,确保代码的正确性。这里我们就不一一列举了。然后,逐步根据 AI 的生成情况,或自行修改或引导 AI 生成正确的代码。

对于 GitHub Copilot 目前最好用的 IDE 我感觉还是 VS Code,至少比 Visual Studio 里面集成的 GitHub Copilot 使用体验更好一些。这两个 IDE 各有优缺吧,我一般是配合使用。

再次强调,一定要做好审核,这里画个重点,后面要考。

对于这个驱动,因为我们是参考的 Ili934x 驱动库,这库继承自GraphicDisplay类,所以我们也继承这个类,需要安装下面的库:dotnet add package Iot.Device.Bindings.SkiaSharpAdapter4.2 需要修改的地方虽然 AI 帮我们生成了大部分代码,但是还是有一些地方需要我们手动修改的,使其符合我们的偏好,并纠正一些错漏的地方。相对于原始的Ili934x驱动库,我们需要修改的地方其实不多,主要是在构造类主文件和Command文件中。对于Command文件,我们需要根据 NV3030B 的数据手册,修改一些初始化命令,以及一些特殊的命令。这里直接按照 Python 驱动的初始化命令来修改即可。AI 这里虽然帮了大忙,但是最后因为调试没通过,后面将这个命令还有初始化的实现代码,一个一个核对了好几遍 o(╥﹏╥)o

除了初始化代码外以及基础配置信息,如频率和屏幕大小外,还有一些细节代码需要修改:

SetWindow方法,按照 Python 的驱动y0y1有一个偏移,这里我们也需要做同样的偏移:/// /// Set display window for drawing/// private void SetWindow(int x0, int y0, int x1, int y1){ y0 += 20; y1 += 20; /* ... */}

其他的基本不需要修改,这里我们优化了一下调光,原始的只有高低电平,我们这里增加了一个 PWM 调光,这样可以更好的控制亮度:

public NV3030B(SpiDevice spiDevice, int dataCommandPin, int resetPin, int backlightPin = -1, int backlight_frequency = 1000, int spiBufferSize = DefaultSPIBufferSize, gpioController? gpioController = , bool shouldDispose = true){ /* ... */ if (_backlightPin != -1) { _gpioDevice.OpenPin(_backlightPin, PinMode.Output); _backlightChannel = new SoftwarePwmChannel(backlightPin, backlight_frequency,controller: _gpioDevice); _backlightChannel.Start; SetBacklight(100); } /* ... */}/// /// Set backlight brightness (0-100)/// public void SetBacklight(int brightness){ if (_backlightChannel is ) throw new InvalidOperationException("Backlight pin not configuRed"); if (brightness 100) throw new ArgumentOutOfRangeException(nameof(brightness), "Brightness must be between 0 and 100"); double dutyCycle = brightness / 100.0; _backlightChannel.DutyCycle = dutyCycle;}

至此,我们应该修改的差不多了,应该算是完成了 NV3030B 的驱动编写。但是这还不算完,半场开香槟,可不可取,还需要测试。

在测试之前,我们需要编写一个简单的测试程序,用于初始化显示屏并显示一些内容,需要有基本的图形绘制还有图片显示测试,图片可以直接使用 Python 驱动的测试图片LCD_1inch5.jpg。// 测试基本图形display.ClearScreen(System.Drawing.Color.Red, true);Task.Delay(10000).Wait;Console.WriteLine("Testing fill rectangle...");display.FillRect(System.Drawing.Color.Blue, 0, 0, 100, 100);display.FillRect(System.Drawing.Color.Green, 100, 0, 100, 100);display.SendFrame(false);Task.Delay(10000).Wait;using var image = BitmapImage.CreateFromFile("LCD_1inch5.jpg");display.DrawBitmap(image);

发布程序到树莓派上,运行测试程序,观察显示屏是否正常显示内容。如果一切正常,恭喜你,你已经成功编写了 NV3030B 的驱动。然而,这里我们不出意外的出了意外:

异常然后,我便开始了四五天之久的 Debug ,期间也问过了各种大模型,试了给出的各种建议,都没有解决问题。经过几番测试,在原始的LCD_1inch5.pyShowImage方法增加文件处理后的数据保存后,使用 .NET 读取二进制直接发送到屏幕,竟然是正常显示的。根据这个突破口,最后发现竟然还是SetWindow方法的问题,在 Python 中除了+20的调整外,还有-1的调整,而原始库Ili9341直接发送byteSendBitmapPixelData方法是有一个-1的操作,所以是正常的。

终于是破案了,但是这个问题也是让我头疼了好几天,和大模型的几番较量,有时候是真嘴硬啊,承认,但就是不改。

所有你前面用大模型省下的代码,当有坑的时候,都会变成你爬坑时流下的泪。

不过吧,也算好事,原来是大模型熟悉这个代码,现在我也算烂熟了,等后面有时间,有多个显示屏接入了,提取个基类,把这些共有的部分提取出来,并做个深度优化,方便后面快速接入新的显示屏。

驱动编写完成后,我们可以将其发布到 NuGet 上,方便其他开发者使用。这里我们就不展开了,项目已开源,有兴趣的可以参考 NV3030B[3]

在这篇文章中,详细介绍了如何从零开始为 NV3030B 编写一个.NET IoT 设备驱动。通过验证SPI接线和设备的正常运行,逐步迁移 Python 代码到 .NET,最终实现了驱动的编写和测试。希望这篇文章能帮助你更好地理解和掌握.NET IoT开发。如果你有任何问题或建议,欢迎在评论区留言。

References

[1]树莓派 GPIO 接口图:

[2]Ili934x TFT LCD 驱动库:https://github.com/dotnet/iot/tree/main/src/devices/Ili934x?wt.mc_id=DT-MVP-5005195

[3]NV3030B:https://github.com/sangyuxiaowu/NV3030B?wt.mc_id=DT-MVP-5005195

来源:opendotnet

相关推荐