Introduction: Automated Wireless Dust Collector
I work in a theater scene shop and I thought it would be a fun challenge to automate out dust collection system for our power tools. We have a large dust collector in the corner of the shop with ducting reaching to several tools, including a miter saw, band saw, panel saw, and belt sander. Before, we had a remote that came with the dust collector that remotely power it on when we wanted to use any of the tools. My project automated this so whenever a tool was powered on, the dust collector would power on automatically. This was done by monitoring the current of the tools. Whenever the current transformer detected current, it would send out the wireless signal to power on the dust collector and start a countdown timer. This timer was installed because the motor on the dust collector doesn't like to turn on and off repeatedly. It is happier, and will therefore last longer, if it stays powered on or off, and this timer lets the carpenter take their time with measuring the next cut without having to worry about the dust collector powering off. The timer is displayed on the lid of the enclosure with a 7-segment display. The duration of the timer can be changed by hand by opening the lid, pressing a tactile button on the board and rotating the multi-turn potentiometer. If a tool is powered on while the vacuum is on the timer will start over to its original time.
Step 1: Hardware
These are the parts included in the project
1 @ Arduino Uno
1 @ Current Transformer (Current monitor)
1 @ Multi-turn potentiometer
1 @ 315 MHz Transmitter (or whatever frequency your system is operating on)
1 @ 7 segment display
33 ohm resistor or whatever gets you there and 2 10k resistors
1 @ capacitor
1 @ dust resistant box
1 @ 120v AC to 12v DC power supply
In order for the Arduino to interpret the current transformer, you need to add some supporting circuitry. I've included the image I used for reference. The resistor between the leads is specifically 33 ohms and the others are 10k ohms.
I've included an image I used to create the antenna for the transmitter. Antennas are very particular and temperamental but this style seems to work for this frequency and my setup. I placed the Arduino strategically to put the antenna in the corner closest to the dust collector to give myself a fighting chance.
For the 7 segment display, I sanded a bit of plexiglass to give a more diffused display and act as a protective shield for the hole in the box. I used standoffs to attach the 7 segment and plexiglass together, and hot glued the plexiglass to the lid to prevent dust ingress. I included a divider between the lower voltage and high voltage areas simply because it seemed like the thing to do.
Step 2: Software
To handle the Current Transformer I used the Emon library from OpenEnergyMonirto.org. This did the heavy lifting, letting me use one command to get a nice number to use. It is really easy to use and comes with excellent examples. I used the SevenSegmentTM1637 and SevenSegmentExtended libraries to handle the 7 segment display.
The extremely long arrays are the binary signal the original remote used to communicate on or off with the dust collector. My friend Chris captured the signal using Processes, the precursor to Arduino. By monitoring the antenna pin on the microcontroller on the original remote he captured the PWM of the signal and using excel we determined the order of 1s and 0s based on how long the pin was on or off. This array was my best solution for carrying this binary sequence and allow for timed iteration when I want a signal sent. Whenever the current monitor reads a high enough value, it iterates through the array, delaying 390 microseconds between each to simulate the original remote's timing. Each time I want to power on or off the dust collector I send two signals to ensure it is received.
//0nLibrary examples openenergymonitor.org, Licence GNU GPL V3/* SevenSegmentTM1637 and SevennSegmentExtended Created 25 September 2015 By Bram Harmsen https://github.com/bremme/arduino-tm1637 #include "SevenSegmentTM1637.h" #include "SevenSegmentExtended.h" #include "EmonLib.h" // Include Emon Library EnergyMonitor emon1; // Create an instance</p><p>int ant = 2; int butt = 3; int pot = A1; int del = 389; /* Binary signal for the On signal */ int ONsig[164] = {1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1}; /* Binary signal for the Off signal */ int OFFsig[164] = {1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1}; bool toolstate = false; bool vacState = false; double Irms = 0; const byte PIN_CLK = 8; const byte PIN_DIO = 9; SevenSegmentExtended display(PIN_CLK, PIN_DIO); /* minutes and seconds are for storing the time given by the pot tempMin and tempSec are for displaying the time and controlling the delay to send off signal */ int rawTime = 0; int minutes = 0; int seconds = 0; int tempMin = 0; int tempSec = 0; long lastTime = millis(); /* controls how long a second is */ void setup() { pinMode(ant, OUTPUT); pinMode(butt, INPUT); Serial.begin(9600); emon1.current(A0, 111.1); /* Current: input pin, calibration.*/ display.begin(); display.setBacklight(100); readPot(); /* store the time given by the pot */ delay(5000); /*pauses the Arduino so it doesn't trigger sendONSig when the powersuply pulls current to power on */ } //-----------------------loop-----------------------------------------------------// void loop() { /* read Current detector level */ Irms = emon1.calcIrms(1480); // Calculate Irms only /*only send the On signal if current is detected and the tool is not on then turn on vacuum state and tool state */ if (Irms > 10 && !toolstate) { sendONSig(); delay(1000); /* Delay and send again to ensure it is recieved */ sendONSig(); vacState = true; toolstate = true; readPot(); /* this is here to restart the timer whenever the tool is powered on */ } /* tool is off so record its state */ if (Irms < 6) { toolstate = false; } /* adjust the count down delay by pressing the button and rotating the pot */ if (digitalRead(butt) == HIGH && !vacState) { readPot(); } /* run the timer if the vacuum is on */ if (vacState) startTimer(); /* if the vacuum is off display the maximum delay */ if (!vacState) { display.printTime(minutes, seconds, false); } } //----------------------SendONSig-------------------------------// /* Send the Binary ON signal to the antenna and turn the antenna low to prevent jamming the original remote's signal */ void sendONSig() { for (int i = 0; i <= sizeof(ONsig); i++) { digitalWrite(ant, ONsig[i]); delayMicroseconds(del); } digitalWrite(ant, LOW); } //----------------------SendOFFSig-----------------------------// /* Send the Binary OFF signal to the antenna and turn the antenna low to prevent jamming the orignal remote's signal */ void sendOFFSig() { for (int i = 0; i <= sizeof(OFFsig); i++) { digitalWrite(ant, OFFsig[i]); delayMicroseconds(del); } digitalWrite(ant, LOW); } //---------------------startTimer------------------------------// /* Run the logic to count down in seconds. The elapsed time from lastTime and millis() is not 1000 because the Emon library's comand takes quite a bit of time */ void startTimer() { if (millis() - lastTime >= 775) { display.printTime(tempMin, tempSec, false); lastTime = millis(); /* if the timer reaches 0 send the OFF signal twice to ensure it is recieved */ if (tempMin == 0 && tempSec == 0) { sendOFFSig(); delay(1000); sendOFFSig(); vacState = false; return; } if (tempSec == 0) { tempSec = 60; tempMin --; } tempSec --; } } //---------------------------------readPot-------------------------------------// /* Read the pot level and convert that to 0 to 5 minute range. Convert the raw position to minutes and seconds */ void readPot() { rawTime = map(analogRead(pot), 0, 1023, 0, 300); minutes = rawTime / 60; tempMin = minutes; seconds = rawTime % 60; tempSec = seconds; }
Attachments
Step 3: Final Product!
It works great! Every time a saw is powered on the dust collector turns on right after and stays on for the expected time and turns off once the counter reaches 0. A bug I wasn't predicting was when the power supply and the Arduino were powered on when the tool power switch was flipped it sent the on signal to the dust collector. This happens because the power supply pulls enough current long enough that the Arduino has time to turn on and check the current and detect a spike, sending the on signal but not starting the counter for some reason. I fixed this by having the Arduino pause for 5 seconds on boot up so the power supply can get situated and return to normal levels. Other than that the construction and testing went pretty smoothly.