摘要
文章主要是记录自己的整活过程中涉及到的技术包括:.NET IoT、.NET Web、.NET MAUI、框架采用的是最新的.NET 7。
本人是用的树莓派Zero 2 W(ubuntu-22.04)进行开发测试,但是.NET IoT库也有社区张高兴提交的香橙派GPIO引脚的映射,香橙派型号对应的驱动https://github.com/dotnet/iot/tree/main/src/devices/Gpio/Drivers。
主要预算不够的.NET开发老哥可以尝试用香橙派改改代码跑跑看,回头我再实机测试。
项目开源地址-Verdure.Kame.DotNet
https://github.com/maker-community/Verdure.Kame.DotNet
.NET IoT操作SPI编写屏幕驱动
有图有真相
关于什么是SPI大家可以先看完张高兴的一篇文章温习下:
张高兴的 .NET IoT 入门指南:(四)使用 SPI 进行通信https://www.cnblogs.com/zhanggaoxing/p/10943822.html
在知道什么是SPI之后,大概应该知道我们要做什么了,我们买的屏幕通讯协议有很多种,我呢恰好选择了这个SPI协议的屏幕,厂家的文档中心,会有详细介绍。
SPI初始化=>传输图片数据=>屏幕正常显示
屏幕使用文档https://www.waveshare.net/wiki/1.47inch_LCD_Module
上图表示我们需要如何传输图片数据,才能正常使用,下面我引用文档的介绍。
本款LCD使用的内置控制器为ST7789V3,是一款240 x RGB x 320像素的LCD控制器,而本LCD本身的像素为172(H)RGB x 320(V),同时由于初始化控制可以初始化为横屏和竖屏两种,因此LCD的内部RAM并未完全使用。该LCD支持12位,16位以及18位每像素的输入颜色格式,即RGB444,RGB565,RGB666三种颜色格式,本例程使用RGB565的颜色格式,这也是常用的RGB格式 LCD使用四线SPI通信接口,这样可以大大的节省GPIO口,同时通信是速度也会比较快
我买的屏幕分辨率是172 * 320的,支持16位色,一张图片传输的总数据为172 * 320 * 2字节。
大家可以参考文档里的python代码和我的实现进行学习屏幕驱动的简单编写,由于我不是专业的嵌入式我就不展开了。
屏幕芯片驱动程序的构造函数
代码语言:javascript复制public ST7789V3(int dataCommandPin,
SpiDevice sensor,
int resetPin = -1,
PwmChannel? pwmBacklight = null,
PinNumberingScheme pinNumberingScheme = PinNumberingScheme.Logical,
GpioController? gpioController = null,
bool shouldDispose = true)
{
if (dataCommandPin < 0)
{
throw new ArgumentOutOfRangeException();
}
_dataCommandPin = dataCommandPin;
_pwmBacklight = pwmBacklight;
_pwmBacklight?.Start();
_sensor = sensor ?? throw new ArgumentNullException(nameof(sensor));
_gpio = gpioController ?? new GpioController(pinNumberingScheme);
_resetPin = resetPin;
_shouldDispose = shouldDispose || gpioController is null;
Initialize();
}
数据传输的代码如下:
代码语言:javascript复制public void SpiWrite(bool isData, ReadOnlySpan<byte> writeData)
{
Console.WriteLine($"writeData length:{writeData.Length}");
_gpio.Write(_dataCommandPin, isData ? PinValue.High : PinValue.Low);
if (writeData.Length > 4096)
{
for (int i = 0; i < 26; i )
{
var query = writeData[(i * 4096)..((i * 4096) 4096)];
_sensor.Write(query);
}
var dataLcdList1 = writeData[(26 * 4096)..110080];
_sensor.Write(dataLcdList1);
}
else
{
_sensor.Write(writeData);
}
}
SPI对数据一次传输的长度有限制,也就是4096字节,所以大家要注意手动分段传输。
1.47寸显示屏c#驱动 https://github.com/GreenShadeZhang/dotnet-iot-tutorial-code/tree/main/src/ST7789V3
目前驱动部分测试是OK的,但是由于图片数据转换到RGB565的时候会有问题,导致有些彩色不太正常,不过黑白ok,就暂时这样使用了。
.NET IoT操作I2C控制16路舵机驱动器
这个舵机驱动部分,社区已经有贡献了,所以我直接通过.NET IoT进行一次封装就可以控制16路舵机驱动器了,有兴趣的可以看下源码和我COPY官方的测试程序。
Pca9685 16路舵机驱动板测试程序https://github.com/GreenShadeZhang/dotnet-iot-tutorial-code/tree/main/src/Pca9685/Pca9685.Sample
Pca9685 - I2C PWM Driver
https://github.com/dotnet/iot/tree/main/src/devices/Pca9685
服务端搭建
先来张架构图:
树莓派主要是用来跑用.NET编写的web服务,然后调用上面提到的驱动驱动屏幕和舵机驱动板,进行相关硬件的操作。
协议文件主要定义了播放图片到屏幕,播放视频到屏幕,四足机器人的舵机控制。
服务端很简单,只做简单的数据转发,不处理数据,数据处理放在客户端也就是MAUI程序里进行。
客户端搭建
客户端采用MAUI框架,用到了MAUI对应的windows的特有的库,比如opencvsharp,MAUI客户端的功能目前比较单一,还是等我测试完毕,再加新功能吧。
总结
对于使用.NET进行全场景的开发进行了实践,发现其实还是大有可为的,能够很快的实现一些功能,而不用再花很多的时间学习其他的技术栈。
但是MAUI由于平台的不同,有些功能还是需要针对特定的平台进行单独处理,这个就增加了开发的复杂性。
来张四足机器人的全图吧,代码是实现完了,可惜因为疫情,有些零件快递收不到,先来张实体图吧,到时候会把屏幕也放上去,有比较感兴趣的话可以关注我B站账号,到时候放视频上去。https://space.bilibili.com/25228512
推荐项目
- .NET IoT Libraries
https://github.com/dotnet/iot
- nanoFramework IoT.Device Library repository
https://github.com/nanoframework/nanoFramework.IoT.Device
- RaspberryPi-Minikame
https://github.com/LakshBhambhani/RaspberryPi-Minikame
- Verdure.Kame.DotNet
https://github.com/maker-community/Verdure.Kame.DotNet