作用:
1.上位機選擇舵機角度和步進電機步數,通過串口發送給Arduin驅動多個舵機和步進電機.
2.上位機控制軟件采用Processing (串口可選).
3.舵機及步進電機電源采用外接.
test.JPG (112.32 KB, 下載次數: 86)
下載附件
2019-3-31 18:10 上傳
材料:
1.Arduino UNO
2.三個9g 舵機
3.一個步進電機
4.I2C LCD1602
5.PC(Processing)
連線圖:
Untitled Sketch_bb.jpg (1.17 MB, 下載次數: 77)
下載附件
2019-3-31 18:31 上傳
Arduino代碼:
//arduino
- #include <Wire.h>
- #include <LiquidCrystal_I2C.h> //引用I2C庫
- //I2C 引腳接A4, A5
- //設置LCD1602設備地址,這里的地址是0x3F,一般是0x20,或者0x27,具體看模塊手冊
- LiquidCrystal_I2C lcd(0x27,16,2);
- #include <Stepper.h>
- #include<Servo.h>
- Servo myservo0;
- Servo myservo1;
- Servo myservo2;
- Servo myservo3;
- char data;
- int servo0=2;
- int servo1=3;
- int servo2=4;
- int servo3=5;
- int pos0;
- int pos1;
- int pos2;
- int pos3;
- int step0;
- int bj;
- int temp=0;
- int mark = 0;
- //底盤步進電機
- const int stepsPerRevolution=200;
- Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11); //步進電機 Pin
- int step=0;
- void setup() {
- Serial.begin(9600);
- lcd.init(); // 初始化LCD
- lcd.backlight(); //設置LCD背景等亮
- myservo0.attach(servo0);
- myservo1.attach(servo1);
- myservo2.attach(servo2);
- myservo3.attach(servo3);
- pos0=0;
- pos1=0;
- pos2=0;
- pos3=0;
- step0=0;
- bj=0;
- myStepper.setSpeed(60);
- updateServo();
- }
- void loop(){
- recv_data();
- show_data();
- updateServo();
- }
- void recv_data(){ //
- while(Serial.available()){
- data=Serial.read();
- if(data=='%'){
- pos0=Serial.read();
- delay(100);
- pos1=Serial.read();
- delay(100);
- pos2=Serial.read();
- delay(100);
- pos3=Serial.read();
- delay(100);
- step0=Serial.read();
- delay(100);
- bj=Serial.read();
- delay(100);
- }
- mark = 1;
- }
- }
- void updateServo(){
- if(mark == 1){
- myservo0.write(pos0);
- delay(1000);
- myservo1.write(pos1);
- delay(1000);
- myservo2.write(pos2);
- delay(1000);
- myservo3.write(pos3);
- delay(1000);
- if(bj==1 && !temp==step0){
- Stepper(step0); //步進電機+轉
- delay(500);
- temp=step0;
- }
- if(bj==0 && !temp==step0 ){
- Stepper(-step0); //步進電機-轉
- delay(500);
- temp=step0;
- }
- mark = 0;
- }
- }
- void show_data(){
- lcd.setCursor(0,0);
- lcd.print("0=");
- lcd.setCursor(2,0);
- lcd.print(pos0);
- lcd.setCursor(5,0);
- lcd.print("1=");
- lcd.setCursor(7,0);
- lcd.print(pos1);
- lcd.setCursor(10,0);
- lcd.print("2=");
- lcd.setCursor(13,0);
- lcd.print(pos2);
- lcd.setCursor(0,1);
- lcd.print("3=");
- lcd.setCursor(2,1);
- lcd.print(pos3);
- lcd.setCursor(5,1);
- lcd.print("4=");
- lcd.setCursor(7,1);
- lcd.print(step0);
- }
- //步進電機
- void Stepper(int stepsPerRevolution) {
- myStepper.step(stepsPerRevolution);
- delay(500);
- }
- [b][b]Processing 代碼:[/b][/b]
- import processing.serial.*;
- PFont font;
- String ComX[] = null;
- String SerialName = "COM1";
- boolean serial;
- int pos0=0;
- int pos1=0;
- int pos2=0;
- int pos3=0;
- int step0=0;
- int value=10;
- int value1=10;
- String mesg1="";
- String mesg2="";
- String mesg3="";
- String mesg4="";
- String mesg5="";
- String mesg="";
- int bj=0;
- void setup(){
- size(800, 600);
- ComX = myPort.list();
- font = createFont("宋體.vlw",48);
- textFont(font);
- frameRate(30);
- smooth();
- printArray(ComX);
- }
- void draw(){
- background(255);
- drawWindows(20,50);
- Serial_Handle(20,50);
- CheckBoxHandle();
- CheckBoxHandle_S();
- }
- void drawWindows(float x, float y){
- drawForm(x,y);
- if(button(x + 350, y + 450,"選串口")!= 0){
- Serial_SetClick();
- }
- if(button(x + 500, y + 450,"發送指令") != 0){
- if(SerialName==null){
- }else{
- send_data();
- }
- }
- if(button(x + 650, y + 450,"退 出") != 0){
- exit();
- }
- }
- //繪制主窗口
- void drawForm(float x, float y){
- strokeWeight(2);
- textSize(18);
- text("Processing-Arduino 四自由度機械臂操控", 200,23);
- fill(0);
- strokeWeight(1);
- textSize(12);
- text("( 探索軟件制 @ CopyRight 2019 )", 560,25);
- textSize(18);
- strokeWeight(1);
- fill(0);
- textSize(18);
- line(0,25,1000,36);
- line(0,450,1000,450);
- text("舵機-0",5,65);
- text("舵機-1",5,110);
- text("舵機-2",5,155);
- text("舵機-3",5,200);
- line(0,280,1000,280);
- text("步電-0",5,320);
- text("POS0=",350,65);
- text(int(pos0),420,65);
- text("POS1=",350,110);
- text(int(pos1),420,110);
- text("POS2=",350,155);
- text(int(pos2),420,155);
- text("POS3=",350,200);
- text(int(pos3),420,200);
- text("Step0=",350,320);
- text(int(step0),420,320);
- mesg="POS0="+pos0+","+"POS1="+pos1+","+"POS2="+pos2+","+"POS3="+pos3+","+"step0="+step0+","+"bj="+bj;
- fill(237,28,36);
- text(mesg1,280,65);
- text(mesg2,280,110);
- text(mesg3,280,155);
- text(mesg4,280,200);
- text(mesg5,280,320);
- textSize(16);
- strokeWeight(2);
- fill(0);
- text("向Arduino發送數據:",50,580);
- text(mesg,200,580);
- text("角度增量選擇=", 20, 260);
- text(value, 125, 260);
- text("度", 145, 260);
- text("步數增量選擇=", 20, 370);
- text(value1, 125, 370);
- text("步", 150, 370);
- text("當前串口=", 20, 420);
- text(SerialName + " 9600bps", 100,420);
- if(button(60, 45,"向前") != 0){
- mesg1="向前進";
- pos0=pos0+value;
- pos0=constrain(pos0,0,180);
- }
- if(button(165, 45,"向后") != 0){
- mesg1="向后進";
- pos0=pos0-value;
- pos0=constrain(pos0,0,180);
- }
- if(button(545, 45,"歸零") != 0){
- mesg1="歸零";
- pos0=0;
- pos0=constrain(pos0,0,180);
- }
- if(button(60, 90,"向前") != 0){
- mesg2="向前進";
- pos1=pos1+value;
- pos1=constrain(pos1,0,180);
- }
- if(button(165, 90,"向后") != 0){
- mesg2="向后進";
- pos1=pos1-value;
- pos1=constrain(pos1,0,180);
- }
- if(button(545, 90,"歸零") != 0){
- mesg2="歸零";
- pos1=0;
- pos1=constrain(pos1,0,180);
- }
- if(button(60, 135,"向前") != 0){
- mesg3="向前進";
- pos2=pos2+value;
- pos2=constrain(pos2,0,180);
- }
- if(button(165, 135,"向后") != 0){
- mesg3="向后進";
- pos2=pos2-value;
- pos2=constrain(pos2,0,180);
- }
- if(button(545, 135,"歸零") != 0){
- mesg3="歸零";
- pos2=0;
- pos2=constrain(pos2,0,180);
- }
- if(button(60, 180,"向前") != 0){
- mesg4="向前進";
- pos3=pos3+value;
- pos3=constrain(pos3,0,180);
- //send_data();
- }
- if(button(165, 180,"向后") != 0){
- mesg4="向后進";
- pos3=pos3-value;
- pos3=constrain(pos3,0,180);
- }
- if(button(545, 180,"歸零") != 0){
- mesg4="歸零";
- pos3=0;
- pos3=constrain(pos3,0,180);
- }
- if(button(60, 300,"向前") != 0){
- mesg5="向前進";
- step0=step0+value1;
- step0=constrain(step0,0,360);
- bj=1;
- }
- if(button(165, 300,"向后") != 0){
- mesg5="向后進";
- step0=step0-value1;
- step0=constrain(step0,0,360);
- bj=0;
- }
- if(button(545, 300,"歸零") != 0){
- mesg5="歸零";
- step0=0;
- step0=constrain(step0,0,360);
- bj=0;
- }
- }
- byte button(float x , float y , String str){
- byte ret = 0;
- //fill(0,255,0);
- fill(0,0,0);
- strokeWeight(2);
- //stroke(255,255,0);
- if((mouseX > x) && (mouseY > y) && (mouseX < (x + 100) ) &&(mouseY < (y + 30))){
- fill(128,255,255);
- if (mousePressedFlag && (mouseButton == LEFT)) {
- mousePressedFlag = false;
- fill(0,128,128);
- ret = 1;
- }
- }
- rect(x,y, 100, 30);
- fill(255,255,255);
- textSize(16);
- text(str, x + 24, y + 22);
- return ret;
- }
- //舵機角度選擇
- boolean X_checkBox = true;
- boolean Y_checkBox = false;
- boolean Z_checkBox = false;
- boolean A_checkBox = false;
- boolean B_checkBox = false;
- boolean C_checkBox = false;
- boolean D_checkBox = false;
- boolean E_checkBox = false;
- void CheckBoxHandle(){
- if(CheckBox(240,245,X_checkBox, "10")== 1){
- X_checkBox = (X_checkBox == false) ? true: false;
- value=10;
- }
- if(CheckBox(300,245,Y_checkBox, "20") == 1){
- Y_checkBox = (Y_checkBox == false) ? true: false;
- value=20;
- }
- if(CheckBox(360,245, Z_checkBox, "30") == 1){
- Z_checkBox = (Z_checkBox == false) ? true: false;
- value=30;
- }
- if(CheckBox(420,245, A_checkBox, "40") == 1){
- A_checkBox = (A_checkBox == false) ? true: false;
- value=40;
- }
- if(CheckBox(480,245, B_checkBox, "50") == 1){
- B_checkBox = (B_checkBox == false) ? true: false;
- value=50;
- }
- if(CheckBox(540,245, C_checkBox, "60") == 1){
- C_checkBox = (C_checkBox == false) ? true: false;
- value=60;
- }
- if(CheckBox(600,245, D_checkBox, "70") == 1){
- D_checkBox = (D_checkBox == false) ? true: false;
- value=70;
- }
- if(CheckBox(660,245, E_checkBox, "80") == 1){
- E_checkBox = (E_checkBox == false) ? true: false;
- value=80;
- }
- }
- boolean checkBox_GetXFlag(){
- return X_checkBox;
- }
- boolean checkBox_GetYFlag(){
- return Y_checkBox;
- }
- boolean checkBox_GetZFlag(){
- return Z_checkBox;
- }
- boolean checkBox_GetAFlag(){
- return A_checkBox;
- }
- boolean checkBox_GetBFlag(){
- return B_checkBox;
- }
- boolean checkBox_GetCFlag(){
- return C_checkBox;
- }
- boolean checkBox_GetDFlag(){
- return D_checkBox;
- }
- boolean checkBox_GetEFlag(){
- return E_checkBox;
- }
- byte CheckBox(float x, float y, boolean sL, String str){
- noFill();
- //stroke(255,255,0);
- if(sL){
- fill(0,255,0);
- }
- rect(x, y, 20, 20);
- textSize(16);
- fill(0);
- strokeWeight(2);
- text(str, x + 30, y + 20);
- if((mouseX > x) && (mouseY > y) && (mouseX < (x + 20) ) &&(mouseY < (y + 20))){
- if (mousePressedFlag && (mouseButton == LEFT)) {
- mousePressedFlag = false;
- return 1;
- }
- }
- return 0;
- }
- //步進電機步數選擇
- boolean S1_checkBox = true;
- boolean S2_checkBox = false;
- boolean S3_checkBox = false;
- boolean S4_checkBox = false;
- boolean S5_checkBox = false;
- boolean S6_checkBox = false;
- boolean S7_checkBox = false;
- boolean S8_checkBox = false;
- void CheckBoxHandle_S(){
- if(CheckBox_S(240,350,S1_checkBox, "10")== 1){
- S1_checkBox = (S1_checkBox == false) ? true: false;
- value1=10;
- }
- if(CheckBox_S(300,350,S2_checkBox, "20") == 1){
- S2_checkBox = (S2_checkBox == false) ? true: false;
- value1=20;
- }
- if(CheckBox_S(360,350, S3_checkBox, "30") == 1){
- S3_checkBox = (S3_checkBox == false) ? true: false;
- value1=30;
- }
- if(CheckBox_S(420,350, S4_checkBox, "40") == 1){
- S4_checkBox = (S4_checkBox == false) ? true: false;
- value1=40;
- }
- if(CheckBox_S(480,350, S5_checkBox, "50") == 1){
- S5_checkBox = (S5_checkBox == false) ? true: false;
- value1=50;
- }
- if(CheckBox_S(540,350, S6_checkBox, "60") == 1){
- S6_checkBox = (S6_checkBox == false) ? true: false;
- value1=60;
- }
- if(CheckBox_S(600,350, S7_checkBox, "70") == 1){
- S7_checkBox = (S7_checkBox == false) ? true: false;
- value1=70;
- }
- if(CheckBox_S(660,350, S8_checkBox, "80") == 1){
- S8_checkBox = (S8_checkBox == false) ? true: false;
- value1=80;
- }
- }
- boolean checkBox_GetS1Flag(){
- return S1_checkBox;
- }
- boolean checkBox_GetS2Flag(){
- return S2_checkBox;
- }
- boolean checkBox_GetS3Flag(){
- return S3_checkBox;
- }
- boolean checkBox_GetS4Flag(){
- return S4_checkBox;
- }
- boolean checkBox_GetS5Flag(){
- return S5_checkBox;
- }
- boolean checkBox_GetS6Flag(){
- return S6_checkBox;
- }
- boolean checkBox_GetS7Flag(){
- return S7_checkBox;
- }
- boolean checkBox_GetS8Flag(){
- return S8_checkBox;
- }
- byte CheckBox_S(float x, float y, boolean sL, String str){
- noFill();
- //stroke(255,255,0);
- if(sL){
- fill(0,255,0);
- }
- rect(x, y, 20, 20);
- textSize(16);
- fill(0);
- strokeWeight(2);
- text(str, x + 30, y + 20);
- if((mouseX > x) && (mouseY > y) && (mouseX < (x + 20) ) &&(mouseY < (y + 20))){
- if (mousePressedFlag && (mouseButton == LEFT)) {
- mousePressedFlag = false;
- return 1;
- }
- }
- return 0;
- }
- int name = 0;
- String strName = String.valueOf(name);
- byte click = 0;
- byte comNum = 0;
- byte Serial_StopFlag = 0;
- boolean Serial_OpenFlag = false;
- boolean Serial_DatareadFlag = false;
- byte[] Serial_buffer = new byte[6];
- Serial myPort;
- String strSerial = "com1";
- boolean Serial_GetdataFlag = false;
- String[] strComBuff = new String[4];
- void Serial_Handle(float x, float y){
- if(click != 0){
- comNum = 0;
- Serial_DrawComX(20, 50);
- }
- else{
- textSize(12);
- //fill(255);
- fill(0);
- }
- Serial_GetdataFromCom();
- }
- void Serial_DrawComX(float x, float y){
- int i = 0;
- int len = ComX.length;
- textSize(12);
- while(i < len){
- if(comNum != 0){//選擇了端口
- break;
- }
- Serial_DrawCom(x + 350, y + 480 + i * 30, ComX[i]);
- i++;
- }
- }
- void Serial_DrawCom(float x, float y, String str){
- fill(255);
- //noStroke();
- rect(x, y, 101, 30);
- if(mouseX > x && mouseY > y && mouseX < x + 100 && mouseY < y + 30){
- fill(175,183,203);
- rect(x,y, 101, 30);
- if (mousePressed && (mouseButton == LEFT)) { //按鍵按下
- if(str.equals("COM1") == true){
- comNum = 1;
- }
- else if(str.equals("COM2") == true){
- comNum = 1;
- }
- else if(str.equals("COM3") == true){
- comNum = 1;
- }
- else if(str.equals("COM4") == true){
- comNum = 1;
- }
- else if(str.equals("COM5") == true){
- comNum = 1;
- }
- else if(str.equals("COM6") == true){
- comNum = 1;
- }
- else if(str.equals("COM7") == true){
- comNum = 1;
- }
- else if(str.equals("COM8") == true){
- comNum = 1;
- }
- else if(str.equals("COM9") == true){
- comNum = 1;
- }
- if(str.equals(SerialName) != true){
- SerialName = str;
- if(comNum != 0){
- click = 0;
- if(Serial_StopFlag != 0){
- myPort.stop();//停止上一個串口
- }
- myPort =new Serial(this,SerialName,9600 );
- myPort.bufferUntil(10);
- Serial_StopFlag = 1;
- Serial_OpenFlag = true;
- }
- }
- click = 0;
- }
- }
- fill(0,0,255);
- text(str,x + 10, y + 25);
- }
- void Serial_SetClick(){
- click = 1;
- }
- void Serial_GetdataFromCom(){
- if(Serial_OpenFlag != true){
- strComBuff[0] = " ";
- strComBuff[1] = " ";
- strComBuff[2] = " ";
- return;
- }
- if(myPort.available() > 0){
- Serial_GetdataFlag = true;
- strSerial = myPort.readString();
- strComBuff = strSerial.split(",");
- }
- }
- float Serial_String2float(String str){
- float a = 0;
- a = float(str)*150;
- return a;
- }
- boolean Serial_GetdataFlag(){
- return Serial_GetdataFlag;
- }
- boolean Serial_GetComOpenFlag(){
- return Serial_OpenFlag;
- }
- void serialEvent(Serial p) {
- Serial_GetdataFlag = true;
- strSerial = p.readString();
- strComBuff = strSerial.split(",");
- }
- //send data to Arduino
- void send_data(){
- print("pos0=");
- print(pos0);
- print(',');
- print("pos1=");
- print(pos1);
- print(',');
- print("pos2=");
- print(pos2);
- print(',');
- print("pos3=");
- print(pos3);
- print(',');
- print("step0=");
- print(step0);
- print(',');
- print("bj=");
- println(bj);
- myPort.write('%');
- myPort.write(int(pos0));
- myPort.write(int(pos1));
- myPort.write(int(pos2));
- myPort.write(int(pos3));
- myPort.write(int(step0));
- myPort.write(int(bj));
- serial=false;
- }
- boolean mousePressedFlag = false;
- void mousePressed() {
- mousePressedFlag = true;
- }
- boolean SaveFlag = false;
復制代碼
|