Arduino M&M and Skittles Color Sorter (2024)

  • Overview
  • Things
  • Story
  • Schematics
  • Code
  • Credits
  • Comments(4)

Arduino M&M and Skittles Color Sorter (1)

Mirko Pavleski

Published January 7, 2019 © GPL3+

Color sorter based on Arduino Nano, TCS230/TCS3200 color sensor, step motor with gear, and small 9g servo.

AdvancedFull instructions provided15,313

Things used in this project

Hardware components

Arduino M&M and Skittles Color Sorter (3)
Arduino Nano R3
×1
  • Buy from Newark
  • Buy from CPC
tcs3200 colour sensor
×1
Arduino M&M and Skittles Color Sorter (4)
Texas Instruments Dual H-Bridge motor drivers L293D
×1
  • Buy from Newark
  • Buy from Adafruit
  • Buy from CPC
  • Buy from www.ti.com
geared stepper motor
×1
Arduino M&M and Skittles Color Sorter (5)
SG90 Micro-servo motor
×1

Software apps and online services

Arduino M&M and Skittles Color Sorter (6)
Arduino IDE

Hand tools and fabrication machines

Arduino M&M and Skittles Color Sorter (7)
Soldering iron (generic)

Story

<_e_1o1V>

The project was developed according to the instructions of Christopher Bartolome presented at: https://www.instructables.com/id/MM-Color-Sorter. I adapted the project to the conditions and materials that I had. I use a stepper motor from an old thermal printer, and I made plastic parts from 3 mm PVC. I also increased the sensitivity of the sensor by changing original LEDs with high angle LEDs.

Read more

Schematics

schematic

Arduino M&M and Skittles Color Sorter (8)

Code

  • code

code

Arduino

/************* M&M Sorter *************************** Christopher Bartolome MAKE Course Fall 2015 ************* ***************************/  //Include necessary libraries#include <TimerOne.h>#include <StepperAK.h>#define S0 7#define S1 5#define S2 4#define S3 3#define OUT 2#define SERVO_PIN 6#define gearratio 64 //Define global variablesint g_count = 0; // count the frequecyint g_array[3]; // store the RGB valueint g_flag = 0; // filter of RGB queuefloat g_SF[3]; // save the RGB Scale factorboolean volatile servoHigh = false;const int stepsPerRevolution = 2048; uint16_t volatile servoTime = 0;uint16_t volatile servoHighTime = 3000; // instantiate a 4-wire stepper on pins 19 through 16:Stepper myStepper(stepsPerRevolution, 19,18,17,16); //Setup for functionvoid setup(){ //Setup for servo servoInit(); servoSetPosition(1600); delay(1000);  //Setup for Color Sensor TSC_Init(); Serial.begin(115200); Timer1.initialize(); // defaulte is 1s Timer1.attachInterrupt(TSC_Callback);  attachInterrupt(0, TSC_Count, RISING);  delay(4000); for(int i=0; i<3; i++)  { Serial.println(g_array[i]); g_SF[0] = 255.0/ g_array[0]; //R Scale factor g_SF[1] = 255.0/ g_array[1] ; //G Scale factor g_SF[2] = 255.0/ g_array[2] ; //B Scale factor } Serial.println(g_SF[0]); Serial.println(g_SF[1]); Serial.println(g_SF[2]);  //Setup for stepper motor myStepper.setSpeed(0.15*gearratio);  // initialize the serial port: Serial.begin(115200); }//Main loopvoid loop(){ //Prints RGB value for scaling factor g_flag = 0; int R = int(g_array[0] * g_SF[0]); int G = int(g_array[1] * g_SF[1]); int B = int(g_array[2] * g_SF[2]);   //Evaluates Conditionals, and based on these conditionals  if((R>225) && (R<400) && (G>210) && (G<275) && (B>210) && (B<275)) // White { Serial.println("Color is white"); servoSetPosition(1500); delay(500); myStepper.step(stepsPerRevolution/6); } else if((R>=190) && (R<=210) && (G>B) && (G>R) && (B>=185) && (B<=205)) // Green { Serial.println("Color is green"); servoSetPosition(700); delay(500); myStepper.step(stepsPerRevolution/6);   } else if((R>=185) && (R<=210) && (G>=185) && (G<=208) && (B>=185) && (B<=208)) // Brown { Serial.println("Color is brown");  servoSetPosition(1450); delay(500); myStepper.step(stepsPerRevolution/6);  } else if((R>=195) && (R<=212) && (G>=190) && (G<=210) && (B>G) && (B>=194) && (B<=210)) // Blue { Serial.println("Color is blue"); servoSetPosition(1700); delay(500); myStepper.step(stepsPerRevolution/6); } else if((R>=205) && (R<=225) && (G>=190) && (G<=203) && (B>=185) && (B<=205)) // Orange { Serial.println("Color is Orange");  servoSetPosition(2050); delay(500); myStepper.step(stepsPerRevolution/6); } else if((R>=210) && (R<=230) && (G>=205) && (G<=220) && (B<R) && (B<G)) // Yellow {  Serial.println("Color is yellow");  servoSetPosition(1250); delay(500); myStepper.step(stepsPerRevolution/6); } else if((R>B) && (R>G) && (G>=185) && (G<=206) && (B>=185) && (B<=200)) // Red { Serial.println("Color is red");  servoSetPosition(1000);  delay(500); myStepper.step(stepsPerRevolution/6); } else { Serial.print("Red = "); Serial.println(R); Serial.print("Green = "); Serial.println(G); Serial.print("Blue = "); Serial.println(B); }; delay(4000); }/************Functions for color sensor*******/ // Init TSC230 and setting Frequency. void TSC_Init() { pinMode(S0, OUTPUT); pinMode(S1, OUTPUT); pinMode(S2, OUTPUT); pinMode(S3, OUTPUT); pinMode(OUT, INPUT); digitalWrite(S0, LOW); // OUTPUT FREQUENCY SCALING 2% digitalWrite(S1, HIGH);  } // Select the filter color  void TSC_FilterColor(int Level01, int Level02) { if(Level01 != 0) Level01 = HIGH; if(Level02 != 0) Level02 = HIGH; digitalWrite(S2, Level01);  digitalWrite(S3, Level02);  } void TSC_Count() { g_count ++ ; } void TSC_Callback() { switch(g_flag) { case 0:  TSC_WB(LOW, LOW); //Filter without Red break; case 1: g_array[0] = g_count; TSC_WB(HIGH, HIGH); //Filter without Green break; case 2: g_array[1] = g_count; TSC_WB(LOW, HIGH); //Filter without Blue break; case 3: g_array[2] = g_count; TSC_WB(HIGH, LOW); //Clear(no filter)  break; default: g_count = 0; break; } } void TSC_WB(int Level0, int Level1) //White Balance { g_count = 0; g_flag ++; TSC_FilterColor(Level0, Level1); Timer1.setPeriod(1000000); // set 1s period } /********Functions for Servo************/ ISR(TIMER2_COMPA_vect) { // The time that passed since the last interrupt is OCR2A + 1 // because the timer value will equal OCR2A before going to 0. servoTime += OCR2A + 1;  static uint16_t highTimeCopy = 3000; static uint8_t interruptCount = 0;  if(servoHigh) { if(++interruptCount == 2) { OCR2A = 255; }  if(servoTime >= highTimeCopy) { // The pin has been high enough, so do a falling edge. digitalWrite(SERVO_PIN, LOW); servoHigh = false; interruptCount = 0; } }  else { // The servo pin is currently low. if(servoTime >= 40000) { // We've hit the end of the period (20 ms), // so do a rising edge. highTimeCopy = servoHighTime; digitalWrite(SERVO_PIN, HIGH); servoHigh = true; servoTime = 0; interruptCount = 0; OCR2A = ((highTimeCopy % 256) + 256)/2 - 1; } } }  void servoInit() { digitalWrite(SERVO_PIN, LOW); pinMode(SERVO_PIN, OUTPUT); // Turn on CTC mode. Timer 2 will count up to OCR2A, then // reset to 0 and cause an interrupt. TCCR2A = (1 << WGM21); // Set a 1:8 prescaler. This gives us 0.5us resolution. TCCR2B = (1 << CS21); // Put the timer in a good default state. TCNT2 = 0; OCR2A = 255;  TIMSK2 |= (1 << OCIE2A); // Enable timer compare interrupt. sei(); // Enable interrupts. }  void servoSetPosition(uint16_t highTimeMicroseconds) { TIMSK2 &= ~(1 << OCIE2A); // disable timer compare interrupt servoHighTime = highTimeMicroseconds * 2; TIMSK2 |= (1 << OCIE2A); // enable timer compare interrupt }

Credits

Mirko Pavleski

150 projects • 1287 followers

Comments

Related channels and tags
  • arduino color sorter
  • tcs3200
Arduino M&M and Skittles Color Sorter (2024)
Top Articles
Latest Posts
Recommended Articles
Article information

Author: Twana Towne Ret

Last Updated:

Views: 6498

Rating: 4.3 / 5 (44 voted)

Reviews: 83% of readers found this page helpful

Author information

Name: Twana Towne Ret

Birthday: 1994-03-19

Address: Apt. 990 97439 Corwin Motorway, Port Eliseoburgh, NM 99144-2618

Phone: +5958753152963

Job: National Specialist

Hobby: Kayaking, Photography, Skydiving, Embroidery, Leather crafting, Orienteering, Cooking

Introduction: My name is Twana Towne Ret, I am a famous, talented, joyous, perfect, powerful, inquisitive, lovely person who loves writing and wants to share my knowledge and understanding with you.