原文 C#串口控制舵机、arduino源码 及C#源码及界面

1.舵机原理简介

控制信号由接收机的通道进入信号调制芯片,获得直流偏置电压。它内部有一个基准电路,产生周期为20ms,宽度为1.5ms的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。最后,电压差的正负输出到电机驱动芯片决定电机的正反转。当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为0,电机停止转动。

舵机的控制一般需要一个20ms左右的时基脉冲,该脉冲的高电平部分一般为0.5ms-2.5ms范围内的角度控制脉冲部分,总间隔为2ms。以180度角度伺服为例,那么对应的控制关系是这样的:

0.5ms--------------0度;

1.0ms------------45度;

1.5ms------------90度;

2.0ms-----------135度;

2.5ms-----------180度;

2.arduino下位机源码

相关源码已压缩上传,需要请下载对应附件

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include<Servo.h>  //库文件
Servo servo1;     
static int v=0;
String mycommand="";
void setup()
  {
    Serial.begin(9600);//此处为串口设置的波特率 ,可以修改 必须同上位机设置的波特路一致。
    servo1.attach(3);  // 控制的端口是~3号
    servo1.write(90);
  }
void loop() 
 {
    while(Serial.available()>0)
    {
      mycommand+=char(Serial.read());
      delay(2);
    }
    for(int m=0;m<mycommand.length();m++) // 
       {
          char ch = mycommand[m];   //读取串口数据
          switch(ch)
             {
                 case '0'...'9':
                       v = v*10 + ch - '0';   //字符转换成十进制
                        break;
                  case 'a':   //如果数据后带a,则表示是一号舵机的数据,比如串口发送85a
                        //if(v >= 5 || v <= 175 )   
                         servo1.write(v); // 让A从66度旋转到9度 (可修改角度)                     
                         //用于设定舵机旋转角度的语句,可设定的角度范围是0°到180°,“V”得到所输入的值而改变角度,比如85a为85度角
                         Serial.println(v+"°");//舵机角度改变后 发送改变的角度到上位机。
                         v = 0;
                          break;
                     }
    
          }  
   mycommand="";
}

我选择我的是arduino Uno,舵机的接线方法是红色(VCC)端接控制板的5V处,棕色端接板子的GND,舵机的橙色线为信号线,接板子上的3号口;

3.C#上位机源码及界面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace 舵机上位机源码
{
    public partial class Form1 : Form
    {
        bool open = false;
        public delegate void HandleInterfaceUpdataDelegate(string text);
        private HandleInterfaceUpdataDelegate interfaceUpdataHandle;
        int a;
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            comboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());//从系统获取已有串口
            if (comboBox1.Items.Count > 0)
            {
                comboBox1.SelectedIndex = 0;//串口变量初始化
                serialPort1.RtsEnable = true;//DataReceived事件委托
                serialPort1.ReceivedBytesThreshold = 1;//设置 DataReceived 事件发生前内部输入缓冲区中的字节数
                serialPort1.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(this.serialPort1_DataReceived);
                comboBox2.SelectedIndex = 6;
            }
            else
            {
                MessageBox.Show("未检测到设备\r\n");
            }
        }
        //监听串口
        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            try
            {
                string text = string.Empty;
                byte[] result = new byte[serialPort1.BytesToRead];
                serialPort1.Read(result, 0, serialPort1.BytesToRead);
                text = Encoding.UTF8.GetString(result);
            }
            catch 
            {
                
            }
        }
        //串口刷新按钮
        private void button2_Click(object sender, EventArgs e)
        {
            comboBox1.Items.Clear();
            comboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
            if (comboBox1.Items.Count > 0)
            {
                comboBox1.SelectedIndex = 0;
            }
            else
            {
                MessageBox.Show("未检测到串口\r\n");
            }
        }
         
        //打开串口
        private void btnOpen_Click(object sender, EventArgs e)
        {
            if (open == false)
            {
                 
                if (serialPort1.IsOpen)
                {
                    MessageBox.Show("串口已经打开""提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
                //串口
                if (comboBox1.Text == string.Empty)
                {
                    MessageBox.Show("请选择串口""提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
                //波特率
                if (comboBox2.Text == string.Empty)
                {
                    MessageBox.Show("请选择波特率""提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
                serialPort1.BaudRate = int.Parse(comboBox2.Text);
                try
                {
                    serialPort1.PortName = comboBox1.SelectedItem.ToString();
                    serialPort1.Open();
                }
                catch
                {
                    try
                    {
                        comboBox1.SelectedIndex = comboBox1.SelectedIndex + 1;
                    }
                    catch
                    {
                        comboBox1.SelectedIndex = 0;
                    }
                    serialPort1.Close();
                }
                btnOpen.Text = "关闭";
                comboBox1.Enabled = false;
                comboBox2.Enabled = false;
                open = true;
                trackBarSend_Scroll(thisnull);
                btnReserch.Enabled = false;
                btnsend.Enabled = true;
                tbxSend.Enabled = true;
                trackBarSend.Enabled = true;
                pictureBox1.BackColor = Color.Lime;
            }
            else
            {
                try
                {
                    serialPort1.Close();
                    btnOpen.Text = "打开";
                    open = false;
                    comboBox1.Enabled = true;
                    comboBox2.Enabled = true;
                    btnReserch.Enabled = true;
                    btnsend.Enabled = false;
                    tbxSend.Enabled = false;
                    trackBarSend.Enabled = false;
                    pictureBox1.BackColor = Color.Silver;
                }
                catch
                {
                }
            }
        }
        private void trackBarSend_Scroll(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                a = trackBarSend.Value;
                string duojiA = trackBarSend.Value.ToString() + "a";
                try
                {
                    serialPort1.WriteLine(duojiA);
                    tbxSend.Text = a.ToString(); ; ;
                }
                catch
                {
                }
            }
        }
        private void btnsend_Click(object sender, EventArgs e)
        {
            try
            {
                byte[] SendBuf = new byte[100000];
                SendBuf = System.Text.Encoding.Default.GetBytes(tbxSend.Text+"a");
                serialPort1.Write(SendBuf, 0, SendBuf.Length);
            }
            catch (Exception err)
            {
                if (serialPort1.IsOpen)
                    serialPort1.Close();//如果是写数据时出错,此时窗口状态为开,就应关闭串口,防止下次不能使用,串口是不能重复打开和关闭的
                MessageBox.Show(err.ToString(), "错误");
            }
        }
        private void tbxSend_ValueChanged(object sender, EventArgs e)
        {
            trackBarSend.Value = (int)tbxSend.Value;
        }
    }
}

未连接设备状态

连接设备后

这是自己做的机械臂控制软件 相关源码也有

这是wifi智能小车控制软件

第一次写博文,有不好的地方还请多多包涵。

C#串口控制舵机、arduino源码 及C#源码及界面的更多相关文章

  1. Arduino控制舵机

    一.接线 舵机 Arduino GND GND +5V 5V PWN 10 其中信号线PWN接arduino上任意带波浪号的引脚都可,我这里选择的是10号引脚,注意在程序中绑定的引脚要和连接的引脚相同 ...

  2. C#上位机串口控制12864显示

    实现的效果 上面是用Proteus仿真的,,对了如果自己想用proteus仿真需要安装下面这个软件 再看一下实物显示效果 先做上位机部分........... 为了程序一启动就把电脑上能用的串口号显示 ...

  3. 51单片机 小车 L298N pwm调速 串口控制 按键控制

    难点:1.串口定时器T1,和T0定时器优先级 2.pwm频率与占空比的设置 按键控制 按键1——前进 按键2——后退 按键3——加速 按键4——减速 (板子上只有四个按键) 串口控制 ‘1’——前进 ...

  4. 串口控制RGB灯程序

    实验目的: 通过上位机给串口发送数据(字符); STM32收到数据进入中断程序原封不动返回上位机,并且根据收到的信息产出相应的进行操作.(1- led_on  2 – ledoff...); 源码   ...

  5. spring源码解析——spring源码导入eclipse

    一.前言     众所周知,spring的强大之处.几乎所有的企业级开发中,都使用了spring了.在日常的开发中,我们是否只知道spring的配置,以及简单的使用场景.对其实现的代码没有进行深入的了 ...

  6. [译] 给PHP开发者的PHP源码-第一部分-源码结构

    文章来自:http://www.hoohack.me/2016/02/04/phps-source-code-for-php-developers-ch 原文:http://blog.ircmaxel ...

  7. PWM波控制舵机总结

    文章转自:http://www.geek-workshop.com/thread-70-1-1.html 一.关于舵机: 舵机(英文叫Servo):它由直流电机.减速齿轮组.传感器和控制电路组成的一套 ...

  8. 【转】Android手机客户端关于二维码扫描的源码--不错

    原文网址:https://github.com/SkillCollege/QrCodeScan QrCodeScan 这是Android手机客户端关于二维码扫描的源码,使用了高效的ZBar解码库,并修 ...

  9. STM32学习笔记(四)——串口控制LED(中断方式)

    目录: 一.时钟使能,包括GPIO的时钟和串口的时钟使能 二.设置引脚复用映射 三.GPIO的初始化配置,注意要设置为复用模式 四.串口参数初始化配置 五.中断分组和中断优先级配置 六.设置串口中断类 ...

随机推荐

  1. 编写ATL控件的简单做法

    作者:朱金灿 来源:http://blog.csdn.net/clever101 ATL并不像MFC库那样提供了很多的控件窗口类,因此要使用ATL的话需要自己去封装.封装的做法很简单.比如现在我需要一 ...

  2. 微信小程序开发实战视频教程发布

    昨日(9月23),腾讯终于发布了没有APPid,无需申请也可以进行微信小程序开发的视频教程了,我在在第一时间尝试并发布了这7个小视频教程,入门足够了.... 各位免费拿去,慢慢享用: 链接: http ...

  3. Javascript中eval解析的json的几种用法

    eval解析json字符串可用的三种方式都可以实现... <!DOCTYPE html> <html> <head> <meta charset=" ...

  4. Oracle数据库零散知识04 --- 其常用内置函数

    1,数值函数 Select abs(-9),--9 绝对值 Mod(5,3),--2 余数 Sign(-9),-- -1 标记 Ceil(9.4),--10 Floor(9.8),--9 Sqrt(1 ...

  5. 作为电磁波的 Wi-Fi 信号

    常用 WiFi:2.4 GHz,而同样是电磁波的可将光,频率是 WiFi 的十几万倍: 如何让家里的 WiFi 信号变得更好,移动路由器到合适位置: 1. Wi-Fi:穿墙有术还是穿墙无术? 我们都会 ...

  6. MySQL实现类似Oracle中的nextval和currval

    CREATE TABLE `sequence` ( `seq_name` varchar(50) NOT NULL, `current_val` int(11) NOT NULL, `incremen ...

  7. BZOJ 1003 ZJOI2006 物流运输trans 动态规划+SPFA

    标题效果:给定一个无向图.输送n日,有一天的某一时刻不能去,更换行考虑k,求总成本 一阶cost[i][j]用于第一i为了天j天正在同一航线的最低消费 这种利用SPFA处理 然后就是移动的法规问题 订 ...

  8. Android——四大组件、六大布局、五大存储

    一.android四大组件 (一)android四大组件详解 Android四大组件分别为activity.service.content provider.broadcast receiver. 1 ...

  9. leetcode先刷_Valid Sudoku

    我没有看到这个问题,这使其在现货需求数独,害怕一直没敢做.后来我发现原来的标题就是这么简单.推断现在只有数字全不符合的就可以了棋盘上的形势的要求. 是不是正确的三个周期..人是不能满意地看到每一行.每 ...

  10. 寄存器,cache、伙伴系统、内存碎片、段式页式存储管理

    cache.伙伴系统.内存碎片.段式页式存储管理 目录 分层的存储管理 cache 局部性原理 置换算法 写回策略 linux环境下的cache 连续内存分配与内存碎片 内部碎片与外部碎片 动态分区分 ...