Go Down

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

cattledog

Quote
Hi, I can easily install a switch for AC trigger but I am not clear on it's purpose.
How will the program know to run the dual trigger pulse instead of the standard single pulse trigger for the cdi module?

Quote
To answer the last question I need to understand what you refer to as AC trigger.
I am referring to the two +/- voltage pulses as an AC trigger for the cdi module. If you have other terminology like "bipolar trigger" or anything else you like, let me know. I focus on the word trigger, because the pulses are used to trigger the delayed response from the module and we have used the word trigger in the existing code to refer to the outgoing pulse from the arduino.

tom_bauer

#166
Jan 20, 2019, 07:03 pm Last Edit: Jan 20, 2019, 07:41 pm by tom_bauer
Oh OK, I see what you think. No this as you say AC trigger, completely replaces the old single trigger.

Before I had the single trigger go to a very small transformer so as the trigger turns on it energizes the transformer and makes a output pulse, then it stays on for period of time and when it turns off the collapse of field in transformer also makes a opposite pulse. Crude but it works, now I just wanted to improve the system. Also I can code the Arduino to drive more bits of the DAC to make a better sine wave.

By the way I have a Hantek DSO5072P. I love it. Before I had a Tektronic 585A, 50 years old now and still works.
Tom

tom_bauer

The output pins can be 4 and 5. I see that it may be necessary to have a switch to tell Arduino to do - or + first, no electronic way to easily swap them.
Tom

cattledog

Here's some code to test to see if we have the output pulses correct. Please check that I have the correct output to the DAC pins for the +/- 12 and 0 voltage.  I have tried to keep nomenclature similar to the original code. To get the two pulses, I have changed the timer mode from what we had, and broke the 360 degree cycle into two unequal pieces, each containing one pulse. Output compare interrupt B always turns off the pulses. I tested with an led indicator and a slower rpm and timer prescaler, but have left these adaptations commented in the code.  Throw a scope on this and tell me what you get. Ask any questions for clarification.

Code: [Select]
//You can use pots to set RPM, pulseWidthDegrees, and barWidth
unsigned int RPM = 1200;
//unsigned int RPM = 400;
unsigned int pulseWidthDegrees = 10;
unsigned int barWidthDegrees = 60;
unsigned long pulseWidthTime;
unsigned long timerTopValue;//sets 360 degree cycleTime
unsigned int timerTicksPerDegree;
const byte pinA = 4; //to DAC pins tied together
const byte pinB = 5; //to pin5 DAC

void setup() {
  pinMode(13, OUTPUT); //telltale led
  pinMode(pinA, OUTPUT);
  pinMode(pinB, OUTPUT);
  //initialize timer
  TCCR1A = 0;
  TCCR1B = 0;
  //set Timer1 mode Fast PWM to ICR1
  TCCR1B |= (1 << WGM13) | (1 << WGM12);
  TCCR1A |= (1 << WGM11);
 
  timerTopValue = 15000000UL / RPM;
  //15000000 timerTicksperMinute at 4 us per tick with prescaler 64
  //timerTopValue = 12500 at 1200 RPM 50ms per revolution
  timerTicksPerDegree = timerTopValue/360;
  ICR1 = timerTopValue;//initial placeholder
  pulseWidthTime = pulseWidthDegrees*timerTicksPerDegree;
  OCR1B = pulseWidthTime;

  //start Timer apply prescaler
  //TCCR1B |= (1 << CS12) | (1 << CS10); //1024 for led test
  TCCR1B |= (1<<CS11) | (1<<CS10);//64 for .5 us tick

  //enable B OutputCompare and Overflow interrupts
  TIMSK1 |= (1 << OCIE1B) | (1 << TOIE1);
}

void loop() {
}

ISR(TIMER1_COMPB_vect) {
  digitalWrite(13, LOW); //turn off pulse
  digitalWrite(pinA, LOW); //tied pins LOW
  digitalWrite(pinB, HIGH); //DAC5 HIGH
}

ISR(TIMER1_OVF_vect) {
  //alternate ICR1 values to generate two outputs
  //360 degree cycle time broken into two pieces
  static byte count = 0;
  if (count == 0)
  {
    ICR1 = timerTicksPerDegree*(pulseWidthDegrees+barWidthDegrees); //first pulse and bar width
    digitalWrite(13, HIGH);
    //positive pulse
    digitalWrite(pinA, HIGH);
    digitalWrite(pinB, HIGH);
  }
  if (count == 1)
  {
   ICR1 = timerTicksPerDegree*(360-(pulseWidthDegrees+barWidthDegrees));//second pulse and dead band
    digitalWrite(13, HIGH);
    //negative pulse
    digitalWrite(pinA, LOW);
    digitalWrite(pinB, LOW);
  }
  count++;
  if (count == 2)
    count = 0;
}


tom_bauer

OK, I have some parts on order and need to wire it up so it may be a few days. Thanks, I will keep in touch.
Tom

cattledog

Can you scope the output from the Arduino and confirm that it is what you want before connecting to all the other hardware down stream? I'd like to try and separate any software issues from subsequent hardware issues.

tom_bauer

OK I will look at it soon but I am tied up with other work til mid week
Tom

tom_bauer

#172
Jan 23, 2019, 12:56 am Last Edit: Jan 23, 2019, 12:57 am by tom_bauer
OK pin 4 = yellow, 5 = blue

cattledog

#173
Jan 23, 2019, 02:41 am Last Edit: Jan 23, 2019, 05:32 am by cattledog
I think that's what we wanted.


Quote
Before I had the single trigger go to a very small transformer so as the trigger turns on it energizes the transformer and makes a output pulse, then it stays on for period of time and when it turns off the collapse of field in transformer also makes a opposite pulse.
Where to want to start timing the return pulse. How have you been using the R and F settings?

I think there are 4 places we can time from Start and Finish of the tied pins(yellow trace/PinA) going High and back to Low, or the Start and Finish of the single pin to DAC5(blue trace/PinB) going Low and then back to High.

I hope I have the pin and color designations correct. I think we should change the nomenclature from pinA and pinB to something else. dacTiedPins and dacPin5 works to clarify things for me. Do you ahve something else to call then which makes better sense to you?

Code: [Select]
const byte dacTiedPins = 4; //to DAC pins tied together
const byte dacPin5 = 5; //to pin5 DAC

tom_bauer

Hi, OK maybe this helps? I have to think about the R and F, to see if I only really use one.

cattledog

#175
Jan 23, 2019, 04:43 am Last Edit: Jan 23, 2019, 04:43 am by cattledog


Some comments on your understanding of what line in the code does what.

I recommend that you consider the cycle to start with the +12v pulse and that it is done with the code at lines 54-61. This + pulse (and the - pulse as well) are taken back to 0v with the code at line 44. The code triggering the -12v is at lines 62-69.

There are two interrupts which turn the pulses on and off.

Turn Off code, is in the Compare B interrupt which always occurs after 10 degrees of pulse length.

Turn On code, with either +12 or -12, is in the Overflow interrupt, and the time to overflow, or overall cycle length, is set by the rpm.

You could consider the alternating pulses as a switch case, or state machine, situation where the two alternating cases are 1)give a positive pulse and wait at 0v for the bar length time and 2)give a negative pulse and wait at 0v for the remainder of the cycle time.



tom_bauer

#176
Jan 24, 2019, 01:30 am Last Edit: Jan 24, 2019, 01:32 am by tom_bauer
here is a little easier to see pattern, but yes it looks to do what is needed.
pin 4 = yellow
pin 5 = blue

tom_bauer

OK I have changed the comments a little to help me, so I hope you also think it is good description.
Also to consider, I leave the Rise / Fall switch at Rise all the time so it could be done just in code, no need for a switch anymore.
The other thing is that there should be a switch to choose Pos first or Neg first for this trigger pulse.

Code: [Select]


//You can use pots to set RPM, pulseWidthDegrees, and barWidth
unsigned int RPM = 1200;
//unsigned int RPM = 400;
unsigned int pulseWidthDegrees = 10;
unsigned int barWidthDegrees = 60;
unsigned long pulseWidthTime;
unsigned long timerTopValue;//sets 360 degree cycleTime
unsigned int timerTicksPerDegree;
const byte pinA = 4; //to DAC pin 6 - 12, called 6
const byte pinB = 5; //to DAC pin 5

void setup() {
  pinMode(13, OUTPUT); //telltale led
  pinMode(pinA, OUTPUT);
  pinMode(pinB, OUTPUT);
  //initialize timer
  TCCR1A = 0;
  TCCR1B = 0;
  //set Timer1 mode Fast PWM to ICR1
  TCCR1B |= (1 << WGM13) | (1 << WGM12);
  TCCR1A |= (1 << WGM11);
 
  timerTopValue = 15000000UL / RPM;
  //15000000 timerTicksperMinute at 4 us per tick with prescaler 64
  //timerTopValue = 12500 at 1200 RPM 50ms per revolution
  timerTicksPerDegree = timerTopValue/360;
  ICR1 = timerTopValue;//initial placeholder
  pulseWidthTime = pulseWidthDegrees*timerTicksPerDegree;
  OCR1B = pulseWidthTime;

  //start Timer apply prescaler
  //TCCR1B |= (1 << CS12) | (1 << CS10); //1024 for led test
  TCCR1B |= (1<<CS11) | (1<<CS10);//64 for .5 us tick

  //enable B OutputCompare and Overflow interrupts
  TIMSK1 |= (1 << OCIE1B) | (1 << TOIE1);
}

void loop() {
}

ISR(TIMER1_COMPB_vect) {
  digitalWrite(13, LOW);    //turn off pulse for 0 volt
  digitalWrite(pinA, LOW);  //DAC 6 LOW
  digitalWrite(pinB, HIGH); //DAC 5 HIGH
}

ISR(TIMER1_OVF_vect) {
  //alternate ICR1 values to generate two outputs
  //360 degree cycle time broken into two pieces
  static byte count = 0;
  if (count == 0)
  {
    ICR1 = timerTicksPerDegree*(pulseWidthDegrees+barWidthDegrees); //first pulse and bar width
    digitalWrite(13, HIGH);    //turn on pulse for +12v
    digitalWrite(pinA, HIGH);  //DAC 6 HIGH
    digitalWrite(pinB, HIGH);  //DAC 5 HIGH
  }
  if (count == 1)
  {
   ICR1 = timerTicksPerDegree*(360-(pulseWidthDegrees+barWidthDegrees));//second pulse and dead band
    digitalWrite(13, HIGH);   //turn on pulse for -12v
    digitalWrite(pinA, LOW);  //DAC 6 LOW
    digitalWrite(pinB, LOW);  //DAC 5 LOW
  }
  count++;
  if (count == 2)
    count = 0;
}




cattledog

Quote
OK I have changed the comments a little to help me, so I hope you also think it is good description.
Looks good to me.

Quote
The other thing is that there should be a switch to choose Pos first or Neg first for this trigger pulse.
I patched in the code for the first pulse polarity. You'll need to set up a toggle switch for this. I think you can use the R/F switch but in the current code it is on pin5 which is becoming an output.

Code: [Select]

//You can use pots to set RPM, pulseWidthDegrees, and barWidth
unsigned int RPM = 1200;
//unsigned int RPM = 400;
unsigned int pulseWidthDegrees = 10;
unsigned int barWidthDegrees = 60;
unsigned long pulseWidthTime;
unsigned long timerTopValue;//sets 360 degree cycleTime
unsigned int timerTicksPerDegree;
const byte pinA = 4; //to DAC pin 6 - 12, called 6
const byte pinB = 5; //to DAC pin 5
//set first pulse state with toggle switch like R/F or charging switch
//const byte setfirstPulseSwitch = ??;
//boolean firstPulsePos = true;
boolean firstPulsePos = false;

void setup() {
  pinMode(13, OUTPUT); //telltale led
  pinMode(pinA, OUTPUT);
  pinMode(pinB, OUTPUT);
  /*
    pinMode(setFirstPulseSwitch, INPUT_PULLUP);
    if (digitalRead(setFirstPulseSwitch) == HIGH)
     firstPulsePos = true;
    else
     firstPulsePos = false; //first pulse negative
  */

  //initialize timer
  TCCR1A = 0;
  TCCR1B = 0;
  //set Timer1 mode Fast PWM to ICR1
  TCCR1B |= (1 << WGM13) | (1 << WGM12);
  TCCR1A |= (1 << WGM11);

  timerTopValue = 15000000UL / RPM;
  //15000000 timerTicksperMinute at 4 us per tick with prescaler 64
  //timerTopValue = 12500 at 1200 RPM 50ms per revolution
  timerTicksPerDegree = timerTopValue / 360;
  ICR1 = timerTopValue;//initial placeholder
  pulseWidthTime = pulseWidthDegrees * timerTicksPerDegree;
  OCR1B = pulseWidthTime;

  //start Timer apply prescaler
  //TCCR1B |= (1 << CS12) | (1 << CS10); //1024 for led test 8us tick
  TCCR1B |= (1<<CS11) | (1<<CS10);//64 for .5 us tick

  //enable B OutputCompare and Overflow interrupts
  TIMSK1 |= (1 << OCIE1B) | (1 << TOIE1);
}

void loop() {
}

ISR(TIMER1_COMPB_vect) {
  digitalWrite(13, LOW);    //turn off pulse for 0 volt
  digitalWrite(pinA, LOW);  //DAC 6 LOW
  digitalWrite(pinB, HIGH); //DAC 5 HIGH
}

ISR(TIMER1_OVF_vect) {
  //alternate ICR1 values to generate two outputs
  //360 degree cycle time broken into two pieces
  static byte count = 0;
  if (count == 0) //first pulse
  {
    ICR1 = timerTicksPerDegree * (pulseWidthDegrees + barWidthDegrees); //first pulse and bar width
    digitalWrite(13, HIGH);
    if (firstPulsePos == true)
      setPulsePos();
    else
      setPulseNeg();//first pulse neg if firstPulsePos == false
  }
 
  if (count == 1)//second pulse
  {
    ICR1 = timerTicksPerDegree * (360 - (pulseWidthDegrees + barWidthDegrees)); //second pulse and dead band
    digitalWrite(13, HIGH);
    if (firstPulsePos)
      setPulseNeg();
    else
      setPulsePos();//first pulse was negative
  }
  count++;
  if (count == 2)
    count = 0;
}

void setPulsePos()
{
  digitalWrite(pinA, HIGH);  //DAC 6 HIGH
  digitalWrite(pinB, HIGH);  //DAC 5 HIGH
}

void setPulseNeg()
{
  digitalWrite(pinA, LOW );  //DAC 6 LOW
  digitalWrite(pinB, LOW);  //DAC 5 LOW
}

tom_bauer

Hi, OK it works changing the polarity. I have assigned different pins, here is my choice,
D3 - timing signal from clamp on probe.
D4 - polarity switch
D5 - rise / fall
D6 - controls AC - DC output
D7 - output for charge pulses
D8 - to DAC 5
D9 - to DAC 6 - 12

This is the schematic of the whole tester.
Thanks, Tom

Go Up