CNC/Laser Engraver using G120

I’m considering to make a large format CNC/Laser Engraver and maybe even bubble jet color printer combination using G120TH or FEZ Cobra III board

I’m new to NETMF and I’m looking for suggestions from experienced in NETMF people.

Issue #1
I don’t think that controlling several stepper motors by switching digital pins on and off in managed .net code will be fast. SPI or i2c motor drivers are out of the question as it probably will be impossible to synchronize.

Issue #2
G120TH or FEZ Cobra III boards may not have enough pins to connect all devices:
[ul]Touchscreen display (25 pins?)
WiFi module (6 pins?)
Minimum 3 motor drivers (2 digital out pins for each motor)
Minimum 3 limit switches (1 digital out pin for each switch).
Spindle On/Off (1 digital out pin)
Spindle/laser speed control (1 PWM pin)
Step resolution (2 digital out pins)
Definitely will not have enough pins to control 4 print cartridges for color printer option (12 nozzles per cartridge = 48 pins total) Each nozzle is controlled by sending one or more 5μs pulses with a minimum 800μs delay between two pulses on a given nozzle[/ul]
Possible consideration to fix both issues:
One of possibles solution that I can thing off right now is to use several Arduino boards to control stepper drivers and print cartridges and G120 board as a controller for Arduino over SPI or other methods. This could save me several digital out pins and resolve a speed issue…

I already have g-code parser/interpreter written in NETMF, and this in my opinion is the major part of a software.

Oh… It’s going to be a long thread…

1 Like

I take it you’re not thinking of making a custom board that has the drivers, MCU, etc. all on one board? If you are then I would think a G120 SOM or maybe even the G400-D would be a better choice. But, if you’re just talking about your first prototype then the Cobra III is probably the easier option. Compute power-wise they’re the same.

I guess my biggest question is why? What are you trying to achieve? For the same amount of money (or less) there are already existing options but they are not C#. If it’s just for the heck of it then that’s certainly a valid and noble reason, too!

I’ve often thought where NETMF could really shine in the 3D printer system is in the display panel. An add-on system that had a 5"-7" display coupled with a G120 SoM and some @ Skewworks UI goo would make for a really sexy display. Just have connections so that it can interact with the main controller board and display controls, graphs, etc. w/o the main controller having to do anything. Something that’s basically plug&play compatible with a VIKI and/or RRD Smart Controller.

I need this device just for a heck of it, and I could not find already existing options to achieve functionality (Laser/CNC engraver and Bubble jet printer combination) . Even if I find one, its probably would be not what I imagine and hard to use. Most of the open source controllers require to use multiple per-processing software to generate g-code and this is not my goal.

Since I can program almost anything in .NET on Windows, I can go with easier solution:
I develop interface and most of per-processing on windows and cheap windows tablet with USB connected Arduino Mega just to control motors and print cartridges (in one enclosure). But I do want to use NETMF

I’m willing to spend some money on this project.

I would really love to be able to use NETMF for this too, but it just seems too slow and unpredictable. If you use the multithreading then you are limited to the approximately 20ms thread scheduler. Thats a maximum pulse rate of 50hz and the next speed step after that is 25hz so you cant really do nice accelerations or jerk control. There maybe a way to do it with PWM ports, but then you need to accuratly track the number of pulses and stop it perfectly.

I guess it can probably be done with RLP though.

Unpredictable? Explain.

@ EvoMotors - unpredictable because you can not garantee the exact timing of things.

Say you want to move at 100mm per second. Avout normal for a travel move. With normal stepper motor gearing this might require about 100 steps per mm. To do this you need to generate pulses at up to 10KHz. Any jittter on it will cause the stepper to do weird things. All while parsing g-code and running a display. Add in garbage collection pauses and its just not even close.

So you mean that I cannot trust micro controller to perform coded instructions?

PWM not going to work, but SignalGenerator may wok if I correctly understand the functionality.

Can someone explain what the exactly these 2 elements in the time array represents in this code example?

        uint[] time = new uint[] { 500 * 1000, 500 * 1000 };
        SignalGenerator LED = new SignalGenerator(Cpu.Pin.GPIO_Pin1, false);

        // args:  
        //        initial value
        //        array of times,
        //        array start offset,
        //        length of array,
        //        repeat -- if true ==> repeat
        LED.Set(false, time, 0, 2, true);//start the waveform

You cant trust a high level OS to do things with accurate timing. A bare metal uController is totally predictable. The datasheet tells you exactly how many clock cycles each instruction takes. Even then normally you would use a hardware interrupt to make sure things happened on the correct clock tick. These interrupt controllers are abstracted away from you in netMF.

I think you can do it with RLP though. There is a call back function that seems to be very reliable. You can use this for audio recording for instance. It might even be using a hardware interrupt under the surface.

@ hagster -
What about SignalGenerator? Can you control frequency and pulse count using it?
I still not sure what elements in time array represents. Is first element of the array is the duration of ON and second is duration of OFF states?

I will try to avoid RLP if I can for now as I feel more comfortable programming in .NET

It is not possible to drive a stepper motor correctly with the managed framework. It is however possible with RLP. Also there is a SPI stepper controller that you can use which will allow you to have synchronicity.

Where did you get a NETMF based G-Code parser from?

Actually I already doing it using SignalGenerator blocking calls with A4988 driver and it works! Not just works but works perfectly.

private SignalGenerator XStepPort = new SignalGenerator(GHI.Pins.FEZCobraIII.Gpio.D7, false);
private OutputPort XDirectionPort = new OutputPort(GHI.Pins.FEZCobraIII.Gpio.D6, false);
private uint StepsPerMmX = 100;

private double Abs(double val)
    return (val < 0) ? -val : val;

private uint GetIntervalForFeedRate(float mmPerMinute)
    return (uint)(60000000 / (mmPerMinute * StepsPerMmX));

private void MoveX(double distance, int mmPerMinute)
    XDirectionPort.Write(distance > 0);
    uint interval = GetIntervalForFeedRate(mmPerMinute) / 2;
    uint steps = (uint)(StepsPerMmX * Abs(distance));

    uint[] timingBuffer = new uint[steps * 2];

    for (int i = 0; i < steps * 2; i++)
        timingBuffer[i] = interval;

    XStepPort.SetBlocking(false, timingBuffer);

private void TestCW()
    MoveX(50, 500);

private void TestCCW()
    MoveX(-50, 500);

I didn’t tried with non-blocking as blocking works perfectly for me as I need to know when motor is in position. And you are correct RLP may be better option as I could probably implement none blocking SignalGenerator in RLP end set hardware pin to “off” before start and to “on” when movement completes.

You’re not going to be able to drive multiple steppers at once with blocking calls (f.e. for a diagonal move). Also, while your RLP procedure is running, I believe NETMF is effectively paused, meaning you can’t do things like parse GCODE, or calculate the next move, or anything else in C#.

Looks like I can use the non-blocking calls to move multiple steppers at once as the SignalGenerator provides the functionality to check if it finished toggling or not.

// Summary:
//  Whether or not the pin is currently being toggled.
public bool Active { get; }

@ EvoMotors - Yes, possible. One disadvantage might be that it could be up to 20ms or more before that code runs, so it might have stopped running up to 20ms ago. For a laser engraver especially that 20ms might be significant :slight_smile:

And you are correct! But well see how it goes.

[quote]The one who falls and gets up is so much stronger than the one who never fell!![/quote] :wink:

Still have one issue. The slowest part of the code is:

int steps = 16000;
uint interval = 200;

uint[] timingBuffer = new uint[steps];
for (int i = 0; i < steps; i++)
     timingBuffer[i] = interval;

Is there a faster way to populate array in NETMF?

I’m positive that those steppers aren’t being driven correctly. However, they will move with the c# code. There used to be a class called Parallel Port, that allows you to set 8 pins (certain pins) guaranteed simultaneously from c#. I don’t know if its still around though.

@ EvoMotors - Populate? No, but creating the array each time is extremely expensive; only create it once and repopulate it each time.

I will verify movement curacy on different speeds when I install at least one of them on a rail.