Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Manufacturing Technology >> Herstellungsprozess

Fortgeschrittene Farbsortiermaschine mit Arduino und RGB-Sensor

Komponenten und Zubehör

Arduino Nano R3 × 1
TCS34725 RGB-Sensor × 1
LM2596 Step-Down-Wandler × 1
MG-90S Servos × 2
MR105ZZ Kugellager (5 × 10 × 4 mm) × 3
608RS oder 608ZZ Kugellager (8 × 22 × 7 mm) × 1
6003RS Kugellager (17 × 35 × 10 mm) × 1
M3×15 mm Senkschraube × 1
M2×10 Selbstschneidende Schrauben × 20
RGB-LED (gemeinsame Anode) × 1
220 Ω Widerstände × 3
Kabel × 1
2,1 × 5,5 mm Hohlstecker × 1
Schrumpfschlauch × 1
Dupont-Stecker × 1
9 V oder 12 V Netzteil (mind. 1 A) × 1
5× Reagenzgläser 22 mm (Außendurchmesser) × 100 mm (von Danmu Art) × 1
Skittles!!!!!!!!!! × 1

Benötigte Werkzeuge und Maschinen

Über dieses Projekt

Fortgeschrittene Farbsortiermaschine mit Arduino und RGB-Sensor

Einführung

Die lustige Geschichte ist: Dieses Projekt war nie geplant. Vor etwa 3,5 Jahren begann ich mit dem Design einer viel komplexeren Farbsortiermaschine – wie bei vielen meiner Projekte blieb es halbfertig und verstaubte auf der Fensterbank (ich bin sicher, niemand sonst kennt das Problem... haha).

Kurz gesagt: Vor einigen Monaten beschloss ich, das alte Projekt wieder aufzugreifen. Zunächst musste ich herausfinden, wie man Skittles aus einem Vorratsbehälter zuverlässig entnimmt und ihre Farbe prüft, dabei das System so kompakt wie möglich zu halten (was mir beim ersten Versuch misslang). Ich redete mir ein, eine einfachere Farbsortiermaschine zu bauen, nur um das Entnahmesystem richtig zu designen. Ich dachte naiv, das wäre ein Projekt für zwei Wochenenden – schön, einfach und schnell. Wie falsch ich lag!

Es brauchte zwei komplett unterschiedliche Designs und viele angepasste Prototypen, bis etwas in akzeptabler Weise funktionierte (ich habe immer noch gelegentlich Entnahmeprobleme). Dennoch bin ich mit dem Ergebnis ganz zufrieden.

Fortgeschrittene Farbsortiermaschine mit Arduino und RGB-Sensor

Funktionsweise

Die Maschine lässt sich in zwei Hauptstufen unterteilen:

Obere Stufe – Zuführung: Oben befindet sich der Vorratsbehälter für unsortierte Skittles. Am Boden dieses Behälters sitzt der Zuführmechanismus, der Skittles einzeln entnimmt und vor dem Farbsensor positioniert, wo ihre Farbe erfasst wird. Der Zuführmechanismus umfasst einen Arm, der den Behälterinhalt leicht schüttelt, damit die Skittles durch die Öffnung fließen, ohne zu verklemmen (was leider trotzdem manchmal passiert).

Fortgeschrittene Farbsortiermaschine mit Arduino und RGB-Sensor

Untere Stufe – Sortierung: Sobald die Farbe des Skittles erkannt wurde, kommt die zweite Stufe ins Spiel. Der Reagenzgläser-Halter richtet das passende Röhrchen vor dem Zuführmechanismus aus, damit das Skittle hineinfällt. Der Zyklus wiederholt sich, bis der Vorratsbehälter leer ist.

Selbstbau-Anleitung

Alle Dateien und Anleitungen finden Sie unter: www.littlefrenchkev.com/colour-sorting-machine

Fortgeschrittene Farbsortiermaschine mit Arduino und RGB-Sensor

Montage

Nach dem Herunterladen und Drucken der Teile sollten Sie folgende Komponenten haben:

Fortgeschrittene Farbsortiermaschine mit Arduino und RGB-Sensor

Hinweis: Das vordere Gehäuse gibt es in zwei Varianten – sie unterscheiden sich nur optisch.

Fortgeschrittene Farbsortiermaschine mit Arduino und RGB-Sensor

Ein Video zum Montageprozess finden Sie auf der Projektseite.

Ersteinrichtung

Beim ersten Einschalten fahren beide Servos in ihre Anfangsposition. Stellen Sie sicher, dass der Zahnrad/Schaft zum Sammeln der Skittles in oberster Position steht und der Röhrchenhalter mit dem Zuführmechanismus fluchtet.

Fortgeschrittene Farbsortiermaschine mit Arduino und RGB-Sensor

Fehlerbehebung

LED blinkt rot – kein Startablauf

Nach dem Anfahren der Anfangsposition sollte die Maschine ihren Startablauf durchlaufen. Bleibt dieser aus und die LED blinkt rot, liegt ein Problem mit dem RGB-Sensor vor: Entweder ein Verdrahtungsfehler oder der Sensor ist defekt.

Röhrchen richten nicht korrekt aus

Ursache 1: Während des Startablaufs bewegt sich der Röhrchenhalter fünfmal – einmal pro Farbe. Sie bemerken möglicherweise, dass die Röhrchen nicht gut mit dem Zuführmechanismus fluchten. Dies kann an Ungenauigkeiten der Servos oder Drucktoleranzen liegen. Korrektur über Software: Ändern Sie das Array colour_angle. Jeder Wert repräsentiert die Servoposition für eine Farbe – durch Anpassung lässt sich die Stopp-Position feinjustieren.

Ursache 2: Durch Drucktoleranzen kann Spiel in den Zahnrädern des Röhrchenhalters entstehen. Je nach Drehrichtung kann die Trägheit dazu führen, dass die Position überfahren wird. Auch dies lässt sich per Software korrigieren: Ändern Sie die Variablen forward_anti_backlash und backward_anti_backlash. Diese Werte werden zu den Farbwinkeln addiert oder subtrahiert, je nach Drehrichtung, um das Spiel auszugleichen.

Farbmischung

Fortgeschrittene Farbsortiermaschine mit Arduino und RGB-Sensor

Bei Farbmischungen müssen die Arrays colour_limit_values angepasst werden. Jeder Wert repräsentiert Min/Max-Grenzwerte für Rot, Grün und Blau. Zur Kalibrierung: Laden Sie die Maschine nur mit einer Farbe, verbinden Sie sie mit dem Computer und öffnen Sie den Serial Monitor. Bei jedem Farbcheck werden die gemessenen RGB-Werte und die erkannte Farbe ausgegeben – so erhalten Sie Referenzwerte für jede Farbe.

Einige coole Features

RGB-LED: An der Basis der Maschine befindet sich eine RGB-LED. Während des Sortiervorgangs wechselt sie ihre Farbe passend zum gerade sortierten Skittle. Ist der Vorratsbehälter leer, durchläuft sie kontinuierlich alle Skittle-Farben. Bei Sensorfehlern beim Start blinkt sie rot.

Anti-Backlash-Kompensation: Der Röhrchenhalter wird über Stirnräder angetrieben. Durch Drucktoleranzen ist Spiel kaum ganz vermeidbar, weshalb der Halter die ideale Position oft überfährt. Der Code kompensiert dies, indem er den Halter je nach Drehrichtung früher anhält.

Verzögerung mit LED-Übergang: Die Funktion set_led(ms, color) verhält sich wie delay(ms), lässt aber die LED während der Wartezeit sanft in die neue Farbe überblenden. Ideal, um die LED-Farbe zu ändern, während sich der Röhrchenhalter dreht!

Zusätzliche Hinweise

Fortgeschrittene Farbsortiermaschine mit Arduino und RGB-Sensor

Code

LFK_sorting_machine (C/C++)

#include <Wire.h> 
#include "Adafruit_TCS34725.h" 
#include <Servo.h> 

/* Basierend auf Beispielcode der Adafruit TCS34725 Bibliothek */

//======================= Variablen für RGB-Sensor =========================
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_24MS, TCS34725_GAIN_1X);
int colour = 0; // 0=schwarz, 1=gelb, 2=grün, 3=orange, 4=rot, 5=lila
int previous_colour = colour;
int black_count = 0;
int start_measurment_angle = 88;
int measurment_sweep = 2;
int measurment_angle_increment = 4;

// Grenzwerte: {min_rot, max_rot, min_grün, max_grün, min_blau, max_blau}
uint16_t black_limit_values[] = {0, 200, 0, 200, 0, 200};
uint16_t yellow_limit_values[] = {850, 2200, 800, 2200, 400, 1100};
uint16_t green_limit_values[] = {400, 800, 700, 1400, 300, 700};
uint16_t orange_limit_values[] = {650, 1800, 300, 850, 210, 600};
uint16_t red_limit_values[] = {400, 950, 150, 450, 150, 400};
uint16_t purple_limit_values[] = {150, 400, 150, 450, 150, 500};

//======================= Variablen für RGB-LED =========================
byte R_pin = 5, G_pin = 6, B_pin = 11;
int current_red_value = 255, current_green_value = 255, current_blue_value = 255;
const int orange[] = {0, 230, 255};
const int red[] = {0, 255, 255};
const int green[] = {255, 0, 255};
const int yellow[] = {0, 170, 255};
const int purple[] = {0, 255, 40};

//======================= Variablen für Zuführ-Servos =========================
int release_delay = 220;
const int colour_angles[] = {10, 46, 82, 118, 154};
const int backward_anti_backlash = 2;
const int forward_anti_backlash = 2;
Servo feeder_servo;
Servo holder_servo;

//=================================== SETUP =========================================
void setup(void) {
  Serial.begin(9600);
  pinMode(R_pin, OUTPUT); pinMode(G_pin, OUTPUT); pinMode(B_pin, OUTPUT);
  analogWrite(R_pin, 255); analogWrite(G_pin, 255); analogWrite(B_pin, 255);
  feeder_servo.attach(3); holder_servo.attach(2);
  feeder_servo.write(0); holder_servo.write(colour_angles[0]);
  
  int white[] = {0, 0, 0};
  int black[] = {255, 255, 255};
  set_led(1000, white);
  
  if (tcs.begin()) {
    Serial.println("Found sensor");
    starting_sequence();
  } else {
    Serial.println("No TCS34725 found ... check your connections");
    while (1) { set_led(300, red); set_led(300, black); }
  }
}

//=================================== LOOP =========================================
void loop(void) {
  if (black_count < 10) {
    feeder_servo.write(0); delay(450);
    previous_colour = colour;
    get_colour();
    
    if (colour == 0) { black_count++; shake(); }
    else if (colour == 6) { black_count++; }
    else { move_holder(); release_skittle(); black_count = 0; }
  } else { end_loop(1000); }
}

//=================================== GET COLOUR =========================================
void get_colour() {
  uint16_t r, g, b, c;
  uint16_t total_r = 0, total_g = 0, total_b = 0;
  feeder_servo.write(start_measurment_angle); delay(200);
  Serial.println("----------------");
  
  for (int i = 0; i <= measurment_sweep; i++) {
    tcs.getRawData(&r, &g, &b, &c);
    feeder_servo.write(start_measurment_angle + i * measurment_angle_increment);
    total_r += r; total_g += g; total_b += b; delay(15);
  }
  
  total_r /= measurment_sweep; total_g /= measurment_sweep; total_b /= measurment_sweep;
  Serial.print(total_r); Serial.print(" "); Serial.print(total_g); Serial.print(" "); Serial.print(total_b); Serial.println(" ");
  
  // Farberkennung
  if ((total_r < black_limit_values[1]) && (total_g < black_limit_values[3]) && (total_b < black_limit_values[5])) {
    Serial.println("black"); colour = 0;
  } else if ((total_r >= yellow_limit_values[0]) && (total_r < yellow_limit_values[1]) &&
             (total_g >= yellow_limit_values[2]) && (total_g < yellow_limit_values[3]) &&
             (total_b >= yellow_limit_values[4]) && (total_b < yellow_limit_values[5])) {
    Serial.println("yellow"); colour = 1;
  } else if ((total_r >= green_limit_values[0]) && (total_r < green_limit_values[1]) &&
             (total_g >= green_limit_values[2]) && (total_g < green_limit_values[3]) &&
             (total_b >= green_limit_values[4]) && (total_b < green_limit_values[5])) {
    Serial.println("green"); colour = 2;
  } else if ((total_r >= orange_limit_values[0]) && (total_r < orange_limit_values[1]) &&
             (total_g >= orange_limit_values[2]) && (total_g < orange_limit_values[3]) &&
             (total_b >= orange_limit_values[4]) && (total_b < orange_limit_values[5])) {
    Serial.println("orange"); colour = 3;
  } else if ((total_r >= red_limit_values[0]) && (total_r < red_limit_values[1]) &&
             (total_g >= red_limit_values[2]) && (total_g < red_limit_values[3]) &&
             (total_b >= red_limit_values[4]) && (total_b < red_limit_values[5])) {
    Serial.println("red"); colour = 4;
  } else if ((total_r >= purple_limit_values[0]) && (total_r < purple_limit_values[1]) &&
             (total_g >= purple_limit_values[2]) && (total_g < purple_limit_values[3]) &&
             (total_b >= purple_limit_values[4]) && (total_b < purple_limit_values[5])) {
    Serial.println("purple"); colour = 5;
  } else { Serial.println("unknown"); colour = 6; }
}

//============================== MOVE HOLDER =============================
void move_holder() {
  int new_holder_position = colour_angles[colour - 1];
  int holder_delay = (abs(previous_colour - colour) * 70);
  if (holder_delay < 0) holder_delay = 0;
  
  if (previous_colour > colour) {
    int anti_backlash_angle = new_holder_position - backward_anti_backlash;
    holder_servo.write(anti_backlash_angle);
  } else {
    int anti_backlash_angle = new_holder_position + forward_anti_backlash;
    holder_servo.write(new_holder_position);
  }
  
  if (colour == 1) set_led(holder_delay, yellow);
  else if (colour == 2) set_led(holder_delay, green);
  else if (colour == 3) set_led(holder_delay, orange);
  else if (colour == 4) set_led(holder_delay, red);
  else if (colour == 5) set_led(holder_delay, purple);
}

//============================= RELEASE SKITTLE ===========================
void release_skittle() { feeder_servo.write(180); delay(release_delay); }

//================================= SHAKE =================================
void shake() {
  int shake_delay = 80, shake_amount = 5, shake_min_value = 90, shake_max_value = 180;
  feeder_servo.write(180); delay(release_delay);
  feeder_servo.write(120); delay(80);
  for (int i = 0; i <= shake_amount; i++) {
    feeder_servo.write(shake_min_value); delay(shake_delay);
    feeder_servo.write(shake_max_value); delay(shake_delay);
  }
}

//============================ STARTING SEQUENCE ============================
void starting_sequence() {
  colour = 1; move_holder(); set_led(300, yellow); delay(400);
  colour = 2; move_holder(); set_led(300, green); delay(400);
  colour = 3; move_holder(); set_led(300, orange); delay(400);
  colour = 4; move_holder(); set_led(300, red); delay(400);
  colour = 5; move_holder(); set_led(300, purple); delay(400);
  previous_colour = colour; colour = 3; move_holder(); end_loop(200);
}

//================================ END LOOP =================================
void end_loop(int duration) {
  set_led(duration, orange); set_led(duration, red);
  set_led(duration, green); set_led(duration, yellow);
  set_led(duration, purple);
}

//============================ SET RGB LED COLOUR =======================
void set_led(int duration, int color[3]) {
  int start_time = millis(), current_time = start_time, current_duration = 0;
  while (current_duration < duration) {
    analogWrite(R_pin, map(current_duration, 0, duration, current_red_value, color[0]));
    analogWrite(G_pin, map(current_duration, 0, duration, current_green_value, color[1]));
    analogWrite(B_pin, map(current_duration, 0, duration, current_blue_value, color[2]));
    current_time = millis(); current_duration = current_time - start_time;
  }
  current_red_value = color[0]; current_green_value = color[1]; current_blue_value = color[2];
}

Schaltplan

Die Verkabelung ist recht einfach. Stellen Sie nur sicher, dass Ihr Step-Down-Wandler 5 V ausgibt, bevor Sie etwas anschließen!

Fortgeschrittene Farbsortiermaschine mit Arduino und RGB-Sensor

Herstellungsprozess

  1. EEG-Geräte: Design, Fertigung und neue Anwendungen
  2. Automaten: Eine 36,6-Milliarden-Dollar-Industrie in den USA
  3. Die Entwicklung und Fertigung von Nähmaschinen: Von der Innovation des 19. Jahrhunderts zur modernen Automatisierung
  4. Fernsehen: Von mechanischen Ursprüngen zur smarten Zukunft
  5. Spindellager: Präzision & Qualitätssicherung für Hochleistungsspindeln
  6. Wichtige Teile einer Drehmaschine: Funktionen & Überblick
  7. Drehmaschinen verstehen: Geschichte, Typen und Anwendungen
  8. Fräsmaschinen-Komponenten: Alle Baugruppen und ihre Funktionen
  9. Was ist eine Maschine? Ein umfassender Leitfaden
  10. JW Machine: Präzise CNC-Lohnfertigungs-Services