[PYTHON] Aktualisierte Software für Rubik Cube Robot 6. Maschinenbetrieb (Arduino)

Was ist dieser Artikel?

Ich entwickle gerade einen Roboter, der einen 2x2x2 Rubic Cube löst. Dies ist eine Sammlung von Kommentaren zum Roboterprogramm. soltvvo3.jpg Ich habe einmal eine Sammlung von Artikeln geschrieben, die durch den Artikel [hier] repräsentiert werden (https://qiita.com/Nyanyan_Cube/items/60f3699db96dba4a4bf5), aber seitdem wurde die Software erheblich aktualisiert, sodass ich ein neues Programm einführen werde. Überlegen.

Der entsprechende Code ist hier verfügbar [https://github.com/Nyanyan/soltvvo/tree/master/Soltvvo3.2].

Zum Thema passende Artikel

"Lass uns einen Roboter bauen, der den Zauberwürfel löst!"

  1. Übersicht
  2. Algorithmus
  3. Software
  4. Hardware

Aktualisierte Software für Rubik Cube Robot

  1. Grundfunktion
  2. Vorberechnung
  3. Lösungssuche
  4. Statuserkennung
  5. Maschinenbetrieb (Python)
  6. Maschinenbetrieb (Arduino) (dieser Artikel)
  7. Hauptverarbeitung

Dieses Mal werden wir `` `soltvvo3_arduino.ino``` als Edition für Maschinenbedienung (Arduino) einführen.

Konstanten und Variablen

Global platzierte Konstanten und Variablen.

const int magnet_threshold = 50;
const long turn_steps = 400;
const int step_dir[2] = {11, 9};
const int step_pul[2] = {12, 10};
const int sensor[2] = {14, 15};
const int grab_deg[2] = {74, 74};
const int release_deg[2] = {96, 96};
const int offset = 3;

char buf[30];
int idx = 0;
long data[3];

Die Konstante ist die Portnummer oder der Winkel des Servomotors. Variablen werden verwendet, um die angegebenen Werte zu teilen, indem sie durch Leerzeichen getrennt werden.

Rund um die Servobibliothek

Schließen Sie die Servobibliothek in Bezug auf die Verwendung des Servomotors ein und definieren Sie `` `servo0, servo1```.

#include <Servo.h>

Servo servo0;
Servo servo1;

installieren

Installieren.

void setup() {
  Serial.begin(115200);
  for (int i = 0; i < 2; i++) {
    pinMode(step_dir[i], OUTPUT);
    pinMode(step_pul[i], OUTPUT);
    pinMode(sensor[i], INPUT);
  }
  servo0.attach(7);
  servo1.attach(8);
  servo0.write(release_deg[0] + 5);
  servo1.write(release_deg[1] + 5);
  delay(70);
  servo0.write(release_deg[0]);
  servo1.write(release_deg[1]);
}

Definieren Sie Pin-Ein- und Ausgänge und bewegen Sie den Servomotor, um den Arm nach außen zu bewegen.

Drehen Sie den Arm

Es ist eine Funktion, die den Schrittmotor dreht. Ich habe ein trapezförmiges Laufwerk implementiert, aber aus diesem Grund ist es eine etwas uncoole Implementierung, die `` `delay``` ohne Verwendung von Timern usw. verwendet.

void move_motor(long num, long deg, long spd) {
  bool hl = true;
  if (deg < 0) hl = false;
  digitalWrite(step_dir[num], hl);
  long steps = abs(deg) * turn_steps / 360;
  long avg_time = 1000000 * 60 / turn_steps / spd;
  long max_time = 1500;
  long slope = 50;
  bool motor_hl = false;
  long accel = min(steps / 2, max(0, (max_time - avg_time) / slope));
  int num1 = (num + 1) % 2;
  //Beschleunigung
  for (int i = 0; i < accel; i++) {
    motor_hl = !motor_hl;
    digitalWrite(step_pul[num], motor_hl);
    delayMicroseconds(max_time - slope * i);
  }
  //Normale Operation
  for (int i = 0; i < steps * 2 - accel * 2; i++) {
    motor_hl = !motor_hl;
    digitalWrite(step_pul[num], motor_hl);
    delayMicroseconds(avg_time);
  }
  //Verlangsamen
  for (int i = 0; i < accel; i++) {
    motor_hl = !motor_hl;
    digitalWrite(step_pul[num], motor_hl);
    delayMicroseconds(max_time - slope * accel + accel * (i + 1));
  }
}

Grundsätzlich wird es nach folgendem Ablauf verarbeitet.

  1. Berechnen Sie die Anzahl der Schritte, die aus dem Winkel gedreht werden sollen
  2. Berechnen Sie die Impulsbreite aus der Anzahl der Umdrehungen
  3. Berechnen Sie die Anzahl der Schritte zum Beschleunigen und Abbremsen

Armkalibrierung

Kalibrieren Sie den Teil des Arms, der den Schrittmotor verwendet, so, dass er einen geeigneten Winkel hat. Verwenden Sie zu diesem Zeitpunkt den an der Armseite angebrachten Magneten und den an der Seite des Schrittmotors angebrachten Hallsensor (Magnetsensor).

void motor_adjust(long num, long spd) {
  int max_step = 150;
  int delay_time = 800;
  bool motor_hl = false;
  digitalWrite(step_dir[num], LOW);
  while (analogRead(sensor[num]) <= magnet_threshold) {
    motor_hl = !motor_hl;
    digitalWrite(step_pul[num], motor_hl);
    delayMicroseconds(delay_time);
  }
  while (analogRead(sensor[num]) > magnet_threshold) {
    motor_hl = !motor_hl;
    digitalWrite(step_pul[num], motor_hl);
    delayMicroseconds(delay_time);
  }
}

Die erste `` `while``` -Anweisung ist schwierig, aber selbst wenn bereits festgestellt wurde, dass sich der Arm in der richtigen Position befindet, kann der Winkel des Arms leicht abweichen, sodass der Arm einmal verschoben wird. ..

Die zweite `` `while``` -Anweisung dreht den Schrittmotor, bis sich der Magnet vor dem Hallsensor befindet.

Löse das Rätsel

Eine Funktion, die den Arm nach außen bewegt und das Rätsel löst.

void release_arm(int num) {
  if (num == 0)servo0.write(release_deg[num] + offset);
  else servo1.write(release_deg[num] + offset);
}

Es ist keine sehr schöne Art zu schreiben. Wenn Sie wissen, wie man schön schreibt, lassen Sie es mich bitte wissen. Für `Offset``` habe ich ein Überschwingen implementiert, um den Motor schneller zu bewegen, aber ich habe festgestellt, dass es nicht notwendig ist, beim Überschießen zum Zielwert zurückzukehren, und mit` Offset``` hinzugefügt. Es ist geworden.

Schnapp dir das Rätsel

Es ist eine Funktion, die den Arm um die Mitte bewegt und das Puzzle greift.

void grab_arm(int num) {
  if (num == 0)servo0.write(grab_deg[num] - offset);
  else servo1.write(grab_deg[num] - offset);
  delay(70);
  if (num == 0)servo0.write(grab_deg[num]);
  else servo1.write(grab_deg[num]);
}

Das mit `offset erzeugte Überschwingen ist hier nützlich. Ich hoffe, das hilft dir dabei, das Rätsel schneller zu lösen (ich weiß nicht, wie effektiv es wirklich ist).

Hauptschleife

Die Hauptschleife empfängt den Befehl und ruft die entsprechende Funktion auf.

void loop() {
  while (1) {
    if (Serial.available()) {
      buf[idx] = Serial.read();
      if (buf[idx] == '\n') {
        buf[idx] = '\0';
        data[0] = atoi(strtok(buf, " "));
        data[1] = atoi(strtok(NULL, " "));
        data[2] = atoi(strtok(NULL, " "));
        if (data[1] == 1000) grab_arm(data[0]);
        else if (data[1] == 2000) release_arm(data[0]);
        else if (data[1] == 0) motor_adjust(data[0], data[2]);
        else move_motor(data[0], data[1], data[2]);
        idx = 0;
      }
      else {
        idx++;
      }
    }
  }
}

Die aufzurufende Funktion hängt von der Art des Befehls ab.

Zusammenfassung

Dieses Mal habe ich das Arduino-Programm vorgestellt, das den Aktuator tatsächlich bewegt. Ich denke, es ist teilweise unrein, wahrscheinlich wegen meiner mangelnden Sprachkenntnisse. Bitte geben Sie uns eine gute Möglichkeit, in die Kommentare zu schreiben.

Nächstes Mal werde ich die Hauptverarbeitung von Python erklären.

Recommended Posts

Aktualisierte Software für Rubik Cube Robot 6. Maschinenbetrieb (Arduino)
Aktualisierte Software für Rubik Cube Robot 5. Maschinenbedienung (Python)
Aktualisierte Software für Rubik Cube Robot 7. Schlüsseloperationen
Aktualisierte Software für Rubik Cube Robot 2. Vorberechnung
Aktualisierte Software für Rubik Cube Robot 3. Lösungssuche
Aktualisierte Software für Rubik Cube Robot 4. Statuserkennung
Aktualisierte Software für Rubik Cube Robot 1. Grundfunktionen
Lassen Sie uns einen Roboter bauen, der den Zauberwürfel löst! 3 Software