机械臂控制
1. 对比360度舵机和180度舵机控制方法小结
servo.write(x); //x->[0,180];
- 1
360度舵机:
通过x设定舵机的速度(0代表一个方向的全速运行,180代表另一个方向的全速运行,90则不动)。
#include <Servo.h>
Servo myservo;
void setup()
{
myservo.attach(9);
myservo.write(90); // 舵机不动
}
void loop() {}
180度舵机:
通过x设定舵机舵盘的角度。
#include <Servo.h>
Servo myservo;
void setup()
{
myservo.attach(9);
myservo.write(90); // 在中间位置
}
void loop() {}
值得注意的是如果x不等于90,360度舵机会一直不停的转。而180度舵机在到达设定角度后会停下。
writeMicroseconds()
servo.writeMicroseconds(x) //x->[1000,2000]
- 1
360度舵机:
这个函数对于360度舵机的作用就是write()函数的模拟版,[1000,2000]对应[0,180]。比如writeMicroseconds(1500)相当于write(90),舵机不动。
180度舵机 :
通过x设定角度,一般来说1000是完全逆时针旋转后的位置,2000是完全顺时针旋转的位置,1500在中间。
注意有些制造商并不完全遵守这个标准,所以舵机经常会对700到2300之间的数值产生反应。实际数值可以自己试试。
#include <Servo.h>
Servo myservo;
void setup()
{
myservo.attach(9);
myservo.writeMicroseconds(1500); // 舵机设定为中间位置。
}
void loop() {}
Arduino引脚 |
伺服电机(舵机) |
+5V |
红色线-VCC |
GND(接地) |
棕色线-GND |
9(PWM) |
橙色线-PWM控制信号 |
2.1单个电机
/* Sweep
by BARRAGAN <http://barraganstudio.com>
This example code is in the public domain.
modified 8 Nov 2013
by Scott Fitzgerald
http://www.arduino.cc/en/Tutorial/Sweep
*/
#include <Servo.h>
Servo myservo; // 创建一个servo对象控制伺服电机
// 很多开发板允许同时创建12个servo对象
int pos = 0; // 存servo电机角度的信息变量
void setup() {
myservo.attach(9); // servo 对象连接9号引脚上
Serial.begin(9600);
}
void loop() {
for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
Serial.println(pos);
delay(15); // waits 15ms for the servo to reach the position
}
for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
myservo.write(pos); // tell servo to go to position in variable 'pos'
Serial.println(pos);
delay(15); // waits 15ms for the servo to reach the position
}
}
控制伺服电机,另外接一根地线,共地
/*
本示例程序旨在演示如何通过串口监视器控制1个伺服电机(舵机)。
This example code is in the public domain.
*/
#include <Servo.h>
Servo myServo; //创建Servo对象myServo
int dataIndex = 0; //创建整数型变量,存储输入数据序列号
void setup() {
myServo.attach(5);
Serial.begin(9600); //启动串口通讯,传输波特率9600
Serial.println("Please input serial data.");
}
void loop() { // 检查串口缓存是否有数据等待传输
if ( Serial.available()>0 ) {
int pos = Serial.parseInt(); // 解析串口数据中的整数信息并赋值给变量pos
if(pos){
dataIndex++; // 处理数据序列号并通过串口监视器显示
Serial.print("dataIndex = ");
Serial.print(dataIndex);
Serial.print(" , ");
Serial.print("Set servo position: ");
Serial.println(pos); // 通过串口监视器显示变量pos数值
myServo.write(pos); // 使用pos变量数值设置伺服电机
delay(1000);
}
}
}
2.2 串口输入控制多个电机
#include <Servo.h>
Servo base, fArm, rArm, claw; //建立4个电机对象
int dataIndex = 0;
void setup() {
base.attach(11); // base 伺服电机连接引脚11 电机代号'b'
rArm.attach(10); // rArm 伺服电机连接引脚10 电机代号'r'
fArm.attach(9); // fArm 伺服电机连接引脚9 电机代号'f'
claw.attach(6); // claw 伺服电机连接引脚6 电机代号'c'
Serial.begin(9600);
Serial.println("Please input serial data.");
}
void loop() {
if (Serial.available()) { // 检查串口缓存是否有数据等待传输
char servoName = Serial.read(); //获取电机指令中电机编号信息
Serial.print("servoName = ");
Serial.print(servoName);
Serial.print(" , ");
int data = Serial.parseInt(); //获取电机指令中电机角度信息
switch(servoName){ //根据电机指令中电机信息决定对哪一个电机进行角度设置
case 'b': // 电机指令b,设置base电机角度
base.write(data);
Serial.print("Set base servo value: ");
Serial.println(data);
break;
case 'r': // 电机指令r,设置rArm电机角度
rArm.write(data);
Serial.print("Set rArm servo value: ");
Serial.println(data);
break;
case 'f': // 电机指令f,设置fArm电机角度
fArm.write(data);
Serial.print("Set fArm servo value: ");
Serial.println(data);
break;
case 'c': // 电机指令c,设置claw电机角度
claw.write(data);
Serial.print("Set claw servo value: ");
Serial.println(data);
break;
}
}
}
2.3 一维数组控制多个电机
#include <Servo.h>
Servo base, fArm, rArm, claw;
int data[5] = {0, 45, 90, 135, 180};
void setup() {
base.attach(11); // base 伺服电机连接引脚11 电机代号'b'
rArm.attach(10); // rArm 伺服电机连接引脚10 电机代号'r'
fArm.attach(9); // fArm 伺服电机连接引脚9 电机代号'f'
claw.attach(6); // claw 伺服电机连接引脚6 电机代号'c'
}
void loop() {
for (int i = 0; i <= 4; i++){
base.write(data[i]);
delay(100);
rArm.write(data[i]);
delay(100);
fArm.write(data[i]);
delay(100);
claw.write(data[i]);
delay(100);
}
for (int i = 4; i >= 0; i--){
base.write(data[i]);
delay(100);
rArm.write(data[i]);
delay(100);
fArm.write(data[i]);
delay(100);
claw.write(data[i]);
delay(100);
}
}
2.3二维组控制多个电机
#include <Servo.h>
Servo base, fArm, rArm, claw;
int data2dArray[4][5] = { //建立二维数组用以控制四台舵机
{0, 45, 90, 135, 180},
{45, 90, 135, 90, 45},
{135, 90, 45, 90, 135},
{180, 135, 90, 45, 0}
};
void setup() {
base.attach(11); // base 伺服电机连接引脚11 电机代号'b'
rArm.attach(10); // rArm 伺服电机连接引脚10 电机代号'r'
fArm.attach(9); // fArm 伺服电机连接引脚9 电机代号'f'
claw.attach(6); // claw 伺服电机连接引脚6 电机代号'c'
}
void loop() {
for (int i = 0; i <= 4; i++){
base.write(data2dArray[0][i]); //base舵机对应data2dArray数组中第1“行”元素
delay(100);
rArm.write(data2dArray[1][i]); //rArm舵机对应data2dArray数组中第2“行”元素
delay(100);
fArm.write(data2dArray[2][i]); //fArm舵机对应data2dArray数组中第3“行”元素
delay(100);
claw.write(data2dArray[3][i]); //claw舵机对应data2dArray数组中第4“行”元素
delay(500);
}
for (int i = 4; i >= 0; i--){
base.write(data2dArray[0][i]); //base舵机对应data2dArray数组中第1“行”元素
delay(100);
rArm.write(data2dArray[1][i]); //rArm舵机对应data2dArray数组中第2“行”元素
delay(100);
fArm.write(data2dArray[2][i]); //fArm舵机对应data2dArray数组中第3“行”元素
delay(100);
claw.write(data2dArray[3][i]); //claw舵机对应data2dArray数组中第4“行”元素
delay(500);
}
}
源自于8.3.通过网页文本框控制ESP8266开发板的PWM引脚
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266WebServer.h>
#include <FS.h>
#include <Servo.h>
Servo myServo;
ESP8266WiFiMulti wifiMulti; // 建立ESP8266WiFiMulti对象
ESP8266WebServer esp8266_server(80);// 建立ESP8266WebServer对象,该对象用于响应HTTP请求。监听端口(80)
void setup(void){
myServo.attach(14); //D5
Serial.begin(9600);
Serial.println("");
pinMode(LED_BUILTIN, OUTPUT); // 初始化NodeMCU控制板载LED引脚为OUTPUT
wifiMulti.addAP("yang1234", "y123456789"); // 将需要连接的一系列WiFi ID和密码输入这里
wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2"); // ESP8266-NodeMCU再启动后会扫描当前网络
wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3"); // 环境查找是否有这里列出的WiFi ID。如果有
Serial.println("Connecting ..."); // 则尝试使用此处存储的密码进行连接。
int i = 0;
while (wifiMulti.run() != WL_CONNECTED) { // 尝试进行wifi连接。
delay(1000);
Serial.print(i++); Serial.print(' ');
}
// WiFi连接成功后将通过串口监视器输出连接成功信息
Serial.println('\n');
Serial.print("Connected to ");
Serial.println(WiFi.SSID()); // 通过串口监视器输出连接的WiFi名称
Serial.print("IP address:\t");
Serial.println(WiFi.localIP()); // 通过串口监视器输出ESP8266-NodeMCU的IP
if(SPIFFS.begin()){ // 启动闪存文件系统
Serial.println("SPIFFS Started.");
} else {
Serial.println("SPIFFS Failed to Start.");
}
//初始化网络服务器
esp8266_server.on("/LED-Control", handleLEDControl);
esp8266_server.onNotFound(handleUserRequest); // 处理其它网络请求
// 启动网站服务
esp8266_server.begin();
Serial.println("HTTP server started");
}
void loop(void){
esp8266_server.handleClient(); //处理网络请求
}
void handleLEDControl(){
// 从浏览器发送的信息中获取PWM控制数值(字符串格式)
String ledPwm = esp8266_server.arg("ledPwm");
// 将字符串格式的PWM控制数值转换为整数
int ledPwmVal = ledPwm.toInt();
// 实施引脚PWM设置
myServo.write(ledPwmVal); // 使用pos变量数值设置伺服电机
// analogWrite(LED_BUILTIN, ledPwmVal);
// 建立基本网页信息显示当前数值以及返回链接
String httpBody = "Led PWM: " + ledPwm + "<p><a href=\"/LED.html\"><-LED Page</a></p>";
esp8266_server.send(200, "text/html", httpBody);
}
// 处理用户浏览器的HTTP访问
void handleUserRequest() {
// 获取用户请求资源(Request Resource)
String reqResource = esp8266_server.uri();
Serial.print("reqResource: ");
Serial.println(reqResource);
// 通过handleFileRead函数处处理用户请求资源
bool fileReadOK = handleFileRead(reqResource);
// 如果在SPIFFS无法找到用户访问的资源,则回复404 (Not Found)
if (!fileReadOK){
esp8266_server.send(404, "text/plain", "404 Not Found");
}
}
bool handleFileRead(String resource) { //处理浏览器HTTP访问
if (resource.endsWith("/")) { // 如果访问地址以"/"为结尾
resource = "/index.html"; // 则将访问地址修改为/index.html便于SPIFFS访问
}
String contentType = getContentType(resource); // 获取文件类型
if (SPIFFS.exists(resource)) { // 如果访问的文件可以在SPIFFS中找到
File file = SPIFFS.open(resource, "r"); // 则尝试打开该文件
esp8266_server.streamFile(file, contentType);// 并且将该文件返回给浏览器
file.close(); // 并且关闭文件
return true; // 返回true
}
return false; // 如果文件未找到,则返回false
}
// 获取文件类型
String getContentType(String filename){
if(filename.endsWith(".htm")) return "text/html";
else if(filename.endsWith(".html")) return "text/html";
else if(filename.endsWith(".css")) return "text/css";
else if(filename.endsWith(".js")) return "application/javascript";
else if(filename.endsWith(".png")) return "image/png";
else if(filename.endsWith(".gif")) return "image/gif";
else if(filename.endsWith(".jpg")) return "image/jpeg";
else if(filename.endsWith(".ico")) return "image/x-icon";
else if(filename.endsWith(".xml")) return "text/xml";
else if(filename.endsWith(".pdf")) return "application/x-pdf";
else if(filename.endsWith(".zip")) return "application/x-zip";
else if(filename.endsWith(".gz")) return "application/x-gzip";
return "text/plain";
}
python脚本
import requests
role = 178
response = requests.get("http://192.168.31.249/LED-Control?ledPwm=%s" % role)
print(response.text)
BigClaw爪子(86mm)
产品名称 | 控制方式 | 重量 | 扭力 | 电源范围 | 特点 |
---|---|---|---|---|---|
LDX-335MG | PWM | 64g | 20kg.cm | 6-8.4V | 堵转保护、过温保护、金属齿轮、数字舵机、电压/位置/温度反馈、串口控制 |
HTS-16L | PWM | 60g | 16kg.cm | 6-8.4V | 角度回读、堵转保护、过温保护、金属齿轮、总线舵机 |
本文作者: 永生
本文链接: https://yys.zone/detail/?id=175
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
评论列表 (0 条评论)