4 Attachment(s)
INVERT PWM SIGNAL IN GBRL 1.1f OUTPUT FOR LASER
Hello, I bought a small 5W LASER diode machine. I changed the STM32 original CPU and placed an Arduino Nano LASER CNC shield as my other similar machine has. This Lubandiy shield has optocouplers to completely isolate de power stages from the Arduino Nano module, even the ground signals are different. No schematics or manual were provided and couldn't find documentation in their website. Flashed GRBL 1.1f , and checked every signal coming from the Arduino to the Pololu stepper drivers. Pin D11 drives the IRF540 MOSFET for the PWM required for LASER beam modulation.
Everything is working fine except that the PWM output signal is inverted, low S command values lead to a high power beam and viceversa. The MOSFET optocoupler and related NPN transistor are inverting the signal making the shield unusable. Before I start cutting the board traces and installing an extra inverter in the middle of pin D11 and the optocoupler to invert the signal by hardware, I thought that the timer could be initialized to provide an inverted PWM.
The Atmel ATmega328P datasheet explains at 19.9.1 that COM1B1 and COM1B0 bits of the TC0 Control Register A set with "11", can produce this inverted output. The stepper_init() function found in stepper.c GRBL library module shows code that initializes the timer.
// Initialize and start the stepper motor subsystem
void stepper_init()
{
// Configure step and direction interface pins
STEP_DDR |= STEP_MASK;
STEPPERS_DISABLE_DDR |= 1<<STEPPERS_DISABLE_BIT;
DIRECTION_DDR |= DIRECTION_MASK;
// Configure Timer 1: Stepper Driver Interrupt
TCCR1B &= ~(1<<WGM13); // waveform generation = 0100 = CTC
TCCR1B |= (1<<WGM12);
TCCR1A &= ~((1<<WGM11) | (1<<WGM10));
TCCR1A &= ~((1<<COM1A1) | (1<<COM1A0) | (1<<COM1B1) | (1<<COM1B0)); // Disconnect OC1 output
// TCCR1B = (TCCR1B & ~((1<<CS12) | (1<<CS11))) | (1<<CS10); // Set in st_go_idle().
// TIMSK1 &= ~(1<<OCIE1A); // Set in st_go_idle().
// Configure Timer 0: Stepper Port Reset Interrupt
TIMSK0 &= ~((1<<OCIE0B) | (1<<OCIE0A) | (1<<TOIE0)); // Disconnect OC0 outputs and OVF interrupt.
TCCR0A = 0; // Normal operation
TCCR0B = 0; // Disable Timer0 until needed
TIMSK0 |= (1<<TOIE0); // Enable Timer0 overflow interrupt
#ifdef STEP_PULSE_DELAY
TIMSK0 |= (1<<OCIE0A); // Enable Timer0 Compare Match A interrupt
#endif
}
Attached: stepper.c and stepper.h files, Atmel daasheet, pictures of the shield and mentioned optocouplers.
Could somebody please help me change the code to obtain the PWM signal inverted correctly?
Thank you in advance
Roberto
Re: INVERT PWM SIGNAL IN GBRL 1.1f OUTPUT FOR LASER
The spindel PWM is set by void spindle_set_speed(uint8_t pwm_value). You find this in spindle_control.c.
Re: INVERT PWM SIGNAL IN GBRL 1.1f OUTPUT FOR LASER
The spindel enable pin is also used as PWM pin.
You probably can invert the output in the file config.h
// Inverts the spindle enable pin from low-disabled/high-enabled to low-enabled/high-disabled. Useful
// for some pre-built electronic boards.
// NOTE: If VARIABLE_SPINDLE is enabled(default), this option has no effect as the PWM output and
// spindle enable are combined to one pin. If you need both this option and spindle speed PWM,
// uncomment the config option USE_SPINDLE_DIR_AS_ENABLE_PIN below.
// #define INVERT_SPINDLE_ENABLE_PIN // Default disabled. Uncomment to enable.
change the last line to:
#define INVERT_SPINDLE_ENABLE_PIN // Default disabled. Uncomment to enable.
1 Attachment(s)
Re: INVERT PWM SIGNAL IN GBRL 1.1f OUTPUT FOR LASER
Thank you hfjbuis for you reply.
The solution you kindly offer is useful to switch the order of the spindle enable pin with the direction pin.
What I need is to invert the PWM signal, meaning that every time it is '1', it should change to '0' and viceversa.
This produces that LASER power gets inverted (or spindle speeds). Higher S command values will produce lower LASER powers (or spindle speeds) and viceversa.
I finally found the solution and it is working for me.
A change in the initialization of the timer that generates the PWM signal for a spindle motor with variable speed.
I added the following to the original cpu_map.h file in the Arduino GRBL library. Attached is the modified file.
At the top of the file I added a definition for 2 new bits COM2A0 and COM2A1 that the timer needs to be set in order to invert the output of the PWM signal:
#define INVERTPWM 1
If the inverting of the PWM signal is no needed (original GRBL) this line must be commented
Then, the code inside the SPINDLE_TCCRA_INIT_MASK can be altered as follows with a conditional compilation section:
#ifdef INVERTPWM
#define SPINDLE_TCCRA_INIT_MASK ((1<<COM2A0) | (1<<COM2A1)| (1<<WGM20) | (1<<WGM21)) // PWM INVERTED mode COM2A0 and COM2A1 bits are also set
#else
#define SPINDLE_TCCRA_INIT_MASK ((1<<WGM20) | (1<<WGM21)) // Configures fast PWM mode - NORMAL ORIGINAL GRBL
#endif
The COM2A0 and COM2A1 bits located in the TCCR2A register need to be set as part of the initialization to invert the output signal.
This will alter the functionality of the spindle_init() function inside the spindle_control.c module to correctly set the PWM timer for my needs.
In a hardware inverted configuration as in the shield I bought this is now working. Some other lines of code may need further change, but by now this is working fine as in any of my other little machines.
Problem solved.
Re: INVERT PWM SIGNAL IN GBRL 1.1f OUTPUT FOR LASER
Great to hear you got it working.
I have checked the grbl code (again) and did not find an option to invert the PWM output.
Thanks for sharing
Re: INVERT PWM SIGNAL IN GBRL 1.1f OUTPUT FOR LASER
You are right, to my knowledge there is not an "easy" option.
Since my new Arduino shield for LASER effectively inverts this signal by hardware, compared to many other similar shields that do not, it would have been nice to include an onboard jumper option for this purpose.
In this board the PWM signal path is: Arduino pin D11 => NPN transistor => PC817 optocoupler /// => NPN transistor => IRF540 PWM MOSFET gate
At first, I had properly skipped the MOSFET NPN transistor with a wire and the solution worked, after a copule of hours following the PCB with an Ohmmeter by hand. IMHO these 2 NPN transistors are unnecessary.
Maybe the GRBL development group would like to include this new option in future versions of the firmware.
Greetings from Buenos Aires, Argentina.
Re: INVERT PWM SIGNAL IN GBRL 1.1f OUTPUT FOR LASER
Quote:
Maybe the GRBL development group would like to include this new option in future versions of the firmware.
In the original grbl repository, the activity has stopped for some years now.
When I start controlling the spindel speed of my lathe (using PWM), I will add your changes to the GRBL-L-Mega repository. I will also try to add it to the GRBL-L repository but in this repository the the free code space is just a few bytes.
Regards from the Netherlands,
Huub
Re: INVERT PWM SIGNAL IN GBRL 1.1f OUTPUT FOR LASER
When I start controlling the spindel speed of my lathe (using PWM),
Quote:
I will add your changes to the GRBL-L-Mega repository. I will also try to add it to the GRBL-L repository but in this repository the the free code space is just a few bytes.
YES hfjbuis !! , please feel free to do that.
I would like to remark that I had touched the initialization of the timer just at the segment of code that filled my own needs. There could be the need to also touch a couple of extra lines for the case of normal operation for plain CNC use (not LASER) in which an axis motor is used. Please, this changes should be thoroughly tested before use. My version is now working fine after several hours of electronics printed circuit boards since last 48 hours.
Cheers !
Roberto
[email protected]
Re: INVERT PWM SIGNAL IN GBRL 1.1f OUTPUT FOR LASER
Roberto,
You are so right, changes should be thoroughly tested in all kinds of situations. That is the reason why I postpone this until I start using PWM spindle control for my lathe.
Huub
Re: INVERT PWM SIGNAL IN GBRL 1.1f OUTPUT FOR LASER
I was thinking about configuring an unused Arduino pin as a digital input to switch this option on and off (INVERTED / NORMAL). Maybe next week and I will post it here.
Re: INVERT PWM SIGNAL IN GBRL 1.1f OUTPUT FOR LASER
In that case you could also make a grbl $xx option to invert the pin.
Re: INVERT PWM SIGNAL IN GBRL 1.1f OUTPUT FOR LASER
hfjbuis I will take a look at that too, it is a great idea !
It could take some time though.
Thank you