nortd / driveboardapp

Next generation Lasersaur control app.
http://www.lasersaur.com
15 stars 19 forks source link

feature: add a multi-trigger option to firmware (via mailing list) #10

Open stefanix opened 7 years ago

stefanix commented 7 years ago

Sure! I'm very far from running standard code at this point and I don't have time to merge and test my hacked code with the main branch. But this should work for the current version.

CAVEAT: I'm running this on a machine with mechanical limit switches. Someone needs to test this on a machine with magnetic limit switches before the code is committed into the mainstream.

The change is in the firmware stepper motor control code:

firmware/src/stepper.c

Someplace up at the top of the file, add this:

/*
  Some Lasersaurs pick up electrical noise on the limit switch
  wires when the laser fires.  Real limit switch events are
  long in duration - and since there is a gap of several
  millimeters between where the switch triggers and the
  mechanical limit, we can afford to filter the signal a
  little to reject short noise pulses without risk of
  ignoring an actual limit switch impact.

  A larger SENSOR_NOISE_DURATION number rejects more noise,
  but has the side-effect of delaying real limit switch events,
  so don't make this value bigger than you strictly need!
*/

// Number of main loop cycles for which a limit switch hit
// has to persist before we consider it "real".

#define SENSOR_NOISE_DURATION 5

// Count of the number of consecutive limit hit events:
static uint8_t limit_count = 0 ;

The magic number '5' was the first number I tried - it worked perfectly for me - so I never did try to figure out the smallest value I could get away with. 5 stepper motor steps is a small fraction of a millimeter - so this shouldn't risk cause a mechanical impact.

Then (at around line 225) look for this code:

#ifndef DEBUG_IGNORE_SENSORS
    // stop program when any limit is hit or the e-stop turned the power off
    if (SENSE_LIMITS) {
      stepper_request_stop(STATUS_LIMIT_HIT);
      busy = false;
      return;
    }
    #ifndef DRIVEBOARD
      else if (SENSE_POWER_OFF) {
        stepper_request_stop(STATUS_POWER_OFF);
        busy = false;
        return;
      }
    #endif
  #endif

Replace it with:

#ifndef DEBUG_IGNORE_SENSORS
    // stop program when any limit is hit for more
    // than a handful of consecutive cycles.

    if (SENSE_LIMITS)
      limit_count++ ;
    else
      limit_count = 0 ;

    if ( limit_count > SENSOR_NOISE_DURATION )
    {
      stepper_request_stop(STATUS_LIMIT_HIT);
      busy = false;
      return;
    }

#ifndef DRIVEBOARD
    // stop program if the e-stop turned the power off

    if (SENSE_POWER_OFF) {
      stepper_request_stop(STATUS_POWER_OFF);
      busy = false;
      return;
    }
#endif
#endif

This is really just a quick hack. However, it's simple and it's working extremely well for me right now.

There could be more sophistication here - like counting the number of noise cycles for each switch independently - and with a better 'tuned' number for SENSOR_NOISE_DURATION. Also, it would be better if the duration was specified in milliseconds rather than in the number of main loop iterations.

Counting the number of ignored "noise events" over time would be useful and logging a message when the number is unreasonably high would be a good thing. I get maybe one event per several hours! If you're seeing a much higher rate than that - then you should try moving the high voltage wire that goes to the laser tube to be further from the driverboard and from the limit switch wiring.

That said, the less code we have in the main stepper loop the better, so arguably, "less is more"!

Noise on the door switches might also be an issue - but the software doesn't monitor that and the consequences of a door switch glitch are so minor you'll probably never know that they happened!

YMMV!

-- Steve