I'm working on a P-Stop sensor based around an LDR, "encoder" wheel, and ATtiny85. I'm still in the first iteration of the hardware, and it needs quite a bit of mangling before it's ready for prime time. The "sensor" is a small encoder wheel that the filament rides over, held in place by a spring tensioned bearing arm. The LDR and LED pair shine through the wheel. As the filament travels, the encoder spins and the LDR detects differences in the light level.
/*
MakerBot Filament Jam Sensor V2
Written by Aaron Ciuffo
May 8 2013
(gmail aaronl.ciuffo)
Released under Creative Commons - Share Alike
*/
#include <Debounce.h>
// Constants
// Pin assignments
#define ldrPin 2
#define ledOnPin 0
#define buttonPin 2
#define ledErrorPin 1
//sampling and time keeping
#define checkDelay 10000
#define sampleRate 50
// Global Variables
// Error LED fading variables
int brightness = 0;
int fadeAmount = 5;
boolean ledError = false;
//time keeping variables
unsigned long currentTime = millis(); // current time
unsigned long prevSensTime = 0; //millis(); // time of last sensor reading
unsigned long prevCheckTime = 0; //millis(); // time of last check for a fault
int delayMult = 2; //multiplier for delay - adjust with button input
// sensor variables
int absDifference = 0; // absolute difference between readings
int ldrVal = 0; // raw LDR value
int lastReading = 0; // previous LDR reading for comparrision
int changeCounter = 0; // count the number of times the sensor value has not significantly changed
// button variables
Debounce debouncer = Debounce (20, buttonPin); //initialize debouncer
void setup ()
{
pinMode(buttonPin, INPUT);
pinMode(ledErrorPin, OUTPUT);
pinMode(ledOnPin, OUTPUT);
digitalWrite(ledOnPin, HIGH);
Serial.begin(9600); // start the serial connection -- FIX ME remove this after debugging
}
void pulse ()
{
analogWrite(ledErrorPin, brightness);
brightness = brightness + fadeAmount;
if (brightness == 0 || brightness == 255) {
fadeAmount = -fadeAmount;
}
delay(10);
}
void strobe ()
{
for (int x = 0; x < 3; x++) {
digitalWrite(ledOnPin, LOW); // flash the power light to show a reset has happened
delay (100);
digitalWrite(ledOnPin, HIGH);
}
}
void loop ()
{
currentTime=millis(); // set current time
if (currentTime - prevSensTime > sampleRate ) { // sample ldr every sampleRate millisec
ldrVal = analogRead(ldrPin);
absDifference = ldrVal - lastReading; // do not do any math in the abs() function - see documentation
absDifference=abs(absDifference);
Serial.println(changeCounter);
if ( absDifference <= 3 ) { // record the number of times that no significant change has occurred since the last cycle
changeCounter++;
}
/*
else {
digitalWrite(ledOnPin, LOW); // flash the power light to show active sampling
delay (100);
digitalWrite(ledOnPin, HIGH);
}
*/
prevSensTime = currentTime;
}
lastReading = ldrVal; // end sampleRate check
if (currentTime - prevCheckTime > checkDelay) {
if (changeCounter > .9 * (checkDelay/sampleRate) ) { // if there is no change in the ldr for 90% of the cycles, error out
Serial.println("ERROR!");
ledError = true;
}
Serial.println("new timing cycle; resetting everything");
changeCounter = 0;
prevCheckTime = currentTime;
} // end checkDelay
if (ledError) {
pulse(); // Pulse the RED led to show an error state
}
debouncer.update(); // debounce the button
// reset the error condition if the button is pressed
if (debouncer.read()) {
ledError = false; // turn off the error condition
changeCounter = 0; // set the error conditions to zero
prevCheckTime = currentTime;
digitalWrite(ledErrorPin, LOW); //pull the error LED low
strobe();
//delay(20000); //give 20 seconds grace before sampling again ;
// pull the endstop pin high -- check the sailfish documentation!
}
}