在树莓派上使用C#实现:通过按钮操作PWM调节LED灯亮度

作者:V君 发布于:2018-10-28 2:45 Sunday 分类:折腾手记

TLDR:

源代码:SVNGit

依赖库:WiringPi


操作步骤:

0)树莓派上需要安装好mono软件包并启动远程调试器

1)从依赖库官网下载源码包并在树莓派上通过自带的构建脚本进行安装;

2)引出第18pin(只有这pin支持PWM),经过330欧姆电阻接到LED灯,另一边回到负极。

3)再引出两个GPIO(源代码里是17和27)经过同样的电阻接按钮,另一边回到3.3v正极。

4)在VS里打开源代码,连接到树莓派上启动调试。

此时LED灯会亮起来,并能够通过两个按钮调节亮度


原来LED亮度是用PWM的占空比来控制的,学到新姿势了 乂目

标签: 软件开发 树莓派 C# 嵌入式

评论(0) 引用(0) 浏览(1261)

在VS15上远程调试Mono应用程序:原来还有这么舒服的姿势!

作者:V君 发布于:2018-10-27 22:48 Saturday 分类:折腾手记

小试一把确认可行之后就来写博文了,稍后再扯,先TLDR:

关键字「mono remote debug」喂狗,吐出「MonoRemoteDebugger」插件。

顺着介绍导航到其GitHub仓库看用法

0)目标机器需要先安装Mono的软件包,这次用的是「mono-devel」
1)下载预编译版本zip到目标机器,解包执行,进入等待状态。
2)在VS里装好插件,新建一个控制台项目,
  点击菜单「
MonoRemoteDebugger -> Debug with Mono (remote)
  在弹出的对话框输入目标机器IP,点击连接按钮。
3)当前应用程序会自动推送到目标机器并以调试模式启动,
  如果在主线程设置断点,将会在断点处停下来,此时可以查看变量值。

需要注意的是Mono调试器并没有原生的那么强大,做不到编辑并继续的体验。
受到远程调试器完善程度的影响,目前还不支持用户线程断点。

不过没关系能打断点看变量值已经很奢侈啦!

进入闲话时间

还记得之前为了调试树莓派GPIO所做的C/S远程控制接口吗?
最近忽然想玩PWM,想试着用它来控制LED灯的亮度。
首先想到的是树莓派自带的Remote gpio功能,然而资料并不多,只能找到py的,没有C#的。
之后换了个想法,如果能直接在上面跑调试那该多好。
虽然知道可以在上面直接安装MonoDevelop来调试,但这货太过于臃肿。
又试着去咕狗看看,结果就找到这货啦!


标签: 软件开发 树莓派 C# 嵌入式 调试技术

评论(0) 引用(0) 浏览(1377)

活久见:有些异常是不能被catch(Exception)捕获的,你得把catch参数去掉

作者:V君 发布于:2017-6-14 0:25 Wednesday 分类:折腾手记

TL;DR: 

当你发现本应被捕获的异常却被无视 try-catch 语句时,

你应该试着去掉 catch(Exception ex) 中高亮的部分

写成 try {....} catch{....} 这种写法将不能直接取得异常实例,

你可以将上下文对象值记录下来作为排查线索。


本例:

将 MVC 5.2.3 站点部署到装了 mono 4.2.2 的Debian@树莓派。

首先就遇到一大堆兼容性问题。去掉一系列不兼容的组件。

(ApplicationInsights系列、CodeDom系列

总算能报出些看起来有点线索的异常。

System.Reflection.ReflectionTypeLoadException: The classes in the module cannot be loaded.
  at (wrapper managed-to-native) System.Reflection.Assembly:GetTypes (System.Reflection.Assembly,bool)
  at System.Reflection.Assembly.GetTypes () <0x721db540 + 0x00023> in <filename unknown>:0 
  at Ease.Ioc.IocManager.RegisterInterface (System.Reflection.Assembly[] assemblies, System.Type iface,
System.Func`1 lifetimeManager) <0x721db0c0 + 0x000fb> in <filename unknown>:0 
  at Ease.Ioc.IocManager..ctor () <0x721fb130 + 0x00283> in <filename unknown>:0 
  at Ease.Ioc.IocManager..cctor () <0x721faff8 + 0x00027> in <filename unknown>:0 

这是模仿 ABP 在当前应用域中的所有程序集中寻找实现了指定接口的类,然后加到 IoC 容器。

(哎……谁让 ABP 还不支持 mono 呢。。。)

在对某个程序集调用 GetType 时爆炸了……

于是在其周围加上常规异常处理 try-catch(Exception) 试图找出有问题的程序集。

然而异常依旧引发,就跟没写 try-catch(Exception) 一样……

试着调整方法结构,避免一些在首次访问方法就引发异常的状况 —— 无果……

心一横,去掉 catch 语句的参数,记下当前调用 GetTypes 的程序集。

try
{
types.AddRange(asm.GetTypes().Where(p => false == p.IsAbstract && false == p.IsInterface && iface.IsAssignableFrom(p)));
}
catch
{
throw new Exception("Asm load fail?" + asm);
}

功夫不负有心人 or 瞎猫撞上死耗子? bingo! 抓到你啦!

Asm load fail?System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35

咋办? 没办法哇! 试着把引用干掉看看吧…… 果然就没事儿了!

稍稍去了解一下那玩意儿,发现是一堆辅助类, 反正一时半会也用不上。


于是就这样,用作类似 Hello world 的站点首页就成功呈现出来啦!

 —— 尽管是乱码…… 因为偷懒直接输出 Content 嘛! 接下来可以慢慢折腾啦!

标签: 软件开发 树莓派 C# linux mono 运行时错误

评论(0) 引用(0) 浏览(1533)

在树莓派使用C#访问GPIO设备文件操作74HC595驱动LED数码管

作者:V君 发布于:2016-8-8 6:36 Monday 分类:折腾手记

首先简短的介绍一下如何访问 GPIO, 然后再接着使用 GPIO 操作数码管.

在 Raspbian 中操作 GPIO 和其他常见 Linux 版本是一样的:

使用前首先分配针脚,

 向 /sys/class/gpio/export 写入字符串形式针脚编号, 

接着等待 100 毫秒让文件系统反应过来, 

然后是设置 I/O 方向

 向 /sys/class/gpio/gpio{针脚编号}/direction 写入 "in" 或 "out"

设置完 I/O 方向之后仍然要等 100 毫秒

这时候就可以往 /sys/class/gpio/gpio{针脚编号}/value 读取或写入数据了

 写入字符 "0" 表示低电平, 反之写入 "1"

 

最后用完了还要释放掉,

 向 /sys/class/gpio/unexport 写入字符串形式的针脚编号.


可以简单的使用 C# 中的 File.WriteAllText 来写入设备文件,但这性能并不太理想

换成文件流来写就能快不少, 只是每次写之前需要 seek 回到 0.

 

这儿有个封装好的 C#实现 , 可以不依赖第三方库直接拿来参考.

参考了 Edi.Wang 的实现, ta 用的是 Win10, 咱用的是官方系统, 这并没太大差别

摸透 74HC595 的套路, 就可以开始了.

和 Edu.Wang 一样, 咱也是从万能的马云上淘来的 4 位数码管模块.

准备工作:

74HC595 一共要接5条线, 分别是 3.3V GND DIO SCLK RCLK

先确定除了电源以外的三根数据接口针脚编号,然后连接到树莓派上和在程序中定义对应编号

接下来讲讲74HC595的操作方法.

 初始化:

   分配对应的三个针脚, 写入低电平.

 写入数据位:

   将要写入的位以 1 高电平, 0 低电平的方式写入 DIO

   每写入一个位必须给 SCLK 一个脉冲, 也就是写入高电平后紧接着写入低电平

 更新显示:

   给 RCLK 一个脉冲, 之前写入的位就会对应显示到数码管上.

 

 有了操作方法, 接下来就是指令格式了,

 每个模块需要两个字节的数据

  前一个字节确定显示8段数码管中要显示的段, 低电平表示亮, 高电平表示灭.

  后一个字节低4位表示要将这些数据显示在哪个数位上, 如果低4位全都是1那么4位都会显示

 写入完数据后需要更新显示

不断更新显示位和显示内容, 就让人眼看起来像4个数码管都同时亮了


这是写好的 C#实现 很简单吧!


编译好之后丢进树莓里, 在终端运行它, 数码管就会按你的指令显示了.


还可以再稍稍扩展一下: 这玩意还可以串联.

串联之后的指令格式也很简单, 只需要无脑的给每一个模块两个字节就可以了

最先写入的两个字节会被最后一个模块显示. 

“yooo 233!”

点击查看原图

 

btw: 每次都编译然后扔进树莓, 是不是略蛋疼啊? 如果有bug, 这要如何de呢?

mono 似乎不能让VS做远程调试, 就算能远程调试也不能愉快的编辑并继续啊...

别急, 反正咱是不会屈服每次传文件再运行这么麻烦的方式.

于是 -- 咱写了个 C/S 架构的 GPIO 操作封装 这下可以愉快的调试了!

标签: 软件开发 树莓派 C# mono GPIO

评论(0) 引用(0) 浏览(2407)

[失败]修改 ASP.NET Boilerplate 0.9.1 源代码, 让其支持 Mono

作者:V君 发布于:2016-6-25 15:25 Saturday 分类:折腾手记

直接部署能在IIS上跑的版本到Linux Mono(树莓)上会报错.

看来ABP没有考虑平台兼容啊,只能自己改改看了


▲Directory '****/bin\' not found.

  at System.IO.Directory.GetFiles (System.String path, System.String searchPattern, SearchOption searchOption) <0x71c1cbb0 + 0x0002b> in <filename unknown>:0 

  at Abp.Web.WebAssemblyFinder.GetAllAssembliesInternal () <0x71c1bcd0 + 0x000eb> in <filename unknown>:0 

一看就知道是没考虑兼容Linux,直接写死的反斜杠,

找到 WebAssemblyFinder 对应源代码第50行

bin后面反斜杠改成目录分隔符或直接删掉.

 

▲No currently authenticated user.

  at System.Web.HttpApplication.get_User () <0x6f94e678 + 0x000d4> in <filename unknown>:0 

  at Abp.Web.AbpWebApplication.TrySetTenantId () <0x6f94e328 + 0x0002b> in <filename unknown>:0 

去看了源代码 AbpWebApplication 类第112行的取得用户, 再反编译跟进去

发现系统类库居然在取不到值时抛出异常, 果断加个try, 遇到异常时就当做取到空.


▲Could not find method overriding System.Threading.Tasks.Task`1[Abp.Auditing.AuditLog] InsertAsync(Abp.Auditing.AuditLog) on type Abp.EntityFramework.Repositories.EfRepositoryBase.....

  at Castle.DynamicProxy.Internal.InvocationHelper.ObtainMethod......

我去,不仅Abp本身没考虑, 就连AOP代理拦截的Castle也不支持?!

接着找Castle的源代码, Abp 0.9.1 使用的 Castle 是 3.3.0, 根据异常堆栈跟进去看.

插入调试代码发现更多细节, System.Threading.Tasks.Task`1[Abp.Auditing.AuditLog] InsertAsync(Abp.Auditing.AuditLog) 报错的原因是找不到这个方法,

造成找不到方法的原因是 Castle 对要做的方法取了 GetBaseDefinition 来做签名比较

得到了 System.Threading.Tasks.Task`1[TEntity] InsertAsync(TEntity)

明显和要找的方法不匹配. 源代码里也注释了一句

 this implementation sucks, feel free to improve it.

好吧, 那么就动手改改吧, 虽然不知道为啥要取 GetBaseDefinition 

那么就在你找不到之后接着不 GetBaseDefinition 然后比较吧.


▲Failure has occurred while loading a type.

  at Abp.Domain.Uow.UnitOfWorkInterceptor.Intercept (IInvocation invocation) <0x6f8e8688 + 0x0007f> in <filename unknown>:0 


懵逼了,不知道这个异常是怎样引发的..

先放着不管, 找到法子再更吧


等 .NET Core 的ARM版本软件包出现, 或许可以不做修改直接跑了吧。

M¥给点力快点啊。。。

标签: 软件开发 树莓派 C# linux mono MVC

评论(0) 引用(0) 浏览(2252)

Powered by emlog 去你妹的备案 sitemap