I have done several pen and laser machines lately, so I decided to create a custom PCB for Grbl_ESP32 for these types of machines. This is a small (70mm x 60mm) PCB with all the features a pen plotter or laser cutter/engraver would need.
These typically use stepper motors for the X and Y axes. On pen plotters, the Z axis is controlled by a servo or solenoid. On lasers you need an accurate PWM for laser power control.
Here are the features of the PCB assembly
(2) Stepper Motor Driver Sockets for standard stepper driver modules.
(1) Hobby Servo Connector.
(1) High Current (10A max) Output Control. This can be used for a solenoid, fans, etc.
(2) limit/Home Switch Connectors.
Laser Power PWM connector
Removable Micro SD card. Upload files via Wifi to reliably run off-line.
5V 3A Step Down Power Supply
Standard DC Barrel Connector for power input. (9-28 VDC)
Power Output Connection for laser module.
Grbl_ESP32 Advanced Features
32-Bit dual core processor
Fast 120kHz step rates
WiFi
Access point or station modes
Complete web user interface
Telnet
Bluetooth Serial
Compatible with phone apps
Compatible with most serial port gcode senders
16 bit laser power control.
Core XY kinematics supported for T style machines.
RTOS (real time operating system) allows the use of custom tasks.
Precise servo control accurately mapped to Z motion, plus interactive calibration.
Precise control of solenoids via adjustable pull and hold strengths using PWM. This allows a strong pull, yet a cool hold temperature.
Instant On/Off – Unlike a Raspberry Pi, there is no long boot time or formal shutdown required. It is typically ready to go in a few seconds.
How to control it
There are several ways to connect to the controller, but to run jobs, you basically either stream the gcode or run it from a file on the SD card. The SD card is a great feature because it is free from connectivity interruptions and you don’t need to stay connected to your machine while it is running the job. You can quickly upload files via WiFi or remove it and plug it into your computer.
Serial port
This controller is compatible with virtually all of the serial port gcode senders for Grbl. The default baud rate is 115200.
Bluetooth Serial
This is a great way to use your phone to control a machine. When you connect via bluetooth, your phone or computer will create a virtual serial port. This means you can then use existing serial port based gcode senders.
Wifi – WebUI
The controller has a web server. The controller can create its own WiFi access point or connect to an existing WiFi network. You connect to the controller with a web browser and it serves a full featured machine controller to browser.
Controlling the Pen Up/Down Servo
The servo is controlled using a separate RTOS task on the controller. Grbl thinks it is running a normal stepper motor on the Z axis. Each time the servo task runs, it looks at the current position of the Z. It then computes and sets a position for the servo. You map the servo’s range to a Z range. For example the range could be set for 0-5mm. Any values of Z above or below this range would would be limited by the range, so any Z value above 5mm in this example would not move the servo past where it was at 5mm.
You can calibrate the end points of the servo to fine tune it. We use the Z axis resolution and max travel settings to do this. $102=100 (100%) would be no change to the first end point. %102=90 or $120=110 would be 10% changes in either direction. $132 works the same way for the other end point. Make sure you do not adjust the servo so it hits the physical end point of its travel. You will feel the servo continuously vibrating as it pushes against the end point. This is very hard on a servo and will overheat and damage it.
The servo updates its position 20 times per second. Therefore it will do a good job of respecting the acceleration and speed settings in the gcode.
The feature also uses the $1 (Step idle delay) setting. It the steppers motors disable, so will the servo and can be moved manually.
Additional parts you need
The controller uses plug in modules for the the ESP32 controller and the stepper motor drivers.
ESP32 Controller
The ESP32 controller needs to be a ESP32 Dev Module. It should have 2 rows of 19 pins. The rows should be spaced 0.9 inch (22.86mm) apart. Be careful: Some similar controllers have a wider pitch.
Stepper Motor Drivers
The drivers are the standard StepStick (Pololu) style footprint. The (3) microstepping selection pins (MS1, MS2, MS3) are all connected to logic high. This typically results in the highest resolution (1/16 or 1/32). The Grbl_ESP32 step rates are high enough to make that not an issue. I typically use TI DRV 8825 or Allego A4988 modules, but others can be used as long as the pins are compatible. The PCB silkscreen has the corner pins labeled. Use them to insure you correctly install your driver modules.
Source Files (coming soon)
A completely assembled PCB is available on Tindie. The profits from Tindie help me to continue to develop the hardware and firmware for projects like this. If you want to roll your own, the source files are linked below.
I have been working on some games for the ESP32 and needed some decent quality audio with a minimum number of additional components. I was bouncing between using the DAC and using the I2S bus. The DAC requires less external parts, so I went that way. I ended up creating a very simple library for use in he Arduino IDE. (Note: This only works with ESP32)
DACs
The ESP32 has (2) internal 8 bit DACs. DACs are Digital to Analog Converters. You give them an 8 bit value and they output an analog voltage. The voltage range of the 0-255 8-bit value is roughly Gnd to 3.3V on the ESP32. If you digitize an audio file, you can then play it back through the DAC. The DAC can’t directly drive a basic speaker, but you can connect it to an amplifier or amplified external speakers. The 8-bit quality is not great, but more than good enough for simple games.
The sound data comes from wave (.wav) files. This uses the 8 bit, unsigned, uncompressed format. Wave files can be saved with any sampling rate you want. To get a decent sound you need to sample the analog files at thousands of times per second. I have found that 4000 Hz is about the minimum for anything musical or spoken. 8000 sounds pretty good for most stuff. For reference, CDs are sampled a 44100 Hz (also 16-bit not 8-bit). This means there is a lot of data even for short duration audio. The typical ESP32 board has 2 to 4MB. At an 8000Hz sampling rate that gives you 125 seconds per MB. That is plenty for what I am working on, so I decided to store the data on the ESP32. If that is not good enough, you could use an SD card.
Here is a reference of the wave format. Only a few of the values are used.
Byte
Length
Description
0
4
Always "RIFF"
4
4
File size in Bytes
8
4
Always "WAVE"
12
4
Always "fmt " with a null
16
4
Length of format
20
2
Audio format (1=PCM)
22
2
Number of channels
24
4
Sample rate
28
4
Byte Rate
32
2
Block Align
34
2
Bits per sample (8,16)
36
4
Alaways "data"
40
4
File size
44
...
Start of data
References
I found some good references to help me with this library.
IoT Sharing: This was a great reference for understanding the basics, but it uses an SD card to save the data.
Xtronical: This was very helpful and my code is very close to this.
I started with the Xtronical XT_DAC_Audio library, but found it got be very unstable when I added it to my game. It often crashed when seemingly unrelated code was added. I think the problem was due to trying to use floating point math in the interrupt. As soon as I took that out, it got very stable. They make reference to the issue in the code and suggest it could get fixed via compiler updates.
How it works
The wave data is stored in large char arrays. An interrupt reads the data and feeds that to the DAC. Using an interrupt allows the audio to play “in the background” while the game is running. The Xtronical library uses a fixed interrupt rate of 50kHz. It does some floating math in the interrupt to adjust to the actual sample rate of the wav file. I decided to change the interrupt rate to the actual sample rate of the wav data.
Here is a snippet of what wave data array looks like.
The sample rate is stored in the header of the wav data. When you play the file, it sets the interrupt rate to match the sample rate, so no math is required. You can use a mix of sample rates in the waves you use. It will adjust as needed before it is played back. It allows 2000Hz to 50000Hz sample rates. If you try to go outside that range it will use 2000 Hz. You will easily know there is a problem if you hear that.
Game Related Features
I added some features that might be needed when using with a game.
Check to see if the audio player is currently playing anything.
Interrupt The Current Wave – If something happens like an explosion you need to immediately switch to that sound. This is an option when you send a command to play a wave.
Change the Frequency – I had some sounds that needed to change based on game speed. There is an option speed up r slow down the play back speed by a multiplier to give.
Install the library using the Sketch…Include Library…Add .ZIP Library menus.
It will also add an example. Open that using the File…Examples…Game_Audio menus.
Create a character array of the wav data. See this video from XTronical for how to do that.
Give the XTronical video a thumbs up and a nice comment 🙂
Create a Game_Audio_Class object. The first parameter is the DAC pin number you want to use. It should be 25, 26. The second parameter is the timer number to use. Example: Game_Audio_Class GameAudio(25,0);
Create a Game_Audio_Wav_Class object. The only parameter is name of the char array of you wave data. Example: Game_Audio_Wav_Class pmDeath(pacmanDeath);
Here is the demo that installs with the library
#include "SoundData.h";
#include "Game_Audio.h";
Game_Audio_Class GameAudio(25,0);
Game_Audio_Wav_Class pmDeath(pacmanDeath); // pacman dyingsound
Game_Audio_Wav_Class pmWav(pacman); // pacman theme
void setup() {
Serial.begin(115200);
Serial.println("Begin...");
}
void loop() {
// ------------- Play 2 wavs one after the other ----------------
Serial.print("Pacman Theme Sample Rate (Hz):");
Serial.println(pmWav.getSampleRate());
Serial.print("Duration (secs):");
Serial.println(pmWav.getDuration());
GameAudio.PlayWav(&pmWav, false, 1.0);
// wait until done
while(GameAudio.IsPlaying()){
}
delay(200);
GameAudio.PlayWav(&pmDeath, false, 1.0);
// wait until done
while(GameAudio.IsPlaying())
{
}
// -------- Play a wav then interrupt it after 600ms ------------
GameAudio.PlayWav(&pmWav, false, 1.0);
delay(600); // this is less than the duration of the last wav
// this wav will not play because the other is playing and interruptCurrent is false
GameAudio.PlayWav(&pmWav, false, 1.0);
// this will interrupt the playing file
GameAudio.PlayWav(&pmDeath, true, 1.0);
// --------- Play a wav with increacing sample rate (speeds up playback)
for (int i=0; i<10; i += 2)
{
while(GameAudio.IsPlaying()){// wait for wav to complete
}
GameAudio.PlayWav(&pmWav, false, (1.0) + (float)i / 10.0);
}
while (true) { // stop here program is done...but anything still playing will complete
}
}
Video
Next Steps
I’ll am working on some games, so new features might be added.
I’ll probably add the option to use I2S audio rather than the DAC.
I might add the option to pull files from an SD card.
If you want to be notified of future blog posts, please subscribe.
In a previous post I showed how to use the HC-06 Bluetooth module. In this post we will be using the HC-05. They are very similar, but the HC-05 has more features. The ability to be a master is the main feature. A master can create a connection with other Bluetooth devices. In this post we will only being using it as a slave.
The basic module looks like this.
It is typically purchased soldered to carrier PCB with some additional electronics. The HC-05 typically has a 6 pin header, rather than the 4 pin HC-06 header. The two extra pins are state and enable (en). State gives the state of the Bluetooth connection and enable can power down the module by turning off the power regulator. I will not be using the enable. I will use the state to allow programming of the Arduino via Bluetooth.
Here is a schematic of the carrier board. Not all carrier boards are the same, though.
The parts on the carrier PCB are pretty basic
3.3V Low Dropout Regulator, which allows you to power it from 3.6V to 6V.
An LED to show the mode.
Fast Blink = Waiting for Bluetooth connection3.6
Slow Blink = In AT command mode
Double Blink = Connected via Bluetooth
A button to enter AT Command Mode
A diode, probably for reverse voltage protection.
Various Pull Up/Down resistors and bypass capacitors.
Configuring the HC-05
Like the HC-06, the HC-05 has a AT command mode, but the commands are a little different. The HC-05 is put in the AT command mode by holding in the switch while applying power. It will do a slow blink when in AT mode. AT Mode accepts commands at 38400 baud , N,8,1 using the Rx and Tx pins. You should level shift the Tx out of your Arduino to 3.3V using a resistor divider. Commands are sent with line feed and carriage return appended to the end. Most serial monitors can do this for you including the Arduino Serial Monitor.
Any command that sets a parameter can also get it.
Set commands are in this format “AT+CMD=PARAM” like … AT+NAME=FRED to set the name to FRED. Some commands have multiple parameters that are separated by commas.
Get commands are in this format AT+CMD?” like AT+PSWD? to get the password. Weirdly, they all seem to work except AT+NAME?.
Here are the commands you needs for slave mode. Remember, each is followed by a line feed and carriage return.
AT (This is just a way to test the connection. It will respond “OK”)
AT+VERSION? (This returns firmware version info)
AT+ROLE=x (for x use 0 =Slave role, 1 = Master role, 2 = Slave-Loop role default = 0)
AT+NAME=xxxxx (to change name to xxxxx default=HC-05″)
AT+POLAR=a,b (a=PIO8 (LED), b=PIO9 for both 0=low turn on, 1 = high turn on. (see below for how we use this)
AT+ORGL (reset all parameters to defaults)
AT+RESET (restarts the HC-05. Will not be in AT mode afterward unless button held”)
Using an Arduino to program the HC-05
We need some hardware to talk to the HC-05. An Arduino will easily do that. Here is a diagram and sketch to do this using an Arduino UNO.
This is the hardware diagram. I show an UNO, but virtually any hardware (Nano, Mega, etc) will work. The HC-05 is a 3.3V device so we need to level shift the Arduino 5V Tx signal down to 3.3V. The diagram uses a resistor divider to do this. The Arduino should have no trouble reading the 3.3V Tx signal from the HC-05, so we don’t need to shift that.
The State connection through the capacitor is optional. This will force a reboot of the Arduino when a Bluetooth connection is made. More on that later.
BTW: A lot of people don’t bother to level shift and it appears to work fine, at least in the short term 🙂
The Arduino Sketch
Here is the sketch I use. We will be setting up 2 serial links. One link will be from the PC to the Arduino to send the commands from the keyboard over USB. We also need a serial connection from the Arduino the HC-05. We will use a software serial port for this and can use any remaining pins to do this. HC-05 uses 38400 baud for AT commands, regardless of the what you set it to for Bluetooth operation. I used 115200 for the PC to Arduino connection. Set the Serial monitor like this.
You can then type AT commands in the Sereial Monitor.
Here is the sketch…
#include <SoftwareSerial.h>
#define SOFT_RX 11
#define SOFT_TX 12
SoftwareSerial hcSerial(SOFT_RX, SOFT_TX); // RX, TX
String fromPC = "";
void setup() {
Serial.begin(115200); // hardware serial for the USB-PC
hcSerial.begin(38400); // software serial Arduino to HC-06 (38400 is default)
// print instructions
Serial.println("HC-05 AT Command Programmer V1.2");
Serial.print("For Arduino Rx use pin ");
Serial.println(SOFT_RX);
Serial.print("For Arduino Tx use pin ");
Serial.println(SOFT_TX);
Serial.println(" -- Command Reference ---");
Serial.println("To Read use '?', Like AT+PSWD?");
Serial.println("AT (simply checks connection)");
Serial.println("AT+VERSION (requests the firmware verison)");
Serial.println("AT+ROLE=x (0 =Slave role, 1 = Master role, 2 = Slave-Loop role default = 0)");
Serial.println("AT+NAME=xxxxx (to change name to xxxxx default=HC-05");
Serial.println("AT+PSWD=nnnn (to change password to 4 digit nnnn default = 1234");
Serial.println("AT+UART=nnnn,s,p (nnnn=Baud, s=stop bits (0=1, 1=2), p=parity (0=None, 1=Odd, 2=Even)");
Serial.println("AT+POLAR=a,b (a=PIO8 (LED), b=PIO9 for both 0=low turn on, 1 = high turn on.");
Serial.println("AT+ORGL (reset all parameters to defaults)");
Serial.println("AT+RESET (restarts the HC-05. Will not be in AT mode afterward unless button held");
}
void loop() {
// Read from HC-05
if (hcSerial.available()) {
while(hcSerial.available()) { // While there is more to be read, keep reading.
Serial.print((char)hcSerial.read()); // send it to the PC
}
}
// Read from PC
if (Serial.available()){
delay(10); //
fromPC = (char)Serial.read();
hcSerial.print(fromPC); // show the HC-05 responce
Serial.print(fromPC); // echo it back to the PC
}
}
Arduino Programming over Bluetooth.
Arduinos are programmed over serial via a bootloader. A bootloader is program that runs for a few seconds whenever the Arduino is started. It looks for someone trying to program it. It runs in one part of the Arduino’s memory. If it does not detect an attempt to program the Arduino it switches to the part of memory where the last program (sketch) resides. If it does detect an attempt to program the Arduino, it reads the incoming program instructions over the serial port and writes them to that other part of memory where normal programs (sketches) reside. Once the upload is complete it switches to that program and runs it.
Therefore, in order to program the Arduino over a serial connection, you need to trigger a reboot. The Arduino USB creates a full RS232 connection. In addition to Rx and Tx is has other control lines like DTR (Data Terminal Ready). The Arduino uses the DTR signal to force a reset. To reset an Arduino you pull the reset line to ground. The DTR signal out of the USB chip is high when there is no connection and low (ground) when there is a connection.
If we directly connect DTR to the reset pin, the Arduino will be stuck in permanent reset mode whenever a serial connection is open. To correct that, a capacitor is inserted in the circuit. Capacitors block a continuous signal, but pass a quick transition. Therefore the the change from high to low will look like a quick pulse to ground at the reset pin. That pulse is exactly what is needed to reboot run the bootloader.
Here is what that circuit looks likes on an Arduino Nano schematic. The length of the pulse depend on the value of the capacitor and characteristics of the high to low transition.
The HC-05 state pin will work for this. In its normal mode it is high during a connection. We need that to be low (ground). Fortunately the HC-05 has the Polar command. That allows you to flip that logic. AT+POLAR=1,0 will do the trick. The first parameter is for the LED. We leave that at 1. The second parameter is the state and we switch that from the default of 1 to 0.
I found that the typical 0.1uF capacitor would not generate an adequate pulse to ground, so I bumped it up to 1.0uF. It occasionally does not work when uploading. I think a little less capacitance might be better. The Arduino uses the hardware serial connections for programming, so you use those pins. When programming the Arduino use the virtual serial port you got when pairing the Bluetooth. Do not use Bluetooth and the USB serial port at the same time. Both would be connected to the hardware Rx and Tx and conflict with each other and possibly cause damage.
Other Reset Features
You may not care about uploading code over Bluetooth, but some of your applications may expect that reboot on connect behavior. I have found this with some GCode senders. They open the serial port and expect to see the text Grbl spits out at startup. Without seeing this text, the program wrongly assumes there is a problem and closes the connection.
3D Systems recently acquired Geomagic. Several years ago they acquired Alibre. Alibre is a parametric CAD program. It appears that they are simply re-branding the existing version of Alibre as Geomagic, but will incorporate feature of the Geomagic product line over time. Here is the basic product line.
I have used Alibre and Cubify Invent and find them to be quite capable. Some day I may loose my easy check out access to Pro/Engineer and these products are on the radar as possible solutions. I found the even Cubify invent could do a few little tricks that are a pain in Pro/E.
I love using these jumper wires for prototyping. They work great for breadboards and Arduino headers.
You can buy them all over the place including SparkFun. They are available male/male, male/female and female/female in various lengths.
Sometimes you need to hook up something that already has wires attached. I got these pins and single pin housings from Pololu the other day.
I really like them. The housing works for either male or female pins. You can either manually crimp the pins with a needle nose pliers or use a real crimper. The crimper works for both the male and female pins.
Here are the links to the parts. If you know of other sources, please add them in the comments.
Proper use of a crimper is a learned skill. You need to take the time to learn it. I lend out my crimpers all the time. Many people try to use their first attempt in project. The pin falls off or does not have a connection. They then give up and use pliers. The bottom line is there is no better way to put the pin on than a proper set of crimpers. This is how the professionals do it. It only takes a few attempts to get it right. Take the time.
One of the biggest mistakes newbies make is stripping too much insulation. It is usually just a tiny amount and only the length of the wire barrel portion. It is very important that the insulation barrel of the crimp grabs onto the insulation. That is the thing that really holds the pin from being pulled off.
I always buy my crimpers from eBay where they are usually about 25% of retail. Avoid generic or all purpose crimpers. Try to get the manufacturers brand.
The crimpers I used are Ampmodu Mod 90418-1. The can be found used on eBay for around $50. Pololu suggests you can use this general purpose crimper. I also have that crimper and it works better than anything you could do by hand, but is no where near as good as the real one. The 90418-1 has a little “gate” thing that fits between the part the crimps on the insulation vs the part that crimps on the wire. This allows it to crimp just right on each part and sets the depth of the inserted wire. It also has two different wire size ranges.You can see this gate in the picture as the shiny bit with the square cuts.
I met programmer and maker, Joe Walnes, through a few local Chicago maker groups. He showed me a really cool web based G-code viewer he wrote to preview his 3D printer G-code. It used WebGL for super smooth motion of the model. It also allowed you to drag and drop your own files right into the page. It worked great, but really only worked with 3D printer G-code. He posted the code on GitHub.
I have a couple programming projects in the works that need a G-code viewer, so I decided to update his program to handle more types of programs. Joe had a really nice UI and design pattern for the code, so I left that alone. He also helped me out with a few issues as I worked.
G-code Parser
A parser is a bit of code that breaks down text into tokens, or the basic grammer of the G-code. He was working with very well formatted G-code so his parser was pretty simple.
G1 X5 Y5 Z6 E0.124
I was dealing with really Fugly lines of G-Code like this, so I needed to totally rewrite the parser.
N100G17G91G1X5Y5Z6M03S1000(comment)G1X5;comment
Graphics Generation
Reprap 3D printers basically use G1 (straight moves) for everything. I needed to add the code to handle G2 and G3 (arc moves). This was a little tricky because there are no arcs in WebGL. I had to break them into small line segments. Joe also treated each Z level as a separate layer. That is nice for printers, but not for general G-code. I changed that and the way the color of the lines worked.
A Work in Progress.
It works on all my CAM generated 3D printer and CNC router G-code, but I want to add code to deal with more advanced features that are often hand coded like incremental moves, machine offsets, parameters, math functions and subroutines.
I will post the source code soon.
Usage
You need a WebGL capable browser like Chrome, Opera or Firefox. I hard to turn on WebGL in my Firefox. I got it to run on my Android phone in Opera, but could not spin/zoom the model with the screen controls.
To view your own files, just drag and drop the G-code into the browser. It will use the zoom settings for the previous model, so if you drop something that is a different size or offset to the side you may need to zoom around to find it.
The tool is attached to a hand held frame. Actuators within the frame can move the tool to compensate for errors you would make when trying to cut a complex shape.
A high contrast pattern is placed on the work piece. They are the horizontal bands of shapes in the image above. The tool creates an internal map of the work piece using a camera. It can then accurately determine it’s location anywhere on the work piece without the drift that might occur using incremental positioning sensors. The outline of the cut to be made is shown on the screen. The location of the tool center is also shown on the screen. You only need to follow the line within the correction limits of the tool. The tool digitally corrects to produce remarkably good results.
This same idea could be applied to a lot of different 2D fabrication tools. There is a very comprehensive paper here showing all the details.
Thermal friction drilling very cool (hot actually) drilling technique that is especially useful for creating tapped holes in thin wall materials. The pressure and friction of a specially designed conical bit heats the material to a plastic state and forms it into a hole that has 3-4 times the depth of the wall thickness. It looks like it is best for hollow tubing because the back side of the hole is a little rough. The bit forms the top of the hole into a flat bushing which is perfect for fastening to round tube.
The bit is made from carbide and is held in a special holder/collet assembly that isolates the heat generated on the tool from getting to the machine. Lubrication is required to prevent the material from welding to the bit. Any machine that meet the speed and power requirments, including drill presses can use this technique. According to the web site a 6mm hole would require about 2500-31100 RPM at 1.2kW (1.6 hp).
Most of the thermal drilling companies recommend thread forming taps. These taps form the threads by displacing the metal rather than cutting it. The resulting threads are smoother and stronger than cut threads. I have used them on conventionally drilled holes. The pilot hole needs to be slightly larger than a standard pilot hole. The taps are a lot stronger because they do not have flutes. The can be run faster and don’t bind up with chips. It looks like the combination of thermal drilling and thread form taps creates a very clean operation.
I did not give a lot of in depth thought when choosing the MakerSlide extrusion length to purchase. I did not want a lot of waste, so I just bought the largest piece I could handle. I figured 6″-12″ average waste on each piece could be expected. The longer the piece, the less percentage that would be.
The manufacturing size limit was set by the anodizer who could only handle about 20 foot lengths. The limit on my end was about 15 feet. This was due to what I could realistically cut. My space is about 27 feet long, so if I put the saw in the middle I could cut most reasonable sizes with a 15 foot length.
When it came time to cut the material, the reward requests came in all over the map on length. On past projects I had used some simple logic to fit the pieces into the stock, but that was yielding some serious waste now. I dreaded the thought of 10-15% waste and little chunks lying all over the shop. I had heard about cut optimization software and decided to look into it.
It turns out that there is pretty well established math behind this. There is a good article on Wikipedia about it. It is generally called the Bin Packing problem. There are 1D (length, like my problem), 2D (area, like out of a sheet) and 3D (volume, like boxes in a container) problems that can be solved.
I tried a bunch of freeware, shareware and demo software. I was really impressed with the results. They did not always yield the same results, but generally agreed within about a percent. The choice came down to a flexibility and a few key features. I did not have the time to roll my own solution from free software libraries, but I knew I wanted to do some customizing. I decided to go with an Excel add on from Optimalon. The Excel format allowed a lot of quick macros and imports to be easily added.
The software allows you add in a number of stock lengths. This allows me to put in the standard raw lengths, but also some scraps that might be able to be used. You enter the cuts by length, quantity and ID. The ID can be used to determine what customer the part belongs to.
One feature I wanted was a way to label all the parts.
I have several Dymo label printers that I use extensively. I wanted to automatically print labels from the software. I found that Dymo had an SDK. The optimization software prints a cut table for each piece. I feed this table to an macro that uses the label printer.
This string of labels is now my cut list for each piece of stock. I print one string per piece of stock. A single persons parts are usually scattered among several pieces of stock, so this helps sort it out later.
So far the software works great. The more varied the lengths, the better it does. My target is in the upper 90’s for yield. So far I have found it does really well including some 100% utilizations where the last saw cut is less than the kerf of the blade. Here is a typical final cut piece.
The only drawback is that the cuts are optimized for material usage and not cutting efficiency, so you are often moving the saw stop on every cut. If I CNC the cutter, this will not be a problem and Excel can drive the cutter.
I have had a project going in the background to create a small, but strong and quiet spindle for small CNC routers. This is my second iteration of the design and I think it is close to what I want.
Frame
I started with an UHMW frame. This frame presses together then uses some hi-lo plastic screws to keep it together. UHMW is very stiff, but cuts well on a simple CNC router. I used a 1/8″ single flute end mill for all cuts. I try to ramp plunges wherever possible to limit the meterial that tries to climb the tool. It can all be cut from a sheet from one side with the exception of the pocket for the motor. This is needed to get enough shaft to come through. This pocket does not need close registration with the other so it is easy to flip it and run that side. The frame is rock solid. It feels like you could drive a car over it.
Spindle
The spindle shank was a key find off eBay. It has a ER11 collet which can handle a little larger then 1/4″ bits and there are plenty of cheap metric and inch collets available. The shank steps down to 8mm. This is great because the step can ride right on the lower bearing and cheap normal and angular contact 8mm bearings are available. I used an angular contact bearing on the bottom, and a normal bearing on the top. The top pulley installs with a spring washer to keep a 8-10 lb pre-load on the bearings to eliminate axial play. The bearings press fit into the end plates. The lower angular contact bearing takes the axial load from hard plunges. The axial bearing I found does not have a good seal on it, so I am a little worried about that. I am looking for a better bearing, but I might make my own seal that would seal to the spandle shaft. I might add a cover for the front and top.
Pulleys
I am currently using MXL belting which is rated for about 20k RPM, but at this diameter and length I think it can go a lot higher. I was planning to use multiple rubber o-rings, but that requires custom pulleys.
Size & Weight
The overall size is rather small at 90mm x 84mm x 82mm and total weight is 0.72 kgs. You mount it by tapping holes into back side. I will have a standard set of holes, but leave room for custom mounts.
Motors
It accepts a variety of motors. You can use univeral motors for small power tools. These will work on AC or DC and are good if you want to run it off 120/220VAC. You can also use RC hobby motors. These are available in brushed and brushless DC. A brushed 12VDC motor is cheap and the you can use a cheap PC power supply. I also test a water cooled brushless DC motor. This is the quietest option, but has the added cost of a speed controller. The motor shown will do over 30k RPM. I need to modify the top to give clearance for the water fittings. It can run for a few minutes before it gets hot, if you don’t load the motor too much. This motor can pull over 550 watts continuously. That is more than 2/3HP. I am hoping a simple PC cooling system will do the cooling.
Speed Control
The speed controller is controlled like a hobby servo. It uses pulses in the range of 1ms to 2ms to set the speed. You can program the controller though the servo interface to determine if you want reverse, etc. I decided to use an Arduino to control the speed. There is a servo library that makes it easy. I have the Arduino reading a pot them setting the speed accordingly. You program the controller by powering it up with the pulse input set to max speed. You then can set a few options like range and direction.
Next Steps
The next step is to find a way to do real world testing with it. I need a water cooling system and something to mount it to. The design will be released as open source.