【树莓派+.NET MF打造视频监控智能车】控制篇(.NET MF)

简介: 一般情况下一个驱动器可以驱动两路马达,而驱动一个马达一般需要两路信号,通过控制两路PWM的输出,来控制马达的转速和方向。我们这款小车选用的是一个带光电隔离,高功率的一个驱动器,一路马达,需要三路IO控制,其中2路是控制方向,一路输出PWM控制小车的转速。

在上一篇《遥控篇》文章中,我们介绍了SonyPS2手柄信号的采集和编程,通过简单的封装,以事件的方式向我们提供按键信息。本篇文章主要介绍.NET Micro Framework系统接受到按键信息后,如何驱动小车马达和控制机械手的。

无论是驱动小车马达还是控制机械手,都是通过输出PWM来控制的,只是控制PWM输出的方式有些不同而已,我们先介绍一下小车马达的控制。

由于驱动马达需要相对比较大的电流,所以主芯片的IO是无法直接驱动的,中间需要连接一个驱动器。也就是说主芯片输出PWM控制驱动器,由驱动器输出大电流来驱动马达。

一般情况下一个驱动器可以驱动两路马达,而驱动一个马达一般需要两路信号,通过控制两路PWM的输出,来控制马达的转速和方向。我们这款小车选用的是一个带光电隔离,高功率的一个驱动器,一路马达,需要三路IO控制,其中2路是控制方向,一路输出PWM控制小车的转速。
image.png
一个驱动器模块,需要4个GPIO(控制方向)2路PWM,加上一路3V3和GND,共8路,我们采用标准.NETGadgeteer接口进行连接(10个pin:1个3V3,1个5V,1个GND,7个GPIO通道),可以直接插入凌霄开发板上的两个.NET Gadgeteer接口上,接线显的简单直接(上图所示的两个扁平电缆就是)。

机械手控制就更为容易了,一个舵机三根线,电源(5V),地和信号线(PWM),三个舵机,一共需要3路PWM输出控制。注意电源也需要特别提供。PWM由凌霄开发板IO直接输出。
image.png
下面介绍一下.NETMicro Framework的PWM接口函数类。

public class PWM : IDisposable

    {

        publicPWM(Cpu.PWMChannelchannel, double frequency_Hz,double dutyCycle, boolinvert);

        publicPWM(Cpu.PWMChannelchannel, uint period, uintduration, PWM.ScaleFactorscale, bool invert);

 

        public uint Duration { get; set; }

        public double DutyCycle { get;set; }

        public double Frequency { get;set; }

        public uint Period { get; set; }

     

        public void Start();

       public void Stop();

      

      //… 省略一些非主要函数

   }

两个构造函数,分别介绍一下。
PWM(Cpu.PWMChannel channel, doublefrequency_Hz, double dutyCycle, bool invert);

channel – 通道,不同的系统,支持的通道个数不同,比如凌霄系统支持16路,应该算比较多的。

frequency_Hz – 频率,单位是Hz,发出脉冲的频率值。

dutyCycle – 占空比, 一个0~1之间的数,表示一个周期中,高电平持续时间和整个周期的比值。

Invert – 信号翻转,高低电平翻转切换,一般底层都没有处理该参数,所以一般设置为false。

 

public PWM(Cpu.PWMChannel channel, uintperiod, uint duration, PWM.ScaleFactorscale, bool invert);

channel – 通道。

period – 周期。单位和scale的选项一致。

duration – 高电平持续时间,单位和周期一致。

scale – 周期的时间单位,可以是毫秒、微秒、纳秒,建议选择微秒。

Invert – 信号翻转。
第一个构造函数,一般控制马达用,参数设置显的比较直观。频率可以是1K~250KHz(建议10K左右),通过设置占空比的大小(0就是停止,1就是全速),来进行调速。

第二个构造函数,适合控制舵机用,舵机典型的控制曲线如下:
image.png
F就是所谓的周期了,如果我们设置scale为微秒,则可以直接设置为20000,所谓的脉宽就是duration的值,你可以设置为1000~2000之间(不同舵机,这个区域的值会有不同,请根据实际进行调整)。

有了以上的介绍,我们就可以很容易地完成马达驱动和舵机控制了。

A.驱动马达

马达驱动控制参数定义:

    static PWM[]motor_pwm = new PWM[4];

    static double[]frequency = new double[]{ 10000, 10000, 10000, 10000 };        

    static double[]dutyCycle = new double[]{ 0, 0, 0, 0};                         

    static bool[] states1 = new bool[] { true, false, true, false, true, false, true, false };

    static bool[] states2= new bool[] { false, true, false, true, false, true, false, true };

    static OutputPort[] In = newOutputPort[8];

 

马达驱动初始化:

  //初始化马达控制

    //方向IO

    Cpu.Pin[] pins = new Cpu.Pin[] { Mainboard.Gadgeteer.Socket2.Pin4, Mainboard.Gadgeteer.Socket2.Pin5,Mainboard.Gadgeteer.Socket2.Pin6, Mainboard.Gadgeteer.Socket2.Pin7,

                                        Mainboard.Gadgeteer.Socket1.Pin4, Mainboard.Gadgeteer.Socket1.Pin5,Mainboard.Gadgeteer.Socket1.Pin6, Mainboard.Gadgeteer.Socket1.Pin7};           

    for (int i = 0; i < In.Length; i++)

    {

        In[i] = newOutputPort(pins[i], false);

    }

    //马达速度PWM输出

    Cpu.PWMChannel[] motor_chanels = new Cpu.PWMChannel[] { Mainboard.PWM.Channel13, Mainboard.PWM.Channel14, Mainboard.PWM.Channel2, Mainboard.PWM.Channel3 };

    for (int i = 0; i < motor_pwm.Length; i++)

    {

        motor_pwm[i] = newPWM(motor_chanels[i], frequency[i],dutyCycle[i], false);

        motor_pwm[i].Start();

    }

 

马达控制:
在Sony PS2的事件代码中,我们填写如下代码:

static void ps2_Click(object sender, PS2.ButtonArgs e)

    {

if(e.key == PS2.Key.RRocker)

        {

            PS2ps2 = (PS2)sender;

            PS2.ButtonArgs button = ps2.GetButton(PS2.Key.L2);

            if(button.state == 1) //L2按下

            {

                byte[]buffer = new byte[]{ 0xAA, (byte)e.x, (byte)e.y,0x55 };

                piPort.Write(buffer, 0, 4);

                piPort.Flush();

 

                //左右旋转

                steering_pwm[3].Duration = (UInt32)(durations[3] + (128 - e.x) * 5);

                //上下旋转

                steering_pwm[4].Duration = (UInt32)(durations[4] + (128 - e.y) * 5);

 

            }

            Else  //L2抬起

            {

                //小车运动

                UInt32[]values = new UInt32[4];

                UInt32x = (UInt32)(System.Math.Abs(e.x- 128));

                UInt32y = (UInt32)(System.Math.Abs(e.y- 128));

                for(int i = 0; i < values.Length; i++)values[i] = y;

 

                if(e.y < 128)

                {

                    //前进

                    for(int i = 0; i < In.Length; i++)In[i].Write(states2[i]);

                    //拐弯

                    if(x > 30)

                    {

                        if (e.x < 128)

                        {

                            values[2] = x;

                            values[3] = x;

                        }

                        else

                        {

                            values[0] = x;

                            values[1] = x;

                        }

                    }

                }

                else

                {

                    //后退

                    for(int i = 0; i < In.Length; i++)In[i].Write(states1[i]);

                    //拐弯

                    if(x > 30)

                    {

                        if (e.x < 128)

                        {

                            values[0] = x;

                            values[1] = x;

                        }

                        else

                        {

                            values[2] = x;

                            values[3] = x;

                        }

                    }

                }

                //设置占空比

                for(int i = 0; i < motor_pwm.Length; i++)motor_pwm[i].DutyCycle = (values[i] / 128.0);

            }

        }

    }      

B、驱动舵机

舵机参数定义:

static PWM[] steering_pwm = new PWM[5];

    static UInt32[]periods = new UInt32[]{ 20000, 20000, 20000, 20000, 20000 };//周期        static UInt32[]durations = new UInt32[]{ 1390, 1500, 1390, 1550, 1420 };   //脉宽

 

舵机初始化:

Cpu.PWMChannel[]steering_chanels = new Cpu.PWMChannel[] { Mainboard.PWM.Channel8, Mainboard.PWM.Channel9, Mainboard.PWM.Channel6, Mainboard.PWM.Channel0, Mainboard.PWM.Channel4 };

    for (int i = 0; i < steering_pwm.Length; i++)

    {

        steering_pwm[i] = new PWM(steering_chanels[i],periods[i], durations[i], PWM.ScaleFactor.Microseconds, false);

        steering_pwm[i].Start();

    }

 

舵机控制:

static void ps2_Click(object sender, PS2.ButtonArgs e)

    {

       if (e.key == PS2.Key.LRocker) //左摇杆事件

        {

            //控制机械臂左右旋转

            steering_pwm[0].Duration = (UInt32)(durations[0] + (128 - e.x) * 5);

            //控制机械臂上下旋转

            steering_pwm[1].Duration = (UInt32)(durations[1] + (128 - e.y) * 5);

        }

        else if (e.key == PS2.Key.R2)  //按下右R2键

        {

            //打开钳子

            value += 10; if (value > 255) value = 255;

            steering_pwm[2].Duration = (UInt32)(durations[2] + (value - 128) * 5);

        }

        else if (e.key == PS2.Key.R1)  //按下右R1键

        {  

            //闭合钳子

            value -= 10;if (value < 0) value = 0;

            steering_pwm[2].Duration = (UInt32)(durations[2] + (value - 128) * 5);

        }

     }

C、视频演示
视频链接:http://v.youku.com/v_show/id_XNjY2MTE1NjQ0.html
小结:

1、 .NET Micro Framework PWM类的设计,非常符合用户的认知和使用习惯,可以非常方便地实现相应功能。

2、 通过VS2010/VS2012在线调试,可以快速地测试出合适的控制值。

3、 以上代码大概十几分钟就可以完成,充分体现了.NET Micro Framework快速开发的特性。

相关文章
|
5月前
|
人工智能 缓存 Kubernetes
.NET 9 首个预览版发布:瞄准云原生和智能应用开发
.NET 9 首个预览版发布:瞄准云原生和智能应用开发
|
3月前
|
存储 监控 数据安全/隐私保护
云上智能视频分析:重塑视觉监控与决策的未来
云上智能视频分析平台注重数据安全和隐私保护。通过采用多种技术手段确保视频数据在传输、存储和处理过程中的安全性和隐私性,保护用户隐私和商业秘密不受侵犯。 四、未来发展趋势 4.1 边缘计算与云计算融合 随着物联网设备数量的不断增加和数据量的快速增长,边缘计算将成为云上智能视频分析的重要发展方向。通过将计算能力和数据处理能力下沉到边缘侧,可以减少数据传输延迟和带宽消耗,提高系统的响应速度和稳定性。 4.2 跨领域融合与创新 云上智能视频分析技术将与物联网
150 7
|
3月前
|
机器学习/深度学习 边缘计算 监控
云视界:智能视频分析开启智慧生活新篇章
我们可以期待在未来几年内看到更多创新的应用案例和解决方案。企业和开发者应当积极探索这项技术的潜力,把握住这一变革带来的机遇。
|
3月前
|
机器学习/深度学习 存储 监控
云上智能视频分析:解锁视频数据的无限潜能
更加安全可靠:随着网络安全和数据保护意识的提高,云上智能视频分析系统将更加注重安全性和可靠性保障。未来的系统将采用更加先进的加密技术和安全防护措施,确保视频数据的传输和存储过程安全可靠;同时还将建立完善
95 0
|
5月前
|
缓存 C# Windows
一款.NET开源的小巧、智能、免费的Windows内存清理工具 - WinMemoryCleaner
一款.NET开源的小巧、智能、免费的Windows内存清理工具 - WinMemoryCleaner
144 0
|
存储 人工智能 边缘计算
Net5.5G:2030年的智能世界正在向你招手
Net5.5G:2030年的智能世界正在向你招手
|
存储 监控 前端开发
Net5开发的视频监控管理系统
一个基于.Net 5构建的简单、跨平台视频监控系统,代码清晰简洁、易扩展,采用前后端分离架构。
554 0
Net5开发的视频监控管理系统
|
计算机视觉
《DeepStream 大规模智能视频分析系统》电子版地址
DeepStream: 大规模智能视频分析系统
97 0
《DeepStream 大规模智能视频分析系统》电子版地址
|
机器学习/深度学习 传感器 人工智能
智能视频分析如何改变零售商店
零售格局正在发生前所未有的变化。仔细观察零售商使用IVA驱动的人工智能的不同方式,可以深入了解智能零售的运作方式。
339 0
智能视频分析如何改变零售商店
VS2015 .NET智能提示英文的处理方案
VS2015 .NET智能提示英文的处理方案
223 0