Magnetic encoder for homing CNC SHIELD V3 controlled steppers

Hi guys. I am a student from Romania.

I’m on my way to create my own laser 3d printer using steppers and mirrors.

My setup:

CNC Shield V3 & Arduino Uno

2x TMC2130 stepper drivers SPI controlled for 256 microstepping and interpolation

2x AS5048A SPI interface magnetic absolute encoders

Another Arduino UNO that does the SPI communication for both the drivers and the encoders.

A little introduction. My setup works perfect in terms of drawing with my laser an image using LASER GRBL. Like dimensions, accuracy, speed etc. Now, for my project to reach the end, I have to resolve 2 more problems:

  1. Creating a slicer
  2. Using magnetic encoders as LIMIT SWITCHES.

I’m here for #2 problem.

So, I have 1 idea but is not optimal at all. I want to use second arduino to activate a mosfet when it reaches a certain value to close the limit switch circuit on CNC SHIELD v3.

My goal implementation is a way for the GRBL and CNC SHIELD to communicate with the second Arduino, and when homing is activated , the motors would spin until are reaching a value (that the 2nd Arduino would send) that represents positions of the mirrors that will be never reached while printing, then move mirrors so the laser gets into left corner of the build plate.

In this case the “X” zero position (left to right laser moving mirror) would have to set the mirror parallel to the build plate, and the “Y” zero position (up and down laser moving mirror) would have to set the mirror perpendicular to the build plate, then the mirrors should move an amount of steps so the laser would point in the left corner of the build plate.

I’m open to any idea.
I want an optimal solution and that would not involve any cost (because I already ordered MOSFETS).
I belive my wiring is not important and I cant do one right now,

BUT

My CNC SHIELD V3 have only TMC drivers connected (inserted in slots).

The TMC drivers and the arduino are wired using THIS GUIDE

The magnetic encoders are sharing the MISO, MOSI and SDK pins with the drivers.

PIN 10 and 9 are for the CS pins of the DRIVERS.
PIN 6 and 7 are for SDA/CSn pins on the encoders.

The DRIVERS


THE ENCODERS

CODE OF 2nd ARDUINO

#include <SPI.h> // Throws an error in Windows
#include <AS5048A.h>
#include <Streaming.h>

#include <TMC2130Stepper.h>
TMC2130Stepper X = TMC2130Stepper(2, 3, 4, 10); //Only param 4 (CS pin) matters
TMC2130Stepper Y = TMC2130Stepper(5, 6, 7, 9);

/**

  • Basic angle procedure:
    • Obtain register readings (zero position and current position)
    • Transform to angles with read2angle()
    • Calculate the difference between them
    • normalize() the result
  • NOTE:
  • To see the angles between 0° and 360° comment the following
  • #define, instead, to see the angles between -180° and 180°,
  • uncomment it.

*/

//#define ANGLE_MODE_1 // Between -180° and 180°

AS5048A angleSensor(6);

AS5048A angleSensor1(7);

uint16_t zero_position;
uint16_t zero_position_map;

uint16_t zero_position1;
uint16_t zero_position_map1;

float inline read2angle(uint16_t angle) {
/*

/
return angle
((float)360 / 16383);
};

float normalize(float angle)
{
// http://stackoverflow.com/a/11498248/3167294
#ifdef ANGLE_MODE_1
angle += 180;
#endif
angle = fmod(angle, 360);
if (angle < 0) {
angle += 360;
}
#ifdef ANGLE_MODE_1
angle -= 180;
#endif
return angle;
}

void setup()
{
X.begin(); // Init
X.stealthChop(1);
X.SilentStepStick2130(800);// Current in mA
X.coolstep_min_speed(100);
X.microsteps(255); // Behave like the original Pololu A4988 driver
X.interpolate(1); // But generate intermediate steps
X.sg_stall_value(14);
X.high_speed_mode(1);
X.sync_phases(15);
X.stealth_symmetric(1);

Y.begin(); // Init
Y.stealthChop(1);
Y.SilentStepStick2130(800);// Current in mA
Y.microsteps(255); // Behave like the original Pololu A4988 driver
Y.coolstep_min_speed(100);
Y.interpolate(1); // But generate intermediate steps
Y.sg_stall_value(15);
Y.high_speed_mode(1);
Y.sync_phases(15) ;
Y.stealth_symmetric(1);

Serial.begin(115200);
angleSensor.init();
angleSensor1.init();

zero_position = 10509;
zero_position_map = read2angle(zero_position);

zero_position1 = 4969;
zero_position_map1 = read2angle(zero_position1);

Serial << "> Zero angle : " “> Zero angle1 : " << zero_position
<< “\t” << zero_position_map<<” "<<zero_position_map1<< endl;

}

void loop()
{
delay(200);

uint16_t current_angle = angleSensor.getRawRotation();
float current_angle_map = read2angle(current_angle);
float angle = current_angle_map - zero_position_map;
angle = normalize(angle);

uint16_t current_angle1 = angleSensor1.getRawRotation();
float current_angle_map1 = read2angle(current_angle1);
float angle1 = current_angle_map1 - zero_position_map1;
angle1 = normalize(angle1);

Serial
<< current_angle<<" “<< current_angle1 << “\t” <<endl
<< angle<<” "<<angle1
<< endl << endl;
/*
Serial << rel_angle
<< “\t” << _BIN(rel_angle)
<< “\t” << _HEX(rel_angle) << endl;
*/

if (angleSensor.error()) {
Serial << "ERROR: " << angleSensor.getErrors() << endl;
}
}

GRBL has a "step off" feature for homing built in so ideally you should not need to involve a second Arduino for that.

As for invoking a second Arduino the only reliable method I know of involves the serial port which would already be in use with whatever sender you use. That means the second Arduino would also have to take on some other tasks as the primary sender and relay to the other one what it wants it to do. This may mean some communication issues, delays being introduced.

It sounds like you built the project backwards as many 3D printer people build the printer FIRST and add the laser afterwards as the software used on the boards (often a MEGA) eg. Marlin does a lot of CNC tasks directly from any of the common slicer programs.

Whilst the V3 shield is capable of quite a lot it is a little beyond its limits for 3D printing decently.
You may have gotten off better with the MEGA and a RAMPS board or similar.

Dont forget that for a 3D printer you also need feedback for the hotend, bed temperature, levelling, filament run out, heating times, and much more which the regular CNC shield does not handle OOB.

EDIT

Karma for a great first post BTW !

Thanks a lot for your answer, you got me thinking.

But my 3d printer will have no hotend. I will use an laser to cure resin. That's why i started with grbl, i want to use laser engraving mode of slicing to draw fast multiple passes over resin with a pwm 300mw laser.
I modified a bit grbl parameters so it would not need modification in terms of moving the "nozzle" (in this case the laser pointer with mirrors).

The way i will do the slicer is combining an python dlp slicer that will generate as many images trough the object as layers will have, then use lasergrbl algorithm to generate 4 very fast passes for every image (2 horizontal and 2 vertical) with gcode for Z axis lifting beetween layers. This way i will beat the printing time that cheap laser printers (like Moai) are having.

EDIT

THANKS A LOT FOR KARMA!!

ballscrewbob:
GRBL has a "step off" feature for homing built in so ideally you should not need to involve a second Arduino for that.

As for invoking a second Arduino the only reliable method I know of involves the serial port which would already be in use with whatever sender you use. That means the second Arduino would also have to take on some other tasks as the primary sender and relay to the other one what it wants it to do. This may mean some communication issues, delays being introduced.

It sounds like you built the project backwards as many 3D printer people build the printer FIRST and add the laser afterwards as the software used on the boards (often a MEGA) eg. Marlin does a lot of CNC tasks directly from any of the common slicer programs.

Whilst the V3 shield is capable of quite a lot it is a little beyond its limits for 3D printing decently.
You may have gotten off better with the MEGA and a RAMPS board or similar.

Dont forget that for a 3D printer you also need feedback for the hotend, bed temperature, levelling, filament run out, heating times, and much more which the regular CNC shield does not handle OOB.

EDIT

Karma for a great first post BTW !

Also, you are right about ramps board, but im on a strict budget until i make a working prototype, and i han an cnc shield and 2 unos laying around.

Oh wow a resin laser.

That complicates things a lot more.
Most of those machines even the cheaper ones use a completely different arrangement and MCU !
IIRC they call for at least an STM mcu type board which is at least one up from the MEGA and RAMPS.

Resin lasers are not something I have hands on experience with but I have looked at them.
They use a very fine step control for the resolution and laser focus is super critical.

I think it is time for you to either completely re-think or come up with a detailed list of what you have made including links and pics etc. to the parts.

Either way I am not sure how much help I can add given the "resin" factor but will endeavour to point you where I can.

So I followed Moai resin printer priciple. The only thing i did different is that i am using steppers for precision movements, and Moai is using 20kpps galvos. For now i am using 200 steps extruder nema 17 (a shorter version, so it can perform better at high speed direction changes, having less inertia).

My abordation is less common but is something that works.

Moai is using Cura software, and it draws in resin in the same way a fdm 3d printer is laying down plastic, and that makes the printer very slow! Because it does the same thing as fdm printers at the same speed, but using galvos and laser instead of hotend, and the max layer height is about 1mm, and the medium layer height of MOAI is 0.6mm, so it have significanly more layers.

MOAI is using an 120mw 405nm laser, that's why they need slow movements.

I will use 300mw or 500 mw 405nm laser, and will use the same algorith that LASER GRBL is using for engraving, doing multiple passes if needed, so my printer will perform way better in terms of time needed, and also requiering less efective accuracy then doing complex shspes using mirrors.

Instead of drawing complicated shapes that need a lot of accuracy, I want it to "scan" the area with one vertical laser movement and one horizontal one, and stop the laser where the resin will not be cured.

Belive me, it will work.

At the moment is a very big mess, and i dont have time to clean the build so i can show it.

All I need right now is how to hook up the magnetic encoder to act as a limit swich.

I belive that if i solder from a 2nd arduino a cable directly to the end switch pin of the cnc shield's arduino, then program the 2nd arduino to send a high signal when a certain value is recorded from the magnetic encoder, it will act as a limit swich.

I think i can made it works the same way that Marco Reps ( the guy with TMC drivers tutorial ) uses DIAG0 pins from tmc driver to send a high signal to the limit switches when the motors are crashing ( using crash avoiding system of the drivers).

In conclusion, I want to know what are the pins that GRBL 1.1 is using for limit switches, and if sending an high signal to it will tell to the GRBL that the limit was reached.

The actual pins are labelled on the CNC shield.

Usually 9,10,11 as shown here

ballscrewbob:
The actual pins are labelled on the CNC shield.

Usually 9,10,11 as shown here

Thanks.

And sending a high (or low, depending on $5 value i guess) signal to that pin would make grbl see it as an endswich input?

That depends on how the parameters have been set in GRBL as they can be high or low and that is up to you.