산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

Arduino Mecanum 바퀴 로봇

<메인 클래스="사이트 메인" id="메인">

이 튜토리얼에서는 어떤 방향으로든 움직일 수 있는 Arduino Mecanum Wheels 로봇을 만드는 방법을 배울 것입니다. 로봇의 이러한 독특한 이동성은 메카넘 휠(Mecanum Wheels)이라는 특수한 유형의 바퀴를 사용하여 이루어집니다.

다음 비디오를 보거나 아래에 작성된 튜토리얼을 읽을 수 있습니다.

개요

저는 실제로 이 휠을 디자인하고 3D로 인쇄했습니다. 구매 비용이 조금 비쌀 수 있기 때문입니다. 그것들은 아주 잘 작동하고 나는 이 로봇 플랫폼을 운전하는 것이 매우 재미있다고 말해야 합니다. NRF24L01 무선 송수신기 모듈을 사용하여 로봇을 무선으로 제어할 수 있습니다. 제 경우에는 이전 비디오 중 하나에서 만든 DIY RC 송신기를 사용하고 있습니다.

블루투스 통신을 통해 스마트폰으로도 제어할 수 있도록 했습니다. 메카넘 바퀴 로봇이 어느 방향으로든 움직이도록 제어할 수 있는 맞춤형 Android 애플리케이션을 만들었습니다. 또한 앱의 슬라이더를 사용하여 이동 속도를 제어할 수 있습니다.

이 로봇 플랫폼의 두뇌는 각 바퀴를 개별적으로 제어하는 ​​Arduino Mega 보드입니다. 각 바퀴는 NEMA 17 스테퍼 모터에 부착되어 있으며 스테퍼 모터를 정밀하게 제어할 수 있다는 사실을 알고 앱에 로봇이 자동으로 움직이도록 프로그래밍할 수 있는 멋진 기능을 하나 더 추가했습니다. 저장 버튼을 사용하여 각 위치 또는 단계를 저장할 수 있으며 로봇은 자동으로 이러한 단계를 실행하고 반복할 수 있습니다. 같은 버튼으로 자동 작업을 일시 중지하고 모든 단계를 재설정하거나 삭제하여 새 단계를 저장할 수 있습니다.

메카넘 바퀴 로봇 3D 모델

우선 3D 모델링 소프트웨어를 사용하여 이 Mecanum Wheels 로봇을 설계했습니다. 이 로봇의 기본 플랫폼은 8mm 틱 MDF 보드로 만들 간단한 상자입니다.

4개의 스테퍼 모터가 이 플랫폼에 부착되어 있고 메카넘 휠이 모터의 샤프트에 부착되어 있습니다.

이 3D 모델을 찾아 다운로드할 수 있을 뿐만 아니라 Thangs의 브라우저에서 탐색할 수도 있습니다.

Thangs에서 어셈블리 3D 모델을 다운로드합니다.

3D 인쇄용 STL 파일:

메카넘 바퀴의 작동 원리

메카넘 휠은 원주에 롤러가 부착된 휠입니다. 이 롤러는 대각선으로 또는 휠의 회전 축에 대해 45도 각도로 배치됩니다. 이것은 휠이 후진에서 전진할 때 대각선 방향으로 힘을 가하도록 합니다.

따라서 특정 패턴으로 바퀴를 회전시켜 이러한 대각선 힘을 활용하여 로봇이 어떤 방향으로든 이동할 수 있습니다.

여기서 우리는 종종 왼손잡이와 오른손잡이 메카넘 바퀴라고도 하는 두 가지 유형의 메카넘 바퀴가 필요하다는 점에 주목해야 합니다. 그들 사이의 차이점은 롤러의 방향이며 로봇의 특정 위치에 설치해야 합니다. 각 바퀴의 탑 롤러의 회전축은 로봇의 중심을 가리켜야 합니다.

다음은 바퀴 회전 방향에 따라 로봇이 어떻게 움직이는지 간단하게 보여줍니다.

네 바퀴가 모두 앞으로 움직이면 로봇이 앞으로 움직이고, 그 반대의 경우 모든 바퀴가 뒤로 움직이면 로봇이 뒤로 움직입니다. 오른쪽으로 이동하려면 로봇 내부에서 오른쪽 바퀴가 회전해야 하고 로봇 외부에서 왼쪽 바퀴가 회전해야 합니다. 대각선으로 배치된 롤러로 인한 결과적인 힘으로 인해 로봇이 오른쪽으로 이동합니다. 왼쪽으로 이동할 때도 동일하지만 반대 현상이 발생합니다. 이 바퀴를 사용하면 두 바퀴만 회전하여 대각선 방향으로 이동할 수도 있습니다.

메카넘 바퀴 로봇 만들기

그럼에도 불구하고 이제 제가 이 로봇 플랫폼을 구축한 방법을 보여드리겠습니다. 언급했듯이 플랫폼의 기반을 만들기 위해 8mm 틱 MDF 보드를 사용하고 있습니다. 먼저 테이블 톱을 사용하여 3D 모델 치수에 따라 모든 조각을 자릅니다.

다음으로 3mm 드릴과 25mm Forstner 비트를 사용하여 스테퍼 모터를 부착하기 위해 측면 패널에 구멍을 만들었습니다. 부품이 준비되면 조립을 계속했습니다. 나는 그들을 고정하기 위해 나무 접착제와 약간의 나사를 사용했습니다. 여기서 가장 중요한 것은 나중에 모든 바퀴가 표면에 고르게 닿을 수 있도록 모터의 구멍을 정밀하게 만드는 것입니다.

물론 MDF로 만드는 대신 이 기본 플랫폼을 3D 인쇄할 수도 있으므로 웹 사이트 기사에 3D 파일을 포함하겠습니다. 마지막으로 베이스를 스프레이로 칠하고 커버를 흰색으로 칠해줍니다.

다음은 메카넘 휠입니다. 앞서 말했듯이 이 휠은 구입 비용이 약간 비쌀 수 있으므로 내 자신의 휠을 디자인하고 3D 인쇄하기로 결정했습니다. 바퀴는 M4 볼트와 너트로 고정되어 있는 외부와 내부의 두 부분으로 구성되어 있습니다. 각각 10개의 롤러와 NEMA 17 스테퍼 모터에 맞게 특별히 설계된 샤프트 커플러가 있습니다.

Creality CR-10 3D 프린터를 사용하여 Mecanum 휠의 모든 부품을 3D 인쇄했습니다.

확인하려는 경우를 위해 이 3D 프린터에 대한 링크를 제공합니다.

그래서 일단 3D 프린팅된 부품이 준비되면 롤러용 샤프트를 만드는 작업을 계속했습니다. 이를 위해 3mm 눈금 강선을 사용했습니다. 샤프트의 길이는 약 40mm가 되어야 하므로 회전 도구를 사용하여 그 길이로 와이어를 자릅니다.

4개의 M4 볼트와 너트를 사용하여 양쪽과 샤프트 커플러를 고정하여 메카넘 휠 조립을 시작했습니다. 볼트의 길이는 45mm가 되어야 합니다.

롤러를 설치하려면 먼저 내부 둘레에 있는 구멍을 통해 샤프트를 약간 삽입해야 합니다.

그런 다음 작은 M3 와셔를 삽입하고 롤러를 삽입한 다음 샤프트를 휠 바깥쪽의 슬롯에 끝까지 밀어넣을 수 있습니다. 다른 쪽 와셔를 끼울 공간이 부족해서 싱글 와셔를 사용했습니다.

10개의 모든 롤러에 대해 이 과정을 반복했습니다. 실제로 이 바퀴를 조립하는 것은 쉽고 재미있습니다. 여기서 중요한 것은 롤러가 자유롭게 움직일 수 있어야 한다는 것입니다.

마지막에는 샤프트가 느슨해지지 않도록 각 내부 구멍에 AC 접착제를 몇 방울 떨어뜨렸습니다.

이제 바퀴가 준비되면 전체 로봇을 조립할 수 있습니다. 먼저 스테퍼 모터를 기본 플랫폼에 부착해야 합니다. 제자리에 고정하기 위해 12mm 길이의 M3 볼트를 사용했습니다.

다음으로 바퀴를 모터 샤프트에 부착해야 합니다. 제가 만든 샤프트 커플러에는 M3 너트를 삽입할 수 있는 슬롯이 있는데, 이 홈을 통해 M3 볼트가 통과하여 휠을 샤프트에 고정할 수 있습니다.

다음으로 상단 덮개를 베이스에 고정하기 위해 베이스의 두 모서리에 나사산 막대를 부착했습니다. 커버의 같은 위치에 구멍을 뚫어서 베이스에 커버를 쉽게 끼우고 고정할 수 있었습니다.

베이스 뒷면에는 나중에 전원 스위치를 부착할 수 있는 20mm 구멍과 LED를 부착할 수 있는 5mm 구멍을 만들었습니다.

회로도

이제 전자 제품으로 넘어갈 수 있습니다. 다음은 이 프로젝트의 전체 회로도입니다.

따라서 4개의 DRV8825 스테퍼 드라이버를 사용하여 4개의 NEMA 17 스테퍼 모터를 제어하거나 A4988 스테퍼 드라이버를 사용할 수도 있습니다. 스테퍼와 전체 로봇에 전원을 공급하기 위해 12V 전원 공급 장치를 사용하고 제 경우에는 약 12V를 제공하는 3S Li-Po 배터리를 사용합니다. 무선 통신에는 NRF24L01 모듈을 사용하고 블루투스 통신에는 HC-05 블루투스 모듈을 사용하고 있습니다. 또한 배터리 전압을 모니터링하는 데 사용할 간단한 전압 분배기와 배터리 전압이 11V 아래로 떨어질 때를 표시하는 LED 연결도 포함했습니다.

또한 약 3A의 전류를 제공할 수 있는 전용 5V 전압 조정기를 포함했습니다. 이것은 선택 사항이지만 향후 비디오에서 이 프로젝트를 내 Arduino Robot Arm 프로젝트와 결합할 계획이며, 이를 위해 서보 모터를 구동하는 데 5V가 필요합니다.

아래 링크에서 이 프로젝트에 필요한 구성 요소를 얻을 수 있습니다.

PCB 디자인

그럼에도 불구하고 전자 부품을 정리하고 배선 혼란을 없애기 위해 EasyEDA 무료 온라인 회로 설계 소프트웨어를 사용하여 맞춤형 PCB를 설계했습니다. 이 PCB는 Arduino Mega 보드 위에 직접 연결할 수 있기 때문에 실제로 Arduino MEGA 실드 역할을 합니다. 연결을 실행하기 위해 상단 및 하단 레이어를 모두 사용했습니다. 사용하지 않은 Arduno 핀의 경우 핀 헤더 연결을 포함하여 나중에 사용할 때 사용할 수 있도록 했습니다. 12V, 5V 및 GND 연결 핀과 드라이버의 스테핑 해상도를 선택하기 위한 핀도 포함되어 있습니다.

다음은 이 PCB 디자인의 프로젝트 파일에 대한 링크입니다. 그래서 디자인이 끝나면 PCB 제작에 필요한 Gerber 파일을 생성했습니다.

거버 파일:

그리고 이 영상의 스폰서이기도 한 JLCPCB에서 PCB를 주문했습니다.

여기에서 Gerber 파일을 간단히 끌어다 놓을 수 있으며 업로드되면 Gerber 뷰어에서 PCB를 검토할 수 있습니다. 모든 것이 정상이면 계속해서 PCB에 대해 원하는 속성을 선택할 수 있습니다. 이번에는 Arduino 보드 색상과 일치시키기 위해 PCB 색상을 파란색으로 선택했습니다. 이제 우리는 합리적인 가격에 PCB를 주문할 수 있습니다. JLCPCB에서 처음 주문하는 경우 단돈 2달러에 최대 10개의 PCB를 얻을 수 있습니다.

며칠 후 PCB가 도착했습니다. PCB의 품질이 우수하고 모든 것이 디자인과 동일합니다.

PCB 조립

이제 PCB를 조립하고 조립할 수 있습니다. 나는 더 작은 부품인 저항과 커패시터를 먼저 납땜하는 것으로 시작했습니다. 그런 다음 Arduino 보드에 연결하는 데 사용할 PCB에 Male 핀 헤더를 삽입하고 납땜했습니다.

다음으로 모든 암 핀 헤더를 제자리에 놓고 납땜했습니다. 스테퍼 모터 연결 및 스테핑 분해능을 선택하기 위한 핀에 대해서는 수 핀 헤더를 사용했습니다. 이렇게 하면 모터를 PCB에 직접 연결하고 스테핑 분해능을 선택하기 위해 점퍼를 사용할 수 있습니다. 그런 다음 단자대, 트리머 및 전압 조정기를 납땜했습니다.

이제 PCB가 준비되었으며 드라이버를 삽입하고 모터를 여기에 연결할 수 있습니다. 먼저 스테핑 해상도를 선택하기 위해 점퍼를 배치했습니다. 드라이버의 MS3 핀을 5V에 연결하여 16단계 분해능을 선택했습니다.

그런 다음 그 위에 DRV8825 드라이버를 배치하고 NRF24L01 모듈과 HC-05 Bluetooth 모듈을 연결했습니다. 이제 PCB를 Arduino 보드에 간단하게 부착할 수 있습니다.

다음으로 배터리를 적절한 단자대에 연결하고 베이스 플랫폼에 배치했습니다.

여기에 전원 스위치를 제자리에 삽입하고 다른 터미널 블록에 연결했습니다. 전원 스위치 바로 위에 배터리 표시등 LED도 삽입했습니다.

이제 남은 것은 모터를 PCB에 연결하는 것입니다. 여기서 우리는 반대 모터를 연결할 때 반대쪽 커넥터도 연결해야 한다는 점에 유의해야 합니다. 이것은 나중에 로봇을 프로그래밍할 때 필요합니다. 예를 들어 정방향 명령은 두 모터를 같은 방향으로 움직이지만 실제로는 뒤집혀서 하나는 시계 방향으로, 다른 하나는 시계 반대 방향으로 회전합니다.

마지막에 상단에 덮개를 간단히 삽입할 수 있으므로 이 Mecanum Wheels 로봇 프로젝트가 완료되었습니다.

메카넘 바퀴 로봇 Arduino 코드

이 비디오에 남은 것은 Arduino 코드를 살펴보는 것입니다. 실제로 두 개의 별도 Arduino 코드가 있습니다. NRF24L01 모듈을 이용한 로봇 제어용과 스마트폰을 이용한 로봇 제어용입니다.

NRF24L01 모듈을 사용하여 로봇을 제어하기 위한 Arduino 코드:

/*
   === Arduino Mecanum Wheels Robot ===
     Radio control with NRF24L01 
  by Dejan, www.HowToMechatronics.com
  Libraries:
  RF24, https://github.com/tmrh20/RF24/
  AccelStepper by Mike McCauley: http://www.airspayce.com/mikem/arduino/AccelStepper/index.html

*/

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#include <AccelStepper.h>

RF24 radio(48, 49);   // nRF24L01 (CE, CSN)

const byte address[6] = "00001";
unsigned long lastReceiveTime = 0;
unsigned long currentTime = 0;

// Define the stepper motors and the pins the will use
AccelStepper LeftBackWheel(1, 42, 43);   // (Type:driver, STEP, DIR) - Stepper1
AccelStepper LeftFrontWheel(1, 40, 41);  // Stepper2
AccelStepper RightBackWheel(1, 44, 45);  // Stepper3
AccelStepper RightFrontWheel(1, 46, 47); // Stepper4

int wheelSpeed = 1500;

// Max size of this struct is 32 bytes - NRF24L01 buffer limit
struct Data_Package {
  byte j1PotX;
  byte j1PotY;
  byte j1Button;
  byte j2PotX;
  byte j2PotY;
  byte j2Button;
  byte pot1;
  byte pot2;
  byte tSwitch1;
  byte tSwitch2;
  byte button1;
  byte button2;
  byte button3;
  byte button4;
};
Data_Package data; //Create a variable with the above structure

void setup() {
  // Set initial seed values for the steppers
  LeftFrontWheel.setMaxSpeed(3000);
  LeftBackWheel.setMaxSpeed(3000);
  RightFrontWheel.setMaxSpeed(3000);
  RightBackWheel.setMaxSpeed(3000);

  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setAutoAck(false);
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_LOW);
  radio.startListening(); //  Set the module as receiver

  Serial.begin(115200);
}

void loop() {
  // Check whether we keep receving data, or we have a connection between the two modules
  currentTime = millis();
  if ( currentTime - lastReceiveTime > 1000 ) { // If current time is more then 1 second since we have recived the last data, that means we have lost connection
    resetData(); // If connection is lost, reset the data. It prevents unwanted behavior, for example if a drone jas a throttle up, if we lose connection it can keep flying away if we dont reset the function
  }
  // Check whether there is data to be received
  if (radio.available()) {
    radio.read(&data, sizeof(Data_Package)); // Read the whole data and store it into the 'data' structure
    lastReceiveTime = millis(); // At this moment we have received the data
  }
  // Set speed - left potentiometer
  wheelSpeed = map(data.pot1, 0, 255, 100, 3000);
  
  if (data.j1PotX > 150) {
    moveSidewaysLeft();
  }
  else if (data.j1PotX < 100) {
    moveSidewaysRight();
  }
  else if (data.j1PotY > 160) {
    moveForward();
  }
  else if (data.j1PotY < 100) {
    moveBackward();
  }
  else if (data.j2PotX < 100 & data.j2PotY > 160) {
    moveRightForward();
  }
  else if (data.j2PotX > 160 & data.j2PotY > 160) {
    moveLeftForward();
  }
  else if (data.j2PotX < 100 & data.j2PotY < 100) {
    moveRightBackward();
  }
  else if (data.j2PotX > 160 & data.j2PotY < 100) {
    moveLeftBackward();
  }
  else if (data.j2PotX < 100) {
    rotateRight();
  }
  else if (data.j2PotX > 150) {
    rotateLeft();
  }
  else {
    stopMoving();
  }
  // Execute the steps
  LeftFrontWheel.runSpeed();
  LeftBackWheel.runSpeed();
  RightFrontWheel.runSpeed();
  RightBackWheel.runSpeed();
  
  // Monitor the battery voltage
  int sensorValue = analogRead(A0);
  float voltage = sensorValue * (5.0 / 1023.00) * 3; // Convert the reading values from 5v to suitable 12V i
  // If voltage is below 11V turn on the LED
  if (voltage < 11) {
    digitalWrite(led, HIGH);
  }
  else {
    digitalWrite(led, LOW);
  }
}

void moveForward() {
  LeftFrontWheel.setSpeed(wheelSpeed);
  LeftBackWheel.setSpeed(wheelSpeed);
  RightFrontWheel.setSpeed(wheelSpeed);
  RightBackWheel.setSpeed(wheelSpeed);
}
void moveBackward() {
  LeftFrontWheel.setSpeed(-wheelSpeed);
  LeftBackWheel.setSpeed(-wheelSpeed);
  RightFrontWheel.setSpeed(-wheelSpeed);
  RightBackWheel.setSpeed(-wheelSpeed);
}
void moveSidewaysRight() {
  LeftFrontWheel.setSpeed(wheelSpeed);
  LeftBackWheel.setSpeed(-wheelSpeed);
  RightFrontWheel.setSpeed(-wheelSpeed);
  RightBackWheel.setSpeed(wheelSpeed);
}
void moveSidewaysLeft() {
  LeftFrontWheel.setSpeed(-wheelSpeed);
  LeftBackWheel.setSpeed(wheelSpeed);
  RightFrontWheel.setSpeed(wheelSpeed);
  RightBackWheel.setSpeed(-wheelSpeed);
}
void rotateLeft() {
  LeftFrontWheel.setSpeed(-wheelSpeed);
  LeftBackWheel.setSpeed(-wheelSpeed);
  RightFrontWheel.setSpeed(wheelSpeed);
  RightBackWheel.setSpeed(wheelSpeed);
}
void rotateRight() {
  LeftFrontWheel.setSpeed(wheelSpeed);
  LeftBackWheel.setSpeed(wheelSpeed);
  RightFrontWheel.setSpeed(-wheelSpeed);
  RightBackWheel.setSpeed(-wheelSpeed);
}
void moveRightForward() {
  LeftFrontWheel.setSpeed(wheelSpeed);
  LeftBackWheel.setSpeed(0);
  RightFrontWheel.setSpeed(0);
  RightBackWheel.setSpeed(wheelSpeed);
}
void moveRightBackward() {
  LeftFrontWheel.setSpeed(0);
  LeftBackWheel.setSpeed(-wheelSpeed);
  RightFrontWheel.setSpeed(-wheelSpeed);
  RightBackWheel.setSpeed(0);
}
void moveLeftForward() {
  LeftFrontWheel.setSpeed(0);
  LeftBackWheel.setSpeed(wheelSpeed);
  RightFrontWheel.setSpeed(wheelSpeed);
  RightBackWheel.setSpeed(0);
}
void moveLeftBackward() {
  LeftFrontWheel.setSpeed(-wheelSpeed);
  LeftBackWheel.setSpeed(0);
  RightFrontWheel.setSpeed(0);
  RightBackWheel.setSpeed(-wheelSpeed);
}
void stopMoving() {
  LeftFrontWheel.setSpeed(0);
  LeftBackWheel.setSpeed(0);
  RightFrontWheel.setSpeed(0);
  RightBackWheel.setSpeed(0);
}


void resetData() {
  // Reset the values when there is no radio connection - Set initial default values
  data.j1PotX = 127;
  data.j1PotY = 127;
  data.j2PotX = 127;
  data.j2PotY = 127;
  data.j1Button = 1;
  data.j2Button = 1;
  data.pot1 = 1;
  data.pot2 = 1;
  data.tSwitch1 = 1;
  data.tSwitch2 = 1;
  data.button1 = 1;
  data.button2 = 1;
  data.button3 = 1;
  data.button4 = 1;
}Code language: Arduino (arduino)

설명: 그래서 여기에서는 무선 통신을 위해 RF24 라이브러리를 사용하고 스테퍼 모터를 제어하기 위해 AccelStepper 라이브러리를 사용합니다. 먼저 모든 핀이 연결되는 핀을 정의하고 아래 프로그램에 필요한 몇 가지 변수를 정의하고 설정 섹션에서 스테퍼의 최대 속도를 설정하고 무선 통신을 시작해야 합니다.

루프 섹션에서는 RC 송신기에서 오는 데이터를 읽는 것으로 시작합니다. RC 송신기 코드와 이 통신이 작동하는 방식에 대한 자세한 내용은 내 특정 자습서에서 찾을 수 있습니다.

따라서 수신된 데이터에 따라 예를 들어 왼쪽 조이스틱이 앞으로 이동하면 해당 값은 160보다 크며 이 경우 moveForward() 사용자 정의 함수를 호출합니다. 이 기능을 살펴보면 모터의 속도를 양수로 설정하는 것뿐임을 알 수 있습니다. 뒤로 이동하려면 속도가 음수로 설정됩니다. 따라서 다른 모든 방향으로 이동하려면 처음에 설명한 대로 바퀴의 회전을 적절하게 설정하기만 하면 됩니다.

이러한 명령을 실행하려면 루프 섹션에서 모든 스테퍼에 대해 runSpeed() 함수를 호출해야 합니다. 루프 섹션에서 배터리에서 오는 전압 분배기의 아날로그 입력도 읽고 이 값에 따라 배터리 전압이 언제 11V 아래로 떨어질지 알 수 있으므로 표시 LED를 켤 수 있습니다.

스마트폰을 사용하여 로봇을 제어하기 위한 Arduino 코드:

/*
   === Arduino Mecanum Wheels Robot ===
     Smartphone control via Bluetooth 
  by Dejan, www.HowToMechatronics.com
  Libraries:
  RF24, https://github.com/tmrh20/RF24/
  AccelStepper by Mike McCauley: http://www.airspayce.com/mikem/arduino/AccelStepper/index.html

*/

#include <SoftwareSerial.h>
#include <AccelStepper.h>

SoftwareSerial Bluetooth(A8, 38); // Arduino(RX, TX) - HC-05 Bluetooth (TX, RX)

// Define the stepper motors and the pins the will use
AccelStepper LeftBackWheel(1, 42, 43);   // (Type:driver, STEP, DIR) - Stepper1
AccelStepper LeftFrontWheel(1, 40, 41);  // Stepper2
AccelStepper RightBackWheel(1, 44, 45);  // Stepper3
AccelStepper RightFrontWheel(1, 46, 47); // Stepper4

#define led 14

int wheelSpeed = 1500;

int dataIn, m;

int lbw[50], lfw[50], rbw[50], rfw[50]; // for storing positions/steps
int index = 0;

void setup() {
  // Set initial seed values for the steppers
  LeftFrontWheel.setMaxSpeed(3000);
  LeftBackWheel.setMaxSpeed(3000);
  RightFrontWheel.setMaxSpeed(3000);
  RightBackWheel.setMaxSpeed(3000);

  Serial.begin(38400);
  Bluetooth.begin(38400); // Default baud rate of the Bluetooth module
  Bluetooth.setTimeout(1);
  delay(20);

  pinMode(led, OUTPUT);

}

void loop() {
  // Check for incoming data

  if (Bluetooth.available() > 0) {
    dataIn = Bluetooth.read();  // Read the data

    if (dataIn == 0) {
      m = 0;
    }
    if (dataIn == 1) {
      m = 1;
    }
    if (dataIn == 2) {
      m = 2;
    }
    if (dataIn == 3) {
      m = 3;
    }
    if (dataIn == 4) {
      m = 4;
    }
    if (dataIn == 5) {
      m = 5;
    }
    if (dataIn == 6) {
      m = 6;
    }
    if (dataIn == 7) {
      m = 7;
    }
    if (dataIn == 8) {
      m = 8;

    }
    if (dataIn == 9) {
      m = 9;
    }
    if (dataIn == 10) {
      m = 10;
    }
    if (dataIn == 11) {
      m = 11;
    }

    if (dataIn == 12) {
      m = 12;
    }
    if (dataIn == 14) {
      m = 14;
    }
    // Set speed
    if (dataIn >= 16) {
      wheelSpeed = dataIn * 10;
      Serial.println(wheelSpeed);
    }
  }
  if (m == 4) {
    moveSidewaysLeft();
  }
  if (m == 5) {
    moveSidewaysRight();
  }
  if (m == 2) {
    moveForward();
  }
  if (m == 7) {
    moveBackward();
  }
  if (m == 3) {
    moveRightForward();
  }
  if (m == 1) {
    moveLeftForward();
  }
  if (m == 8) {
    moveRightBackward();
  }
  if (m == 6) {
    moveLeftBackward();
  }
  if (m == 9) {
    rotateLeft();
  }
  if (m == 10) {
    rotateRight();
  }

  if (m == 0) {
    stopMoving();
  }
  //Serial.println(dataIn);
  // If button "SAVE" is pressed
  if (m == 12) {
    if (index == 0) {
      LeftBackWheel.setCurrentPosition(0);
      LeftFrontWheel.setCurrentPosition(0);
      RightBackWheel.setCurrentPosition(0);
      RightFrontWheel.setCurrentPosition(0);
    }
    lbw[index] = LeftBackWheel.currentPosition();  // save position into the array
    lfw[index] = LeftFrontWheel.currentPosition();
    rbw[index] = RightBackWheel.currentPosition();
    rfw[index] = RightFrontWheel.currentPosition();
    index++;                        // Increase the array index
    m = 0;
  }

  if (m == 14) {
    runSteps();
    if (dataIn != 14) {
      stopMoving();
      memset(lbw, 0, sizeof(lbw)); // Clear the array data to 0
      memset(lfw, 0, sizeof(lfw));
      memset(rbw, 0, sizeof(rbw));
      memset(rfw, 0, sizeof(rfw));
      index = 0;  // Index to 0
    }
  }

  LeftFrontWheel.runSpeed();
  LeftBackWheel.runSpeed();
  RightFrontWheel.runSpeed();
  RightBackWheel.runSpeed();

  // Monitor the battery voltage
  int sensorValue = analogRead(A0);
  float voltage = sensorValue * (5.0 / 1023.00) * 3; // Convert the reading values from 5v to suitable 12V i
  //Serial.println(voltage);
  // If voltage is below 11V turn on the LED
  if (voltage < 11) {
    digitalWrite(led, HIGH);
  }
  else {
    digitalWrite(led, LOW);
  }

}

void runSteps() {
  for (int i = index - 1; i >= 0; i--) { // Run through all steps(index)
    LeftFrontWheel.moveTo(lfw[i]);
    LeftFrontWheel.setSpeed(wheelSpeed);
    LeftBackWheel.moveTo(lbw[i]);
    LeftBackWheel.setSpeed(wheelSpeed);
    RightFrontWheel.moveTo(rfw[i]);
    RightFrontWheel.setSpeed(wheelSpeed);
    RightBackWheel.moveTo(rbw[i]);
    RightBackWheel.setSpeed(wheelSpeed);

    while (LeftBackWheel.currentPosition() != lbw[i] & LeftFrontWheel.currentPosition() != lfw[i] & RightFrontWheel.currentPosition() != rfw[i] & RightBackWheel.currentPosition() != rbw[i]) {
      LeftFrontWheel.runSpeedToPosition();
      LeftBackWheel.runSpeedToPosition();
      RightFrontWheel.runSpeedToPosition();
      RightBackWheel.runSpeedToPosition();

      if (Bluetooth.available() > 0) {      // Check for incomding data
        dataIn = Bluetooth.read();
        if ( dataIn == 15) {           // If button "PAUSE" is pressed
          while (dataIn != 14) {         // Wait until "RUN" is pressed again
            if (Bluetooth.available() > 0) {
              dataIn = Bluetooth.read();
              if ( dataIn == 13) {
                stopMoving();
                break;
              }
            }
          }
        }
        if (dataIn >= 16) {
          wheelSpeed = dataIn * 10;
          dataIn = 14;
        }
        if ( dataIn == 13) {
          break;
        }
      }
    }
  }
  // Go back through steps
  for (int i = 1; i <= index - 1; i++) { // Run through all steps(index)

    LeftFrontWheel.moveTo(lfw[i]);
    LeftFrontWheel.setSpeed(wheelSpeed);
    LeftBackWheel.moveTo(lbw[i]);
    LeftBackWheel.setSpeed(wheelSpeed);
    RightFrontWheel.moveTo(rfw[i]);
    RightFrontWheel.setSpeed(wheelSpeed);
    RightBackWheel.moveTo(rbw[i]);
    RightBackWheel.setSpeed(wheelSpeed);

    while (LeftBackWheel.currentPosition() != lbw[i]& LeftFrontWheel.currentPosition() != lfw[i] & RightFrontWheel.currentPosition() != rfw[i] & RightBackWheel.currentPosition() != rbw[i]) {

      LeftFrontWheel.runSpeedToPosition();
      LeftBackWheel.runSpeedToPosition();
      RightFrontWheel.runSpeedToPosition();
      RightBackWheel.runSpeedToPosition();
      //Serial.print("  current: ");
      //Serial.println(LeftBackWheel.currentPosition());

      if (Bluetooth.available() > 0) {      // Check for incomding data
        dataIn = Bluetooth.read();
        if ( dataIn == 15) {           // If button "PAUSE" is pressed
          while (dataIn != 14) {         // Wait until "RUN" is pressed again
            if (Bluetooth.available() > 0) {
              dataIn = Bluetooth.read();
              if ( dataIn == 13) {
                stopMoving();
                break;
              }
            }
          }
        }
        if (dataIn >= 16) {
          wheelSpeed = dataIn * 10;
          dataIn = 14;
        }
        if ( dataIn == 13) {
          //Serial.println("DEKI");
          break;
        }
      }
    }
  }
}

void moveForward() {
  LeftFrontWheel.setSpeed(wheelSpeed);
  LeftBackWheel.setSpeed(wheelSpeed);
  RightFrontWheel.setSpeed(wheelSpeed);
  RightBackWheel.setSpeed(wheelSpeed);
}
void moveBackward() {
  LeftFrontWheel.setSpeed(-wheelSpeed);
  LeftBackWheel.setSpeed(-wheelSpeed);
  RightFrontWheel.setSpeed(-wheelSpeed);
  RightBackWheel.setSpeed(-wheelSpeed);
}
void moveSidewaysRight() {
  LeftFrontWheel.setSpeed(wheelSpeed);
  LeftBackWheel.setSpeed(-wheelSpeed);
  RightFrontWheel.setSpeed(-wheelSpeed);
  RightBackWheel.setSpeed(wheelSpeed);
}
void moveSidewaysLeft() {
  LeftFrontWheel.setSpeed(-wheelSpeed);
  LeftBackWheel.setSpeed(wheelSpeed);
  RightFrontWheel.setSpeed(wheelSpeed);
  RightBackWheel.setSpeed(-wheelSpeed);
}
void rotateLeft() {
  LeftFrontWheel.setSpeed(-wheelSpeed);
  LeftBackWheel.setSpeed(-wheelSpeed);
  RightFrontWheel.setSpeed(wheelSpeed);
  RightBackWheel.setSpeed(wheelSpeed);
}
void rotateRight() {
  LeftFrontWheel.setSpeed(wheelSpeed);
  LeftBackWheel.setSpeed(wheelSpeed);
  RightFrontWheel.setSpeed(-wheelSpeed);
  RightBackWheel.setSpeed(-wheelSpeed);
}
void moveRightForward() {
  LeftFrontWheel.setSpeed(wheelSpeed);
  LeftBackWheel.setSpeed(0);
  RightFrontWheel.setSpeed(0);
  RightBackWheel.setSpeed(wheelSpeed);
}
void moveRightBackward() {
  LeftFrontWheel.setSpeed(0);
  LeftBackWheel.setSpeed(-wheelSpeed);
  RightFrontWheel.setSpeed(-wheelSpeed);
  RightBackWheel.setSpeed(0);
}
void moveLeftForward() {
  LeftFrontWheel.setSpeed(0);
  LeftBackWheel.setSpeed(wheelSpeed);
  RightFrontWheel.setSpeed(wheelSpeed);
  RightBackWheel.setSpeed(0);
}
void moveLeftBackward() {
  LeftFrontWheel.setSpeed(-wheelSpeed);
  LeftBackWheel.setSpeed(0);
  RightFrontWheel.setSpeed(0);
  RightBackWheel.setSpeed(-wheelSpeed);
}
void stopMoving() {
  LeftFrontWheel.setSpeed(0);
  LeftBackWheel.setSpeed(0);
  RightFrontWheel.setSpeed(0);
  RightBackWheel.setSpeed(0);
}Code language: Arduino (arduino)

Description: The other code for controlling the robot using the Android application, is very similar and works the same way. Here instead of the radio module we need to define the Bluetooth module and initialize its communication in the setup section. So again, first we read the incoming data from the smartphone or the Android app, and according to it, tell the robot in which direction to move.

If we take a look at the Android app we can see that it simply sends numbers from 0 to 15 through the Bluetooth when the buttons are pressed.

The app is made using the MIT App Inventor online application and you can find more details about it in my particular tutorial for it.

Here you can download this app as well as the editable project file:

For programming the automatic robot movement with this app, when we press the “SAVE” button we simply store the current positions of the stepper motors into arrays. Then when we press the “RUN” button, we call the runSteps() custom function which executes or runs through all stored steps using some for and while loops.

I hope you enjoyed this tutorial and learned something new. Feel free to ask any question in the comments section below and check my Arduino Projects Collection.


제조공정

  1. Bluetooth를 통해 제어되는 Raspberry Pi Robot
  2. 서보 모터로 로봇을 피하는 장애물
  3. 라인 팔로워 로봇
  4. 음성 제어 로봇
  5. Arduino 제어 피아노 로봇:PiBot
  6. Littlearm 2C:3D 인쇄 Arduino 로봇 팔 제작
  7. 자율 홈 어시스턴트 로봇
  8. Android 앱으로 Arduino 로봇 팔 제어
  9. 멋진 실내 내비게이션용 로봇
  10. WiDC:Wi-Fi 제어 FPV 로봇