Building P-Stop hardware support - Advice needed

58 views
Skip to first unread message

Txoof

unread,
May 8, 2013, 1:30:27 AM5/8/13
to jetty-f...@googlegroups.com
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.  
If an error is detected, the sensor will pull the endstop low pausing the print.  Pressing the reset button on the circuit will clear the error condition for 10 seconds.

The software looks for changes in the light level to indicate that all is well; if no changes are detected for X time, it fires off an error and triggers the P-Stop.  

Here's where I need some advice:
  1. What is a reasonable timeout for no filament movement before triggering an error condition?  Right now it is set for 10 seconds.  
  2. Currently I'm sampling the LDR every 50 milliseconds, and the ATtiny is keeping up just fine - should I sample more frequently?
  3. Should the reset button offer more grace time before sampling again?
Also, if there's any OpenSCAD wizards that would like to help with this project, I could use some help rendering the parts in something better than SketchUP.  If there is any interest in this project, I'll clean up the SU files and post them for conversion.  


Here's the Arduino Sketch that's doing the work if you're interested:

/*
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!
  }
  
}

Isaac Budmen

unread,
May 8, 2013, 5:06:12 AM5/8/13
to jetty-f...@googlegroups.com
Do you have a link to the exact encoder wheel you are using? I'd be happy to lend an extra set of eyes and some OpenSCAD scripting to help find a solution

Jetty

unread,
May 8, 2013, 11:44:22 AM5/8/13
to jetty-f...@googlegroups.com
Try adding another pin to the design to monitor extruder movement.  (Better be 2 pins for dual extruders).
That's because the extruder doesn't always move (during heating, during pausing, during reheating).

From that you should be able to get the pulses per second and see if the movement of the encode wheel approaches that.

Another need feature could be "slippage" detection.  Sometimes there's enough of a drag on the filament that it ends up in less output,
but the filament does still move (this often happens with partially blocked nozzles too).  Detecting the input steps and comparing
the pulse rate to the pulse rate from the encoder should highlight this.  You could accommodate different extruder rates
with some training period, where it learns what's normal for the extruder, then it highlight anything that's outside of a percentage range.

The pulse detection comparison could be done with some kind of digital RC circuit.

Regarding sensing the extruder steps, there's a test point on the Mightyboard called A-Step which you can solder to fairly easily with
a piece of thin wire (I use wire wrapping wire), and then tape over it with kapton, to give it a bit more mechanical strength.

If you are still going with the timeout idea, then it would depend on how close your encoder wheel is to the extruder, and the
timeout would vary according to the feed rate of the extruder.

Just some ideas.

Txoof

unread,
May 9, 2013, 2:48:51 AM5/9/13
to jetty-f...@googlegroups.com
Thanks for the offer!  

I tried a few wheels from the Thingiverse, but I decided that I wanted a wheel with a groove in it so the filament would stay put and I could add a rubber band for added friction.  I will clean up the SU files and post them shortly.  Perhaps you can take a look and see if you can convert them into OpenSCAD?

I'll also clean up the other bits of the model and post those.  The current problem I'm running into is that making small changes in SU is a HUGE project.  I typically end up fouling up some other part in the process.  A good SCAD drawing that has been properly paramatized would be much better.

My SCAD-fu is pretty weak though and I haven't much moved past simple extrusions yet.  This is the most complex thing I've made so far: http://www.thingiverse.com/thing:63756

Txoof

unread,
May 9, 2013, 3:01:32 AM5/9/13
to jetty-f...@googlegroups.com
Wow!  Those are great ideas.  There's a definite need for some more communication between the board and the sensor so it knows when the print has started otherwise you would have to babysit the sensor until printing got under way.

Do you have any idea what pins on the ToM extruder board might yield some extruder data?  

Also, my "encoder" wheel is nothing of the sort.  It really is just an LDR and LED with a wheel that is roughly 50% solid and 50% open.  As you can see from the code, it's just looking for changes in the amount of light.  It doesn't actually measure direction or speed like a real encoder wheel.  

For the moment, I think my skill will probably lead me to the timeout path.  Why does the physical location of the sensor with respect to the extruder matter?  as the filament is pulled, should the sensor not "feel" the pull no matter where along the filament it is?  Or is there more stretch in the filament than I think?

Txoof

unread,
May 9, 2013, 3:16:01 AM5/9/13
to jetty-f...@googlegroups.com
Here's a link to the SU files I've been using.  

Let me know if you have any issues with them.  The mockup shows how everything fits together. I've put some ridiculous support into the opening in the arm and into the small opening on the base plate that will become the housing for the LED.  


On Wednesday, May 8, 2013 11:06:12 AM UTC+2, isaac wrote:

Txoof

unread,
May 9, 2013, 4:45:48 AM5/9/13
to jetty-f...@googlegroups.com
Aaaaaand how about that link: http://www.thingiverse.com/thing:85715

isaac

unread,
May 9, 2013, 6:32:13 AM5/9/13
to jetty-f...@googlegroups.com
I'll take a look at the sketchup files today

Jetguy

unread,
May 9, 2013, 6:43:01 AM5/9/13
to Jetty Firmware
BTW, Dan and I had a quick back and forth on the current P-Stop
implementation. Dan did not turn on the internal pullup in the mega on
the P-stop endstop connector. This allows a second kind of safety in
tht if a user enabled P-Stop, then if there is no P-Stop connected, it
will trigger a pause right away as soon as the print starts. Kind of
an extra failsafe. All I'm saying is that the external device must
pull the pin high normally so the P-Stop if enabled is not triggered,
and then pull the pin low for a trigger event. I was thinking I
prefered the internal pullup on just because the most simple version
of just using a switch simplifies the wiring and eliminated the chance
that if some wiring failure happens, then we don't kill the sensitve 5
volt rail resulting in a stock regulator blowout. In other words, the
pullup off provides an extra kind of idiot proof layer for making sure
the p-stop is connected, but at the same time, now requires we use the
5 volt pin in implementation of the easiest p-stop switches to drive
the sense pin high. I'm open to discussion either way for suggestions
about enabling or disabling the internal pullup.

Also, this was on a Replicator 1.
> >>>    1. What is a reasonable timeout for no filament movement before
> >>>    triggering an error condition?  Right now it is set for 10 seconds.
> >>>    2. Currently I'm sampling the LDR every 50 milliseconds, and the
> >>>    ATtiny is keeping up just fine - should I sample more frequently?
> >>>    3. Should the reset button offer more grace time before sampling

isaac

unread,
May 9, 2013, 7:42:15 AM5/9/13
to jetty-f...@googlegroups.com
On the Sketchup Model I was having some trouble figuring out what was happening where the wheel edge touches the baseplate, but here is the baseplate scad and STL files

Txoof

unread,
May 9, 2013, 11:57:22 AM5/9/13
to jetty-f...@googlegroups.com
Ahh, that bit at the bottom is just a little bit of support so the base plate can be printed on it's side.  The small housing for the LED needed something to keep it from sagging.  

The more I read the posts from you guys, the more I realize I'm in over my head and appreciate all the help you are all offering.  I'm getting really busy at work: the school year is just about to end and I have a mountain of stuff I need to deal with, so this project will probably need to sit on the back bench for a bit.  

I'll take a look at the scad files next week though.  Thanks again!
Reply all
Reply to author
Forward
0 new messages