Coding a Shift Register

Hello!

I'm designing a college project. The project is an M&M's colour sorter using an arduino, an adafruit colour sensor, two inverter drives and two industrial servo motors. (Image in the link)

https://drive.google.com/file/d/0B5kqS701YwHGeWZLbDdzRU9NekU/view?usp=sharing

The motors each have a disk attached. The first disk has 8 holes evenly spaced around the edge. The idea is that as the disk rotates an M&M drops into the hole which is passed under the sensor. The arduino will give out a different digital output to the drive for each colour which will then spin the second disk to 1 of 6 angles to catch the correct colour in each cup.

The first colour is detected at 0 degrees as the disk spins clockwise the second colour is detected when the first colour is at 45 degrees, when the first colour reaches 90 degrees it falls through a hole into the cup and the third colour is detected.

The problem is that I need to delay the digital output for each colour until the next colour is detected as the second motor will move into position while the colour moving from 45 to 90 degrees.

So basically i want to output the signal for the first colour when the next colour is detected if this makes sense?

Does anybody have any suggestions about the best way to go about this in code?

This is the code so far…I’m using a 3 bit binary output for the 6 colours

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

/* Example code for the Adafruit TCS34725 breakout library */

/* Connect SCL    to analog 5
   Connect SDA    to analog 4
   Connect VDD    to 3.3V DC
   Connect GROUND to common ground */
   
/* Initialise with default values (int time = 2.4ms, gain = 1x) */
// Adafruit_TCS34725 tcs = Adafruit_TCS34725();

/* Initialise with specific int time and gain values */
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_24MS, TCS34725_GAIN_16X);

int bit1 = 3;
int bit2 = 4;
int bit4 = 5;


void setup(void) {
  
  pinMode(bit1,OUTPUT);
  pinMode(bit2,OUTPUT);
  pinMode(bit4,OUTPUT);
  
  Serial.begin(9600);
  
  if (tcs.begin()) {
    Serial.println("Found sensor");
  } else {
    Serial.println("No TCS34725 found ... check your connections");
    while (1);
  }
  
  // Now we're ready to get readings!
}

void loop(void) {
  uint16_t r, g, b, c, colorTemp, lux;
  
  tcs.getRawData(&r, &g, &b, &c);
  colorTemp = tcs.calculateColorTemperature(r, g, b);
  lux = tcs.calculateLux(r, g, b);
  
  Serial.print("Color Temp: "); Serial.print(colorTemp, DEC); Serial.print(" K - ");
  Serial.print("Lux: "); Serial.print(lux, DEC); Serial.print(" - ");
  Serial.print("R: "); Serial.print(r, DEC); Serial.print(" ");
  Serial.print("G: "); Serial.print(g, DEC); Serial.print(" ");
  Serial.print("B: "); Serial.print(b, DEC); Serial.print(" ");
  Serial.print("C: "); Serial.print(c, DEC); Serial.print(" ");
  Serial.println(" ");
  



//RED
  if (r >2800 && r <4900 && g >1200 && g <1900 && b >980 && b <1600)
{
  digitalWrite(bit1,LOW);
  digitalWrite(bit2,LOW);
  digitalWrite(bit4,LOW);
}

//Green
  if (r >1900 && r <3150 && g >3250 && g <5400 && b >1350 && b <2450 && c >7000)
{
  digitalWrite(bit1,HIGH);
  digitalWrite(bit2,LOW);
  digitalWrite(bit4,LOW);
 }
 
//Yellow
   if (r >5850 && r <9500 && g >5050 && g <7800 && b >2000 && b <3050)
{
  digitalWrite(bit1,LOW);
  digitalWrite(bit2,HIGH);
  digitalWrite(bit4,LOW);
}

//Brown
if (r >1300 && r <1860 && g >1000 && g <1550 && b >650 && b <2020)
{
  digitalWrite(bit1,HIGH);
  digitalWrite(bit2,HIGH);
  digitalWrite(bit4,LOW);
}
//Orange
  if (r >4950 && r <7470 && g >2100 && g <3340 && b >1100 && b <1970)
{
  digitalWrite(bit1,LOW);
  digitalWrite(bit2,LOW);
  digitalWrite(bit4,HIGH);
 }
 
//Blue
   if (r >800 && r <1650 && g >1900 && g <2700 && b >2100 && b <3550)
{
  digitalWrite(bit1,HIGH);
  digitalWrite(bit2,LOW);
  digitalWrite(bit4,HIGH);
  
}
}

rotate disk1 45 degrees get color rotate disk2 to "X" degrees // based on color rotate disk1 45 degrees // M&M drops into hole. and new M&M is under sensor get color if no M&M detected, rotate disk1 45 degrees

As I see the process, you load a part rotate part under color rotate cups to place correct cup under the drop point rotate detected part to drop point, and new part to detector. repeat.

you do not say how you rotate the color cups. stepper or servo ? a switch to detect rotation is complete might work you could have holes in the color disk with an optical sensor to pick up the location. you could have a reflector under the disk. the the blue one near the edge, the red one in a smidge, the green one wee bit the yellow one a schoche the black on a shebang (not the whole shebang though)

then spin until the detector was HIGH for the correct color.

disk1 could not move until disk2 sensor went HIGH for the correct color.

Thanks for the reply Dave.

The first disk will be spinning at a constant RPM and the second disk will index to one of six positions depending on the colour detected. I’m controlling both Servo motors with two Emerson Industrial Automation drives (Unidrive M700)

http://www.emersonindustrial.com/en-EN/controltechniques/products/manufacturingdrives/m700/Pages/unidrivem700.aspx

The arduino isn’t controlling the motors, its only job is to give a 3 bit binary output to the drive depending on which colour has been detected, the drives will control the motion.

Let me try to explain what I want to code a little better:

Lets say the colours go through the sensor in this order…

  1. Red
  2. Blue
  3. Green

As Red passes under the sensor and meets the condition:
“if (r >2800 && r <4900 && g >1200 && g <1900 && b >980 && b <1600)”

I don’t want the arduino to output the following…

{
digitalWrite(bit1,LOW);
digitalWrite(bit2,LOW);
digitalWrite(bit4,LOW);
}

Until the next colour is detected.

So when Blue passes under the sensor i will get the output which Red should have put out. ie…

{
digitalWrite(bit1,LOW);
digitalWrite(bit2,LOW);
digitalWrite(bit4,LOW);
}

When green gets detected, i want to output for blue…

{
digitalWrite(bit1,HIGH);
digitalWrite(bit2,LOW);
digitalWrite(bit4,HIGH);

}

And so on… So basically it would be as if the sensor was mounted at 45 degrees clockwise.

I hope this makes sense…

think different. i would run motor2 with the jars, as soon as colr is arriving at the drop rotate #1 for memory you have a byte for the one under the sensor then a byte for the intermediate pos this is the jars need to go, if the jar is one pos before the correct one start the motor1.

Rather then storing three bits in separate variables I would store one 3-bit number in an integer and split it out into bits later:

static int newColor, colorAt45;
// Position the right cup under the hole at 90
  digitalWrite(bit1, colorAt45&1);
  digitalWrite(bit2, colorAt45&2);
  digitalWrite(bit4, colorAt45&4);
Rotate45Degrees();  // colorAt45 moves to 90 and drops into cup
colorAt45 = newColor;
// Read the new color
newColor = readTheColor();

ok, disk 2 is spinning, 3-4 times faster thawn disk 1.

the 'red' is half way past the color sensor when disk2 is fed the data that the next color is red. at the same time the 'green' just dropped so now disk2 needs to start rotationg for red. and at the same time the sensor identified 'blue' but is going to hold that,

mills() or a sensor.

you know the speed of disk1 so you know how long it takes to rotate 45 drg.

or

you could put a sensor on disk1 at 45deg to send the signal to disk 2

two options

Thank you John!

dave-in-nj: ok, disk 2 is spinning, 3-4 times faster thawn disk 1.

I had the same confusion. I thought the cups were fixed and the hole moved. When I figured out that that could not possibly work I figured out that disk 2 was fixed, with a hole at 90° and the six cups were rotated under the hole to catch the M&M as it fell through. This has the disadvantage of having to move the cups but the advantage that it will actually work. :) I would have used 6 trap-doors with flex tubes to direct the M&M's to the bins. Open the door when an M&M of the right color is about to pass.

johnwasser: I would have used 6 trap-doors with flex tubes to direct the M&M's to the bins. Open the door when an M&M of the right color is about to pass.

I would like to watch them tossed into containers.

seems like the timing is actually pretty easy. but would need some trial and error.