Optical Rotation Sensor

The optical sensor we used in the Lightino V3 is QRE1113 This IR sensor is used for analog output which will vary depending on the amount of IR light reflected back to the sensor.  But the design made by SparkFun in this product let us use this sensor to feature a digital output, using a capacitor discharge circuit to measure the amount of reflection. The output of the phototransistor is wired to a 10nF capacitor. The faster that capacitor discharges, the more reflective the surface is.

QRE1113 IR reflectance sensor
QRE1113 IR reflectance sensor

The  QRE1113 IR reflectance sensor is composed of two parts – an IR emitting LED and an IR sensitive phototransistor. When the light from the LED is reflected back onto the phototransistor, the output will begin to go lower. So when we design a bearing cap for our spinner, we can pass through in front of the sensor and let it understand a rotation has occurred. We are using a cap shape like below. You can download the STL file and print one for your spinner. We did not send you this cap because it will be great to 3d print it yourself. Your design files can be shared here.

Bearing Cap

 

 

Now we have an indication and a digital signal from the spinner for every turn it made. How can we use this in our code? Our code may increment the number of rotation by one for every turn so that we can understand the total number of the turns in one spin.

Interrupts

If we like to stop the execution of our code and make some special calculations when ever an event occurs (here our optical sensor digital information about the turn) we can use interrupts.

In Wikipedia, an interrupt definition is:

In system programming, an interrupt is a signal to the processor emitted by hardware or software indicating an event that needs immediate attention. An interrupt alerts the processor to a high-priority condition requiring the interruption of the current code the processor is executing.

 

Example Code

 

//***************************************************************
//Lightino is an open source project develop by MakerStorage LLC.
//It is a STEM & EdTech. fidget spinner for students to learn code.
//Please contrubute and suport this project at lightino.org
// e-mail:ne@makerstorage.com
//***************************************************************
//delay functions and graphics taken from Ken (MakerBox)
//***************************************************************



#define BLUE  A1
#define RED   A0
#define GREEN A2
#define LED1 9
#define LED2 8
#define LED3 7
#define LED4 6
#define LED5 5
#define LED6 4
#define LED7 3
#define LED8 2
#define SENSOR A10



uint8_t led_anodes[] = {LED8, LED7, LED6, LED5, LED4, LED3, LED2, LED1};
uint8_t led_cathodes[] = {GREEN, RED, BLUE};
int color = 0; //color index 0 to 2
boolean flag=true;

unsigned long long lastTimeUs;                // time (us) magnet sensed
unsigned long long revTimeUs;                 // time (us) of last full rotation
unsigned long long dwellTimeUs;               // time (us) between LED changes (based on rotation speed)



void setup() {

  // Interupt setting
   PCMSK0 = bit (PCINT6); //Use PCINT6 = PB6 pin 30.
   PCICR |= (1<<PCIE0);   //Enable Pin change interrupt
   sei();

 // Serial.begin(9600);
 //  while (!Serial) ;
  
  TXLED0;// on board leds off
  RXLED0;
  
  pinMode(RED, OUTPUT); 
  pinMode(BLUE, OUTPUT); 
  pinMode(GREEN, OUTPUT); 
  
  pinMode(LED8, OUTPUT);
  pinMode(LED7, OUTPUT);
  pinMode(LED6, OUTPUT);
  pinMode(LED5, OUTPUT);
  pinMode(LED4, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED1, OUTPUT);

  pinMode(SENSOR, INPUT);
  digitalWrite(SENSOR,HIGH); 

   // default off
  digitalWrite(RED, LOW);
  digitalWrite(BLUE, LOW);;
  digitalWrite(GREEN, LOW); 
  
  digitalWrite(LED1, LOW);
  digitalWrite(LED2, LOW);
  digitalWrite(LED3, LOW);
  digitalWrite(LED4, LOW);
  digitalWrite(LED5, LOW);
  digitalWrite(LED6, LOW);
  digitalWrite(LED7, LOW);
  digitalWrite(LED1, LOW);

  lastTimeUs = micros();
}

void loop() {
  unsigned long long curTimeUs;

if (flag){  
flag=false;

   for(int LED=0; LED<8; LED++){
       digitalWrite(led_anodes[LED], 1); 
       setColor (0);    //red   
     } 

}

  AllLedsOff();

}//loop

void AllLedsOff(){

   for(int LED=0; LED<8; LED++){
       digitalWrite(led_anodes[LED], 0); 
       setColor (-1);       
     }  

}


void setColor (int color){

switch (color) {
    case 0:    //red
      digitalWrite(led_cathodes[0], LOW);
      digitalWrite(led_cathodes[1], LOW);
      digitalWrite(led_cathodes[2], HIGH);
      break;
      
    case 1:    //green
      digitalWrite(led_cathodes[0], LOW);
      digitalWrite(led_cathodes[1], HIGH);
      digitalWrite(led_cathodes[2], LOW);
      break;
      
    case 2:    //blue
      digitalWrite(led_cathodes[0], HIGH);
      digitalWrite(led_cathodes[1], LOW);
      digitalWrite(led_cathodes[2], LOW);
      break;

     default:
        // turn all the LEDs off:  
      digitalWrite(led_cathodes[0], LOW);
      digitalWrite(led_cathodes[1], LOW);
      digitalWrite(led_cathodes[2], LOW);
     
  }

  
}



ISR(PCINT0_vect){  // Magnet sensed
 // if (!digitalRead(SENSOR)){
    flag = true;             // Increment volatile variables
   // revolutions += 1;
 // }
}