找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3057|回复: 0
收起左侧

用Processing控制Arduino(多舵机和步进电机)源程序

[复制链接]
ID:426684 发表于 2019-3-31 18:38 | 显示全部楼层 |阅读模式
作用:

1.上位机选择舵机角度和步进电机步数,通过串口发送给Arduin驱动多个舵机和步进电机.

2.上位机控制软件采用Processing (串口可选).

3.舵机及步进电机电源采用外接.


test.JPG


材料:

1.Arduino UNO

2.三个9g 舵机

3.一个步进电机

4.I2C LCD1602

5.PC(Processing)


连线图:

Untitled Sketch_bb.jpg


Arduino代码:

//arduino
  1. #include <Wire.h>
  2. #include <LiquidCrystal_I2C.h> //引用I2C库
  3. //I2C 引脚接A4, A5
  4. //设置LCD1602设备地址,这里的地址是0x3F,一般是0x20,或者0x27,具体看模块手册
  5. LiquidCrystal_I2C lcd(0x27,16,2);  
  6. #include <Stepper.h>
  7. #include<Servo.h>
  8. Servo myservo0;
  9. Servo myservo1;
  10. Servo myservo2;
  11. Servo myservo3;
  12. char data;
  13. int servo0=2;
  14. int servo1=3;
  15. int servo2=4;
  16. int servo3=5;
  17. int pos0;
  18. int pos1;
  19. int pos2;
  20. int pos3;
  21. int step0;
  22. int bj;
  23. int temp=0;
  24. int mark = 0;
  25. //底盘步进电机
  26. const int stepsPerRevolution=200;
  27. Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11);    //步进电机 Pin
  28. int step=0;

  29. void setup() {
  30. Serial.begin(9600);
  31.   lcd.init();                  // 初始化LCD
  32.   lcd.backlight();             //设置LCD背景等亮
  33.   myservo0.attach(servo0);
  34.   myservo1.attach(servo1);
  35.   myservo2.attach(servo2);
  36.   myservo3.attach(servo3);
  37.   pos0=0;
  38.   pos1=0;
  39.   pos2=0;
  40.   pos3=0;
  41.   step0=0;
  42.   bj=0;
  43.   myStepper.setSpeed(60);
  44.   updateServo();
  45. }
  46. void loop(){
  47.   recv_data();
  48.   show_data();
  49.   updateServo();
  50. }
  51. void recv_data(){   //
  52.   while(Serial.available()){
  53.     data=Serial.read();
  54.     if(data=='%'){
  55.     pos0=Serial.read();
  56.     delay(100);
  57.     pos1=Serial.read();
  58.     delay(100);
  59.     pos2=Serial.read();
  60.     delay(100);
  61.     pos3=Serial.read();
  62.     delay(100);
  63.     step0=Serial.read();
  64.     delay(100);
  65.     bj=Serial.read();   
  66.     delay(100);
  67.     }
  68.      mark = 1;
  69.   }
  70. }
  71. void updateServo(){
  72. if(mark == 1){
  73. myservo0.write(pos0);
  74. delay(1000);
  75. myservo1.write(pos1);
  76. delay(1000);
  77. myservo2.write(pos2);
  78. delay(1000);
  79. myservo3.write(pos3);
  80. delay(1000);
  81. if(bj==1 && !temp==step0){
  82. Stepper(step0);        //步进电机+转
  83. delay(500);
  84. temp=step0;
  85. }
  86. if(bj==0  && !temp==step0 ){
  87. Stepper(-step0);       //步进电机-转
  88. delay(500);
  89. temp=step0;
  90. }
  91. mark = 0;
  92. }
  93. }
  94. void show_data(){
  95. lcd.setCursor(0,0);              
  96. lcd.print("0=");     
  97. lcd.setCursor(2,0);         
  98. lcd.print(pos0);     
  99. lcd.setCursor(5,0);            
  100. lcd.print("1=");     
  101. lcd.setCursor(7,0);              
  102. lcd.print(pos1);     
  103. lcd.setCursor(10,0);            
  104. lcd.print("2=");     
  105. lcd.setCursor(13,0);              
  106. lcd.print(pos2);   
  107. lcd.setCursor(0,1);        
  108. lcd.print("3=");   
  109. lcd.setCursor(2,1);         
  110. lcd.print(pos3);     
  111. lcd.setCursor(5,1);           
  112. lcd.print("4=");     
  113. lcd.setCursor(7,1);         
  114. lcd.print(step0);     
  115. }
  116. //步进电机
  117. void Stepper(int stepsPerRevolution) {
  118. myStepper.step(stepsPerRevolution);
  119. delay(500);
  120. }
  121. [b][b]Processing 代码:[/b][/b]
  122. import processing.serial.*;
  123. PFont font;
  124. String ComX[] = null;
  125. String SerialName = "COM1";
  126. boolean serial;
  127. int pos0=0;
  128. int pos1=0;
  129. int pos2=0;
  130. int pos3=0;
  131. int step0=0;
  132. int value=10;
  133. int value1=10;
  134. String mesg1="";
  135. String mesg2="";
  136. String mesg3="";
  137. String mesg4="";
  138. String mesg5="";
  139. String mesg="";
  140. int bj=0;
  141. void setup(){
  142. size(800, 600);
  143. ComX = myPort.list();
  144. font = createFont("宋体.vlw",48);
  145. textFont(font);
  146. frameRate(30);
  147. smooth();
  148. printArray(ComX);
  149. }
  150. void draw(){
  151. background(255);
  152. drawWindows(20,50);
  153. Serial_Handle(20,50);
  154. CheckBoxHandle();
  155. CheckBoxHandle_S();
  156. }
  157. void drawWindows(float x, float y){

  158. drawForm(x,y);

  159. if(button(x + 350, y + 450,"选串口")!= 0){
  160. Serial_SetClick();
  161. }
  162. if(button(x + 500, y + 450,"发送指令") != 0){
  163.   if(SerialName==null){
  164.   }else{
  165. send_data();
  166.   }
  167. }
  168. if(button(x + 650, y + 450,"退  出") != 0){
  169. exit();
  170. }
  171. }

  172. //绘制主窗口
  173. void drawForm(float x, float y){
  174. strokeWeight(2);
  175. textSize(18);
  176. text("Processing-Arduino 四自由度机械臂操控", 200,23);
  177. fill(0);
  178. strokeWeight(1);
  179. textSize(12);
  180. text("( 探索软件制 @ CopyRight 2019 )", 560,25);
  181. textSize(18);
  182. strokeWeight(1);
  183. fill(0);
  184. textSize(18);
  185. line(0,25,1000,36);
  186. line(0,450,1000,450);
  187. text("舵机-0",5,65);
  188. text("舵机-1",5,110);
  189. text("舵机-2",5,155);
  190. text("舵机-3",5,200);
  191. line(0,280,1000,280);
  192. text("步电-0",5,320);
  193. text("POS0=",350,65);
  194. text(int(pos0),420,65);
  195. text("POS1=",350,110);
  196. text(int(pos1),420,110);
  197. text("POS2=",350,155);
  198. text(int(pos2),420,155);
  199. text("POS3=",350,200);
  200. text(int(pos3),420,200);
  201. text("Step0=",350,320);
  202. text(int(step0),420,320);
  203. mesg="POS0="+pos0+","+"POS1="+pos1+","+"POS2="+pos2+","+"POS3="+pos3+","+"step0="+step0+","+"bj="+bj;
  204. fill(237,28,36);
  205. text(mesg1,280,65);
  206. text(mesg2,280,110);
  207. text(mesg3,280,155);
  208. text(mesg4,280,200);
  209. text(mesg5,280,320);
  210. textSize(16);
  211. strokeWeight(2);
  212. fill(0);
  213. text("向Arduino发送数据:",50,580);
  214. text(mesg,200,580);
  215. text("角度增量选择=", 20, 260);
  216. text(value, 125, 260);
  217. text("度", 145, 260);
  218. text("步数增量选择=", 20, 370);
  219. text(value1, 125, 370);
  220. text("步", 150, 370);
  221. text("当前串口=", 20, 420);
  222. text(SerialName + "    9600bps", 100,420);

  223. if(button(60, 45,"向前") != 0){
  224. mesg1="向前进";
  225. pos0=pos0+value;
  226. pos0=constrain(pos0,0,180);
  227. }
  228. if(button(165, 45,"向后") != 0){
  229. mesg1="向后进";
  230. pos0=pos0-value;
  231. pos0=constrain(pos0,0,180);
  232. }
  233. if(button(545, 45,"归零") != 0){
  234. mesg1="归零";
  235. pos0=0;
  236. pos0=constrain(pos0,0,180);
  237. }
  238. if(button(60, 90,"向前") != 0){
  239. mesg2="向前进";
  240. pos1=pos1+value;
  241. pos1=constrain(pos1,0,180);
  242. }
  243. if(button(165, 90,"向后") != 0){
  244. mesg2="向后进";
  245. pos1=pos1-value;
  246. pos1=constrain(pos1,0,180);
  247. }
  248. if(button(545, 90,"归零") != 0){
  249. mesg2="归零";
  250. pos1=0;
  251. pos1=constrain(pos1,0,180);
  252. }
  253. if(button(60, 135,"向前") != 0){
  254. mesg3="向前进";
  255. pos2=pos2+value;
  256. pos2=constrain(pos2,0,180);
  257. }
  258. if(button(165, 135,"向后") != 0){
  259. mesg3="向后进";
  260. pos2=pos2-value;
  261. pos2=constrain(pos2,0,180);
  262. }
  263. if(button(545, 135,"归零") != 0){
  264. mesg3="归零";
  265. pos2=0;
  266. pos2=constrain(pos2,0,180);
  267. }
  268. if(button(60, 180,"向前") != 0){
  269. mesg4="向前进";
  270. pos3=pos3+value;
  271. pos3=constrain(pos3,0,180);
  272. //send_data();
  273. }
  274. if(button(165, 180,"向后") != 0){
  275. mesg4="向后进";
  276. pos3=pos3-value;
  277. pos3=constrain(pos3,0,180);
  278. }
  279. if(button(545, 180,"归零") != 0){
  280. mesg4="归零";
  281. pos3=0;
  282. pos3=constrain(pos3,0,180);
  283. }

  284. if(button(60, 300,"向前") != 0){
  285. mesg5="向前进";
  286. step0=step0+value1;
  287. step0=constrain(step0,0,360);
  288. bj=1;
  289. }
  290. if(button(165, 300,"向后") != 0){
  291. mesg5="向后进";
  292. step0=step0-value1;
  293. step0=constrain(step0,0,360);
  294. bj=0;
  295. }
  296. if(button(545, 300,"归零") != 0){
  297. mesg5="归零";
  298. step0=0;
  299. step0=constrain(step0,0,360);
  300. bj=0;
  301. }
  302. }
  303. byte button(float x , float y , String str){
  304. byte ret = 0;
  305. //fill(0,255,0);
  306. fill(0,0,0);
  307. strokeWeight(2);
  308. //stroke(255,255,0);
  309. if((mouseX > x) && (mouseY > y) && (mouseX < (x + 100) ) &&(mouseY < (y + 30))){
  310. fill(128,255,255);
  311. if (mousePressedFlag && (mouseButton == LEFT)) {
  312. mousePressedFlag = false;
  313. fill(0,128,128);
  314. ret = 1;
  315. }
  316. }
  317. rect(x,y, 100, 30);
  318. fill(255,255,255);
  319. textSize(16);
  320. text(str, x + 24, y + 22);
  321. return ret;
  322. }

  323. //舵机角度选择
  324. boolean X_checkBox = true;
  325. boolean Y_checkBox = false;
  326. boolean Z_checkBox = false;
  327. boolean A_checkBox = false;
  328. boolean B_checkBox = false;
  329. boolean C_checkBox = false;
  330. boolean D_checkBox = false;
  331. boolean E_checkBox = false;

  332. void CheckBoxHandle(){
  333. if(CheckBox(240,245,X_checkBox, "10")== 1){
  334. X_checkBox = (X_checkBox == false) ? true: false;
  335. value=10;
  336. }
  337. if(CheckBox(300,245,Y_checkBox, "20") == 1){
  338. Y_checkBox = (Y_checkBox == false) ? true: false;
  339. value=20;
  340. }
  341. if(CheckBox(360,245, Z_checkBox, "30") == 1){
  342. Z_checkBox = (Z_checkBox == false) ? true: false;
  343. value=30;
  344. }
  345. if(CheckBox(420,245, A_checkBox, "40") == 1){
  346. A_checkBox = (A_checkBox == false) ? true: false;
  347. value=40;
  348. }
  349. if(CheckBox(480,245, B_checkBox, "50") == 1){
  350. B_checkBox = (B_checkBox == false) ? true: false;
  351. value=50;
  352. }
  353. if(CheckBox(540,245, C_checkBox, "60") == 1){
  354. C_checkBox = (C_checkBox == false) ? true: false;
  355. value=60;
  356. }
  357. if(CheckBox(600,245, D_checkBox, "70") == 1){
  358. D_checkBox = (D_checkBox == false) ? true: false;
  359. value=70;
  360. }
  361. if(CheckBox(660,245, E_checkBox, "80") == 1){
  362. E_checkBox = (E_checkBox == false) ? true: false;
  363. value=80;
  364. }
  365. }
  366. boolean checkBox_GetXFlag(){
  367. return X_checkBox;
  368. }
  369. boolean checkBox_GetYFlag(){
  370. return Y_checkBox;
  371. }
  372. boolean checkBox_GetZFlag(){
  373. return Z_checkBox;
  374. }
  375. boolean checkBox_GetAFlag(){
  376. return A_checkBox;
  377. }
  378. boolean checkBox_GetBFlag(){
  379. return B_checkBox;
  380. }
  381. boolean checkBox_GetCFlag(){
  382. return C_checkBox;
  383. }
  384. boolean checkBox_GetDFlag(){
  385. return D_checkBox;
  386. }
  387. boolean checkBox_GetEFlag(){
  388. return E_checkBox;
  389. }


  390. byte CheckBox(float x, float y, boolean sL, String str){
  391. noFill();
  392. //stroke(255,255,0);
  393. if(sL){
  394. fill(0,255,0);
  395. }
  396. rect(x, y, 20, 20);
  397. textSize(16);
  398. fill(0);
  399. strokeWeight(2);
  400. text(str, x + 30, y + 20);
  401. if((mouseX > x) && (mouseY > y) && (mouseX < (x + 20) ) &&(mouseY < (y + 20))){
  402. if (mousePressedFlag && (mouseButton == LEFT)) {
  403. mousePressedFlag = false;
  404. return 1;
  405. }
  406. }
  407. return 0;
  408. }
  409. //步进电机步数选择
  410. boolean S1_checkBox = true;
  411. boolean S2_checkBox = false;
  412. boolean S3_checkBox = false;
  413. boolean S4_checkBox = false;
  414. boolean S5_checkBox = false;
  415. boolean S6_checkBox = false;
  416. boolean S7_checkBox = false;
  417. boolean S8_checkBox = false;
  418. void CheckBoxHandle_S(){
  419. if(CheckBox_S(240,350,S1_checkBox, "10")== 1){
  420. S1_checkBox = (S1_checkBox == false) ? true: false;
  421. value1=10;
  422. }
  423. if(CheckBox_S(300,350,S2_checkBox, "20") == 1){
  424. S2_checkBox = (S2_checkBox == false) ? true: false;
  425. value1=20;
  426. }
  427. if(CheckBox_S(360,350, S3_checkBox, "30") == 1){
  428. S3_checkBox = (S3_checkBox == false) ? true: false;
  429. value1=30;
  430. }
  431. if(CheckBox_S(420,350, S4_checkBox, "40") == 1){
  432. S4_checkBox = (S4_checkBox == false) ? true: false;
  433. value1=40;
  434. }
  435. if(CheckBox_S(480,350, S5_checkBox, "50") == 1){
  436. S5_checkBox = (S5_checkBox == false) ? true: false;
  437. value1=50;
  438. }
  439. if(CheckBox_S(540,350, S6_checkBox, "60") == 1){
  440. S6_checkBox = (S6_checkBox == false) ? true: false;
  441. value1=60;
  442. }
  443. if(CheckBox_S(600,350, S7_checkBox, "70") == 1){
  444. S7_checkBox = (S7_checkBox == false) ? true: false;
  445. value1=70;
  446. }
  447. if(CheckBox_S(660,350, S8_checkBox, "80") == 1){
  448. S8_checkBox = (S8_checkBox == false) ? true: false;
  449. value1=80;
  450. }
  451. }
  452. boolean checkBox_GetS1Flag(){
  453. return S1_checkBox;
  454. }
  455. boolean checkBox_GetS2Flag(){
  456. return S2_checkBox;
  457. }
  458. boolean checkBox_GetS3Flag(){
  459. return S3_checkBox;
  460. }
  461. boolean checkBox_GetS4Flag(){
  462. return S4_checkBox;
  463. }
  464. boolean checkBox_GetS5Flag(){
  465. return S5_checkBox;
  466. }
  467. boolean checkBox_GetS6Flag(){
  468. return S6_checkBox;
  469. }
  470. boolean checkBox_GetS7Flag(){
  471. return S7_checkBox;
  472. }
  473. boolean checkBox_GetS8Flag(){
  474. return S8_checkBox;
  475. }
  476. byte CheckBox_S(float x, float y, boolean sL, String str){
  477. noFill();
  478. //stroke(255,255,0);
  479. if(sL){
  480. fill(0,255,0);
  481. }
  482. rect(x, y, 20, 20);
  483. textSize(16);
  484. fill(0);
  485. strokeWeight(2);
  486. text(str, x + 30, y + 20);
  487. if((mouseX > x) && (mouseY > y) && (mouseX < (x + 20) ) &&(mouseY < (y + 20))){
  488. if (mousePressedFlag && (mouseButton == LEFT)) {
  489. mousePressedFlag = false;
  490. return 1;
  491. }
  492. }
  493. return 0;
  494. }
  495. int name = 0;
  496. String strName = String.valueOf(name);
  497. byte click = 0;
  498. byte comNum = 0;
  499. byte Serial_StopFlag = 0;
  500. boolean Serial_OpenFlag = false;
  501. boolean Serial_DatareadFlag = false;
  502. byte[] Serial_buffer = new byte[6];
  503. Serial myPort;
  504. String strSerial = "com1";
  505. boolean Serial_GetdataFlag = false;
  506. String[] strComBuff = new String[4];


  507. void Serial_Handle(float x, float y){
  508. if(click != 0){
  509. comNum = 0;
  510. Serial_DrawComX(20, 50);
  511. }
  512. else{
  513. textSize(12);
  514. //fill(255);
  515. fill(0);
  516. }
  517. Serial_GetdataFromCom();
  518. }

  519. void Serial_DrawComX(float x, float y){
  520. int i = 0;
  521. int len = ComX.length;
  522. textSize(12);
  523. while(i < len){
  524. if(comNum != 0){//选择了端口
  525. break;
  526. }
  527. Serial_DrawCom(x + 350, y + 480 + i * 30, ComX[i]);
  528. i++;
  529. }
  530. }
  531. void Serial_DrawCom(float x, float y, String str){
  532. fill(255);
  533. //noStroke();
  534. rect(x, y, 101, 30);
  535. if(mouseX > x && mouseY > y && mouseX < x + 100 && mouseY < y + 30){
  536. fill(175,183,203);
  537. rect(x,y, 101, 30);
  538. if (mousePressed && (mouseButton == LEFT)) { //按键按下
  539. if(str.equals("COM1") == true){
  540. comNum = 1;
  541. }
  542. else if(str.equals("COM2") == true){
  543. comNum = 1;
  544. }
  545. else if(str.equals("COM3") == true){
  546. comNum = 1;
  547. }
  548. else if(str.equals("COM4") == true){
  549. comNum = 1;
  550. }
  551. else if(str.equals("COM5") == true){
  552. comNum = 1;
  553. }
  554. else if(str.equals("COM6") == true){
  555. comNum = 1;
  556. }
  557. else if(str.equals("COM7") == true){
  558. comNum = 1;
  559. }
  560. else if(str.equals("COM8") == true){
  561. comNum = 1;
  562. }
  563. else if(str.equals("COM9") == true){
  564. comNum = 1;
  565. }
  566. if(str.equals(SerialName) != true){
  567. SerialName = str;
  568. if(comNum != 0){
  569. click = 0;
  570. if(Serial_StopFlag != 0){
  571. myPort.stop();//停止上一个串口
  572. }
  573. myPort =new Serial(this,SerialName,9600 );
  574. myPort.bufferUntil(10);
  575. Serial_StopFlag = 1;
  576. Serial_OpenFlag = true;
  577. }
  578. }
  579. click = 0;
  580. }
  581. }
  582. fill(0,0,255);
  583. text(str,x + 10, y + 25);
  584. }

  585. void Serial_SetClick(){
  586. click = 1;
  587. }
  588. void Serial_GetdataFromCom(){
  589. if(Serial_OpenFlag != true){
  590. strComBuff[0] = " ";
  591. strComBuff[1] = " ";
  592. strComBuff[2] = " ";
  593. return;
  594. }
  595. if(myPort.available() > 0){
  596. Serial_GetdataFlag = true;
  597. strSerial = myPort.readString();
  598. strComBuff = strSerial.split(",");
  599. }
  600. }

  601. float Serial_String2float(String str){
  602. float a = 0;
  603. a = float(str)*150;
  604. return a;
  605. }

  606. boolean Serial_GetdataFlag(){
  607. return Serial_GetdataFlag;
  608. }

  609. boolean Serial_GetComOpenFlag(){
  610. return Serial_OpenFlag;
  611. }

  612. void serialEvent(Serial p) {
  613. Serial_GetdataFlag = true;
  614. strSerial = p.readString();
  615. strComBuff = strSerial.split(",");
  616. }

  617. //send data to Arduino
  618. void send_data(){
  619. print("pos0=");
  620. print(pos0);
  621. print(',');
  622. print("pos1=");
  623. print(pos1);
  624. print(',');
  625. print("pos2=");
  626. print(pos2);
  627. print(',');
  628. print("pos3=");
  629. print(pos3);
  630. print(',');
  631. print("step0=");
  632. print(step0);
  633. print(',');
  634. print("bj=");
  635. println(bj);
  636. myPort.write('%');
  637. myPort.write(int(pos0));
  638. myPort.write(int(pos1));
  639. myPort.write(int(pos2));
  640. myPort.write(int(pos3));
  641. myPort.write(int(step0));
  642. myPort.write(int(bj));
  643. serial=false;
  644. }

  645. boolean mousePressedFlag = false;
  646. void mousePressed() {
  647. mousePressedFlag = true;
  648. }
  649. boolean SaveFlag = false;
复制代码




评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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