2018-08-12 09:06:21 yongtongguan9284 阅读数 12018
  • arduino实战

    学习如何在arduino中使用各种传感器,包括人体红外传感器,超声波传感器,舵机控制,温湿度传感器,激光接收传感器等,空气质量传感器,wifi模块等....课程内容会不断的更新增加,只要发现比较有趣的传感器就会做对应的实战视频

    579 人正在学习 去看看 陈贤能

Arduino Uno控制直流电机

这是我本科毕业设计的部分内容,之前回答别人相关问题时留下了QQ号,这几年总有人加我问相关的问题。今天也有一个本科生咨询,趁这个机会,就把相关资料贴出来吧。
其实,三年前的东西都已经记不清楚了。研究生没有做硬件,相关的都快看不懂了!为了让大家看得懂程序,将总的系统设计思路贴出来,如下:
这里写图片描述
整个系统是实现“太阳能智能控制环保路灯控制器设计”,主要是用直流电机控制太阳能电池板转动,确保其在每个时间段能够实现最高的发电效率,仿向日葵实现东西转动。
Arduino Uno手册上有其关于控制直流电机的详细介绍,如果仔细阅读,实现起来很简单的。可以结合本文的系统,对其进一步理解,则可以编写响应的代码。

主程序

//#include
int pinI1=8;
int pinI2=9;
int pinI3=2;
//int pinI4=3;
int pinI5=4;
//int pinI6=5;
//int pinI7=6;
int speedin=11;
volatile int state=LOW;
void setup()
{
pinMode(pinI1,OUTPUT);
pinMode(pinI2,OUTPUT);
pinMode(pinI3,INPUT);
// pinMode(pinI4,OUTPUT);
pinMode(pinI5,OUTPUT);
// pinMode(pinI6,OUTPUT);
// pinMode(pinI7,OUTPUT);
pinMode(speedin,OUTPUT);
// myPID.SetMode(AUTOMATIC);
// attachInterrupt(0,light,HIGH);
}
void loop()
{
while(1)
{
int m=analogRead(A0);
int n=analogRead(A1);
int err,err1,err2;
int pidspeed1;
float kp=0.1 ,ki=0,kd=0;
err=m-n;
pidspeed1=(int)(err*kp-err1*ki+err2*kd);
err1=err;
err2=err1;
state=digitalRead(pinI3);
digitalWrite(pinI5,state);
if (m>n)
{
// while(1)
// {
digitalWrite(pinI1,LOW);
digitalWrite(pinI2,HIGH);
analogWrite(speedin,100+pidspeed1);
// }
// delay(2000);
}
else if(m
{
// while(1)
// {
digitalWrite(pinI1,HIGH);
digitalWrite(pinI2,LOW);
analogWrite(speedin,100-pidspeed1);
// delay(2000);
// }

}

else

{
// while(1)
// {
digitalWrite(pinI1,HIGH);
digitalWrite(pinI2,HIGH);
//delay(2000);
// }
}
}
}

 这是我本科毕业设计的部分内容,之前回答别人相关问题时留下了QQ号,这几年总有人加我问相关的问题。今天也有一个本科生咨询,趁这个机会,就把相关资料贴出来吧。
 其实,三年前的东西都已经记不清楚了。研究生没有做硬件,相关的都快看不懂了!为了让大家看得懂程序,将总的系统设计思路贴出来,如下:

PID算法控制程序

该部分系统原理图如下,有助于理解代码,可根据应用环境不同修改代码:
这里写图片描述这里写图片描述
这里写图片描述
int m=analogRead(A0);

int n=analogRead(A1);

int err,err1,err2;

int pidspeed1;

float kp=0.1 ,ki=0,kd=0;

err=m-n;

pidspeed1=(int)(err*kp-err1*ki+err2*kd);

err1=err;

err2=err1;

void light();

SetMotor(Output);

void SetMotor()

{

if (m>n)

 {       

    digitalWrite(pinI1,LOW);

   digitalWrite(pinI2,HIGH);

analogWrite(speedin,100+pidspeed1);}

else if(m

{ digitalWrite(pinI1,HIGH);

   digitalWrite(pinI2,LOW);

 analogWrite(speedin,100-pidspeed1);}

else

{digitalWrite(pinI1,HIGH);

digitalWrite(pinI2,HIGH);}

}

最近开始上班了,决定在CSDN记录我的程序员人生。这是我之前在新浪写的一篇博客,把它搬过来,顺便熟悉一下CSDN的用法,原博客地址:
http://blog.sina.com.cn/s/blog_bfb629e50102xrau.html

2019-02-26 10:21:59 woshi_ziyu 阅读数 284
  • arduino实战

    学习如何在arduino中使用各种传感器,包括人体红外传感器,超声波传感器,舵机控制,温湿度传感器,激光接收传感器等,空气质量传感器,wifi模块等....课程内容会不断的更新增加,只要发现比较有趣的传感器就会做对应的实战视频

    579 人正在学习 去看看 陈贤能

集成Wekinator DTW Mouse Explorer应用程序并使用Arduino和DC电机测试其控制

所需的组件

● L298N电机驱动

● Arduino Uno开发板

● Wekinator

● DTW Mouse Explorer

本篇文章主要介绍如何在Wekinator软件平台中使用Dynamic Time Warping(DTW)Mouse Explorer功能来控制连接到Arduino Uno开发板的直流电机。

DTW Mouse Explorer应用程序主要用于Processing过程控制,它可以执行不同的手势。该应用程序检查在一段时间内从传感器收回的数据,并识别何时产生的手势。

在本篇文章中,我们将调整Mouse Explorer应用程序的默认功能,向Wekinator发送2个输入,并接受最多9个类的1个DTW输出。

在第一个示例中,1个DTW输出将与4个类一起使用,以及发送X和Y输入值。

在本篇文章中,将在Mouse Explorer应用程序中记录四个手势,Wekinator将根据它们进行训练。然后Wekinator应该将应用程序设置为“运行”模式并重绘手势。

Wekinator将识别手势并将输出发送回Processing,后者将数据转发到Arduino Uno以控制电机。

Processing草图

可以在Wekinator网站上下载DTW Mouse Explorer应用程序文件。

它将提供2个输入并接受1个DTW输出。修改草图的目的是将Wekinator的输出值发送到Arduino Uno来控制电机。

Processing代码

在Processing中运行代码并检查下面的窗口,以获取它应该如何显示的示例。

在这里插入图片描述

上传处理草图时如何显示Processing窗口的示例

Arduino说明

Processing草图将Wekinator的训练输出发送到Arduino,以便相应地控制电机。

更多内容请参考以下链接:https://www.yiboard.com/thread-1063-1-1.html

2017-07-11 19:44:50 Janet_1994 阅读数 7713
  • arduino实战

    学习如何在arduino中使用各种传感器,包括人体红外传感器,超声波传感器,舵机控制,温湿度传感器,激光接收传感器等,空气质量传感器,wifi模块等....课程内容会不断的更新增加,只要发现比较有趣的传感器就会做对应的实战视频

    579 人正在学习 去看看 陈贤能

通过增量式编码器来测量电机的转速,常规的单片机的程序架构是通过定时器来实现精确的时间定时,并利用外部中断来实现对脉冲数目的计数,然后计算出一定时间内脉冲的数目,从而得到转速数值并输出。
直流电机是Arduino机器人制作中的主要动力来源,但是由于电机的参数一致性有所差别,即使是相同型号的电机在相同电压下的转速都不完全相同,而且在带负载或负载不同的情况下,更加会导致电机转速发生变化,这就会导致制作的Arduino轮式机器人不能实现直线行走,因为这是一个开环控制,没有任何反馈信号返回。如果给直流电机加上编码器作为反馈器件,也就可以测量得到电机的当前转速,如果将其与设定值计算差值,并通过PID算法计算得到新的控制信号,从而可以动态的测量和控制电机的转速,形成一个闭环控制系统。
2.1测量转速方法 测量转速方法有3种,分别为测频法(M法)、 测周法(T法)及混合法(M/T法)。 测频法是在一定时间内,通过测量旋转引起的单位时间内的脉冲数,实现对旋转轴转速测量的一种方法,适用于高、中转速的测量。该法本质上属于定时测角法,为提高测量的准确度,有时采用多标记或开齿的方法,其不确定度主要取决于时间测量和计数量化。

测周法是在转速脉冲的间隔内,用时钟脉冲来测量转速的一种方法,适合于低转速测量。该法实际上就是定角测量法,即用时标填充的方法来测量相当于某一旋转角度的时间间隔。在高、中转速时,可采用多周期平均来提高测量准确度,其不确定度主要取决于时间测量、计数量化及触发的不确定度。 混合法是在测频法的基础上,吸取测周法的优点汇集而成的一种转速测量方法。它是在转速传感器输出脉冲启动定时脉冲的同时,计取传感器输出脉冲个数和时钟脉冲个数,而当到达测量时间时,先停止对传感器输出脉冲的计数,在下一个定时脉冲启动之前再停止时钟脉冲的计数。因此,该种方法可在较宽的范围内使用。

此处,我们选择测频法来测量转速,其工作原理为:当被测信号在特定时间段T内的周期个数为N时,则被测信号的频率f=N/T。 ###2.2转速测量程序设计 利用TimerOne定时器库来实现定时,通过外部中断对电机编码器输出的脉冲进行计数,计数值除以定时时间即为一定时间内的转速。实现1秒内转速测量的程序如程序代码2所示。

#include <TimerOne.h>
long counter_val[2] = {0,0};  //定义数组,用于存放外部中断计数值
byte CurCnt = 0;    //定义当前计数器标志,用于判断当前正在计数的数组
int j=0;        //定义定时器中断标志,用于判断是否发生中断
void setup() {
  delay(2000);
  Serial.begin(115200);//初始化波特率为115200
  attachInterrupt(0, counter, RISING);//设置中断方式为上升沿
  Timer1.initialize(1000000); // 设置定时器中断时间,单位微秒,此处为1秒
  Timer1.attachInterrupt( timerIsr ); // 打开定时器中断
  interrupts();  //打开外部中断
}

void loop()
{
  long lTemp = 0; //定义临时存储数据变量
  if(j==1)   //判断是否发生定时器中断,即定时时间是否到达
   {
     j=0;   //清除定时器中断标志位
    if((CurCnt&0x01) == 0) //当前使用的是偶数计数器,则上次频率值存放在第二个元素中
     {
         lTemp = counter_val[1];  //读取数组第二个元素中的数值
         counter_val[1]=0;       //读完清除原来的数值,以便下次使用
     }
     else   //当前使用的是奇数计数器,则上次频率值存放在第一个元素中
     {
       lTemp = counter_val[0];  //读取数组第二个元素中的数值
       counter_val[0]=0;  //读完清除原来的数值,以便下次使用
     }
        Serial.print("S");    //发送帧头大写S
        Serial.print( lTemp);  //发送频率数据,并回车换行
     }
}

//外部中断处理函数
void counter()
{
    //通过当前计数器来实现对外部中断计数值存储的切换
     counter_val[CurCnt& 0x01] += 1;    //发生一次中断则加1
}

//定时器中断处理函数
void timerIsr()
{
  j=1;     //置位定时器中断标志位
  CurCnt++; //当前计数器的值加1,实现另一个计数值切换
}

验证频率测量的准确性 前面提到了Arduino的模拟输出(PWM)的频率约为490Hz,且转速测量采用的是测频法,此时用来正好来验证一下程序设计的正确性。在上面的转速测量程序中的void setup()里面delay(2000)之前增加如下代码,以产生方波。串口输出的频率测量结果如图4所示

pinMode(3,OUTPUT);
analogWrite(3,127);

转速比例控制的程序设计

#include <TimerOne.h>
#define Kp 3
#define set_point 100
long counter_val[2] = {0,0};
byte CurCnt = 0;
int j=0;
int output_value=0;
void setup()
{
  delay(2000);
  pinMode(12,OUTPUT);
  pinMode(3,OUTPUT);
  pinMode(9,OUTPUT);       //启用电机A的三个管脚,全部设置为输出状态
  digitalWrite(9, LOW);       //松开电机A的制动
  digitalWrite(12, HIGH);      //设置方向为正向旋转
  Serial.begin(115200);//初始化波特率为115200
  attachInterrupt(0, counter, RISING);//设置编码器A相位上升沿中断
  attachInterrupt(1, counter, RISING);//设置编码器B相位上升沿中断
  Timer1.initialize(10000); // 设置定时器中断时间,单位微秒
  Timer1.attachInterrupt( timerIsr ); // 打开定时器中断
  interrupts();  //打开外部中断
}
void loop()
{
  long lTemp = 0; //定义临时存储数据变量
  if(j==1)   //判断是否发生定时器中断,即定时时间是否到达
   {
     j=0;   //清除定时器中断标志位
    if((CurCnt&0x01) == 0) //当前使用的是偶数计数器,则上次频率值存放在第二个元素中
     {
         lTemp = counter_val[1];  //读取数组第二个元素中的数值
         counter_val[1]=0;       //读完清除原来的数值,以便下次使用
     }
     else   //当前使用的是奇数计数器,则上次频率值存放在第一个元素中
     {
       lTemp = counter_val[0];  //读取数组第二个元素中的数值
       counter_val[0]=0;  //读完清除原来的数值,以便下次使用
     }
        Serial.print("A");      //发送转速帧头大写A
        Serial.print( lTemp);   //发送转速数据
        output_value =( set_point -lTemp)*Kp+ output_value;  //比例计算得到控制量
        if(output_value >255)   //限制PWM在0-255范围内
        output_value =255;
if(output_value <0)   //限制PWM在0-255范围内
        output_value =0;
        analogWrite(3, output_value);      //将计算得到的控制量输出
    Serial.print("B");                //发送PWM帧头大写B
        Serial.println(output_value);       //发送PWM数据
     }
}
//外部中断处理函数
void counter()
{
     counter_val[CurCnt& 0x01] += 1;    //每一个中断加一
}
//定时器中断处理函数
void timerIsr()
{
  j=1;     //定时时间达到标志
  CurCnt++; //切换计数数组
}
2015-10-21 08:26:19 u014249394 阅读数 1656
  • arduino实战

    学习如何在arduino中使用各种传感器,包括人体红外传感器,超声波传感器,舵机控制,温湿度传感器,激光接收传感器等,空气质量传感器,wifi模块等....课程内容会不断的更新增加,只要发现比较有趣的传感器就会做对应的实战视频

    579 人正在学习 去看看 陈贤能
  • 介绍

步进电机是一种特殊的减速电机,扭矩比较大,精度高,一般能用于机械臂的转动。那用单片机(例如:arduino)怎么控制呢?

  • 参考

http://blog.csdn.net/yingcloud/article/details/19033043

http://www.arduino.cn/thread-1168-1-1.html

查看原文:http://surenpi.com/2015/10/21/arduino%e6%8e%a7%e5%88%b6%e6%ad%a5%e8%bf%9b%e7%94%b5%e6%9c%ba/

2019-03-14 10:57:21 qq_33583069 阅读数 3500
  • arduino实战

    学习如何在arduino中使用各种传感器,包括人体红外传感器,超声波传感器,舵机控制,温湿度传感器,激光接收传感器等,空气质量传感器,wifi模块等....课程内容会不断的更新增加,只要发现比较有趣的传感器就会做对应的实战视频

    579 人正在学习 去看看 陈贤能

注意下面Stepper steppermotor(STEPS_PER_ROTOR_REV, 8, 10, 9, 11);这句话有坑,并不是按顺序的。

#include<Stepper.h>
 
// 定义电机控制用常量
 
// 电机内部输出轴旋转一周步数
const int STEPS_PER_ROTOR_REV = 32; 
 
//  减速比
const int GEAR_REDUCTION = 64;
 
/*
 * 转子旋转一周需要走32步。转子每旋转一周,电机输出轴只旋转1/64周。
 * (电机内部配有多个减速齿轮,这些齿轮会的作用是让转子每旋转一周,
 * 输出轴只旋转1/64周。)
 * 因此电机输出轴旋转一周则需要转子走32X64=2048步,即以下常量定义。
*/
 
// 电机外部输出轴旋转一周步数 (2048)
const float STEPS_PER_OUT_REV = STEPS_PER_ROTOR_REV * GEAR_REDUCTION;
 
// 定义电机控制用变量
 
// 电机旋转步数
int StepsRequired;
 
// 建立步进电机对象
// 定义电机控制引脚以及电机基本信息。
// 电机控制引脚为 8,9,10,11 
// 以上引脚依次连接在ULN2003 驱动板 In1, In2, In3, In4 
 
Stepper steppermotor(STEPS_PER_ROTOR_REV, 8, 10, 9, 11); 
 
void setup()
{
//setup函数内无内容
}
 
void loop()
{
  // 极慢转动4步用于观察ULN2003电机驱动板LED变化
  steppermotor.setSpeed(1);    
  StepsRequired  =  4;
  steppermotor.step(StepsRequired);
  delay(1000);
 
   // 慢速顺时针旋转一圈
  StepsRequired  =  STEPS_PER_OUT_REV; 
  steppermotor.setSpeed(500);   
  steppermotor.step(StepsRequired);
  delay(1000);
  
  // 快速逆时针旋转一圈
  StepsRequired  =  - STEPS_PER_OUT_REV;   
  steppermotor.setSpeed(800);  
  steppermotor.step(StepsRequired);
  delay(2000);
 
}
没有更多推荐了,返回首页