EPG Testing sequential pulsar using the Arduino

~Russ

EPG Testing sequential pulsar using the Arduino
« on April 22nd, 2011, 04:59 AM »Last edited on October 2nd, 2012, 01:12 AM by ~Russ/Rwg42985
~Russ’s EPG Testing sequential pulsar using the Arduino Duemilanove

please see here for the projects page: http://open-source-energy.org/?tid=440
 
Here is a video of what I'm talking about as far as hardware:

https://www.youtube.com/watch?v=J3sHZ9gtAIU


I will be using a 20x4 LCD text screen that I would like to display the out put frequency, pulse duty cycle, and if the system is enabled or disabled.
 
I will have 2 pots for the adjustments. One for the frequency of the coil firing, and one for the adjustment of the pulse duty cycle.
 
I will have 2 switches, one will enable the entire system, and one will switch between sequence firing and firing all the coils at the same time.
 
I need to fire 5 coils in a sequence, one right after the other.
 
I will also need to fire all the coils at the same time.
 
This is the basic testing platform I would like to start with.
 
Place the inputs and out puts where you would like on the arduino. I will make necessary adjustments.
 
Please give your thoughts and your test code.
 
Thanks, ~Russ
 

rawbush

RE: EPG Testing sequential pulsar using the Arduino
« Reply #1, on April 22nd, 2011, 01:13 PM »
Do you have a frequency range to start with?  Duty cycle range? How many outputs?  The arduino has limited pwm pins. The rest seems straight forward.  See what I can put together.  Peace rawbush

~Russ

RE: EPG Testing sequential pulsar using the Arduino
« Reply #2, on April 22nd, 2011, 01:37 PM »
Quote from rawbush on April 22nd, 2011, 01:13 PM
Do you have a frequency range to start with?  Duty cycle range? How many outputs?  The arduino has limited pwm pins. The rest seems straight forward.  See what I can put together.  Peace rawbush
0-100 duty cycle,

Let go with a push button that changes the frequency range?

So push once 1-100 Hz
Push again 100-1000hz
Push again   1000-10,000
Push aging 10,000-100,000
Push again 100k-1m
ECT. Till it won't go any faster!

Then push again and go back to 1-100
This all in HZ of corse.

Let me know?  

Thanks! ~Russ

rawbush

RE: EPG Testing sequential pulsar using the Arduino
« Reply #3, on April 22nd, 2011, 05:11 PM »
So the frequency/duty cycle is same for all 5 coils? Also how many pins from the arduino do you need to use lcd display, I think my 2 line lcd takes 5 pins to run. Anyway got some ideas now and will get something started.

~Russ

RE: EPG Testing sequential pulsar using the Arduino
« Reply #4, on April 22nd, 2011, 05:29 PM »Last edited on April 22nd, 2011, 05:32 PM by ~Russ/Rwg42985
Quote from rawbush on April 22nd, 2011, 05:11 PM
So the frequency/duty cycle is same for all 5 coils? Also how many pins from the arduino do you need to use lcd display, I think my 2 line lcd takes 5 pins to run. Anyway got some ideas now and will get something started.
Yeah, The coils will fire 1,2,3,4,5,1,2,3,4,5,1 Ect!  the frequancy and duty cycle will be for all the coils. So one cycle is 1,2,3,4,5. Or you can make each coil one cycle,  what ever is best for the program? Your call!  Make sence? The LCD is the same pin count strangely...

I have the arduino you sent me, you know the pin out! It has plenty, just look at a photo on the arduino site for the PWM pins...

Let me know,

Thanks!!!!!!  
~Russ

Thanks, Russ
Quote from Rwg42985 on April 22nd, 2011, 05:29 PM
Quote from rawbush on April 22nd, 2011, 05:11 PM
So the frequency/duty cycle is same for all 5 coils? Also how many pins from the arduino do you need to use lcd display, I think my 2 line lcd takes 5 pins to run. Anyway got some ideas now and will get something started.
Yeah, The coils will fire 1,2,3,4,5,1,2,3,4,5,1 Ect!  the frequancy and duty cycle will be for all the coils. So one cycle is 1,2,3,4,5. Or you can make each coil one cycle,  what ever is best for the program? Your call!  Make sence? The LCD is the same pin count strangely...

I have the arduino you sent me, you know the pin out! It has plenty, just look at a photo on the arduino site for the PWM pins...

Let me know,

Thanks!!!!!!  
~Russ

Thanks, Russ
Each coil I want to be able to change the duty cycle! Make sence?

~Russ

rawbush

RE: EPG Testing sequential pulsar using the Arduino
« Reply #5, on April 24th, 2011, 09:04 AM »Last edited on April 24th, 2011, 09:13 AM by rawbush
here is a link to a multi 555 timer circuit that would work great. http://books.google.com/books?id=pv9nUimtuvsC&pg=PA188&lpg=PA188&dq=555+sequential+output&source=bl&ots=d5mitqL_kE&sig=OVtGtw_fBpyWvB4B3Z9P2XVUZrI&hl=en&ei=mjuyTYurMqrZiAKwzYSwBg&sa=X&oi=book_result&ct=result&resnum=4&ved=0CDAQ6AEwAw#v=onepage&q=555%20sequential%20output&f=false
The resistors could be pots to make adjusting easy. Looks like one shot burst sequentially and there are online calculators to determine pulses.
peace
rawbush

~Russ

RE: EPG Testing sequential pulsar using the Arduino
« Reply #6, on April 24th, 2011, 10:34 AM »
Quote from rawbush on April 24th, 2011, 09:04 AM
here is a link to a multi 555 timer circuit that would work great. http://books.google.com/books?id=pv9nUimtuvsC&pg=PA188&lpg=PA188&dq=555+sequential+output&source=bl&ots=d5mitqL_kE&sig=OVtGtw_fBpyWvB4B3Z9P2XVUZrI&hl=en&ei=mjuyTYurMqrZiAKwzYSwBg&sa=X&oi=book_result&ct=result&resnum=4&ved=0CDAQ6AEwAw#v=onepage&q=555%20sequential%20output&f=false
The resistors could be pots to make adjusting easy. Looks like one shot burst sequentially and there are online calculators to determine pulses.
peace
rawbush
Good find! But!

I have thought long and hard on using IC chips and came up with a selection of ideas... But! For testing I think it is a good idea to stick with a micro controller that can be changed with minimal hardware changes.

This is the only reason why I went with a micro controller!

Also. For anyone else, the arduino can be programed with C if some one knows that better...

~Russ    
RE: EPG Testing sequential pulsar using the Arduino
« Reply #7, on April 24th, 2011, 11:44 AM »
Here Is the arduino I'm using,

http://arduino.cc/en/Main/ArduinoBoardDuemilanove

Those who can program in C can check out the board and pin out!

Thanks! ~Russ

rawbush

RE: EPG Testing sequential pulsar using the Arduino
« Reply #8, on April 24th, 2011, 01:13 PM »Last edited on April 24th, 2011, 02:11 PM by rawbush
So the easiest way to do this with the arduino is with "delaymicroseconds" command. You could pick on/off time in microseconds. Could easily add serial input to change times on the fly. I will write up a quick concept later today (finishing lathe work) and post it here. Peace
rawbush


Code: [Select]

#include







// constants won't change. They're used here to set pin numbers

const int coilone   = 15;  //controls coil one.. pin Anolog 1
const int coiltwo   = 16;  //controls coil one.. pin Anolog 2
const int coilthree = 17;  //controls coil one.. pin Anolog 3
const int coilfour  = 18;  //controls coil one.. pin Anolog 4
const int coilfive  = 19;  //controls coil one.. pin Anolog 5

int ONTIME  = 1000;  // This is in Microseconds...Us
int OFFTIME = 1000;  // This is in Microseconds...Us

void setup() {
  pinMode(coilone,   OUTPUT);
  pinMode(coiltwo,   OUTPUT);
  pinMode(coilthree, OUTPUT);
  pinMode(coilfour,  OUTPUT);
  pinMode(coilfive,  OUTPUT);
}
 
void loop() {  
 
digitalWrite(coilone,HIGH);
delayMicroseconds (ONTIME);
digitalWrite(coilone,LOW);
delayMicroseconds (OFFTIME);  
 
digitalWrite(coiltwo,HIGH);
delayMicroseconds (ONTIME);
digitalWrite(coiltwo,LOW);
delayMicroseconds (OFFTIME);  

digitalWrite(coilthree,HIGH);
delayMicroseconds (ONTIME);
digitalWrite(coilthree,LOW);
delayMicroseconds (OFFTIME);

digitalWrite(coilfour,HIGH);
delayMicroseconds (ONTIME);
digitalWrite(coilfour,LOW);
delayMicroseconds (OFFTIME);

digitalWrite(coilfive,HIGH);
delayMicroseconds (ONTIME);
digitalWrite(coilfive,LOW);
delayMicroseconds (OFFTIME);
}
 

~Russ

RE: EPG Testing sequential pulsar using the Arduino
« Reply #9, on April 24th, 2011, 03:11 PM »
Quote from rawbush on April 24th, 2011, 01:13 PM
So the easiest way to do this with the arduino is with "delaymicroseconds" command. You could pick on/off time in microseconds. Could easily add serial input to change times on the fly. I will write up a quick concept later today (finishing lathe work) and post it here. Peace
rawbush


Code: [Select]

#include



Sweet deal! Played with it this weekend and got some cool 5 LED sequence stuff to work just fine.

I'll be awaiting the code!

Also, how do I desplay the frequency of the millisecond delay on the LCD?

This will come together nicly!!!

thanks! ~Russ



// constants won't change. They're used here to set pin numbers

const int coilone   = 15;  //controls coil one.. pin Anolog 1
const int coiltwo   = 16;  //controls coil one.. pin Anolog 2
const int coilthree = 17;  //controls coil one.. pin Anolog 3
const int coilfour  = 18;  //controls coil one.. pin Anolog 4
const int coilfive  = 19;  //controls coil one.. pin Anolog 5

int ONTIME  = 1000;  // This is in Microseconds...Us
int OFFTIME = 1000;  // This is in Microseconds...Us

void setup() {
  pinMode(coilone,   OUTPUT);
  pinMode(coiltwo,   OUTPUT);
  pinMode(coilthree, OUTPUT);
  pinMode(coilfour,  OUTPUT);
  pinMode(coilfive,  OUTPUT);
}
 
void loop() {  
 
digitalWrite(coilone,HIGH);
delayMicroseconds (ONTIME);
digitalWrite(coilone,LOW);
delayMicroseconds (OFFTIME);  
 
digitalWrite(coiltwo,HIGH);
delayMicroseconds (ONTIME);
digitalWrite(coiltwo,LOW);
delayMicroseconds (OFFTIME);  

digitalWrite(coilthree,HIGH);
delayMicroseconds (ONTIME);
digitalWrite(coilthree,LOW);
delayMicroseconds (OFFTIME);

digitalWrite(coilfour,HIGH);
delayMicroseconds (ONTIME);
digitalWrite(coilfour,LOW);
delayMicroseconds (OFFTIME);

digitalWrite(coilfive,HIGH);
delayMicroseconds (ONTIME);
digitalWrite(coilfive,LOW);
delayMicroseconds (OFFTIME);
}
 

rawbush

RE: EPG Testing sequential pulsar using the Arduino
« Reply #10, on April 24th, 2011, 04:42 PM »Last edited on April 24th, 2011, 06:46 PM by rawbush
Here I have added the switch for sequential/ single fire, and also the coding for it. I am looking for a better (cleaner) way of firing all at once.  I have used the Analog pins (as digital) so that one plug can be used at the board? Analog 0 is also digital pin 14 and so on.
Code: [Select]


 
 
  // constants won't change. They're used here to set pin numbers
 
  const int switchone = 14;  //sequencial/fire all switch.. pin Anolog 0
  const int coilone   = 15;  //controls coil one.. pin Anolog 1
  const int coiltwo   = 16;  //controls coil two.. pin Anolog 2
  const int coilthree = 17;  //controls coil three.. pin Anolog 3
  const int coilfour  = 18;  //controls coil four.. pin Anolog 4
  const int coilfive  = 19;  //controls coil five.. pin Anolog 5
   //int allcoils[] = {15, 16, 17, 18, 19};
   //int coilcount = 5;
  int switchval = HIGH;
  int ONTIME  = 1000;  // This is in Microseconds...Us
  int OFFTIME = 1000;  // This is in Microseconds...Us
 
  void setup() {
    pinMode(coilone,   OUTPUT);
    pinMode(coiltwo,   OUTPUT);
    pinMode(coilthree, OUTPUT);
    pinMode(coilfour,  OUTPUT);
    pinMode(coilfive,  OUTPUT);
    pinMode(switchone,  INPUT);
    //pinMode (allcoils, OUTPUT);
    digitalWrite (switchone, HIGH); // Turns on internal pull-up resistor
   
  }
 
   
  void loop() {  
  switchval = digitalRead (switchone);
   if (switchval == HIGH)
  {
  digitalWrite(coilone,HIGH);
  delayMicroseconds (ONTIME);
  digitalWrite(coilone,LOW);
  delayMicroseconds (OFFTIME);  
   
  digitalWrite(coiltwo,HIGH);
  delayMicroseconds (ONTIME);
  digitalWrite(coiltwo,LOW);
  delayMicroseconds (OFFTIME);  
 
  digitalWrite(coilthree,HIGH);
  delayMicroseconds (ONTIME);
  digitalWrite(coilthree,LOW);
  delayMicroseconds (OFFTIME);
 
  digitalWrite(coilfour,HIGH);
  delayMicroseconds (ONTIME);
  digitalWrite(coilfour,LOW);
  delayMicroseconds (OFFTIME);
 
  digitalWrite(coilfive,HIGH);
  delayMicroseconds (ONTIME);
  digitalWrite(coilfive,LOW);
  delayMicroseconds (OFFTIME);
  }
    else {
  digitalWrite(coilone,HIGH);
  digitalWrite(coiltwo,HIGH);
  digitalWrite(coilthree,HIGH);
  digitalWrite(coilfour,HIGH);
  digitalWrite(coilfive,HIGH);
  delayMicroseconds (ONTIME);
  digitalWrite(coilone,LOW);
  digitalWrite(coiltwo,LOW);
  digitalWrite(coilthree,LOW);
  digitalWrite(coilfour,LOW);
  digitalWrite(coilfive,HIGH);
  delayMicroseconds (OFFTIME);    
    }
  }

Peace
rawbush

Main power switch added. Moved both switches to digital pins 11 and 12, output to coil triggers are still on analog pins 1-5 in order. I have not tested these on mine yet but should work fine. I will try to write a wiring schematic for this asap.
Code: [Select]


 
 
  // constants won't change. They're used here to set pin numbers
 
  const int switchone = 11;  //on / off switch.. pin Digital 11
  const int switchtwo = 12;  //sequencial/fire all switch.. pin Digital 12
  const int coilone   = 15;  //controls coil one.. pin Anolog 1
  const int coiltwo   = 16;  //controls coil two.. pin Anolog 2
  const int coilthree = 17;  //controls coil three.. pin Anolog 3
  const int coilfour  = 18;  //controls coil four.. pin Anolog 4
  const int coilfive  = 19;  //controls coil five.. pin Anolog 5
   //int allcoils[] = {15, 16, 17, 18, 19};
   //int coilcount = 5;
  int switchoneval = HIGH;
  int switchtwoval = HIGH;
  int ONTIME  = 1000;  // This is in Microseconds...Us
  int OFFTIME = 1000;  // This is in Microseconds...Us
 
  void setup() {
    pinMode(coilone,   OUTPUT);
    pinMode(coiltwo,   OUTPUT);
    pinMode(coilthree, OUTPUT);
    pinMode(coilfour,  OUTPUT);
    pinMode(coilfive,  OUTPUT);
    pinMode(switchone,  INPUT);
    pinMode(switchtwo,  INPUT);
    //pinMode (allcoils, OUTPUT);
    digitalWrite (switchone, HIGH); // Turns on internal pull-up resistor
    digitalWrite (switchtwo, HIGH); // Turns on internal pull-up resistor
  }
 
   
  void loop() {
  switchoneval = digitalRead (switchone);
   if (switchoneval == HIGH)
   
  switchtwoval = digitalRead (switchtwo);
   if (switchtwoval == HIGH)
  {
  digitalWrite(coilone,HIGH);
  delayMicroseconds (ONTIME);
  digitalWrite(coilone,LOW);
  delayMicroseconds (OFFTIME);  
   
  digitalWrite(coiltwo,HIGH);
  delayMicroseconds (ONTIME);
  digitalWrite(coiltwo,LOW);
  delayMicroseconds (OFFTIME);  
 
  digitalWrite(coilthree,HIGH);
  delayMicroseconds (ONTIME);
  digitalWrite(coilthree,LOW);
  delayMicroseconds (OFFTIME);
 
  digitalWrite(coilfour,HIGH);
  delayMicroseconds (ONTIME);
  digitalWrite(coilfour,LOW);
  delayMicroseconds (OFFTIME);
 
  digitalWrite(coilfive,HIGH);
  delayMicroseconds (ONTIME);
  digitalWrite(coilfive,LOW);
  delayMicroseconds (OFFTIME);
  }
    else {
  digitalWrite(coilone,HIGH);
  digitalWrite(coiltwo,HIGH);
  digitalWrite(coilthree,HIGH);
  digitalWrite(coilfour,HIGH);
  digitalWrite(coilfive,HIGH);
  delayMicroseconds (ONTIME);
  digitalWrite(coilone,LOW);
  digitalWrite(coiltwo,LOW);
  digitalWrite(coilthree,LOW);
  digitalWrite(coilfour,LOW);
  digitalWrite(coilfive,HIGH);
  delayMicroseconds (OFFTIME);    
    }
  }




Peace
rawbush

~Russ

RE: EPG Testing sequential pulsar using the Arduino
« Reply #11, on April 24th, 2011, 08:15 PM »
Do you think we should stick with the PWM out puts for the coils???

That's pins, 3,5,6,9,10,11 for my board...???

I'll give this a try soon!!! Thanks for the quick sketch!

~Russ
RE: EPG Testing sequential pulsar using the Arduino
« Reply #12, on April 25th, 2011, 03:47 AM »
ok, so here is what i came up with to let us adjust the frequancy and dutycycle with pots...

will this work or am i way out of it...???

Code: [Select]


  int FRQADJ = 0; // Pot 0  for adjusting the frequncy... pin analog in 0
  int DUTYADJ = 0; // pot 1 for adjusting the duty cycle of the pulse... pin analog in 1
 
  int delayVal ()
{
int ONTIME;  // This is in Microseconds...Us
ONTIME = analogRead (FRQADJ);
return ONTIME;
}

  int delayVal ()
{
int OFFTIME;  // This is in Microseconds...Us
ONTIME = analogRead (DUTYADJ);
return ONTIME;
}


??? waht do you think?

what have it got? will it work?

PS> you have a HIGH where it should be LOW in the last bit of your code... but i fixed it... :)

let me know?

~Russ

rawbush

RE: EPG Testing sequential pulsar using the Arduino
« Reply #13, on April 25th, 2011, 08:09 AM »
If you want to output a pwm then yes the pwm pins must get used.  You will need to modify the LCD library because it uses some of those pins. Have you tried the frequently Gen I sent on Skype? The sketch I wrote is as simple as it can get, the only problem is that a scope would be needed to figure real frequency out.  I am still working on something better.  Will the optometry circuit work for you?  Peace
 Rawbush

~Russ

RE: EPG Testing sequential pulsar using the Arduino
« Reply #14, on April 25th, 2011, 10:17 AM »
Quote from rawbush on April 25th, 2011, 08:09 AM
If you want to output a pwm then yes the pwm pins must get used.  You will need to modify the LCD library because it uses some of those pins. Have you tried the frequently Gen I sent on Skype? The sketch I wrote is as simple as it can get, the only problem is that a scope would be needed to figure real frequency out.  I am still working on something better.  Will the optometry circuit work for you?  Peace
 Rawbush
I have been looking over the skype code and... Yeah.

There displaying as HZ? Is there a function there to do that?

It's even used as HZ?

What do you think?

Yeah I should be able to use what you got. But still working on the pot input for adjustment!

I will be getting some optoiosalater and MOSFET drivers and make up a circuit... :)



~Russ
RE: EPG Testing sequential pulsar using the Arduino
« Reply #15, on April 26th, 2011, 04:09 PM »


ok, i got this to work but i changed to seconds delay so i could see what was going on...

i also had to change pins to get this to work... its that way you have it in your schmatic.

Code: [Select]


// constants won't change. They're used here to set pin numbers
 
  const int switchone = 11;  //on / off switch.. pin Digital 11
  const int switchtwo = 12;  //sequencial/fire all switch.. pin Digital 12
  const int coilone   = 1;  //controls coil one.. pin Anolog 1
  const int coiltwo   = 2;  //controls coil two.. pin Anolog 2
  const int coilthree = 3;  //controls coil three.. pin Anolog 3
  const int coilfour  = 4;  //controls coil four.. pin Anolog 4
  const int coilfive  = 5;  //controls coil five.. pin Anolog 5
   //int allcoils[] = {1, 2, 3, 4, 5};
   //int coilcount = 5;
  int switchoneval = HIGH;
  int switchtwoval = HIGH;
  int ONTIME  = 100;  // This is in Microseconds...Us
  int OFFTIME = 100;  // This is in Microseconds...Us
 
  void setup() {
    pinMode(coilone,   OUTPUT);
    pinMode(coiltwo,   OUTPUT);
    pinMode(coilthree, OUTPUT);
    pinMode(coilfour,  OUTPUT);
    pinMode(coilfive,  OUTPUT);
    pinMode(switchone,  INPUT);
    pinMode(switchtwo,  INPUT);
    //pinMode (allcoils, OUTPUT);
    digitalWrite (switchone, HIGH); // Turns on internal pull-up resistor
    digitalWrite (switchtwo, HIGH); // Turns on internal pull-up resistor
  }
 
   
  void loop() {
  switchoneval = digitalRead (switchone);
   if (switchoneval == HIGH)
 
  switchtwoval = digitalRead (switchtwo);
   if (switchtwoval == HIGH)
  {
  digitalWrite(coilone,HIGH);
  delay (ONTIME);
  digitalWrite(coilone,LOW);
  delay (OFFTIME);  
   
  digitalWrite(coiltwo,HIGH);
  delay (ONTIME);
  digitalWrite(coiltwo,LOW);
  delay (OFFTIME);  
 
  digitalWrite(coilthree,HIGH);
  delay (ONTIME);
  digitalWrite(coilthree,LOW);
  delay (OFFTIME);
 
  digitalWrite(coilfour,HIGH);
  delay (ONTIME);
  digitalWrite(coilfour,LOW);
  delay (OFFTIME);
 
  digitalWrite(coilfive,HIGH);
  delay (ONTIME);
  digitalWrite(coilfive,LOW);
  delay (OFFTIME);
  }
    else {
  digitalWrite(coilone,HIGH);
  digitalWrite(coiltwo,HIGH);
  digitalWrite(coilthree,HIGH);
  digitalWrite(coilfour,HIGH);
  digitalWrite(coilfive,HIGH);
  delay (ONTIME);
  digitalWrite(coilone,LOW);
  digitalWrite(coiltwo,LOW);
  digitalWrite(coilthree,LOW);
  digitalWrite(coilfour,LOW);
  digitalWrite(coilfive,LOW);
  delay (OFFTIME);    
    }
  }



now what about duty cycle? and pot inputs?

thanks! ~Russ

ill post a video update and show you what it looks like!  

txqNL

RE: EPG Testing sequential pulsar using the Arduino
« Reply #16, on April 27th, 2011, 11:16 AM »Last edited on April 30th, 2011, 07:28 AM by txqNL
Hi Russ,

I've created some code for your project to pulse fire the magnagas transformer.
Here is a vid of it: https://www.youtube.com/watch?v=F0YO2hN2X88

And here is the code with the trigger mode switch bug fixed :)
Code: [Select]

Lastest code somewhere in thread.


All the magic happens in the ISR(TIMER1_OVF_vect) function where
the output is timed and shifted to the leds.
The forum removed the includes it should be: (without spaces)
Code: [Select]

#include < avr/io.h >
#include < avr/interrupt.h >
#include < avr/pgmspace.h >


Edit again updated code to add spaces for workaround eager greater then removal, now it should compile after removed the spaces in the include statements.

rawbush

RE: EPG Testing sequential pulsar using the Arduino
« Reply #17, on April 27th, 2011, 05:58 PM »
right on, cleaner then what I came up with.   Also Russ
const int coilone   = 1;  //controls coil one.. pin Anolog 1
  const int coiltwo   = 2;  //controls coil two.. pin Anolog 2
  const int coilthree = 3;  //controls coil three.. pin Anolog 3
  const int coilfour  = 4;  //controls coil four.. pin Anolog 4
  const int coilfive  = 5;  //controls coil five.. pin Anolog 5
1-5 need to be 15-19 to use analog as a digital pin, the wire still goes to analog 1-5.

txqNL

RE: EPG Testing sequential pulsar using the Arduino
« Reply #18, on April 28th, 2011, 06:51 AM »Last edited on April 30th, 2011, 07:27 AM by txqNL
This forum is way to eager in trying to remove xml tags, it also removes them from
code block if there is a character behind the greater then sign.
Looks like a dirty regex instead of tags list or better proper escaping.
You can work around it by adding a space after the greater then sign.

Anyway back to subject about the pin I/O.
Computers alway count from 0 and to output data direct to multiple pins
you have to connect from 0. (of shift a lot more)

The Arduino had 3 bus outputs but for lower bits output only 2 options are
there analog 0-5 and digital 8-13 see; PinMapping168

I do think it is better to not use the LCD because it used to much io pins (6pins) maybe an gui application on PC is also an option.
When we also want lcd and analog inputs this is the best mapping;
Code: [Select]

A0-A3  = LCD DATA
A4     = Analog input0
A5     = Analog input1

D0/D1  = Rx/Tx Serial console (is mapped to usb on Arduino)
D2     = Interupt hardware trigger for pulse train via hall sensor (pulse_trigger=2)
D3     = Input0 Manual trigger input with switch to ground
D4     = Input1 Push button walks thru the diffent analog input selections.
D5     = Interups hardware for timer clock (pulse_clock=6or7)
D6     = LCD RS
D7     = LCD E
D8-D13 = Max 6 outputs to LED(+R) to ground.


When working on my autolpm device I noticed it can be tricky to do correct analog measurements,
on internet I see a lot usages of I2C bus external adc and temp sensors usage which connect to;
A4 and A5 with hardware controller in chip which is a nice option.

The main reason is you get noise from the cpu running, so correct way should be start adc,
halt cpu, cpu awakes when adc is ready.
But all interrupts awake cpu so when using the timer for pwm/pulse fire output which currently awakes
every 16 clock cycles the analog messurement may not be ready yet.

With setting speed_int to 49536 which gives every 16000 clock cycles an interrupt we can hopefully work around that.
(which limit upper step freq to 1Khz)
But also the (step_) relax time (duty) resolution also gets smaller because it is must be in steps of the timer overflowing.
We can't use delay function on interrupt functions because that kills other interrupt stuff like serial communication.

While writing there maybe is an option to use another timer for the duty between pulses
that would possible give us the resolution back.
Anyway a lot to think about, I hope now that the forum copy past errors are gone that we get good results :)

m3sca1

RE: EPG Testing sequential pulsar using the Arduino
« Reply #19, on April 28th, 2011, 07:12 PM »
OK my initial approach to this was to use a decade counter run by a 555 timer in a cheap kit circuit,that was intended for a LED light chaser.
By co-incidence it was a 5 channel setup allowing me to run 5 coils same as what Russ is working on.
I got some FET's from some surplus junk i desoldered and hooked a coil to the FET,triggered by the light chaser circuit.
I put a potentiometer on the 555 timer instead of the fixed resistor-this allowed me to speed the chase sequence up to the point where the LED's appeared to be on all the time and would give a decent wave effect across the drive coils

The FET started getting hot and the signal on the 'scope shows the on time is too long.
I believe the optimal duty cycle would be well under 50%,since i dont think we want to saturate the core material.
Saturation leads to heat and heat leads to inefficiency.
Also i think that seperate cores would be required,so that each coil is a magnet in its own right.

I bought an arduino clone a little while back so i figured its time to jump into the fire and try it with that.
i dont have programming experience,so its a little daunting for me but im sure the code you guys come with will do the job.

Meyer spoke about going further torward increasing efficiency by oscillating the gas without pushing it around so perhaps a function where instead of sequence chasing,the coils can be made to fire in a bouncing back and forward pong like fashion like a LED scanner circuit.
Maybe only using 2 coils instead if all five since to send something back and forward you only need 2 coils.

~Russ

RE: EPG Testing sequential pulsar using the Arduino
« Reply #20, on April 29th, 2011, 07:51 AM »Last edited on April 29th, 2011, 08:00 AM by ~Russ/Rwg42985
Quote from rawbush on April 27th, 2011, 05:58 PM
right on, cleaner then what I came up with.   Also Russ
const int coilone   = 1;  //controls coil one.. pin Anolog 1
  const int coiltwo   = 2;  //controls coil two.. pin Anolog 2
  const int coilthree = 3;  //controls coil three.. pin Anolog 3
  const int coilfour  = 4;  //controls coil four.. pin Anolog 4
  const int coilfive  = 5;  //controls coil five.. pin Anolog 5
1-5 need to be 15-19 to use analog as a digital pin, the wire still goes to analog 1-5.
wow... How silly I am... :) I see now :) thanks! ~Russ
Quote from txqNL on April 28th, 2011, 06:51 AM
This forum is way to eager in trying to remove xml tags, it also removes them from
code block if there is a character behind the greater then sign.
Looks like a dirty regex instead of tags list or better proper escaping.
You can work around it by adding a space after the greater then sign.

Anyway back to subject about the pin I/O.
Computers alway count from 0 and to output data direct to multiple pins
you have to connect from 0. (of shift a lot more)

The Arduino had 3 bus outputs but for lower bits output only 2 options are
there analog 0-5 and digital 8-13 see; PinMapping168

I do think it is better to not use the LCD because it used to much io pins (6pins) maybe an gui application on PC is also an option.
When we also want lcd and analog inputs this is the best mapping;
Code: [Select]

A0: LCD D0
A1: LCD D1
A2: LCD D2
A3: LCD D3
A4: Analog user input 0
A5: Analog user input 1

D0: Rx
D1: Tx
D2: External pulse train trigger
D3: External clock for pulse speed
D4: Digital user input 0 (Push button pulse train trigger)
D5: Digital user input 1
D6: LCD RS
D7: LCD E

D8:  Pulse fire output 0
D9:  Pulse fire output 1
D10: Pulse fire output 2
D11: Pulse fire output 3
D12: Pulse fire output 4
D13: Pulse fire output 5


When working on my autolpm device I noticed it can be tricky to do correct analog measurements,
on internet I see a lot usages of I2C bus external adc and temp sensors usage which connect to;
A4 and A5 with hardware controller in chip which is a nice option.

The main reason is you get noise from the cpu running, so correct way should be start adc,
halt cpu, cpu awakes when adc is ready.
But all interrupts awake cpu so when using the timer for pwm/pulse fire output which currently awakes
every 16 clock cycles the analog messurement may not be ready yet.

With setting speed_int to 49536 which gives every 16000 clock cycles an interrupt we can hopefully work around that.
(which limit upper step freq to 1Khz)
But also the (step_) relax time (duty) resolution also gets smaller because it is must be in steps of the timer overflowing.
We can't use delay function on interrupt functions because that kills other interrupt stuff like serial communication.

While writing there maybe is an option to use another timer for the duty between pulses
that would possible give us the resolution back.
Anyway a lot to think about, I hope now that the forum copy past errors are gone that we get good results :)
Wow! Yeah alot of code... :) I'm having a hard time fowling the logic VS no using serial connection... But I will play with it.

Can I change the duty cycle with this code also? I got to sit down and look at it better!

Now, can you have a pot input for the adjustments? Like duty cycle and frequncy... ????

Also I want the duty cycle and frequency   to be displayed on a'n a 20x4 LCD screen ??? Can we do that with your code?

Thanks man!!!! Looks good and thanks for the demo video!!!

~Russ

txqNL

RE: EPG Testing sequential pulsar using the Arduino
« Reply #21, on April 29th, 2011, 07:18 PM »Last edited on May 21st, 2011, 04:39 PM by txqNL
Quote from Rwg42985 on April 29th, 2011, 07:51 AM
Also I want the duty cycle and frequency   to be displayed on a'n a 20x4 LCD screen ??? Can we do that with your code?
I've cleaned the code a bit now the logic is almost readable. :D
Added also some features like;
- Independent step duty time
- simple lcd output
- analog input (selectable)
- clk and trigger input working (in vid did only show trigger)
- pulse mode and pulse init data configable.
- started with calculation of speeds.

See new Pulse Fire Video

Code: [Select]

Lastest code somewhere in thread.

rawbush

RE: EPG Testing sequential pulsar using the Arduino
« Reply #22, on April 29th, 2011, 07:30 PM »Last edited on April 29th, 2011, 07:59 PM by rawbush
Are there any changes needed to run on a mega 1280? Thanks much for what you have written, way beyond my level. Peace
rawbush
http://arduino.cc/en/Main/ArduinoBoardMega

txqNL

RE: EPG Testing sequential pulsar using the Arduino
« Reply #23, on April 29th, 2011, 08:06 PM »
Quote from rawbush on April 29th, 2011, 07:30 PM
Are there any changes needed to run on a mega 1280? Thanks much for what you have written, way beyond my level. Peace
rawbush
http://arduino.cc/en/Main/ArduinoBoardMega
Looks like pin and software compatible, try compiling and use pin layout as
in header of source/vid.
On mega print the digital pins are labeled as pwm pins and just leave the extra communications,high analog and high digital pins empty.


rawbush

RE: EPG Testing sequential pulsar using the Arduino
« Reply #24, on April 29th, 2011, 08:19 PM »
Quote from txqNL on April 29th, 2011, 08:06 PM
Quote from rawbush on April 29th, 2011, 07:30 PM
Are there any changes needed to run on a mega 1280? Thanks much for what you have written, way beyond my level. Peace
rawbush
http://arduino.cc/en/Main/ArduinoBoardMega
Looks like pin and software compatible, try compiling and use pin layout as
in header of source/vid.
On mega print the digital pins are labeled as pwm pins and just leave the extra communications,high analog and high digital pins empty.
Thanks, here is a freq gen that I got with the board Russ has, maybe use to get good frequency?
Code: [Select]

////////////////////////////////////////////////////////////////////////////////////////////
// NOTE: (1) The PWM code that this program uses was modified from the Yucca.pde          //
//           Open Source Code.                                                            //
//                                                                              //
//  THIS WILL RUN ON ARDUINO (OR FREEDUINO) BOARD WITH NUELECTRONICS LCD SHIELD           //
//                                                                                        //
//  PLEASE NOTE: ANALOG PIN 0 IS USED FOR THE LCD DISPLAY AND MUST NOT BE USED            //
//  ANY WHERE ELSE. UNFORTUNATLY THIS MEANS THAT THERE ARE ONLY 5 SENSOR PORTS            //
//  AVAILABLE.                                                                            //
////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////                                                                                        //
// MENU ITEMS:                                                                            //
//            (1) PWM Freguency and Duty Cycle: Frequency adjustable between 0-999,999Hz  //
//                                              Duty Cycle adjustable between 0-100%      //
//                DISPLAY = "1)000,000Hz 000%"                                            //
//                                                                                        //
//            (2) PSEUDO Save Button Emulator:  Allows user to Save to non-volitile      //
//                                              memmory. By setting the option to a 1 the //
//                                              'Button Pushed' emulation begins. The     //
//                                              Proigram option are witten to EEPROM and  //
//                                              the 'Button' is returned to it's normal   //
//                                              state of Off (0).                         //
//                DISPLAY = "2) 0 Save Option"                                            //                                                                          
//                                                                                        //
//  NOTE: Any number of Menu Items can be Added and Coded.
////////////////////////////////////////////////////////////////////////////////////////////

//  Initialising screen:
#define TITLE_LINE_1 "Digital Freg Gen"
#define TITLE_LINE_2 " V1.01 11/09/09 "

////////////////////////////////////////////////////////////////////////////////
//  Includes
#include
#include
#include
#include
#include   // The library files can be found here:
                           // http://www.nuelectronics.com
#include          // include Wire library for I2C
#include        // for persistent system state
//#include       // Use for Dallas Temperature Sensor - AllGood

///////////////////////////////////////////////////////////////////////////////////////////
// FUNCTION TEMPLATES:                                                                   //
//                                                                                       //
// This is a Template taken directly from arduino.cc/playground/Code/EEPROMWriteAnything //
// This creates two functions that will allow us to save 'Confiuration' data. The data   //
// will be stored in a Structure (which I have created) that will contain ALL of the     //
// values that we use so that there is only one 'Save' and one 'Read' required.          //
///////////////////////////////////////////////////////////////////////////////////////////
template int EEPROM_writeAnything(int ee, const T& value)
{
    const byte* p = (const byte*)(const void*)&value;
    int i = 0;
    for (i = 0; i < sizeof(value); i++)
 EEPROM.write(ee++, *p++);
    return i;
}

template int EEPROM_readAnything(int ee, T& value)
{
    byte* p = (byte*)(void*)&value;
    int i = 0;
    for (i = 0; i < sizeof(value); i++)
 *p++ = EEPROM.read(ee++);
    return i;
}
// END FUNCTION TEMPLATES:

////////////////////////////////////////////////
//  Macros                                    //
////////////////////////////////////////////////
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif

#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

///////////////////////////////////////////////////////////////////////
// Constants:                                                        //
// This is where you would setup, add or change  some Default values //
///////////////////////////////////////////////////////////////////////
const long MIN_FREQUENCY1 = 0;// Straight DC out of Pin
const long MAX_FREQUENCY1 = 999999;//1MHz

const int MIN_DUTYCYCLE = 1;   // Effectively DC ground
const int MAX_DUTYCYCLE = 99; // Effectively 5volt DC

const int LCD_WIDTH = 16; // just some values for the 2 line 16 char display
const int LCD_HEIGHT = 2;

const int NUM_CURSOR_POSITIONS = LCD_WIDTH; // sets the number of cursor positions

const int MS_SCREEN_RESTART = 5000;  //used to restart the LCD to get out of screwups

/////////////////////////////////////////////////////////////////////////////////
// These next set of  variables are used as a small lookup table. The cursor   //
// will be setting at a position on the display from 0-15. Depending on which  //
// Menu item we are wanting to change/modify we will 'Look' at this table for  //
// the correct muliplier at the given Cursor position.                         //
/////////////////////////////////////////////////////////////////////////////////
const long alFreqDutyMultipliers[NUM_CURSOR_POSITIONS] = {
  0,0,100000,10000,1000,0,100,10,1,0,0,0,100,10,1,0};  //Frequency and Duty Cycle multipliers

 
const long alSaveButtonEmulator[NUM_CURSOR_POSITIONS] = {
  0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0};//only  position 4 is use. set 1 wil save settings to eeprom

////////////////////////////////////////////////////
// Menu Items:                                   //
// Add and 'Definition' of new menu itens here.  //
///////////////////////////////////////////////////
enum MENU_ITEMS
{
  MENU_SOFT_FREQ = 0, // PWM Frequency and Duty Cycle
  MENU_SAVE_OPTS = 1, // Save All the option settings
  MENU_NUM_ITEMS = 2, //always last one on the 'MENU_ITEMS' stack
};

///////////////////////////////////////////////////////////////////////////////////
// Set some static values for Current Sensor, Frequency and Duty Cycle.          //
// NOTE: Static values are values that do not change unless forced to.           //
///////////////////////////////////////////////////////////////////////////////////

static long lFrequency_0 = 0;          // Set and initialize Frequensy 'Test' value  //
static unsigned char iDutyCycle_0 = 0; // Set and initialize Duty Cycle 'Test' value //

////////////////////////////////////////////////////
// Variables:                                     //
////////////////////////////////////////////////////
int iMenuSelect = 0;      //use to select each menu item

long lFrequency[1];    //main frequency in Hz
int iDutyCycle[1];     //Duty cycle of waveform in%

int iSaveSettingVal[1];// Force a write to eeprom of all the current settings.

int iCursorPosition;  //the current  cursor position

bool bCursorUp;       // state of the bottom line cursor
bool bRedrawLine1;    // set true whenever you want the LCD to refresh line1
bool bRedrawLine2;    // set true whenever you want the LCD to refresh line2
bool UseFcnPWM;

/////////////////////////////////////////////////////
// Set up the IO, A/D and PWM pins on the Arduino  //
/////////////////////////////////////////////////////
//const int PIN_PWM_OUTPUT = 10;  // The high precision PWM pin
const int PIN_PWM_OUTPUT = 10;  // The high precision PWM pin
long previousMillis = 0;        // will store last Delay Time
long previousRefresh = 0;       // will store last Display Refresh Time


///////////////////////////////////////////////////////////////////////////
// STRUCTURES:                                                           //
//                                                                       //
// This structure will contain ALL of the parameter and variables        //
// that we will want to maintain in a consistant state even if the       //
// Arduino is powered off. This Strucure can contain as many elements    //
// as we desire and we can Add to it at any time. The Item in the        //
// structure must caontain item of the same TYPE that we are using for   //
// a given 'Option'. Example: if we define a variable/option as a LONG   //
// then we must have a cooresponding element in the structure define as  //
// a LONG as well.                                                       //
//                                                                       //
// NOTE: The current structure is just a place holder for the moment-RRB //
///////////////////////////////////////////////////////////////////////////
struct config_t
{
    ///////////////////////////////////////////////////////////////////////
    // Please note: it is ok to use the same name here because these are //
    // Outside the 'Regular Scope' of the main program. It is nice       //
    // because it make it easier to 'Match' up with a cooresponding      //
    // Value/variable.                                                   //
    ///////////////////////////////////////////////////////////////////////
   
    long lFrequency[1];
    int iDutyCycle[1];
   
   
} configuration;

//END STRUCTURES:

//////////////////////////////////////////////////////////////////
// Objects:                                                     //
//////////////////////////////////////////////////////////////////
LCD4Bit_mod lcd = LCD4Bit_mod(LCD_HEIGHT);//LCD handling object

///////////////////////////////////////////////////////
// Initialise                                        //
///////////////////////////////////////////////////////
void setup()
{
  ////////////////////////////////////////
  // start serial port Added by AllGood //
  ////////////////////////////////////////
  Serial.begin(9600);
  UseFcnPWM = true;

  /////////////////////////////////////////////////////////////////////////
  // Before we do anything else Read the Configuration Structure and     //
  // preset all the Option Values currently used in the progam for each  //
  // each function.                                                      //
  //////////////////////////////////////////////////////////////////////////
  // EEPROM_readAnything(0, configuration);
 
  if(EEPROM_readAnything(0, configuration) <=0) // If no data is returned then nothing is saved
  {
    lFrequency[0] = 1000;  // This is the startup PWM frequency change to whatever
    iDutyCycle[0] = 50;    // This is the startup PWM Duty Cycle change to whatever
   
    iSaveSettingVal[0] = 0; // This sets the PSEUDO Save to 'Not Pushed'
     
  }
  else
  {
    ///////////////////////////////////////////////////////////////////////
    // Configuration data was saved so we are able to load the structure //
    // and from there we are able to load all the various variables with //
    // the stored data.                                                  //
    ///////////////////////////////////////////////////////////////////////
    lFrequency[0] = configuration.lFrequency[0];
    iDutyCycle[0] = configuration.iDutyCycle[0];
   
    iSaveSettingVal[0] = 0;
  }

  //////////////////////////////////////////////////////////////
    // insure that the returned values are within a valid range //
    //////////////////////////////////////////////////////////////
    if(lFrequency[0] > 999999 ||  lFrequency[0] < 0) // This is the startup PWM frequency change to whatever
      lFrequency[0] = 1000;
     
    if(iDutyCycle[0] > 100 ||  iDutyCycle[0] < 0) // This is the startup PWM Duty Cycle change to whatever
      iDutyCycle[0] = 50;
   
   
    ////End Check Retuned Values ///////////////////////////////////////
   
  ////////////////////////////////////////////////////////////
  // GUI/Display state:                                     //
  // These are the values that are displayed upon startup.  //
  // The values can be changed at any time but they should  //
  // be set here to some minimal startup values.            //
  ////////////////////////////////////////////////////////////
 

  bCursorUp = true;     // Initilize to a start up value

  //show then splash screen:
  lcd.init();
 
  lcd.printIn(TITLE_LINE_1);
  lcd.cursorTo(2,0);
  lcd.printIn(TITLE_LINE_2);

  delay(5000); //Delay function is alright to use in setup. It does not affect the
               //rest of the program
 
  //display frequency programming Menu screen:
  iCursorPosition = 0;   // Set Cursor to the first position on the LCD screen.
  RedrawLine1();         // Draw/Paint the first line of the display
  RedrawLine2();         // Draw/Paint the Second line of the display
  bRedrawLine1 = false;  // Trun Off the 'Force Redraw' so that it is not
  bRedrawLine2 = false;  // imediately redrawn in the Main Loop
}

///////////////////////////////////////////
//  Main Loop:                           //
///////////////////////////////////////////
void loop()
{
   
  //poll keypad
  PollKeyPad();
 
  //Poll PWM
  PollPWM();
 
  //Poll Save Settings
  PollSaveSettings();
 
 
  //look for a screen refresh for line 1:
  if(bRedrawLine1)
  {
    bRedrawLine1 = false; // Turn the 'Do Refresh' signal off
    RedrawLine1();
  }

  //look for a screen refresh for line 2:
  if(bRedrawLine2)
  {
    bRedrawLine2 = false;
    RedrawLine2();
  }
 
  delay(10);  // pause slightly: may be able to eliminate this delay...
 
}

////////////////////////////////////////////////////
//  This polls the buttons on the 2 line display  //
////////////////////////////////////////////////////
void PollKeyPad(void)
{
  static int iKeyOld = -1;
  int iKeyNew = GetKeyVal();
  bool exitFlag = false;
 
  if(iKeyOld != iKeyNew)
  {
    if(!bCursorUp)
    {
      bCursorUp = true;
      bRedrawLine2 = true;
    }

    delay(5);//wait for ADC value to settle; delay is ok here too

    iKeyNew = GetKeyVal();

    switch(iKeyNew)
    {
    case 0: // Right Button Selected:
      IncCursor(true);
      break;
    case 1: // Up Button Selected:
      if(iCursorPosition != 0)
        IncrDecrVal(true);   //Call the function to Increment the value

        break;
    case 2: // Down Button Selected:
      if(iCursorPosition != 0)
        IncrDecrVal(false);  //Call the function to Increment the value

        break;
    case 3: // Left Button Selected:
      IncCursor(false);
      break;
    case 4: // Enter/Select Button Selected:
      if(++iMenuSelect >= MENU_NUM_ITEMS) // select the next menu item
        iMenuSelect = 0;// if no more menu items go back to the begining
       
        //exitFlag = false;
        previousRefresh = millis(); // Save last time a refresh ocurred.
        bRedrawLine1 = true;//Force LCD update

      break;
    default:
      break;
    }
   
    iKeyOld = iKeyNew; // save the last button selected.
  }
}
//////////////////////////////////////////////////////
//  function to determing which button was pressed  //
//////////////////////////////////////////////////////
int GetKeyVal(void)
{
  const int PIN_ADC_KEYPAD = 0; // Pin 0 is used here. DO NOT USE it anywhere ales
  const int NUM_KEYS = 5;       // Set the number of 'usable' buttons
 
  // look up table of values returned
  static int aiKeyVal[NUM_KEYS] ={30, 150, 360, 535, 760};
   
  // for each of the 5 push buttons
  int iRaw = analogRead(PIN_ADC_KEYPAD);
 
   // loop through and look for which button was pushed
  for(int k = 0; k < NUM_KEYS; k++)
  {
    if(iRaw < aiKeyVal[k])
      return k;    // pass back the 'Key' value to the 'Calling Function'
  }
  return -1;
}

//////////////////////////////////////////////
//  Increment/Decrement cursor position     //
//////////////////////////////////////////////
void IncCursor(bool bInc)
{
  if(bInc)
  {  //increment
    if(++iCursorPosition >= NUM_CURSOR_POSITIONS)
      iCursorPosition = 0; // if cursor at the last position move it to the first position
  }
  else
  {  //decrement
    if(--iCursorPosition < 0)
      iCursorPosition = NUM_CURSOR_POSITIONS-1; // move cursor to the last position
  }
  bRedrawLine2 = true;//Force LCD update
}

/////////////////////////////////////////////////////////////////////////////////
// Display the 'current' menu item and any values that may have been changed   //
//                                                                             //
// NOTE: Since the Disply is only 16 characters long it is relatively easy     //
//       to keep track of where each character should be displayed. Therefore  //
//       I have kept this section very simple so that other MENU items can be  //
//       added and manipulated easily and without complication.                //
//                                                                             //
//       Also NOTE that by Hard coding values instead of using variables save  //
//       processing time by not having to do Arithmetic computations.          //
/////////////////////////////////////////////////////////////////////////////////
void RedrawLine1(void)
{
  static char pStr[LCD_WIDTH + 1];//line buffer
  //static char tmpStr1[LCD_WIDTH + 1];//line buffer
  //static char tmpStr2[LCD_WIDTH + 1];//line buffer

  long n = 0;
  int j = 0;
  float ibaseValue = 0;
  float iremainderVal  = 0;
  float fAmpVal = 0;
 
  ////////////////////////////////
  // Current Menu Items         //
  ////////////////////////////////
  // 1)000,000Hz 000%           //
  // 2) 0 Save Option           //
  ////////////////////////////////

  switch(iMenuSelect)
  {
    case 0: //First Menu item - Frequency and Duty cycle

      ///////////////////////////////////////////////
      // MENU ITEM TO DISPLAY: "1)000,000Hz 000%"  //
      //////////////////////////////////////////////
      n = lFrequency[0]; // Get current frequency value
      j = 0;

      pStr[j++] = '1';  // Collect the first 2 characters to display
      pStr[j++] = ')';

      j = 8; // set j (cursor pointer)  to the end of the frequency string only.
     
      // collect the next 7 digits including the comma (,) for the frequency
      for(int i = 0; i < 6; i++)
      {  
        pStr[j--] = n % 10 + '0'; // if not an integer value then display a zero (0)
        if(i == 2)
          pStr[j--] = ',';  // Add the comma (,) to the display
        n /= 10;            // integer pointer arithmatic
      }
   
      j = 9; // set j back to the end of the frequency string + 1 and display the HZ
      pStr[j++] = 'H'; pStr[j++] = 'z'; pStr[j++] = ' '; // Add the next 2 characters


     
      // now insert the duty cycle into the string:
      n = iDutyCycle[0]; // Get the duty cycle
      j = 14; // j to the end of the duty cycle string;

      for(int i = 0; i < 3; i++) // get the next 3 digits to display - Duty cycle value
      {  
        pStr[j--] = n % 10 + '0';
        n /= 10;
      }
      j = 15;
      pStr[j++] = '%'; // Add the last character


      break;

   
    case 1: // 2nd menu item is used initate a SAVE option. When changed from 0 to 1 a write to
            // eeprom is initiated. This can be looked at as a PSEUDO Save Button
      /////////////////////////////////////////////
      // MENU DISPLAY ITEM: "8) 0 Save Option"  //
      ////////////////////////////////////////////
      sprintf(pStr, "2) %01d Save Option",iSaveSettingVal[0]);
     
      break;
    default:
      break;
  }
  //Print it:
  lcd.cursorTo(1,0);           // move cursor to line 1 position 1
  lcd.printIn(pStr);           // print/disply the resulting string
  previousRefresh = millis();  // save the last time the display was 'Refreshed'
}

/////////////////////////////////////
//  Draw line 2 string with cursor //
/////////////////////////////////////
void RedrawLine2(void)
{
  int iCursorPos;
  iCursorPos = iCursorPosition;

  static char pStr[LCD_WIDTH + 1];//line buffer

  for(int i=0; i < LCD_WIDTH; i++)
  {
    if(i == iCursorPos)
    {
      if(bCursorUp)
        pStr[i] = '^';
      else
        pStr[i] = 'o';
    }
    else
    {
      pStr[i] = ' ';
    }
  }
  lcd.cursorTo(2,0);
  lcd.printIn(pStr);
}

void IncrDecrVal(bool bInc)
{
  switch(iMenuSelect)
  {
    case 0:
      if(iCursorPosition < 12)
      {
        if(bInc)
          lFrequency[0] += alFreqDutyMultipliers[iCursorPosition];
        else
          lFrequency[0] -= alFreqDutyMultipliers[iCursorPosition];
      }

      if(iCursorPosition > 11)
      {
        if(bInc)
          iDutyCycle[0] += alFreqDutyMultipliers[iCursorPosition];
        else
          iDutyCycle[0] -= alFreqDutyMultipliers[iCursorPosition];
         
          //RedrawLine1();
          //delay(1000);
      }
      break;
     
    case 1:
      if(iCursorPosition < 5)
      {
        if(bInc)
        {
          iSaveSettingVal[0] += alSaveButtonEmulator[iCursorPosition];
          RedrawLine1();
        }
         
      }
      break;
  }

  if(lFrequency[0] > MAX_FREQUENCY1)
    lFrequency[0] = MAX_FREQUENCY1;

  if(iDutyCycle[0] > MAX_DUTYCYCLE)
    iDutyCycle[0] = MAX_DUTYCYCLE;

  if(lFrequency[0] < MIN_FREQUENCY1)
    lFrequency[0] = MIN_FREQUENCY1;

  if(iDutyCycle[0] < MIN_DUTYCYCLE)
    iDutyCycle[0] = MIN_DUTYCYCLE;
   
  bRedrawLine1 = true;//Force LCD update
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// This function sets up 16bit Timer 1 to do PWM wave with makeup of passed variables,                 //
// it chooses the best prescaler and timer top value so that the frequency is as accurate as possible. //
/////////////////////////////////////////////////////////////////////////////////////////////////////////
unsigned int SetPwm(long lFrequency, int iDuty)
{
  lFrequency *= 2;              //When using phase correct mode, you get 1/2 speed waves
  const int DIGITAL_PIN = 10;   //this is the digital output pin to use, it can be set to 9 or 10
  const long CPU_FREQUENCY = 16000000;//16MHz
  const int NUM_PRESCALERS = 5;
  const int aiPRESCALER[NUM_PRESCALERS] = {
    1,8,64,256,1024                                      };
  long alFrequency[NUM_PRESCALERS];//used to store frequency results of different prescalers
  long alCouterTop[NUM_PRESCALERS];//used to store counter top values of different prescalers
  float fPeriod = 1 / (float)lFrequency;//desired period in seconds

  //Initialise only once:
  static bool bOnce = true;
  if(bOnce)
  {
    bOnce = false;

    //Select desired output pin
    if(DIGITAL_PIN == 9)
      sbi(TCCR1A, COM1A1);//D9
    else
      sbi(TCCR1A, COM1B1);//D10

    //Set PWM Type
    sbi(TCCR1B, WGM13);
    cbi(TCCR1B, WGM12);
    cbi(TCCR1A, WGM11);
    sbi(TCCR1A, WGM10);

    //Start PWM
    pinMode(PIN_PWM_OUTPUT, OUTPUT);
  }

  //  Try all different prescalers
  for(int i = 0; i < NUM_PRESCALERS; i++)
  {
    float fQuanta = aiPRESCALER[i] / (float)CPU_FREQUENCY;//counter granularity in seconds
    alCouterTop[i] = fPeriod / fQuanta;
    if(alCouterTop[i] > 0xFFFF)
      alCouterTop[i] = 0xFFFF;//limit to 16 bits
    alFrequency[i] = 1 / (fQuanta * alCouterTop[i]);
  }

  //  Look for best prescaler
  int iIndex = 0;
  long lSmallestError = 1000000;
  for(int j = 0; j < NUM_PRESCALERS; j++)
  {
    long lError = (abs)(lFrequency - alFrequency[j]);
    if((lSmallestError > lError))
    {
      if(alCouterTop[j] >= 4)
      {
        lSmallestError = lError;
        iIndex = j;
      }
    }
  }

  //  Configure the prescaler
  switch (iIndex)
  {
  default:
  case 0:// 001 = /1
    cbi(TCCR1B, CS12);
    cbi(TCCR1B, CS11);
    sbi(TCCR1B, CS10);
    break;
  case 1:// 010 = /8
    cbi(TCCR1B, CS12);
    sbi(TCCR1B, CS11);
    cbi(TCCR1B, CS10);
    break;
  case 2:// 011 = /64
    cbi(TCCR1B, CS12);
    sbi(TCCR1B, CS11);
    sbi(TCCR1B, CS10);
    break;
  case 3:// 100 = /256
    sbi(TCCR1B, CS12);
    cbi(TCCR1B, CS11);
    cbi(TCCR1B, CS10);
    break;
  case 4:// 101 = /1024
    sbi(TCCR1B, CS12);
    cbi(TCCR1B, CS11);
    sbi(TCCR1B, CS10);
    break;
  }

  //set PWM top
  OCR1A = alCouterTop[iIndex];

  //set PWM duty
  float fDuty = (OCR1A / (float)100);
  iDuty = fDuty * iDuty;
  OCR1B = iDuty;
}

void PollPWM(void)
{
  //SetPwm(1, 50);
  //SetPwm(lFrequency[0], iDutyCycle[0]);
 
  if(UseFcnPWM == true)
  {
   
    //look for a frequency or duty cycle change of:
    if((lFrequency_0 != lFrequency[0]) || (iDutyCycle_0 != iDutyCycle[0]))
    {
      lFrequency_0 = lFrequency[0];
      iDutyCycle_0 = iDutyCycle[0];
      SetPwm(lFrequency[0], iDutyCycle[0]);
   
        // If we are watching the Frequency or Duty Cycle value
        // refresh the display only every 2.5 seconds otherwise
        // the Display interupt/refresh sequence messes up the
        // timing on the Complimentary output function
        if(iMenuSelect == 0)
        {
            if (millis() - previousRefresh >= (long)(2500)) // If true then 'Time is up'; Refresh
            {
              previousRefresh = millis();  // save last time 'Refresh' ocurred - eliminates Delay()
              bRedrawLine1 = true;         // Redraw on next loop
            }
        }
    }
  }
}


void PollSaveSettings(void)
{
  ////////////////////////////////////////////////////////////////////////
  // Check to see if the user wants to save their current settings. If  //
  // so then save them and set the value back to zero.                  //
  ////////////////////////////////////////////////////////////////////////
  if( iSaveSettingVal[0] >=1 )
  {
    configuration.lFrequency[0] = lFrequency[0];
    configuration.iDutyCycle[0] = iDutyCycle[0];
   
    EEPROM_writeAnything(0, configuration);

    iSaveSettingVal[0] = 0;
    bRedrawLine1 = true;
  }
 
}

just finished watching the video, very impressive