How to set a LASER PULSE

Hello All. Hello Repetier,

I have probably a simple question but first here is my setup:

Atmega 2560 with RAMPS 1.4

Full Cartesian Printer

REPETIER_VERSION "0.92.8"

Configuration.h setup:

#define SUPPORT_LASER 1
#define LASER_PIN 44
#define LASER_ON_HIGH 1
#define LASER_PULSE 1000

I am using the printer with a pulsed laser (nd yag) so I am trying to modify the code to send an "on" or 255 at a pulse rate setup in Configuration.h as #define LASER_PULSE 1000. I'm not sure this is the best place to do this or the best way to do this.

I need to know where in the code I need to implement this pulse condition and if possible, could you give me a sample piece of code to accomplish this?

Thanks in advance.

robgs

  


Comments

  • You can not set pulse/intensity in the default code. The driver is written extendable so you can add a event to overwrite default behaviour. It is defined in driver.h/cpp. If you see the simple code it should be clear how to add own behaviour.







    #if defined(SUPPORT_LASER) && SUPPORT_LASER

    uint8_t LaserDriver::intensity = 255; // Intensity to use for next move queued if we want lasers. This is NOT the current value!

    bool LaserDriver::laserOn = false;

    void LaserDriver::initialize()

    {

        if(EVENT_INITALIZE_LASER)

        {

    #if LASER_PIN > -1

            SET_OUTPUT(LASER_PIN);

    #endif

        }

        changeIntensity(0);

    }

    void LaserDriver::changeIntensity(uint8_t newIntensity)

    {

        if(EVENT_SET_LASER(newIntensity))

        {

            // Default implementation

    #if LASER_PIN > -1

            WRITE(LASER_PIN,(LASER_ON_HIGH ? newIntensity > 199 : newIntensity < 200));

    #endif

        }

    }

    #endif // SUPPORT_LASER

  • Hello Repetier and thank you for the reply. :)
    Yes. Through trial and error i did find that code (as im just learning c++). I noticed that alternating

    uint8_t LaserDriver::intensity =

    between 255 and 0 does turn the laser on and off which is fine for a CW style laser. But, again im limited in c++ programming, how can i write the code to set a "pulse" output at the Laser_pin? Can you give me some sample code to accomplish this?

    Thanks
  • If that is a pwm pin with a timer not used by firmware you could simply use arduinos analogWrite command. The main problem is normally you need a high pulse rate to cover the complete line with pulses. Depends of course on laser diameter and speed.

    Other solution would be a hardware board with pwm timer programmable with SPI so you coudl use a software spi to program the chip to du the pulses.

    For my little laser it is enough to change intensity by changing move speed instead.
  • edited April 2016
    Hi RepRoland. Yes. Ive been contemplating that solution as well (using a seperate board or card) but i will have other uses for the pulse that need to coincide with the laser firing... and yes im sure i can still accomplish this with more IO but id like to see if this can be done with no add-on's.
    The pin d44 is a digital pin, i believe with no pwm, and i would like to keep it that way if i can. The behavior of the code "as is" when i run the default settings is perfect except the laser stays on continually.
    To try to get a pulse, the only thing ive done that works so far is a loop in the

    WRITE(LASER_PIN,(LASER_ON_HIGH ? newIntensity > 199 : newIntensity < 200));
    and
    WRITE(LASER_PIN,(!LASER_ON_HIGH ? newIntensity > 199 : newIntensity < 200));

    Section of code. But then the loop causes communication issues.

    So it would be nice if someone can suggest a bit of code that will work to accomplish this and a proper place to put the code.

    But perhaps im not understanding you. If you are saying i can change the pin to a pwm pin and leave the default settings. Then i could ( if i knew how) modulate the pin between 0...255? Is that possible?
  • Just looking at the schematic and from what i see posted, p44 is a digital PWM pin so modulating can be done there. Its an interesting concept which could work if i can get very low frequencies like 2 or 3 Hz.

    Im going to have to read up on PWM and its coding

    Again im just learning so most of my comments are going to be pretty elementary at this point and my code is going to be very "hack". But any help is appreciated.
  • Why do you want low frequencies like 2 or 3 hz? Don't you want a continious line?

    Anyhow pin 44 uses time 5 whcih is not used by firmware, so you could use the hardware pwm with the arduino funtion for example.
  • edited April 2016
    Hi Repetier.
    i really like that idea because it would accomplish exactly what i need. My laser has a max pulse output of 1 kHz and even at that i think it would go through bulbs like crazy. Its a flash lamp pumped nd yag and the bulbs are $360 US so its in my financial best interest to keep the pulse rate low. At this point the speed of the machine movement at a very slow rate will be sufficient.

    The default code (not using the CUSTOM_EVENTS), which is very well written by the way ☺, works exactly the way i want. Im not using a special software like inkscape to generate G3 S*** commands because it isnt what im doing with the machine. Im just using repetier host with slic3r. If i add the M452 to gcode to slic3r with no M3 commands, and start a print, repetier fires exactly at the start of each layer and shuts off during moves which is perfect. I just need it to fire at a required frequency. Im using relay logic to communicate with the laser so thats another reason to keep the frequency down. If i find i need higher frequency ill switch to TTL, but relay will work just fine for now.. and its simpler.

    Without adjusting the frequency for the PWM pin 44, the best result ive got is to modify the code to loop

    LaserDriver::changeIntensity = 255
    and
    LaserDriver::changeIntensity = 0

    using an appropriate trigger that stays "true" only during the realtime print of the current layer. So far ive been using fanSpeed == cur->secondSpeed && linesCount != 0. This works ok but the laser is on during the initial move which is not good. But works perfect for all layers after that. Can you suggest a trigger that would work better?

    As well, the PWM will ultimately work the best because i can leave the repetier code as-is and do the frequency through the pin 44. Can you tell me a good way to modulate that pin at full 5 vdc @ 1Hz - 1kHz?

    I am going to create two firmware versions with the two methods. I will use the one that works the best for what i am doing.

    Thanks for your help Repetier!
  • If you need full control over the pwm wave form, you need to read the AVR data sheet. It explains exactly which wave forms are available and how to set them. It is a bit difficult to understand but for exact control you need to know that stuff.

    Apart from this I have problems to understand exactly what you try to achieve. But I only have a simple led laser, no nd yag which seems to have some other input. But I can still not understand how you can cut a line with 10hz unless you move with 1mm/s.
  • edited May 2016

    Hi Repetier. Yes. I downloaded the avr data sheet. Its pretty complex so it will take me some time to understand. i'll work on that solution last as i dont want to mess my current settings until im comfortable i know what im doing.

    You're absolutely right. Im currently running my machine at 1 mm/s. Speed is not important to me right now. I'll set the speed faster when i do some performance testing.


    But what will help me the most at this moment is if you can tell me the part of the code that i can use in my "while" loop to ensure the laser isnt coming on during the first move. Im having a hard time locating it in the code. Your code turns the laser on perfectly at the start of the print line and off when its finished the printline... except its on constantly with no pulse. Im trying to leave your code as is, and adding a simple loop so that i can set a pulse frequency.

    Here is the loop I'm using:



    #if defined(SUPPORT_LASER) && SUPPORT_LASER
                {
                    // disable laser for G0 moves
                    bool laserOn = LaserDriver::laserOn;
                    if(com->G == 0 && Printer::mode == PRINTER_MODE_LASER) {
                        LaserDriver::laserOn = false;

    if(Printer::mode == PRINTER_MODE_LASER) {

       while ("Need trigger here :)") {

          LaserDriver::changeIntensity(255);
          Com::printFLN(PSTR("LaserOn:"));
          HAL::delayMilliseconds(LASER_PULSE);
          LaserDriver::changeIntensity(0);
          Com::printFLN(PSTR("LaserOff:"));
           HAL::delayMilliseconds(LASER_OFF_DURATION);

         }

    }

    I know it's probably not the best way or place to put the code, but it seems to work except it turns the laser on for the first move into position to print the first layer. all other layers after that are OK. If you could suggest a better way or place to accomplish this that would be great!

    I got a lot to learn, but we all got to start somewhere :)


    Thanks.

  • I try to understand what you´re doing so why don´t you add an external pulse generator to the laser output?
    means pulses start/stop  is triggered by laseron/off .
    pulses generated by for example CD4047 or if you want to change pulse/pause separately f.e.by 74hc4538
  • edited May 2016
    Hi RAyWB.
    I just looked that up. Yes im sure i can add more to my setup but id like to try it without adding any extra components if i dont have to. ;).

    It just seems more simple to add a "blink" to the existing code. But im no expert.
  • Hey. Good news. It turns out the code i wrote above works just fine. As i was trying different code to set my "while" loop, i started looking at the setup of slic3r. The pre print code was setting the fan to 255 as soon as the printer started its move to the first layer start position. So i just made sure that command was below 200 and now the laser pulses at the frequency i choose only while printing a line.
    Now ill work on the pwm method to create the pulse.
  • Not sure why you think so complicated. Take a look at the LaserDriver class in Drivers.cpp. It has a enable/disable function where you simply set PWM in enable according to intensity. No need to find all code parts. YOu can also not use a while look to pulse - that woudl block rest of firmware. That's the fine thing about pwm. Once set it does it in hardware without surveilance needed.
  • edited May 2016
    Hi Repetier. Thanks for the hint. Ill look in that section to set the pwm. Ive been reading up on the PWM and the lowest frequency it can be set to. Setting the devisor (prescaler) to 1024 should give me < 30Hz... does that sound right? Can i vary that devisor at any time to give me different frequencies?

    I wont run the two different ways (ie PWM and loop statement) together. I am making two different versions of the firmware. One with PWM and the other with a loop statement. Then i will see which one will work best for my application.

    Repetier, i find some of this complicated because im new to arduinos and c++ programming. Ive found the best way I learn is to dive in at the deep end of the pool. Its problems like these that help me to learn the most, learning from ppl like you the experts :).



  • One easy solution is temperature timer in HAL.cpp. It gets called 3906 times per second. You could use that for a easy solution to set low frequencies.

    Hardware timer can be changed any time, that is also possible.  30Hz might be possible. Or 61 Hz if you switch every time counter is 255.
  • Thanks Repetier. Ill check it out and let you know what i find.
Sign In or Register to comment.