Go Down

Topic: CDI tester project (Read 14331 times) previous topic - next topic

cattledog

Quote
I also noted  that changing the OCR1B value does not change the width of the pulses
I just saw your edit about pulseWidth. Here is the section of code which sets it to one degree. The actual pulseWidth time varies with RPM. You can change the math for any length you want. What did you have in mind?

Code: [Select]
pulseWidth = (60000000/RPM)/360; // time for 1° in us

    timerTopValue = 15000000UL / RPM;
    OCR1B = pulseWidth;
    OCR1A = OCR1B + pulseWidth; //2*pulsewidth



Quote
I have been unable to put any separation between them as I think I will need to do. I think that just putting milliseconds there won't be ideal as the pulse separation should be based on rpm since the faster it turns the shorter the time.
How long of a gap do you want? You might be able to get away with using a gap of less than 10 microseconds by using some no operations (NOP) to create a delay in the COMP_B isr. The number of NOP's called can vary with RPM.

Longer than that, we may need to go back to the bipolar pulse code with the period divided into two parts. 

I also think that if you can put the outputs on pins 9 and 10  it might open some options as we can use the hardware pwm outputs to turn the two pins on and off with a variable gap between them.



tom_bauer

#271
May 01, 2019, 04:37 am Last Edit: May 01, 2019, 04:54 am by tom_bauer
OK 9 and 10 are available. What I was thinking, not understanding timers, was a way to have the gap between the pulses be a function of degrees. If pulseWidth is 1° then how would you put 4° gap for instance. That way the gap would narrow along with the actual pulse width.

What I was asking earlier was regarding line 76:
OCR1B = 500; // sets trigger pulse width, 500 = 2Ms, 250 = 1Ms, 125 = .5Ms, set to 1250 for 5013
I used to be able to set the pulse width here but not now, was curious why.
Tom

cattledog

Quote
If pulseWidth is 1° then how would you put 4° gap for instance. That way the gap would narrow along with the actual pulse width.
This is starting to sound alot like the bipolar pulse code where the pulse separation was set by barWidth, and was based on degrees. I will look at modifying that code to make the two pin output separated by a degree value which can be variable with a pot and read in the loop along with RPM and pickup.

Can you test the hardware for the two pulses by putting a delayMicroseconds() call in the COMP_B isr where I indicated with the comment?

tom_bauer

Yes I will do that in morning. Don't put any time into it yet, I need to see what the output of the transformer looks like. It does not need to be variable with a pot, just set for the best response from transformer and The magnetic characteristics will determine most of that.
Tom

cattledog

Quote
OCR1B = 500; // sets trigger pulse width, 500 = 2Ms, 250 = 1Ms, 125 = .5Ms, set to 1250 for 5013
I used to be able to set the pulse width here but not now, was curious why.
This is just a placeholder in setup. It may have come from original development when RPM was hard coded before the value was put on a pot for adjustment, or from an earlier time when we were working with time values and not degrees.   

The setup default is overridden by the setting in loop when the RPM pot is read.

tom_bauer

Hi, well the transformer had more magnetic ringing issues than it is worth dealing with so version 15 looks to be the one I will use. I never did figure out how to not start the second timer as you noted. Thanks for all the help, if someone wants to see the schematic for this I can upload it, it is very useful for testing.
Best, Tom

cattledog


Quote
I never did figure out how to not start the second timer as you noted.
Remove the timing start from the COMP_B isr.

Code: [Select]
ISR(TIMER1_COMPB_vect) {
  digitalWrite(outputPin, LOW);

 // {
 //   delayPeriodStart = micros(); // start looking for response as pulse falls
 //   trigger = true;
  //}
}


This removes the delay timing start the falling edge of the trigger pulse. If you want to use it, remove the equivalent code from the COMPA ISR which starts the timing from the rising edge. The two edges are separated by 1 degree, so the timing change is not large.

If you are not sure of what you want to use, you can put the R/F edge selector code back.



tom_bauer

Cattledog,
OK thanks, I see that now and start to understand! Well thanks for all the help, I will be putting this together in a week or so.
Best, Tom

tom_bauer

Cattledog,
While working with several small transformers I think that the core may being saturated at higher rpm so I would like to narrow the pulse width for the charge pulses. I am not clear on how to do that.
Thanks, Tom

cattledog

Tom--

Please post the code you are currently using, and want me to modify. Currently, the 5 charge pulses are 30 degrees wide. I can see a way to easily give you the same 5 pulses either 15 degrees wide or 10 degrees wide.

The code currently divides the 360 degree period into 12 slices of 30 degrees, but turns on and off every other slice. I can easily modify the code to make 24 slices of 15 degrees and 36 slices of 10 degrees.

I've not really looked close enough to see how to get complete flexibility. But I'd like so see what you need.

tom_bauer

Here is the code that I settled on, 15A, it does everything well. I think going to 10° charge pulse width from 30° will show me if the saturation of the core is the issue.
Tom

Code: [Select]

// last change 4/21/2019
// 8/17 added code for pulse out width
// 7/14/2017 added correct math and setting for position of pickup
// 10 10/28/2016 adds charging pulse with Timer 2
// lowest RPM = 615 with charge pulse to keep OCR2A <= 255
// CDI Tester Pulse Generator Serial Output Arduino Code
// replaced on 7/22/18 mod on 4/18/2019 changed to go simple transformer control of pos / neg trigger
// update 7/14/2017 added correct math and setting for position of pickup
// revision 10 10/28/2016 adds charging pulse with Timer 2
// lowest RPM = 615 with charge pulse to keep OCR2A <= 255
// CDI Tester Pulse Generator Serial Output Arduino Code
// 8/17 added code for pulse out width

#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h> // include i/o class header
hd44780_I2Cexp lcd; // declare lcd object: auto locate & config display for hd44780 chip

int pot1 = A1; // select the input pin for the pot for rpm
int pot2 = A2; // select the input pin for the pot for pickup location in degrees
int potValue = 0; // variable to store the value coming from the sensor
int pickupValue = 0; // position of pickup in degrees
int timerTopValue = 12500; // changed from timerTopValue = 0
int outputPin = 4; // select the pin for the output for trigger pulse, changed from 8
int output2Pin = 5;
int chargePin = 7; // select the pin for the output for charge pulses

volatile boolean trigger = false;
volatile unsigned long delayPeriod;
unsigned long copy_delayPeriod;
volatile unsigned long delayPeriodStart;
float delayDegrees; // changed from int to float for decimal place display
int RPM;
int pickup;
int pulseWidth;
volatile boolean interruptFlag;
unsigned long analogReadInterval = 500; // read pots and map
unsigned long lastAnalogRead;
const byte setChargePulseSwitch = 6;
boolean chargePulse = false ;  // default dc powered mode
volatile byte timeSliceCount = 0; // TDC 0 degrees

void setup() {
// Serial.begin(115200);
// Serial.println("starting...");
  lcd.begin(20, 4); // initialize the lcd for 20 chars 4 lines, turn on backlight
  lcd.setCursor(1, 0); // lcd display setup of unchanging headings
  lcd.print("RPM:"); // print fixed characters
  lcd.setCursor(12, 0);
  lcd.print("Deg");
  lcd.setCursor(1, 1);
  lcd.print("Pos:");
  lcd.setCursor(1, 2);
  lcd.print("Us Delay:");
  lcd.setCursor(1, 3);
  lcd.print("Deg Advance:");

  pinMode(outputPin, OUTPUT); // declare the outputPin as an OUTPUT
  pinMode(output2Pin, OUTPUT);
  pinMode(chargePin, OUTPUT); // declare the chargePin as an OUTPUT
  pinMode(setChargePulseSwitch, INPUT_PULLUP);

  if (digitalRead(setChargePulseSwitch) == LOW)
    chargePulse = true; // AC CDI

 // Timer1 default set up .5ms trigger pulse every 50 ms
  TCCR1A = (1<< WGM11);//Fast PWM to ICR1
  TCCR1B = (1 << WGM13) | (1 << WGM12);
  //TCCR1B = (1 << WGM12); // CTC mode to OCR1A
  TCCR1B = (1 << WGM13) | (1 << WGM12);//CTC mode to ICR1
  //OCR1A = timerTopValue;
  ICR1 = timerTopValue;
  TIMSK1 |= (1 << OCIE1A); // interrupt enable compareA
  TIMSK1 |= (1 << OCIE1B); // interrupt enable compareB
  TIMSK1 |= (1<< TOIE1);//overflow interrupt at top
  OCR1B = 250; // sets trigger pulse width, 500 = 2Ms, 250 = 1Ms, 125 = .5Ms, set to 1250 for 5013 *********************************************
  OCR1A = OCR1B +500;//add default
  TCCR1B |= (1 << CS11) | (1 << CS10); // prescaler 64 4us/tick

// Timer2 default setup charge pulse 12 periods 30 degrees each; only 5 get turned on
// charge pulse timing interval = Timer1 trigger period/12 = timerTopValue/96
  TCCR2A = 0;
  TCCR2B = 0;
  TCCR2A = 1 << WGM20; // lsb of mode 7 pwm to OCR2A
  TCCR2B = 1 << WGM22; // msb of mode 7 pwm to OCR2A;
  OCR2A = timerTopValue / 96; // 96 = 12*4*2 (#periods, prescaler difference, up/down timer mode )
  TIMSK2 = 0;
  TIMSK2 = 1 << TOIE2; // enable overflow interrupt
// actually start timer in ISR(TIMER1_COMPA_vect
// to prevent out of sync charge pulse, no prescaler set here

  attachInterrupt(digitalPinToInterrupt(3), delayPeriodTiming, FALLING);

}

void loop()
{
  unsigned long analogReadInterval = 500; // read pots and map
  if (millis() - lastAnalogRead >= analogReadInterval)
  {
    lastAnalogRead += analogReadInterval;
    potValue = analogRead(pot1); // rpm
    pickupValue = analogRead(pot2); // pickup position

    if (digitalRead(setChargePulseSwitch) == LOW)
    chargePulse = true; // AC CDI
    else chargePulse = false;
   
// Timer2 OCR2A requires max value 255 => 615 lowest RPM
// if (chargePulse)
    {
      RPM = map(potValue, 0, 1023, 615, 10000);
      pickup = map(pickupValue, 0, 1023, 10, 75); // position so advance will read based on delay, 57 for yamaha 350 2 pu, 74 for 1 pu, 72 for tw200, 25 for 5013
      pulseWidth = (60000000/RPM)/360; // time for 1° in uS
    }

    timerTopValue = 15000000UL / RPM;
    OCR1B = pulseWidth;
    OCR1A = OCR1B + pulseWidth;

    lcd.setCursor(6, 0);
    lcd.print("     "); // print blank spaces to clear old data
    lcd.setCursor(6, 0);
    lcd.print(RPM);  // print rpm

    lcd.setCursor(16, 0);
    lcd.print("  ");
    lcd.setCursor(16, 0);
    lcd.print(pulseWidth, 1); // print us per degree
   
    lcd.setCursor(6, 1);
    lcd.print("   ");
    lcd.setCursor(6, 1);
    lcd.print(pickup); // print pickup coil position

    lcd.setCursor(11, 2);
    lcd.print("       ");
    lcd.setCursor(11, 2);
    lcd.print(copy_delayPeriod);
   
    lcd.setCursor(14, 3);
    lcd.print("      ");
    lcd.setCursor(14, 3);
    lcd.print(delayDegrees, 1);   // delayDegrees, 1);
  }
 
  if (trigger == true && interruptFlag == true )
  {
    trigger = false;
    interruptFlag = false;
    noInterrupts();
    copy_delayPeriod = delayPeriod;
    interrupts();

    delayDegrees = pickup - (360.0 * (copy_delayPeriod) / (timerTopValue * 4.0)); // for decimal place in deg display.
    }
}

//ISR(TIMER1_COMPA_vect) {
ISR(TIMER1_OVF_vect){
  //OCR1A = (timerTopValue); // value to set delay between pulses to trigger cdi
  ICR1 = (timerTopValue);
  digitalWrite(chargePin, LOW); // guarantee off charge pin at trigger
  digitalWrite(outputPin, HIGH); // turn on pin  trigger

  {
    delayPeriodStart = micros(); // start looking for response as pulse rises
    trigger = true;
  }
// start Timer 2 for charge pulses
  if (chargePulse)
  {
    timeSliceCount = 0;
    TCNT2 = 0;
    OCR2A = timerTopValue/96; // set 12 periods
    TCCR2B |=  1 << CS22 | 1 << CS21; //prescaleer 256 16us/tick
  }
}

ISR(TIMER1_COMPB_vect) {
  digitalWrite(outputPin, LOW);
  //could add short delayMiocroseconds here for gap
  digitalWrite(output2Pin,HIGH);

  //{
  //  delayPeriodStart = micros(); // start looking for response as pulse falls
  //  trigger = true;
  //}
}

ISR(TIMER1_COMPA_vect) {
  digitalWrite(output2Pin, LOW);
}

void delayPeriodTiming()
{
  delayPeriod = micros() - delayPeriodStart;
  interruptFlag = true;
}

ISR(TIMER2_OVF_vect)
// 5 pulses of 30 degrees starting at 60 degrees
// ON at 60,120,180,240,300 = 2,4,6,8,10
// OFF at 90,150,210,270,330 = 3,5,7,9,11
{
  if (timeSliceCount != 0 && timeSliceCount % 2 == 0)
  {
    digitalWrite (chargePin, HIGH);
  }
  else // if (timeSliceCount == 0 || timeSliceCount % 2 == 1)
  {
    digitalWrite(chargePin, LOW);
  }
  timeSliceCount++;

  if (timeSliceCount == 12)
  {
    timeSliceCount = 0;
// stop Timer2 by clearing prescaler bits
    TCCR2B &= ~1<< CS22;
    TCCR2B &= ~1<< CS21;
  }
}

cattledog

#281
May 11, 2019, 01:33 am Last Edit: May 11, 2019, 01:34 am by cattledog
I think this will give 5 pulses of 10 degrees width starting at 60, 120, 180, 240, 300. Instead of creating 12 periods for a cycle I used 36, and turn on with modulo 6 (%6) instead of modulo 2(%2). Please verify with a scope as I have not done any testing. I have not looked closely if there are minimum or maximum rpm requirements. If the shorter pulse is important, we can test deeper.

Code: [Select]
//change charge pulse to 10 degrees from 30
// last change 4/21/2019
// 8/17 added code for pulse out width
// 7/14/2017 added correct math and setting for position of pickup
// 10 10/28/2016 adds charging pulse with Timer 2
// lowest RPM = 615 with charge pulse to keep OCR2A <= 255
// CDI Tester Pulse Generator Serial Output Arduino Code
// replaced on 7/22/18 mod on 4/18/2019 changed to go simple transformer control of pos / neg trigger
// update 7/14/2017 added correct math and setting for position of pickup
// revision 10 10/28/2016 adds charging pulse with Timer 2
// lowest RPM = 615 with charge pulse to keep OCR2A <= 255
// CDI Tester Pulse Generator Serial Output Arduino Code
// 8/17 added code for pulse out width

#include <Wire.h>
#include <hd44780.h>
#include <hd44780ioClass/hd44780_I2Cexp.h> // include i/o class header
hd44780_I2Cexp lcd; // declare lcd object: auto locate & config display for hd44780 chip

int pot1 = A1; // select the input pin for the pot for rpm
int pot2 = A2; // select the input pin for the pot for pickup location in degrees
int potValue = 0; // variable to store the value coming from the sensor
int pickupValue = 0; // position of pickup in degrees
int timerTopValue = 12500; // changed from timerTopValue = 0
int outputPin = 4; // select the pin for the output for trigger pulse, changed from 8
int output2Pin = 5;
int chargePin = 7; // select the pin for the output for charge pulses

volatile boolean trigger = false;
volatile unsigned long delayPeriod;
unsigned long copy_delayPeriod;
volatile unsigned long delayPeriodStart;
float delayDegrees; // changed from int to float for decimal place display
int RPM;
int pickup;
int pulseWidth;
volatile boolean interruptFlag;
unsigned long analogReadInterval = 500; // read pots and map
unsigned long lastAnalogRead;
const byte setChargePulseSwitch = 6;
boolean chargePulse = false ;  // default dc powered mode
volatile byte timeSliceCount = 0; // TDC 0 degrees

void setup() {
// Serial.begin(115200);
// Serial.println("starting...");
  lcd.begin(20, 4); // initialize the lcd for 20 chars 4 lines, turn on backlight
  lcd.setCursor(1, 0); // lcd display setup of unchanging headings
  lcd.print("RPM:"); // print fixed characters
  lcd.setCursor(12, 0);
  lcd.print("Deg");
  lcd.setCursor(1, 1);
  lcd.print("Pos:");
  lcd.setCursor(1, 2);
  lcd.print("Us Delay:");
  lcd.setCursor(1, 3);
  lcd.print("Deg Advance:");

  pinMode(outputPin, OUTPUT); // declare the outputPin as an OUTPUT
  pinMode(output2Pin, OUTPUT);
  pinMode(chargePin, OUTPUT); // declare the chargePin as an OUTPUT
  pinMode(setChargePulseSwitch, INPUT_PULLUP);

  if (digitalRead(setChargePulseSwitch) == LOW)
    chargePulse = true; // AC CDI

 // Timer1 default set up .5ms trigger pulse every 50 ms
  TCCR1A = (1<< WGM11);//Fast PWM to ICR1
  TCCR1B = (1 << WGM13) | (1 << WGM12);
  //TCCR1B = (1 << WGM12); // CTC mode to OCR1A
  TCCR1B = (1 << WGM13) | (1 << WGM12);//CTC mode to ICR1
  //OCR1A = timerTopValue;
  ICR1 = timerTopValue;
  TIMSK1 |= (1 << OCIE1A); // interrupt enable compareA
  TIMSK1 |= (1 << OCIE1B); // interrupt enable compareB
  TIMSK1 |= (1<< TOIE1);//overflow interrupt at top
  OCR1B = 250; // sets trigger pulse width, 500 = 2Ms, 250 = 1Ms, 125 = .5Ms, set to 1250 for 5013 *********************************************
  OCR1A = OCR1B +500;//add default
  TCCR1B |= (1 << CS11) | (1 << CS10); // prescaler 64 4us/tick

// Timer2 default setup charge pulse 36 periods 10 degrees each; only 5 get turned on
// charge pulse timing interval = Timer1 trigger period/12 = timerTopValue/96
  TCCR2A = 0;
  TCCR2B = 0;
  TCCR2A = 1 << WGM20; // lsb of mode 7 pwm to OCR2A
  TCCR2B = 1 << WGM22; // msb of mode 7 pwm to OCR2A;
  //OCR2A = timerTopValue / 96; // 96 = 12*4*2 (#periods, prescaler difference, up/down timer mode )
  OCR2A = timerTopValue / 288; //  = 36*4*2 (#periods, prescaler difference, up/down timer mode )
  TIMSK2 = 0;
  TIMSK2 = 1 << TOIE2; // enable overflow interrupt
// actually start timer in ISR(TIMER1_COMPA_vect
// to prevent out of sync charge pulse, no prescaler set here

  attachInterrupt(digitalPinToInterrupt(3), delayPeriodTiming, FALLING);

}

void loop()
{
  unsigned long analogReadInterval = 500; // read pots and map
  if (millis() - lastAnalogRead >= analogReadInterval)
  {
    lastAnalogRead += analogReadInterval;
    potValue = analogRead(pot1); // rpm
    pickupValue = analogRead(pot2); // pickup position

    if (digitalRead(setChargePulseSwitch) == LOW)
    chargePulse = true; // AC CDI
    else chargePulse = false;
   
// Timer2 OCR2A requires max value 255 => 615 lowest RPM
// if (chargePulse)
    {
      RPM = map(potValue, 0, 1023, 615, 10000);
      pickup = map(pickupValue, 0, 1023, 10, 75); // position so advance will read based on delay, 57 for yamaha 350 2 pu, 74 for 1 pu, 72 for tw200, 25 for 5013
      pulseWidth = (60000000/RPM)/360; // time for 1° in uS
    }

    timerTopValue = 15000000UL / RPM;
    OCR1B = pulseWidth;
    OCR1A = OCR1B + pulseWidth;

    lcd.setCursor(6, 0);
    lcd.print("     "); // print blank spaces to clear old data
    lcd.setCursor(6, 0);
    lcd.print(RPM);  // print rpm

    lcd.setCursor(16, 0);
    lcd.print("  ");
    lcd.setCursor(16, 0);
    lcd.print(pulseWidth, 1); // print us per degree
   
    lcd.setCursor(6, 1);
    lcd.print("   ");
    lcd.setCursor(6, 1);
    lcd.print(pickup); // print pickup coil position

    lcd.setCursor(11, 2);
    lcd.print("       ");
    lcd.setCursor(11, 2);
    lcd.print(copy_delayPeriod);
   
    lcd.setCursor(14, 3);
    lcd.print("      ");
    lcd.setCursor(14, 3);
    lcd.print(delayDegrees, 1);   // delayDegrees, 1);
  }
 
  if (trigger == true && interruptFlag == true )
  {
    trigger = false;
    interruptFlag = false;
    noInterrupts();
    copy_delayPeriod = delayPeriod;
    interrupts();

    delayDegrees = pickup - (360.0 * (copy_delayPeriod) / (timerTopValue * 4.0)); // for decimal place in deg display.
    }
}

//ISR(TIMER1_COMPA_vect) {
ISR(TIMER1_OVF_vect){
  //OCR1A = (timerTopValue); // value to set delay between pulses to trigger cdi
  ICR1 = (timerTopValue);
  digitalWrite(chargePin, LOW); // guarantee off charge pin at trigger
  digitalWrite(outputPin, HIGH); // turn on pin  trigger

  {
    delayPeriodStart = micros(); // start looking for response as pulse rises
    trigger = true;
  }
// start Timer 2 for charge pulses
  if (chargePulse)
  {
    timeSliceCount = 0;
    TCNT2 = 0;
    //OCR2A = timerTopValue/96; // set 12 periods
    OCR2A = timerTopValue/288;//set 36 periods
    TCCR2B |=  1 << CS22 | 1 << CS21; //prescaleer 256 16us/tick
  }
}

ISR(TIMER1_COMPB_vect) {
  digitalWrite(outputPin, LOW);
  //could add short delayMiocroseconds here for gap
  digitalWrite(output2Pin,HIGH);

  //{
  //  delayPeriodStart = micros(); // start looking for response as pulse falls
  //  trigger = true;
  //}
}

ISR(TIMER1_COMPA_vect) {
  digitalWrite(output2Pin, LOW);
}

void delayPeriodTiming()
{
  delayPeriod = micros() - delayPeriodStart;
  interruptFlag = true;
}

ISR(TIMER2_OVF_vect)
// 5 pulses of 10 degrees starting at 60 degrees
// ON at 60,120,180,240,300 = slice count 6,12,18,24,30
// OFF at 70,130,190,250,310
{
  if (timeSliceCount != 0 && timeSliceCount % 6 == 0)
  {
    digitalWrite (chargePin, HIGH);
  }
  else
  {
    digitalWrite(chargePin, LOW);
  }
  timeSliceCount++;

  if (timeSliceCount == 36)
  {
    timeSliceCount = 0;
// stop Timer2 by clearing prescaler bits
    TCCR2B &= ~1<< CS22;
    TCCR2B &= ~1<< CS21;
  }
}

tom_bauer

Hi, OK the good news this worked fine. Bad news is the transformer responded worse to this width pulse!
So what I have is about the best that I can get.
Again many thanks, Tom

cattledog

Quote
Hi, OK the good news this worked fine. Bad news is the transformer responded worse to this width pulse!
Too bad. This project has had many instances where the hardware does not respond well to the software.

Can you explain to me (perhaps again), what is the purpose of the two trigger pulse output?
What two things are being triggered by the outputs, and how do they combine for generate the actual trigger to the cdi module? Is this like the bar width separation between the two pulses we worked with earlier?

tom_bauer

Hi, yes it has been a rocky road at times. At first there was just 1 pulse for 1 revolution to trigger the spark. Then an engineer friend of mine suggested the DAC to make that pulse available in pos and neg polarity, making it more like the actual real life pulse. But the circuit that the DAC controlled, the one that actually supplied the pos and neg, could not provide enough power. That is where we had the 2 trigger pulses, for the DAC. So I went back to the single pulse for the trigger pulse. This is fed to a small audio transformer so as the pulse rises it makes a magnetic field that outputs voltage from the secondary of the transformer. As the pulse stops the field collapses and makes the opposite polarity output.

What you just wrote for me is for the 5 pulses per revolution that simulates the high voltage exciter coil in a bikes magneto. These charge pulses are switched by a large transistor and apply 12 to 30 volts to another transformer which outputs 75 to 200 volts to charge the capacitor in the CDI. It must be recharged every revolution. The pulse was 30° wide and I wondered if the transformer would perform better with a narrower pulse, it was worse.
Happy to explain more if you like, thanks, Tom

Go Up