找回密码
 马上注册

QQ登录

只需一步,快速开始

查看: 12441|回复: 3

用NXT通过ARDUINO MINI控制SERVO(舵机)和电调

[复制链接]
发表于 2013-5-30 21:27:16 | 显示全部楼层 |阅读模式
       NXT有伺服电机,但是这个电机太大了,并不利于用NXT组机器人(比如机械手.......),并且NXT的输出口仅有三个,实在太少,这些因素我想所有在玩乐高机器人的同好都会碰到!
      乐高的第三方扩展器件有专门的SERVO CONTROLLER,价格和运输费用上实在不经济!其实你仔细看,这些第三方的扩展器件也是基于单片机做的,MINDSERSON的舵机控制器就是用PIC做的!这些东西的硬件成本是很低廉的,核心的就是单片机里面的多路PWM控制软件!
      我这里介绍的是用ARDUINO MINI作为舵机主控的一种实现方式,通过I2C接口实现多路舵机控制.
      舵机的控制信号是通过PWM来实现的,以周期为50HZ的PWM来控制,其实这是老式的模拟舵机控制信号标准,现在的数码舵机的PWM频率已经有的达到接近400K(这里不多说了,有兴趣的自己找资料看吧.......)
      废话不说了,直接上菜!

1,你需要的材料(这里是原型的实验,不是成品)
    1,1: arduino 一片(328P,1280,2560全部可以,如果自己买芯片自己做,则还需要USBASP下载线,用以烧写bootloader)
           选择arduino原因是arduino有一个SERVO库,可以不必自己编写繁杂时钟中断,用很简单的几句能编写出所有PWM引脚的舵机控制;
    1,2:一块面包板和电线(用于方便接线而不必焊接)
    1,3:舵机至少一个(模拟的数码的都行)
    1,4:电源(4节AA电池=6V,锂电池也行,用2S的话需要降压至5-6V,多接几根二极管也可以降压)
    1,5:NXT主机一台+6芯线(你需要自制一条,或者破拆一条)
2,试验的程序(NXC的)
   NXT端的:
   (说明一下,这个主控端的程序目前的工作状态是单路来控制,其实I2C一次最多可以输出16个字节,所以程序是完全可以重写成一次I2C握手发送4路舵机控制信息)
#define ARDUINO_ADDRESS      0x31
#define ARDUINO_SEND_ADDRESS 0x62
#define ARDUINO_COMMAND_REG  0x42
#define I2C_PORT             S1
byte deviceCommand1,deviceCommand2,deviceCommand3,deviceCommand4;
void sendDeviceCommand(const byte deviceAddress,
                       const byte deviceRegister,
                       const byte deviceCommand1,
                       const byte deviceCommand2,
                       const byte deviceCommand3,
                       const byte deviceCommand4)
{
     byte I2C_req_buf[];
     ArrayBuild(I2C_req_buf, deviceAddress, deviceRegister, deviceCommand1, deviceCommand2, deviceCommand3,  deviceCommand4);
     while(I2CCheckStatus(I2C_PORT) == STAT_COMM_PENDING);
     LowspeedWrite(I2C_PORT, 0, I2C_req_buf);
}

task main()
{
     SetSensorLowspeed(I2C_PORT);
     while (TRUE)
     {
            ClearScreen();
            TextOut(0, LCD_LINE1, "NXT-I2C-Arduino " );
            TextOut(0, LCD_LINE2, "    comm test   " );
            TextOut(0, LCD_LINE8, "             Run" );
            until (ButtonPressed(BTNRIGHT, TRUE));
            Wait(50);
            TextOut(0, LCD_LINE8, " Processing ... " );
            deviceCommand1 = '1';
            deviceCommand2 = '2';
            deviceCommand3 = '0';
            deviceCommand4 = 'a';
            //Send command to Arduino
            TextOut(0, LCD_LINE7, "120a " );
            sendDeviceCommand(ARDUINO_SEND_ADDRESS,
                              ARDUINO_COMMAND_REG, deviceCommand1, deviceCommand2, deviceCommand3,  deviceCommand4);
            Wait(4000);
            TextOut(0, LCD_LINE7, "090a " );
            deviceCommand1 = '0';
            deviceCommand2 = '9';
            deviceCommand3 = '0';
            deviceCommand4 = 'a';
            sendDeviceCommand(ARDUINO_SEND_ADDRESS,
                              ARDUINO_COMMAND_REG, deviceCommand1, deviceCommand2, deviceCommand3,  deviceCommand4);
            Wait(4000);
            TextOut(0, LCD_LINE7, "160a " );
            deviceCommand1 = '1';
            deviceCommand2 = '6';
            deviceCommand3 = '0';
            deviceCommand4 = 'a';
            sendDeviceCommand(ARDUINO_SEND_ADDRESS,
                              ARDUINO_COMMAND_REG, deviceCommand1, deviceCommand2, deviceCommand3,  deviceCommand4);
            Wait(4000);
            TextOut(0, LCD_LINE7, "015a " );
            deviceCommand1 = '0';
            deviceCommand2 = '4';
            deviceCommand3 = '5';
            deviceCommand4 = 'a';
            sendDeviceCommand(ARDUINO_SEND_ADDRESS,
                              ARDUINO_COMMAND_REG, deviceCommand1, deviceCommand2, deviceCommand3,  deviceCommand4);
            Wait(4000);
            TextOut(0, LCD_LINE8, "Continue        " );
            until (ButtonPressed(BTNLEFT, TRUE));
      }
}

-----------------------------
arduino从机端
说明:程序里面绝大部份长延时是多余的, requestCommand  = Wire.read();           delay(5);这里的不能少!另外,ARDUINO所有PWM引脚都可以被定义为舵机控制端1


#include <I2Cdev.h>
#include <Servo.h>
#include <Wire.h>
#define I2C_SLAVE_ADDRESS 0x31
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;

byte requestRegister;
byte requestCommand;
void receiveEvent(int howMany)
{   
    static int v = 0;
    requestRegister = Wire.read();
    if (requestRegister = 0x42);
    {
       while (Wire.available() > 0)
       {
         requestCommand  = Wire.read();
           delay(5);
           switch(requestCommand)
             {
              case '0'...'9':
              v = v * 10 + requestCommand - '0';
              break;
              case 'a':
              v = map(v,0,180,0,180);
              servo1.write(v);
              delay(500);
              Serial.println(v);
              v = 0;
              break;
              case 'b':
              v = map(v,0,180,0,180);
              servo2.write(v);
              delay(500);
              Serial.println(v);
              v = 0;
              break;
              case 'c':
              v = map(v,0,180,0,180);
              servo3.write(v);
              delay(500);
              Serial.println(v);
              v = 0;
              break;
              case 'd':
              v = map(v,0,180,0,180);
              servo4.write(v);
              delay(500);
              Serial.println(v);
              v = 0;
              break;
              
              
              
             }
       }
      
      delay(500);
      
    }   
}
void setup()
{
     servo1.attach(8);
     servo2.attach(9);
     servo3.attach(10);
     servo4.attach(11);
     Serial.begin(9600);
     Serial.println("Ready");   
            
     Wire.begin(I2C_SLAVE_ADDRESS);
     Wire.onReceive(receiveEvent);               
}

void loop()
{
  delay(10);
}
----------------------------------------------------------------------------

如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
 楼主| 发表于 2013-5-30 21:28:11 | 显示全部楼层
本帖最后由 blackblue 于 2013-5-31 10:29 编辑

不会做图,大家凑合着看吧!

SERVO库修改频率请看动力老男孩的博客........


ARDU-NXT接线.png
ardu-nxt-servo.png
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2013-5-31 21:27:32 | 显示全部楼层
我正需要!!!这个真的不错。我前两天试了半天没成功。终于找到方法了。加我QQ:391040395吧。交流一下。谢了
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

发表于 2013-11-14 19:51:32 | 显示全部楼层
看不懂
如果您觉得我的帖子对您有用,请不吝给我一个“赞”!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 马上注册

本版积分规则

手机版|中文乐高 ( 桂ICP备13001575号-7 )

GMT+8, 2024-12-22 10:54 , Processed in 0.109478 second(s), 26 queries .

Powered by Discuz! X3.5

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表