DIY Arduino Project: RPM Display for SC2 Lathe, SX2 Mill, and More

I recently purchased from Axminster a Sieg SC2 Lathe, and SX2 Milling Machine. To my dismay there was no way to tell how many RPM’s the spindles were turning. When I looked at the price of the add on LCD display, I was shocked to learn that they sell for £150 each!

Thinking that a simple chip and LCD display in a tacky white plastic box should cost more like £15 I set off on a quest to build my own.

I began by posting a thread on this forum inquiring about the “pinout” of the RPM port on these machines and was lucky enough to get a response that directed me to “” where a guy named Jeffery Nelson had done the grunt work of analyzing the data on the seven pin “RPM” port located on a number of Sieg machines including mine.

BTW he sells an Arduino kit to make your own for £50. Alas me being the cheapskate I am decided to go it on my own,

So I started by hitting up Amazon and purchasing an Arduino R3 clone, an LCD display, a couple of enclousures for them, a few Arduino jumpers, and a seven pin plug to match the port on my machines.

My next issue was learning how to program in the Arduino language, which was suprisingly easy as I spent the last 20 years of my career working in the “C++” language which is very similar.

I began by taking a bit of code that Jeffery had written and modified it to write to the I2C type LCD I had chosen, which used two wires for data as compared to the many that the older LCD’s use. It was an interesting journey thru the world of port addresses and interrupts. Having that sorted I uploaded the code to my Arduino R3 clone, and to my amazment it looked as though it may work. I had added some debugging display statements in the code that output to the LCD at each step and to my amazment it ran!

Here is the Pinout from Jeffery’s web site:

This is the “pinout” of the RPM port on the Seig machines. The drawing is as if you were looking into the port. As you can see there are three data lines, pins 1,2, and 3, and two sets of 5V DC power on pins 4 thru 7. Which Arduino pins to jumper from the Seig RPM port to your Arduino board are defined in the documentation included in my code.

I scoped out the power on pins 4 & 5 and determined it is very clean regulated power at 4.96 Vdc on my lathe and 4.98 Vdc on my mill, perfect to power an arduino board, which solved the issue of needing an external power source to run the board and LCD.

So I hit up good old Amazon and searched for a GX16 type 7 female plug. To my dismay it was the only part of the project I could not find there. Fortunately good ole E-Bay came thru for me, I was able to purchase two of them for a mere £3.

While on Amazon I purchased the remainder of the hardware needed for the project including an Arduino UNO R3 clone, Some arduino jumpers, a bit of heat shrink tubing, an LCD display, and enclosures for the board and display. the total investment for everything was just shy of £30. I am sure you can do even better if you shop around.

First I tackled soldering the five Arduino jumpers to the seven pin connector, which turned out to be tedious. I am sure some choice expletives echoed around my shop while using my antique underpowered soldering iron.

Before assembling the plug I placed a dab of hot glue in the center of the soldered wires and also placed a strip of electrical tape around the outside to insulate the wires from one another and the metal casing on the plug. I finally used a little heat shrinkable tubing to make it pretty.

The next step was to assemble the LCD enclosure, which to be honest I do not like as the back is open to the elemens, which in my shop can include flying metal chips. It will be replaced when I re-engineer this prototype and build a single enclosure for the whole project.

Following this step I placed the R3 clone into its enclosure, attached all the jumpers to the proper pins (which are defined in the code). I put a dab of hot glue on the enclosure where the jumpers were attached just to keep them in place, but still be removable when I disassemble this prototype and build the final enclosure.

I was now ready to test my code for the first time, a scary moment for any progrmmer. For the first test I chose to use my lathe. I inserted my seven pin plug into the port which is labeled “RPM” and to my amazment the boards LED lit, the display came to life, and displayed my first step message “LCD Found”:

Things were looking good. After another second or so the program header message which is displayed when all the pins are defined and the program is ready to begin looping scanning the port was dislayed:

I just had to see my name in lights!

Now the program entered its looping and began reading the four packet groups theat are sent by the Seig controller board. the first message i saw was the “Spindle Stopped” message.

I was really getting excited, the program was behaving as it should, but could it actually read the spindle speed when the packets began to fly? I gingerly twisted the speed control knob a little and to my great pleasure recieved the following:

I was in business! the darn thing worked like a charm. Just to be certain I Checked the spindle speed with the strobe application that i mentioned in an earlier post and clocked it at 322 RPM’s not too shabby.

The Sieg controller board transmits the thousands, hundreds and tens column out the RPM port and always leaves the fourth “ones” column at zero. By playing with the strobe I had determined that The controller board rounds the RPMs up the tens column when the ones column speed gets to a six, so from one to 5 rpm you would see a zero displayed, from six to fifteen you would see 10 dispayed and etc… so accuracy of the Sieg data is never more than 5 RPM’s in error. Way more than accurate enough for the model engineer.

Here is an image of the final product. Using a couple dabs of hot glue I attached the Arduino board on the back side of the lathe’s motor enclosure (visible on back left) and also to the LCD on top where I can easily see it. Notice the port on the Arduino enclosure is facing upwards, so I can easily attach my printer cable to it when and if I apply updates to the program.

Note: I covered the upward facing ports on the Arduino enclosure with a piece of clear cellophane tape, to keep chips and other debris out, also I did the same with the opening on back of the LCD Display.


This is one way you can beat the high price of the ready made RPM display available from Axminster and other supliers, and have some fun learning to use the Arduino system.

This project goal was to build myself a prototype to verify that I had the coding to run the two wire I2c type LCD and that the code I located on the net was still viable. With this done I will now build a permamant home for my little Arduino project. I will post the final product when i have built its permamant enclosure.

Thank you to Jeffery Nelson for making all the information needed to buld this project on his web site: available under his “Hacking the SX2 mini mill” heading.

here is the latest non inclusive list of machines that this code works with:

Sieg Industries - SX2 Mini Mill Drill
Sieg Industries - SX2L Mini Mill Drill
Sieg Industries - SX2P Mini Mill Drill
Sieg Industries - SX2LF Mini Mill Drill
Sieg Industries - SC2 Mini Lathe
Little Machine Shop - 4190 HiTorque Mini Mill, Deluxe
Little Machine Shop - 3990 HiTorque Mini Mill, Solid Column with Air Spring
Little Machine Shop - 3990 HiTorque Mini Mill, Solid Column
Little Machine Shop - 3960 HiTorque Mini Mill, Solid Column
Little Machine Shop - 3900 HiTorque Mini Mill, Tilting Column
Little Machine Shop - 4100 HiTorque 7x12 Mini Lathe, Deluxe
Little Machine Shop - 4200 HiTorque 7x12 Mini Lathe
Little Machine Shop - 5100 HiTorque 7x16 Mini Lathe
Craftex - CX-Series CX612 - 3/4 HP Mini Mill with Brushless Motor

Finally, I attempted to list the code here in this forum but it was too long to post here.

Thanks for reading, I look forward to your coments,

If you would like a copy of the code please e-mail me at:

Good luck! - Jenny


Excellent work Jenny! Very impressive. :+1:

Thank you David. I had good fun building them and I use them almost every day.

Since I wrote this post I completed my second display that I have mounted on my milling machine,


Hi Jenny,

Thanks for the information and the code

Hi all,

As I was looking for a way to set up a tachometer on my mini-lathe and mini-mill, I stumbled upon this post. It was a great relief: what I wanted already existed and was described in great details. So I asked Jenny about this code and she kindly answered me and sent it to me very fast. Then, I started to play with it.

I decided to use an Arduino nano rather than an Arduino Uno so it could fit within the lathe enclosure, with a window cut on the top for the display. As the LCD screen takes almost all the space in the top panel, this implied moving the green power indicator and to remove the yellow fault light. One consequence of moving the fault LED was to add a new feature to the tachometer so it replaces this notification: I wanted the LCD monitor the fault line and display a “FAULT!!!” message message when needed. As the Arduino nano can use interrupts on only two pins, I therefore started by moving around the pins: yellow positive wire to pin2, LCDCL to pin 3, LCDCS to pin 4 and LCDDI to pin 5. With this setting, I could use one interrupt for the LCDCL (clock for RPM data transmission) and another interrupt for the fault line.

I also wanted to change the interrupt routines to use a more explicit API, using attachInterrupt instead of EIMSK/EICRA/SIGNAL(INT1_vect) that were used on the original code. In the Interrupt Service Routine, I also wanted to reduce memory usage by extracting only the single LCDDI bit (instead of the full 8 bits PIND register). This failed dramatically! I tried a lot of different things in the past few weeks and was not able to achieve my goal. It seems to me that despite the board will be idle most of the time (the rotation rate is refreshed only every 750ms), when it is refreshed the bits arrive fast and the board has a hard time coping with the interrupts. The ISR must therefore be really really short to remain fast enough. I also failed simply replacing the SIGNAL(INT1_vect) declaration with a call to attachInterrupt, but this failed too, and here I don’t understand why. I thought it was only an API change and an overhead to pay only once at setup, but it seems to be also more costly when servicing the interrupt. I basically gave up there. So the handling of the fault line is just done by checking the pin status at the top of the loop routine, without using the interrupt that should be available on pin 2. I don’t like this solution and it seems to sometimes displaying the fault message even when the spindle is rotating… I think however that when I did these tests the pin was not connected and so a floating input may take random values. I will probably have to check this again now that I have rewired everything.

During my numerous tests, it occurred to me that the board missed about two third of the refresh! When using a serial console, I got about one RPM message for two communication errors. As the code was mixing some polling/delay part with interrupt-driven logic, I tried to tighten that a bit, removing the delays and using a circular buffer to allow bits to avoid dropping bits if the loop happened to be run in the middle of a message. In this case, we would have just returned, preserving the partial message received so far and have wait for next call was the circular buffer was still filling up with bits. This failed too. It requires an ISR that can fill up a circular buffer and I think the nano was not powerful enough to do it when the bits stream arrived. It failed despite the circular buffer handling was only a few instructions long with index bits masking to wrap up at the end of a buffer whose size was a power of 2. Losing 2 refresh out of 3 is not the end of the world. When using the lathe, looking at the RPM display is not the main activity. When trying to control the proper speed I simply need to stay a few seconds before the display stabilizes. I can cope with this.

So I went back to Jenny original code with only very few changes (currently the FAULT part was also commented out despite the wire is connected).

The advantages of using a tiny board, shoving it in the lathe enclosure and having only the LCD display sticking out are:

  • it takes less space on the headstock
  • there are no risks it will slip and drop with vibrations
  • there’s no need to buy an enclosure
  • there’s no need to buy a special plug

In order to do the connections, I only had to cut the wires and crimp in some salvaged female headers into which the male headers from the Arduino nano plug in. I protected the remaining pins of the nano by putting heat shrink everywhere. I may also use some hot glue to prevent the headers from falling in case of vibrations.

[Post split in several part, as a new user I do not have the rights to put several images in one post…]


[continuing previous message…]

I also wrapped the board in a plastic bag before shoving everything in the enclosure.


Cutting the window for the screen and putting the screws in the right place was quite a challenge because I could not move the enclosure to my mini-mill: it was to tall. I cut the window freehand with a Dremel tool. The following image shows the back of the LCD screen mounted on the top surface of the enclosure. It takes the location of the green power light, the yellow fault light, and the LCD socket.

One can hardly see in the previous image the green power light that was moved below the forward/reverse switch and the main fuse. Desoldering the green power light and resoldering the wires after the move was also tricky as the other end of the wires is connected to other wires, thus preventing the soldering operation to be performed conveniently: one as to do it within the enclosure. I later noticed that I cut the window for the LCD screen slightly too close to the opening
(i.e. too close to the spindle). When mounting the enclosure back to the headstock, it almost
touches it.

As is, it works, thanks a lot to @Jenny for sharing this, it helped me tremendously.

For my training, though, I think I will continue to investigate the software changes I wanted to make initially, perhaps using a more powerful board. I purchased the nano boards from China using Ali Express marketplace. The boards costed only 2€ each (maybe this is the reason the boards cannot keep up…). I will try with other boards I purchased from Mouser the ESP32 pico Kit <>. The provider is more reliable and the ESP32 is far more beefy, probably even overkill for this application. The cost also remains very reasonable (8.73€). Programming is quite different from Arduino, so I will have to change a lot of things.


Great stuff @misty-soul. Really interesting.

Thanks Tim! Just trying to stir up some activity on this under-utilised forum.

Jenny is the one to thank here!
She is the one who provided everything.

Thanks Jenny.
This is now added to my mini mill todo list.

1 Like

Hi Jenny, Thanks for posting your code and all the work you’ve done on this. Much appreciated.

You are very welcome! Between this forum and a couple model engineering forums I posted on over thirty people have successfully implemented it.
One even used an Arduino Nano and was able to contain everything inside his lathe! He mounted the display right into the case. It is s beautiful installation.

thanks for the code Jenny.
it was a delight to work with a code this well written

Jenny I am hoping that this gets to you I have a query on the program you wrote for the Arduino
the following line gets me an error message?

volatile uint8_t packet_bits [PACKET_BITS_COUNT];

"uint8_tpacket_bits_posvoid"does not name a type


Sorry i did not get back sooner, the email notification wound up in my junkmail folder.

I just read thru my code it appears that the variable “PACKET_BITS_COUNT” may not be defined. This causes this one to fail “volatile uint8_t packet_bits[PACKET_BITS_COUNT];”

I would check to see if both the definitions below were somehow commented out. There should be two slashes “//” in front of only one definition like below.

// Uncomment for newer mill protocol
// Uncomment for old mill protocol

That said, upon reading thru the code i do not see where “tpacket_ bits” is referenced again anywhere in the code. It may be that it is an artefact used for debugging that was left in.

If the above two lines are correct (only one commented out)try just commenting out the two lines below.

volatile uint8_t packet_bits[PACKET_BITS_COUNT];
volatile uint8_t packet_bits_pos;

//volatile uint8_t packet_bits[PACKET_BITS_COUNT];
//volatile uint8_t packet_bits_pos;

You are the first of the many people to implement this code to report an issue with this, so i suspect my first solution.

Please let me know if this solves your issue.



Many thanks for thes

Please let me know if it solves your issue


Sorry to be complete pain but have amended the sketch and now it says a line

packet_bits_pos was not declared in this scope

The actual line reads packet_bits_pos = 0;

Hi again,

It is looking like something accidentally deleted or changed where it should not have been. Please email me direct at and ill send you an untouched copy of the code.