|
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);
}
----------------------------------------------------------------------------
|
|