Automatic Dust Collection

 


I find control systems and automation fascinating. So much so, that I am building a career in the field. The whole point of control systems is to automate processes based on input data. This can be as simple as agitating a tank after a predetermined amount of time has elapsed, or as complex as a remote, unmanned natural gas distribution station. As a hobbyist woodworker, the first thing in my shop that comes to mind when contemplating automation is dust collection.

With dust collection, the necessity is real. Not only does it simply keep the shop clean and tools performing well, but more importantly, it keeps excess PM2.5 particles out of the air and subsequently out of my lungs. Yet, sometimes I find myself neglecting to turn on a dust collector. This could be because I just turned it off and want to protect the motor coils from stress, rushing, or sheer laziness. Even though my shop is small and the dust collector is not far away, I fall victim to using machines without dust collection.

So how do I prevent this from happening?

Automate the whole darn thing of course!

 

Overview

Before diving into the control system, let’s briefly go over what a consists a dust collection system. A dust collector is essentially a big vacuum that operates by use of an induction motor. There is a series of air ducts that are plumbed from many machines into a single dust collector. If all duct paths were allowed to suck simultaneously, there would be a severe lack of flow and pressure to any single machine in use. Therefore, there are valves called ‘blast gates’ that are used to direct all of the dust collector’s flow and pressure to a single machine.

In its essence, a modern, digital control system usually consists of inputs, outputs and a software program. Inputs carry some form of data into a controller that uses the software to interpret this information and perform some sort of action by use of its outputs. To decide what these inputs and outputs are and what the software needs to do, we need to refer back to our dust collection system.

When the user turns a machine on, we want the dust collector to turn on, and the particular blast gate at that machine to open too. Taking the first part of this sentence: “When the user turns a machine on […]”, it is obvious that we need to detect when a machine turns on. Therefore, the machines are our inputs. The next two parts of the first sentence: “[…] we want the dust collector to turn on, and the particular blast gate at that machine to open too,” indicates our outputs: our dust collector and the blast gates.

 

Current Sense Circuit Design

So how do we detect when a machine switches on and turn that into something useful that could be used as an input to our so called ‘controller’? Well, most woodworking machines use electricity to drive a motor.

Electricity consists of a voltage – a potential energy – and a current that describes when a load draws charge carriers. When you turn on a large induction motor that most woodworking machines feature, there is a temporary drop in voltage on that circuit (ever notice your lights dim if they’re on the same circuit?), and a current is continually drawn.

If we try to use voltage as a medium to detect when a machine is turned on, we are relying on that one pulse of negative voltage as we switch on a machine. Once the motor finishes accelerating to it’s top rpm, the voltage returns to normal and there is no other indication that the machine is running. Although this type of signal (called an impulse signal, or pulse for short) can be a useful input, I’d rather something that always denotes that the machine is running: a continuous signal.

Since the machine will always draw current when running, it is a good idea to use current as a way of detecting when a machine is switched on and running. So how can we detect when current is flowing through a wire? One way is to use a Hall sensor. Another way is to use a current sense transformer.

A current sense transformer is a very simple device: a coil of wire wrapped around the wire you want to detect the current flowing in. Don’t believe me? Wrap a coil of wire around a wire that’s carrying AC current and measure. This is caused by a concept known as Lens’s Law, and I’ll spare you the gritty details, just another wonder of electromagnetism.

Great! We have a way to detect current! Therefore we have our input signal right? No so fast. The current sense transformer, although has detected the current of our machine, does not carry a useful signal that can be inputted into our so called controller.

A current sense transformer is one of a few electrical devices that act as a current source that needs to be “converted” into a voltage by use of a resistor known as a ‘burden’ resistor. The value of this resistor can be easily calculated if you know three things: how many turns (or coils) your transformer has; the input voltage of the controller; and the Full Load Amperage (FLA) rating of your induction motor. Let’s say our transformer has 200 turns and therefore has a ratio of 200:1. Our controller will have an input voltage of 5 volts peak to peak, but the amplitude is half that. Let’s also suppose our motor has an FLA = 15 a. The calculation is:

 

Burden Resistor Equation

 

Since a 23.6 Ω resistor isn’t particularly standard, it’s okay to round down to the nearest standard resistor value for simplicity, in this case: 22 Ω.

Now we have a signal that might be useful. But if we take a closer look, we realize that our controller has an analogue input voltage from 0 – 5 volts. Right now, we will have a signal that has a peak to peak voltage of 5 volts, but has a zero bias. Therefore, our signal will be continuous from -2.5 v to +2.5 v with respect to ground. Since our controller doesn’t read voltages less than ground, the input signal will appear as a half-rectified wave. This might be workable in code, but it is not ideal. Hence, we need to introduce a bias, or DC offset if you prefer.

We know our controller operates at 5 volts DC. If we simply use 5 volts DC to bias our signal, we will run into the same, but opposite problem. If we can ideally bias our signal at 2.5 volts, then our signal will appear continuous from 0 to 5 volts. By using a simple voltage divider with two equal resistors, we can achieve such a bias. Two 10kΩ resistors will keep the current to a proper level. Since our current sense transformer could potentially push almost half a watt of peak power, we’ll play it safe and use 1-watt resistors (side note, I ordered 2-watt resistors for some reason, not sure why).

A capacitor is needed to isolate the ground from our signal, so a 10μF electrolytic capacitor should be sufficient.

Therefore, our circuit is designed and appears as such:

Schematic

Now we need to take this to the next level and build it in the real world.


 

Building the Circuit

Here’s the list of items we’ll need for each circuit:

  • 200:1 Current Sense Transformer
  • 10kΩ Resistor – 1 watt (x2)
  • 22Ω Resistor – 1 watt
  • 10 μF Electrolytic Capacitor
  • Triple Screw Terminal
  • Perforated Board
  • 22 AWG Solid Wire
  • 22 AWG stranded wire

In general, its easiest to solder components by the shortest height, to the largest height. When the perf board is upside down, it pins the components down while you solder the underside.

Start with soldering the two jumpers using solid wire like such:

Soldering two jumpers using solid wire

Then you can solder the three resistors:

Soldering three resistors

Now solder the triple screw terminal:

Soldering triple screw terminal

And then the capacitor:

Soldering the capacitor

Finally, the current sense transformer:

Soldering current sense transformer

Now we can attach one end of three stranded wires about 3” long from these points (they will go to the switch on the box):

Attaching one end of stranded wires to the switch on the box

Finally, we can create solder bridges to make the necessary paths. Note, this is vertically flipped from the last photo:

Creating soldering bridges

Now that we have our completed circuit, we can attach an electrical box to our machine using self-tapping screws (for convenience). I placed the box near the machine’s switch, on the side where the incoming power is. Before attaching the box, attach two larger cable glands for the incoming and outgoing power, and a smaller gland for the signal, 5 volt and ground wires for our circuit.

Now we pass just one live wire through the current sense transformer. Make sure this is the wire that the (conventional) current is flowing into our machine. The current sense transformer isn’t directional by itself, but our circuit is. Do not attach the circuit to the box, just leave it floating. The machine’s stiff cable will exert too much force on the components if the circuit isn’t able to move freely. We will wire the circuit to our controller in the future.

Drill or cut a hole in the lid of the box to fit our three position, two way switch. This is the switch that controls the three modes of dust collection behaviour. In the off position, the switch opens the circuit from the current sense transformer, so that when the machine turns on, no signal is passed to the controller. When in the ‘auto’ position, the signal is passed through to the controller to detect when a machine turns on. When in the ‘always on’ position, the 5-volt DC power is passed through to the controller, bypassing the voltage divider. The code can interpret this as wanting the dust collection for that machine to turn on, and remain on even if the machine is off. Wire the three stranded wires from the circuit to the switch as follows:

Wiring the switch

 

Blast Gate Motors

Before I launch into how we will open and close the blast gates, I would like the preface this section by explaining my particular blast gates, in which I made. I designed these blast gates keeping in mind that I will be adding a motor to automate them. Most blast gates operate in a linear motion, but it is far simpler and easier to have blast gates that rotate, since electric motors rotate as well. There are linear actuators, but they’re at least double the price of what I ended up paying. You can also have a mechanical cam attached to a motor to operate a linear blast gate too, but, again, it’s just simpler if the blast gate rotates. Click here for a set of free plans to make baltic birch blast gates to be used with Tower Pro MG996R servo motors.

I chose to use servo motors because of how easy they are to code. A servo motor is a simple arrangement of a DC motor, a potentiometer, and a small pulse width modulation (PWM) analog to digital (AD)/digital to analog (DA) converter. The potentiometer receives information regarding the desired angle that the DC motor should turn to. During the coding process, you simply send the motor a number that represents an angle, and the motor will turn to it. Since our blast gates rotate, this makes it very simple to open and close.

The one caveat when working with servos is their voltage. They’re typically used for remote control applications, which typically run at 6 volts (incidentally, 4 x 1.5 volt batteries). Our circuit and controller must run on 5 volts and no greater, otherwise the risk of damage to the controller is high. I tested running the servos on 5 volts but the results were sometimes intermittent, which is not good enough. So, the conclusion is that we need to supply 5 volts to our circuit and the controller, and 6 volts to our servo motors.

Make sure the motor is in the zero degree position when attaching it to the gate, while the gate being closed.

After attaching the motor to my blast gate, I also attach a smaller electrical box with a small cable gland and a terminal strip inside for connecting the servo and other power connections.

 

Controlling the Dust Collector

This is one of the simpler parts of the system because we only really need one component: a relay. A relay is a device that acts like a switch to turn on and off some device, by way of a voltage (instead of a physical interaction with the device, like a light switch). Since our controller operates at 5 volts DC, it would be ideal if we can operate the control voltage of the relay with this voltage.

There are 2ish… 3ish… 2.5 kinds of relays, if you will:

  • Electromechanical Relay
  • Electromechanical Contactor
  • Solid State Relay

An electromechanical relay uses a small electromagnet (coil) to physically open and close electrical contacts by applying a voltage to the electromagnet. These electrical contacts are relatively close together in physical space so that a significant amount of power is not required to operate the electromagnet. These are typically used for devices that draw a smaller current. If you try to control a device that draws too much current, then the current can actually arc across the contacts, resulting in the contacts literally welding themselves together.

All dust collectors (that I’ve seen anyways) use induction motors. The important fact to know about induction motors is that the current rating stamped on the motor plate is what’s called Full Load Amps (FLA) This is an RMS value (sort of like an average value for a sinusoidal wave) of the motor operating at it’s ideal, maximum load. However, when you start an induction motor, as it accelerates, the current draw at the beginning (called In-Rush Current) can be as high as 6 times the FLA rating of the motor. Since my motor has a current rating of 10 amps FLA, I would need an electro-mechanical relay rated for 60 amps, which is not feasible.

The next step up from an electromechanical relay, is an electromechanical contactor. These are, in essence, the same thing as a relay, the only difference is the size. Contactors are way larger, with a way larger gap between the contacts, which will prevent arc welding from occurring. The issue with contactors is the control voltage of the coil is typically no smaller than 120 volts AC. This is because the contacts are so large, that a large electromagnet is needed to operate it. Since we’re hoping to operate the control voltage with 5 volts DC, this will not work by itself.

One option here is to control a smaller electromechanical relay’s control voltage from our controller, which, in turn, controls the coil of a larger electromechanical contactor. This will work and is likely to be a less expensive option too. But at the same time, it is not the simplest nor the most robust option.

The simplest way to achieve our goal in simply turning on the dust collector directly from our controller, is to use a solid-state relay. Solid state relays tend to be a bit pricier, but they will outlast mechanical relays & contactors, they are quieter, and we can control a higher voltage, higher current device with the 5 volts DC that our controller uses. Make sure to use a solid state relay that is rated for use with an induction motor at the horsepower and current specifications.

Other specifications to note in regards to relays is whether the relay is ‘normally open’ (NO) or ‘normally closed’ (NC). We will use a normally open, which means that when no voltage is applied, the ‘switch’ is off, meaning our dust collector is off. Additionally, you can get relays with multiple ‘poles’ for when you want to control more than one circuit (or device). We simply want a single pole relay for a 120v machine. For a 240v machine on split phase (North American) power, you will need a two-pole relay. Here is the relay that I used:

To wire the relay to the dust collector, mount an electrical box near the dust collector switch (similarly to what we did for the sensing circuit above) with two large cable glands for the power cable in and out, and a smaller gland for the control voltage. We do not need to rid our dust collector of the existing switch (I mean, you can if you really want to), but the existing switch needs to remain turned on for the relay to complete the circuit and turn on the dust collector. Note: If your dust collector has an electromagnetic switch, the relay must be placed between the magnetic switch and the motor. If the dust collector has a simple mechanical switch, the relay can be wired either before or after the dust collector’s switch (in fact it’s a little easier to wire it in before the switch).

We will wire the relay to our controller in the future.

 

The Controller

What is this so-called ‘controller’ I keep mentioning? Well, I’m generically calling it a controller up until now, when I define it. A controller can be as simple as a small microcontroller (MCU), a computer (CPU), or a larger, intricate Programmable Logic Controller (PLC), or Remote Telemetry Unit (RTU). Our system may seem complicated, but it is actually quite simple and small. Therefore, the simplest option is usually the best, and that will be a microcontroller (MCU).

You may have heard of an Arduino before. Arduino is a company that sells an open-source board that contains a MCU plus some additional features that make using MCUs more convenient, and less of a project in it of themselves. The MEGA AT2560 features a host of inputs and outputs, including the analog inputs we need for our machine sensors, the PWM outputs to control our servo motor blast gates, and a plethora of more digital inputs and outputs, which we will only use a handful.

Not to go into the technicalities, an MCU contains a memory region that’s purpose is to contain the software code that is running under a continuous loop.

 

The Software

I will post the complete code below, but I want to briefly talk about the basic structure of it. Two disclaimers: The first is that I am not a good coder. I know how to do many things, but I’m not good at making it super proper, with proper formatting, following conventions, etc. The second is that my dust collection system is overly complicated already. Notably that I have two dust collectors, and I have these ‘double’ blast gates, that share a single motor for two openings that are not shared by the same machine. Both of these complications make my code more lengthy, and more cluttered. If you have one dust collector, and only use blast gates that are not shared by multiple tools, it should be much cleaner that mine.

I am fairly certain that the proper way to code this is to do it in the ‘Object-Oriented’ way. I cannot begin to explain what OOP (Object-Oriented Programming) is, but essentially, each blast gate motor is represented as an object in the class blastGate. Likewise, each dust collector is represented as an object in the class dustCollector, and each machine’s current sensing circuit is represented as an object in the class currentSensor.

I think each class should be kept in a separate file from the main loop, but I included it all in the same code. I use the Arduino servo library, as well as a library called EmonLib.h for the RMS current sensing calculation. In hindsight, I could’ve written this myself but it saved me a little time.

I could go back and clean up my code and make different versions for simpler systems, but honestly, I’m probably not going to do that.

Both the dust collector class and the blast gate class have similar fields, with a pin variable that represents the i/o pin of the object, and a status field that represents whether the object is on/off or open/closed for the dust collector and blast gate, respectively. The pin field for both the dust collector and blast gate classes is an input argument in the constructor.

 

The blast gate has an additional argument that represents the angle that the servo motor must turn to for it to open. The blast gate servo at it’s closed position should be at 0 degrees. This needs to be considered when physically attaching the servo motor to the blast gate.

The dust collector class has two methods called on() and off() that write HIGH and LOW to the dust collector relay pin respectively. This turns on and off the relay for controlling the dust collector.

The blast gate class has similar methods called openGate(int ang) and closeGate() which open and close a blast gate object. Note that openGate passes an argument for the angle (ang) that the blast gate needs to turn to properly open. The angle for closeGate() is always 0. Additionally, there is (unfortunately) a delay of 1 second anytime a servo motor is used. I have found that the inputs for the current sensing circuits generate some false readings whenever a servo rotates that causes the controller to think a machine has turned on. The quickest and easiest way to deal with this is to pause the program loop by using the delay function.

The currentSensor class is where the meat and bones of the operation occurs. There are actually two different constructors for this class. The first, which is much simpler, is used for a machine that uses just a single dust collector. The first argument is the analog input pin that the current sensor is wired to. The second argument is the blast gate object that the machine uses. The third argument is the angle that the blast gate needs to turn to (as a note here, if you don’t have double blast gates, this argument could have been in the blastGate constructor, or quite possibly not needed at all). The fourth argument is the dust collector object that the machine uses (not needed if there is only one dust collector).

The currentSensor class has another constructor which is used for when a machine uses two dust collectors. My table saw and router table uses a separate dust collector for underneath the cabinet, and above the table. The arguments are simply doubled for the second dust collector.

Similar to this class’s constructors, there are two methods for controlling the actions resulting from the current sensing inputs. The first method, checkCurrent(), is used for a machine that has one dust collector, and the second, checkCurrentDouble() is for a machine that uses two dust collectors. Both these methods are called in the main program loop and are constantly checking the current sensors for any change in data.

Both methods look for a change in rms AC voltage or a change in DC bias. When the switch on a current sense circuit is in Auto mode, the rms AC voltage will immediately increase when a machine turns on. When the ‘always on’ switch is selected on a current sensing circuit, the DC bias voltage will increase from 2.5 vdc, to 5 vdc. When either of these changes occur, the method has detected that a machine has turned on or otherwise requiring the dust collection for that machine to run.

Using currentMillis, plus the delays that were defined at the top of the code, the method then waits for a certain amount of time to pass before first opening the blast gate, using the openGate method. Then after another defined length of time, the relay for the dust collector will turn on. The checkCurrentDouble method has additional delays for opening the second blast gate and turning on the second dust collector. I defined all these delays as 500 ms, and I haven’t changed it since.

 

When a machine is already detected as being on, and the controller senses that the machine has turned off, the exact opposite chain of events occur, but the delays are different. The delay for the dust collector(s) to turn off is 30 seconds, and 15 seconds later, the blast gates close. This allows time for me to potentially turn the machine back on without the dust collector cycling off/on again. 30 seconds seems fine for now, but I might want to lengthen this time to prevent stress to the dust collector motor.

That concludes the three classes for the blast gates, dust collectors and current sensors.

Beneath the classes in the code, there is space for instantiating each instance of an object. Each blast gate has exactly one instance. This is notable because I have double blast gates, whereby a current sensor object must share a blast gate object with another current sensor object. Do not instantiate more than one instance of a double blast gate.

For the machines that I have that use two dust collectors (the table saw and router table), a currentSensorDouble() object is instantiated for when I want both dust collectors to operate, and a currentSensor() object is instantiated for when I want just the cabinet dust collector to operate, without the overhead dust collection. An additional switch is used at the machine that is wired to a digital pin for the selection of this mode.

The setup() section runs the setup() method for each instance of an object. This is mostly just attaching the object to the correct GPIO pin and, in the case of the blast gates, make’s sure they’re in the closed (angle = 0) position.

The main loop consists of two sections. The first ‘section’ loops through each current sense object while all machines are off, looking for any machine to change state when it turns on. The next ‘section’ loops through the same machine while that particular machine is running. This prevents any other machine from trying to turn off the dust collector while the desired machine is running. There might have been a cleverer way of writing the code to prevent this from happening, but I couldn’t figure it out. The inadvertent effect this causes is that two machines cannot have dust collection at the same time. No big deal for me as I am a single person using my machines, one at a time. Also, the main loop could have been a little more elegant in hindsight, if I had put the current sense objects into an array and simply looped through the array. ¯\_(ツ)_/¯

 



#include "EmonLib.h"
#include 

bool globalState = false;

int gate1DelayOn = 500;
int gate1DelayOff = 15000;
int gate2DelayOn = 500;
int gate2DelayOff = 500;
int dc1DelayOn = 500;
int dc1DelayOff = 30000;
int dc2DelayOn = 5000;
int dc2DelayOff = 500;

class blastGate {
  
  int pin;
  int ang;
  Servo ser;  
  
  public:
  bool state = false;
  
    blastGate(int pin) {
      this->pin = pin;
    }

    void setup() {
      pinMode(pin, OUTPUT);
      ser.attach(pin);
      ser.write(0);
      delay(500);
    }
  
    void openGate(int ang) {
      this->ang = ang;
      if(state == false) {
        Serial.println("Blast Gate Open");
        ser.write(ang);
        state = true;
        delay(1000);
      }
    }
  
    void closeGate() {
      if(state == true) {
        Serial.println("Blast Gate closed");
        ser.write(0);
        state = false;
        delay(1000);
      }
    }
  
};

class dustCollector {
    
  int pin;
    
  public:
    bool state = false;
  
    dustCollector(int pin) {
      this->pin = pin;
    }

    void setup() {
      pinMode(pin, OUTPUT);
    }
    
    void on() {
      if (state == false) {
        Serial.println("Dust Collector On");
        digitalWrite(pin, HIGH);
        state = true;
      }
    }
  
    void off() {
      if(state == true) {
        Serial.println("Dust Collector Off");
        digitalWrite(pin, LOW);
        state = false;
      }
    }
};


class currentSensor {
  
  EnergyMonitor sen;
  blastGate &gate1;
  blastGate &gate2;
  dustCollector &dc1;
  dustCollector &dc2;
  
  bool previousState = false;
  int pin, angle1, angle2;
  unsigned long previousMillis; 
    
  public:

    bool state = false;
    bool shtDwnState = false;

    // CONSTRUCTOR FOR SINGLE DUST COLLECTOR MACHINE
    
    currentSensor(int pin, blastGate &attachToGate1, int angle1, dustCollector &attachToDC1) :
      gate1(attachToGate1),
      dc1(attachToDC1)
    {
      this->pin = pin;
      this->angle1 = angle1;
    }

    // CONSTRUCTOR FOR DOUBLE DUST COLLECTOR MACHINE

    currentSensor(int pin, blastGate &attachToGate1, int angle1, dustCollector &attachToDC1, blastGate &attachToGate2, int angle2, dustCollector &attachToDC2) :
      gate1(attachToGate1),
      gate2(attachToGate2),
      dc1(attachToDC1),
      dc2(attachToDC2)
      {
        this->pin = pin;
        this->angle1 = angle1;
        this->angle2 = angle2;
      }

    void setup() {
      sen.current(pin, 90.9);  // Current: input pin, calibration
    }

    // METHOD FOR SINGLE DUST COLLECTOR MACHINE
  
    void checkCurrent() {
      
      double Irms = sen.calcIrms(1480);  // Calculate Irms only
      double Vdc = analogRead(pin);
      unsigned long currentMillis = millis();
      
      if (Irms >20 | Vdc > 950) {
        state = true;
        globalState = true;
        if (state != previousState) {
          Serial.println("Machine On");
          previousMillis = currentMillis;
          previousState = state;
        }
        else if ((currentMillis - previousMillis >= gate1DelayOn) && (gate1.state == false)) {
          gate1.openGate(angle1);
          previousMillis = currentMillis;
        }
        else if ((currentMillis - previousMillis >= dc1DelayOn) && (gate1.state == true)) {
          dc1.on();
          previousMillis = currentMillis;
        }
      }
  
      if ((Irms < 10 && Vdc < 700) && (gate1.state == true)) {
        state = false;
        if (state != previousState) {
          Serial.println("Machine Off");
          shtDwnState = true;
          previousMillis = currentMillis;
          previousState = state;
        }
        else if ((currentMillis - previousMillis >= dc1DelayOff) && (dc1.state == true)) {
          dc1.off();
          previousMillis = currentMillis;
        }
        else if ((currentMillis - previousMillis >= gate1DelayOff) && (dc1.state == false)) {
          gate1.closeGate();
          globalState = false;
          shtDwnState = false;
          previousMillis = currentMillis;
        }
      }

      Serial.print(Vdc);           // DC offset
      Serial.print(" ");
      Serial.print(Irms);             // Irms
      Serial.print("    ");
    }

    // METHOD FOR DOUBLE DUST COLLECTOR MACHINE

    void checkCurrentDouble() {
      
      double Irms = sen.calcIrms(1480);  // Calculate Irms only
      double Vdc = analogRead(pin);
      unsigned long currentMillis = millis();

      if (Irms > 20 | Vdc > 950) {
        state = true;
        globalState = true;
        if (state != previousState) {
          Serial.println("Machine On");
          previousMillis = currentMillis;
          previousState = state;
        }
        else if ((currentMillis - previousMillis >= gate1DelayOn) && (gate1.state == false)) {
          gate1.openGate(angle1);
          previousMillis = currentMillis;
        }
        else if ((currentMillis - previousMillis >= gate2DelayOn) && (gate2.state == false)) {
          gate2.openGate(angle2);
          previousMillis = currentMillis;
        }
        else if ((currentMillis - previousMillis >= dc1DelayOn) && (gate1.state == true) && (dc1.state == false)) {
          dc1.on();
          previousMillis = currentMillis;
        }
        else if ((currentMillis - previousMillis >= dc2DelayOn) && (gate2.state == true) && (dc2.state == false)) {
          dc2.on();
          previousMillis = currentMillis;
        }
      }
  
      if ((Irms < 10 && Vdc < 700) && (gate2.state == true)) {
        state = false;
        
        if (state != previousState) {
          Serial.println("Machine Off");
          shtDwnState = true;
          previousMillis = currentMillis;
          previousState = state;
        }
        else if ((currentMillis - previousMillis >= dc1DelayOff) && (dc1.state == true)) {
          dc1.off();
          previousMillis = currentMillis;
        }
        else if ((currentMillis - previousMillis >= dc2DelayOff) && (dc1.state == false) && (dc2.state == true)) {
          dc2.off();
          previousMillis = currentMillis;
        }
        else if ((currentMillis - previousMillis >= gate1DelayOff) && (dc2.state == false) && (gate1.state == true)) {
          gate1.closeGate();
          previousMillis = currentMillis;
        }
        else if ((currentMillis - previousMillis >= gate2DelayOff) && (gate1.state == false) && (dc2.state == false) && (gate2.state == true)) {
          gate2.closeGate();
          globalState = false;
          shtDwnState = false;
          previousMillis = currentMillis;
        }
      }

      Serial.print(Vdc);           // DC offset
      Serial.print(" ");
      Serial.print(Irms);             // Irms
      Serial.print("    ");
    }
};

// instantiate dust collector, blast gate, and sensor objects

dustCollector DC1(47);
dustCollector TTL(46);

blastGate rtrOH(2);
blastGate jntr(3);
blastGate tsplnr(4);
blastGate bsdp(5);
blastGate sand(6);
blastGate tsOH(7);
blastGate rtr(8);

currentSensor rtrCS(8, rtr, 90, DC1, rtrOH, 90, TTL);
currentSensor rtrCS2(8, rtr, 90, DC1);
currentSensor tsCS(3, tsplnr, 80, DC1, tsOH, 80, TTL);
currentSensor tsCS2(3, tsplnr, 80, DC1);
currentSensor plnrCS(4, tsplnr, 180, DC1);
currentSensor sandCS(5, sand, 90, TTL);
currentSensor dpCS(6, bsdp, 180, TTL);
currentSensor bsCS(7, bsdp, 80, TTL);


//char input;

void setup()
{
  delay(1000);
  Serial.begin(9600);
  
  rtrOH.setup();
  jntr.setup();
  tsplnr.setup();
  bsdp.setup();
  sand.setup();
  tsOH.setup();
  rtr.setup();
  
  DC1.setup();
  TTL.setup();
  
  rtrCS.setup();
  rtrCS2.setup();
  tsCS.setup();
  tsCS2.setup();
  plnrCS.setup();
  sandCS.setup();
  dpCS.setup();
  bsCS.setup();
  
}

void loop()
{
  // if no machines are turned on, check current sensor on all machines:
  if (digitalRead(44) == HIGH && globalState == false) rtrCS.checkCurrentDouble();
  if (digitalRead(44) == LOW && globalState == false) rtrCS2.checkCurrent();
  if (digitalRead(45) == HIGH && globalState == false) tsCS.checkCurrentDouble();
  if (digitalRead(45) == LOW && globalState == false) tsCS2.checkCurrent();
  if (globalState == false) plnrCS.checkCurrent();
  if (globalState == false) sandCS.checkCurrent();
  if (globalState == false) dpCS.checkCurrent();
  if (globalState == false) bsCS.checkCurrent();
  
  // else if any one machine is turned on, check current sensor of that machine only:
  else if (rtrCS.state == true || rtrCS.shtDwnState == true) rtrCS.checkCurrentDouble();
  else if (rtrCS2.state == true || rtrCS2.shtDwnState == true) rtrCS2.checkCurrent();
  else if (tsCS.state == true || tsCS.shtDwnState == true) tsCS.checkCurrentDouble();
  else if (tsCS2.state == true || tsCS2.shtDwnState == true) tsCS2.checkCurrent();
  else if (plnrCS.state == true || plnrCS.shtDwnState == true) plnrCS.checkCurrent();
  else if (sandCS.state == true || sandCS.shtDwnState == true) sandCS.checkCurrent();
  else if (dpCS.state == true || dpCS.shtDwnState == true) dpCS.checkCurrent();
  else if (bsCS.state == true || bsCS.shtDwnState == true) bsCS.checkCurrent();
  
  Serial.println(" ");

}

 

The Wiring

Mount small electrical boxes with terminal strips on each blast gate. You’ll need at least one small wire gland on each box for the various power and signal cables coming into each. I also mounted a two more of these in specific places in my shop specifically to route the 5-volt power to the machine’s current sense circuits.

For the power and ground wires, I used about 400 feet of 18-gauge stranded wire. For the signal wire, I used about 200 feet of 22-gauge stranded wire. When using stranded wire on a screw-clamp terminal strip, a ferrule is required for a more secure connection. I also purchased a shield for my Arduino that converts the DuPont connectors to screw terminals.

Start with running black 18 AWG ground wire to every machine’s sensor, every blast gate’s servo motor, and the dust collector relay. Then run the 6-volt power to the servo motors, and then the 5-volt power to the current sense circuits. Then run the signal wire to the servos, the current sense circuits, and the relays.

 

Links Below ↓

Back to Shop Projects