Saturday, 13 July 2019

Decoding absolute reference marks on Heindenhain LS378C


After a recent ebay find of affordable 0.001 glass scales, for my lathe cross slide, I now need a suitable DRO. Mixing scales with different reference mark standards, is a bad idea, but I like the challenge. Lets build a DRO capable of decoding Heidenhain reference marks.
 Although there are some DIY solutions out there, nothing I found was open source without custom hardware, thus not usable to extend.

Dedicated chips like ls7366r have automatic decoding for index pulses, but do not support encoded reference marks.

The idea is to use three HCTL2000 chips connected to an arduino, then feed the output to an ESP8266 for serving a simple web page.

The document Linear scales by Heidenhain [1] ,gives the formulae to decode the absolute reference marks on their linear glass scales [page 9].

Below a screenshot of the three tracks, the index pulses appear to be randomly spaced.

 After applying the formula to the input data, the result makes no sense.

my $Mrr = 0; # Signal periods between two reference marks





$B = (2*$Mrr)-$N;
$D = +1; #direction
# P1 Position of the first traversed reference mark in signal periods
$P1 = (abs($B) - sgn($B) -1) * $N/2 + ( sgn($B) - sgn($D) ) * abs( $Mrr) /2;
$N = 1000; #Nominal increment between two fixed reference marks in signal periods (see table below)


References
1 http://www.auto-met.com/heidenhain/08PDF/NC%20Linear.pdf

Saturday, 16 March 2019

Arduino based quadrature decoder experiments


While looking for a very efficient method to decode quadrature signals directly on the Arduino Nano, I came up with this solution for 2 encoders. While not suitable for high resolution encoders, it is at least fast enough for 400 CPR running at 3000 rpm. Interesting finding was the lookup table method found else where on the internet, is about twice as slow. The  subroutine is called from a timer interrupt routine.





// GPL, Hannes de Waal 2019 
// Measured 97 KHz, 5.8us duration with lookup table 
// 128.9 kHz with 3.36us using 2 case statements, instead of lookup

void read_encoder() {

 
  static uint8_t enc1_ab = 0;
  static uint8_t enc1_idx = 0;
  static uint8_t enc2_ab = 0;
  static uint8_t enc3_ab = 0;
  
  /**/
  unsigned char port = PINC;
  enc1_ab <<= 2;               //remember previous state
  enc1_ab |=  ( port & 0x03 );  //add current state
  enc1_idx <<= 1;
  enc1_idx |= ( port & 0b00000100 );
  
  enc2_ab <<= 2; 
  enc2_ab |= ( port>>2 & 0x03 );
 // Pos1 +=  enc_states[( enc2_ab & 0x0f )];
 
/* state transitions
  10 -> 11 +
  11 -> 01 +
  01 -> 00 +
  00 -> 10 +
  10 -> 00 -
  00 -> 01 -
  01 -> 11 -
  11 -> 10 -
  10 -> 01 e
  01 -> 10 e
  00 -> 11 e
  11 -> 00 e
  */
  switch( ( enc1_ab & 0x0f ) ) {
    
    case 0b00001011 : Pos += 1; break;
    case 0b00001101 : Pos += 1; break;
    case 0b00000100 : Pos += 1; break;
    case 0b00000010 : Pos += 1; break;
    
    case 0b00001000 : Pos -= 1; break;
    case 0b00000001 : Pos -= 1; break;
    case 0b00000111 : Pos -= 1; break;
    case 0b00001110 : Pos -= 1; break;
    
    case 0b00001001 : Err ++; break;
    case 0b00000110 : Err ++; break;
    case 0b00000011 : Err ++; break;
    case 0b00001100 : Err ++; break;
   // 0000 hold
   // 0101 hold
   // 1010 hold
   // 1111 hold
        
  }
  

 switch( ( enc2_ab & 0x0f ) ) {
    
    case 0b00001011 : Pos1 += 1; break;
    case 0b00001101 : Pos1 += 1; break;
    case 0b00000100 : Pos1 += 1; break;
    case 0b00000010 : Pos1 += 1; break;
    
    case 0b00001000 : Pos1 -= 1; break;
    case 0b00000001 : Pos1 -= 1; break;
    case 0b00000111 : Pos1 -= 1; break;
    case 0b00001110 : Pos1 -= 1; break;
    
    case 0b00001001 : Err1 ++; break;
    case 0b00000110 : Err1 ++; break;
    case 0b00000011 : Err1 ++; break;
    case 0b00001100 : Err1 ++; break;
        
  }
 
}

Saturday, 12 January 2019

Surface Grinder CNC Notes


Controlling the Z axis

Option A - Stepper motor
Using a stepper motor with 1.8 deg steps will give a resolution of 200 steps in full step mode per rotation. This would require a 46:1 reduction to achieve the desired 0.5um resolution on a 5mm lead screw.  Cons: discreet steps, not sure if this will be an issue, holding torque goes down with reducing step size.

Option B - Servo
With a servo motor using dual loop position feedback control will make more sense since steps are no longer discrete. The dunker motor I have had lying around for years, seems like a good fit. 23:1 gear ratio with a 100ppr encoder, without using the linear encoder as additional feedback this will give a resolution of 9200 steps or 0.543 um. Quick estimation with Bresenham algorithm, gave the following approximations for 0,001um increments. But i would like to hit them exactly...well in theory at least.

1 0,000543
2 0,001087 0,001
3 0,00163
4 0,002174 0,002
5 0,002717
6 0,003261 0,003
7 0,003804 0,004
8 0,004348
9 0,004891 0,005
10 0,005435
11 0,005978 0,006
12 0,006522
13 0,007065 0,007
14 0,007609
15 0,008152 0,008
16 0,008696
17 0,009239 0,009
18 0,009783 0,01
19 0,010326
20 0,01087 0,011
21 0,011413
22 0,011957 0,012
23 0,0125

This made me research the possibility of using dual loop feedback, seems common in commercial machines.
LinuxCNC supports it out of the box
http://wiki.linuxcnc.org/cgi-bin/wiki.pl?Combining_Two_Feedback_Devices_On_One_Axis
http://linuxcnc.org/docs/2.7/html/man/man9/offset.9.html
This great explanation https://granitedevices.com/wiki/Dual-loop_feedback_position_control
Gave me another idea, just use Elm Chan SMC3 Velocity control mode with LinuxCNC, feeding position from Heidenhain encoder to LinuxCNC, which controls the SMC3 servo in velocity mode.
http://elm-chan.org/works/smc/report_e.html

Thursday, 3 January 2019

Writing Software for CNC Applications

Need to synchronise the spindle to the C axis? Or implement an electronic gearbox reduction for a lathe? Stepper on a rotary table? Or just plot a circle on XY planes? all of these implementations have a few common problems to solve, one of which is to coordinate the movement of two or more axis. Since each axis might have different resolution and or require fractional advance of that resolution to accomplish the desired motion. Most open and closed source implementations seem to make use of some sort of  Bresenham's line algorithm here, to deal with the resulting error.

void main () {
   double y0 = 0.00;
   double dy = 0.0125; // 5mm / 100x4
   double dx = 23; // gear ratio
   double k = (double)dy / (double)dx;

    double y = (double)y0;
    double yi = 0.0000;

    for (int x=0; x<23; x++)
    {
        y += k;

        if ((y+0.0005) > yi) // error larger than 0.0005? increment yi
        //if ((int)(y+0.5) > yi)
        {
            yi=yi+0.0005;
        }
      printf("%02d %02f %02f\n", x, y, yi );
    }

}

Let us look at Gear ratios, the concept of accurate synchronized electronic reduction gears for the lathe made me think. Why not use closed loop phased locked control?

1) decode position pulses to direction and 4x steps,
2) Multiply step pules by M an then divide by N. 
3) feed the resulting pules directly to a stepper which can act as the divider

To implement this one would require a PLL for multiplication. Using this method should make it possible to implement any gear ratio without error.  I have implemented this on Arduino making use of the internal clocks and one external PLL 4046. The lock and capture range now determine the spindle speeds. The solution runs entirely on hardware no software is required once the counters have been set. It is abit more complex than this, since direction needs to be accounted for. But here is the gist of it. I then found commercial industrial solution doing exactly this at http://www.motrona.net/encoder_divider.html




Sunday, 30 December 2018

Eagle Surface Grinder MK3 Rebuild - Progress

This will be the last post for 2018. It has been an exciting year with life happening.

I finally managed to get some time to start the reassembling the Eagle Surface Grinder. All the surfaces have now been precision ground. All that is left to do is machine the oil grooves, match the dovetail surfaces, scrape the oil pockets, add the news spindle and ball screws, write some macros for the grbl g-code controller to behave like a surface grinder and the machine is ready for action.

Spindle and Drive Motor
After ordering and installing the new balls as described in a previous post, I am not satisfied with the resulting stiffness and pre-load design of the original spindle. The thinking now is to use a self contained spindle and machine an adapter sleeve. The new spindle axis diameter is 20mm compared to 25mm and the bearings considerably smaller, but for my needs this will be more accurate, even if I can only run 7" wheels. The motor in the base will drive a flat belt transmitting power to a love-joy style coupling in the "head stock" similar to old lathes with addition of the coupling if that makes any sense. Initially I wanted to go with poly V-Belts, but when I saw the very modern Schaublin 102 N-VM-CF still uses crown pulleys and flat belts. I started investigating the advantages of flat belts. The main advantages I could find was, better efficiency, less vibration, and higher speeds. not sure if any of this holds true, but worth a try. Here I will need to design the housing at the back of the spindle housing, which will hold the crown pulley and shaft coupling, for driving the spindle. A direct drive would be more efficient, economical with less vibration, but that would have the motor extend  at the back of the spindle housing, similar to the later eagle model shown below, in a small shop not an option.



Knee Oil groves

On the MK3 model the only the table sports oil groove. As discussed in a previous post, I have decided to go with the zig-zag oil grove pattern, it is more time consuming to machine, but should give better results. Below some images on the layout and machining process. The fixed dovetail had a ridge, where it meets the flat surface on the knee, this had me confused for some time as to why I do not get full bearing on the entire flat surface. a few head-scratches later I used a carbide ball nose end mill to machine some clearance in the corner, all this with a portable hand drill. The only straight edge I could find to fit the angled recess was a carpenters knife blade, this worked great!

Ball Screws /Servo/Stepper Motor
The ACME lead screw needs to be replaced, it has a lead of 10 TPI. I do not feel like cranking the hand wheel so installing a feed motor is a given. Sourcing an ACME 1-1/4" x 10TPI  or similar in my part of the world is not feasible. So I opted to go full CNC and use 5mm pitch ball screws.  After doing some calculations on THK ball screw specifications with a combined load of 100kg., a 20mm diameter screw will work within load ratings, if a maximum sliding speed of 38mm/s is not exceeded. For a 5mm pitch screw this will give maximum motor speed of 456 rpm. And 8NM motor would be required for https://www.nidec.com/en-EU/technology/calc/torque/ballscrew/ to drive this load.

Sunday, 1 July 2018

Deckel FP2 restoration Year 1966, Serial # 5151

Almost two years since I got the machine, and many hours later, the restore is complete. Thanks to www.metalworker.eu, Bruce and some other helpful fellows at https://www.practicalmachinist.com/vb/deckel-maho-aciera-abene-mills/deckel-fp2-1966-restoration-321812/

The machine runs incredibly quiet and is an absolute pleasure to use!



Saturday, 30 June 2018

Surface Speeds - for the Deckel FP2


No more fiddling with a calculator


RPM settings and corresponding surface speeds

Ranges are for HSS tools, extracted from the SO single lip cutter grinder manual. For me, this this is a good starting point for simple cutters. Modern geometries are specified by the manufacturer.

More reading
http://www.stahl-online.de/wp-content/uploads/2013/10/MB137_Zerspanen_von_Stahl.pdf

Sunday, 3 June 2018

Lathe V Ways Calculation for fitting Tailstock and Carriage _/\_

While rebuilding the Chipmaster, the problem of aligning the carriage bed ways ( bottom slide ) and top slide arise, from what information I can find these have to be at right angles. The bottom slide is worn bananas, so a simple spotting technique, on the bed might cause a lot of headache later to align the cross slide. So I decided to align the tail stock base first, and then use it on the lathe to check which original sufaces on the crosslide are closest to allignment, to be used on the mill setup.  I will then cleanup the V groves at the bottom, and do the final spot checking on the lathe beds. So the approach requires three steps.
1) Align the tail-stock on the mill, and touch-up the V slot, and flat surface. Machine one outside surface parallel to the V-Groves. Final fit on the lathe with transfer spotting.

2) Find the best reference surface on the carriage with the fitted tail-stock base as guide. Or bolt an adjustable bar to the back, where the taper attachment usually attaches.

3) Machine the cross-slide base V and flat ways, aligned to identified surface. Fit with transfer bluing.

The calculation for the depth of the V slots require similar math to that used for dovetail calculations. I used two 14 mm end mills as gauge pins, the bottom circle is used for measuring the depth, when the base is upside down on the mill, since I want to do the machining in one setup.

Height with14mm gauge pin in V slot, should be z higher than flat surface          
              
On the drawing, the top two 14mm gauge pins are used to  measure the_ /\_ ways, the
bottom gauge pin is used to measure height over the flat surface, for a level tail stock base.          
              
map the flat surface to find low points, add z, mill out v until this height is reached          
mill down flat surface         






                 measured    38,515    across pins
c1,c2,c3    r    7   
                 a    24,515    measured-2r
                 b    4,949747468   
                 c    2,050252532    r-b
                2d    14,61550506   
                d    7,307752532   
                h    9,358005063    c+d
               w    18,71601013    2*height
               e    9,899494937   
              c3    center    0,541489873    e-h
              z    7,541489873    r+c3 center

Sunday, 20 May 2018

Quadrature decoder ideas for glass scales and rotary encoders on Arduino and AVR

Ever wonder how the Heidenhain glass scales, can measure at increments of 0,5 µm? if the graduation on the scale is only 20um? If you come from the digital world, there are four transitions so the minimum should be 4um.
This mystery made me read up on the Heidenhain signals 1VPP or 11 µAPP ( 1VSS, 11 µASS ) These are analog signals, if you read the older literature it becomes clear that photo sensitive devices are used to generate the current, the 1Vpp signals are probably pre-loaded with a 90ohm resistor. 
Vernier scales are similar, so are modulation techniques like QAM, QPSK. With glass scales there is no amplitude or phase modulation on top of the carrier, only two orthogonal signals, the rotational relationship between the two base-band signals (I/Q) translates to position, speed and velocity. 
So what advantages do analog signals have over digital? The states are infinite, limited only by noise. But how to extract infinite states from two orthogonal signals? Run them through an AD converter and calculate the angle., this will work but the system response is limited by conversion rate and calculation performance.

Investigating further I stumbled on CORDIC https://en.wikipedia.org/wiki/CORDIC

With a search for CORDIC Quardrature decoder, I found various other methods of Sine/Cosine to Digital Conversion
http://www.ichaus.de/upload/pdf/WP7en_High-Precision_Interpolation_140124.pdf

  Flash Conversion

 Vector -Tracking Conversion

 SAR Conversion with Sample-and- Hold Stage

 Continuous -Sampling A/D Conversion
Out of pure curiosity, I will implement the continuous sampling conversion with CORDIS lookup on the Arduino, and perhaps try the vector tracking conversion on the Attiny2313
Should this work, I will try to convert my Sino Digital scales to analog and see what accuracy I can achieve. Perhaps even build a Heidenhain scale interface for the Touch DRO Project.

Resources 

CORDIC


https://eprints.soton.ac.uk/267873/1/tcas1_cordic_review.pdf

https://www.mikrocontroller.net/articles/AVR-CORDIC

Linear interpolation

https://www.mikrocontroller.net/articles/AVR_Arithmetik/Sinus_und_Cosinus_(Lineare_Interpolation) 

Fast Sampling on AVR
http://yaab-arduino.blogspot.com/2015/02/fast-sampling-from-analog-input.html


http://wiki.linuxcnc.org/cgi-bin/wiki.pl?ResolverToQuadratureConverter


Tuesday, 15 May 2018

Useful code snips for working with XML, CSV, and other flat file formats in perl, groovy, python, java, c, c++

Lock files in Windows batch scripts, avoid more than one instance running

REM Check if another instance is running, and exit if true
IF EXIST ".lock" exit 0

echo Batch file start at %time% %date% by %username%.> .lock

REM Script processing starts here

REM Script processing ends here
del .lock


Replace XML tag data with Perl

use strict;
use warnings;
use XML::Twig;

for ( glob "*.xml" ) {
        print "process file $_\n";

XML::Twig->new(
    pretty_print  => 'indented',
    twig_handlers => {
         PaymentAmount => sub {
            $_->set_text( '0' )->flush
        },
    },
)->parsefile_inplace( $_, 'orig_*' );

Groovy and Tokenize or Split

While using tokenize() if you want to discard fields or lines with no data might work as such,

List myList =  inputStream.getText().tokenize("\n\r")

it can not be used if you want to retain the offset format of CSV or pipe delimited fields, since it will not yield the entries with no data.

As example the second field will be discarded. "Line1"|"""|"Name"

Here we will need to use split

List lHeader = sHeader.split("\\|")

Another odd behavior is if you split with a pipe without escapes, "|", split returns an array of characters. This is probably documented, but I did not have the time yet to read all the documentation and can not find any reference to this behavior.

Sunday, 15 April 2018

Howto on the Horizontal Milling Machine - My notes

Comparing a Deckel FP2 to metal shapers, makes me think they are related, part of the evolution of machine tools. Still want to build the clapper box to fit the deckel...

The problem with the quagga or dodo is they have been extinct for a long time, how they once lived and roamed, we know from information passed down by generations. Very similar to me is the concept of the vertical milling machine, almost extinct; and not a lot of information around on how to use it!?

With the old fossil standing in front of you, and me time traveling with my leather apron, old classics humming on the valve amplifier, I force myself to only use the vertical head, and start thinking how to cut angles as example, it becomes clear; a simple but very useful geometry.

Since very little information is available online, I hope to collect a useful how to guide for starters, and perhaps also gather some expert advice in the field.

In a previous post I presented my idea to cut oil groves with a cutting jig, the jig has to have three sides with angles. How to do this with the vertical head, without sine bar? It would be possible with a swivel base vice if the cutter was very slim and long, not ideal or even possible, sequence of operation becomes important. But on a horizontal setup this becomes easy. Set the angle on the base, flip the part upright, cut the first angle, lay it flat for cut two, flip it over and cut third side. Or reverse the order no problem. Only have a short stubby cutter? also no problem.


Chipmaster Gear Cutting

  Calculate all the possible gear combinations for the gear selector to cut a 15TPI thread: Imperial TPI C 5 24 20 Imperial TPI ...