Wednesday, January 21, 2009

Latest code

I've managed to generate the three phase sin wave output without using analog write commands or any delay functions. It uses some lower level commands within the Arduino programming environment.

It works to speed up and slow down the phases, but I haven't been able to control the maximum voltage yet. I think I'm running into a problem of the interrupt service routine being too long.

Cheers.

// this will be an attempt to change how the pwm is done, and use interupts and direct port access with a higher speed

// port C > 7= pin 23
// port C > 6= pin 22
// port C > 5= pin 21
// port C > 4= pin 20
// port C > 3= pin 19
// port C > 2= pin 18
// port C > 1= pin 17
// port C > 0= pin 16

#include
#include

ISR(TIMER0_COMPA_vect) {
callback();
}

boolean ledpin_1 = 1; // 0 or 1 for if the 1st led should be on
boolean ledpin_2 = 1; // 0 or 1 for if the 2nd led should be on
boolean ledpin_3 = 1; // 0 or 1 for if the 3rd led should be on
boolean ledpin_4 = 1; // 0 or 1 for if the 4th led should be on
boolean ledpin_5 = 1; // 0 or 1 for if the 5th led should be on
boolean ledpin_6 = 1; // 0 or 1 for if the 6th led should be on
int pot_value = 0; // input for the potentiometer used to control frequency
int analog_pin = 0; // input pin for pot

int freq = 0; //this is the counter that is counting up the bins
int freqmax = 10; //this will be the amount the counter counts up before going to the next part of the array, by changing this we can alter the frequency

int sinarray [] = {0,0,87,0,0,87,3,0,85,0,0,88,7,0,83,0,0,90,10,0,81,0,0,91,14,0,79,0,0,93,17,0,77,0,0,94,21,0,74,0,0,95,24,0,72,0,0,96,28,0,69,0,0,97,31,0,67,0,0,98,34,0,64,0,0,98,37,0,62,0,0,99,41,0,59,0,0,99,44,0,56,0,0,100,47,0,53,0,0,100,50,0,50,0,0,100,53,0,47,0,0,100,56,0,44,0,0,100,59,0,41,0,0,99,62,0,37,0,0,99,64,0,34,0,0,98,67,0,31,0,0,98,69,0,28,0,0,97,72,0,24,0,0,96,74,0,21,0,0,95,77,0,17,0,0,94,79,0,14,0,0,93,81,0,10,0,0,91,83,0,7,0,0,90,85,0,3,0,0,88,87,0,0,0,0,87,88,0,0,3,0,85,90,0,0,7,0,83,91,0,0,10,0,81,93,0,0,14,0,79,94,0,0,17,0,77,95,0,0,21,0,74,96,0,0,24,0,72,97,0,0,28,0,69,98,0,0,31,0,67,98,0,0,34,0,64,99,0,0,37,0,62,99,0,0,41,0,59,100,0,0,44,0,56,100,0,0,47,0,53,100,0,0,50,0,50,100,0,0,53,0,47,100,0,0,56,0,44,99,0,0,59,0,41,99,0,0,62,0,37,98,0,0,64,0,34,98,0,0,67,0,31,97,0,0,69,0,28,96,0,0,72,0,24,95,0,0,74,0,21,94,0,0,77,0,17,93,0,0,79,0,14,91,0,0,81,0,10,90,0,0,83,0,7,88,0,0,85,0,3,87,0,0,87,0,0,85,0,0,88,3,0,83,0,0,90,7,0,81,0,0,91,10,0,79,0,0,93,14,0,77,0,0,94,17,0,74,0,0,95,21,0,72,0,0,96,24,0,69,0,0,97,28,0,67,0,0,98,31,0,64,0,0,98,34,0,62,0,0,99,37,0,59,0,0,99,41,0,56,0,0,100,44,0,53,0,0,100,47,0,50,0,0,100,50,0,47,0,0,100,53,0,44,0,0,100,56,0,41,0,0,99,59,0,37,0,0,99,62,0,34,0,0,98,64,0,31,0,0,98,67,0,28,0,0,97,69,0,24,0,0,96,72,0,21,0,0,95,74,0,17,0,0,94,77,0,14,0,0,93,79,0,10,0,0,91,81,0,7,0,0,90,83,0,3,0,0,88,85,0,0,0,0,87,87,0,0,3,0,85,88,0,0,7,0,83,90,0,0,10,0,81,91,0,0,14,0,79,93,0,0,17,0,77,94,0,0,21,0,74,95,0,0,24,0,72,96,0,0,28,0,69,97,0,0,31,0,67,98,0,0,34,0,64,98,0,0,37,0,62,99,0,0,41,0,59,99,0,0,44,0,56,100,0,0,47,0,53,100,0,0,50,0,50,100,0,0,53,0,47,100,0,0,56,0,44,100,0,0,59,0,41,99,0,0,62,0,37,99,0,0,64,0,34,98,0,0,67,0,31,98,0,0,69,0,28,97,0,0,72,0,24,96,0,0,74,0,21,95,0,0,77,0,17,94,0,0,79,0,14,93,0,0,81,0,10,91,0,0,83,0,7,90,0,0,85,0,3,88,0,0,87,0,0,87,0,0,88,3,0,85,0,0,90,7,0,83,0,0,91,10,0,81,0,0,93,14,0,79,0,0,94,17,0,77,0,0,95,21,0,74,0,0,96,24,0,72,0,0,97,28,0,69,0,0,98,31,0,67,0,0,98,34,0,64,0,0,99,37,0,62,0,0,99,41,0,59,0,0,100,44,0,56,0,0,100,47,0,53,0,0,100,50,0,50,0,0,100,53,0,47,0,0,100,56,0,44,0,0,99,59,0,41,0,0,99,62,0,37,0,0,98,64,0,34,0,0,98,67,0,31,0,0,97,69,0,28,0,0,96,72,0,24,0,0,95,74,0,21,0,0,94,77,0,17,0,0,93,79,0,14,0,0,91,81,0,10,0,0,90,83,0,7,0,0,88,85,0,3,0,0,87,87,0,0,0,0,85,88,0,0,3,0,83,90,0,0,7,0,81,91,0,0,10,0,79,93,0,0,14,0,77,94,0,0,17,0,74,95,0,0,21,0,72,96,0,0,24,0,69,97,0,0,28,0,67,98,0,0,31,0,64,98,0,0,34,0,62,99,0,0,37,0,59,99,0,0,41,0,56,100,0,0,44,0,53,100,0,0,47,0,50,100,0,0,50,0,47,100,0,0,53,0,44,100,0,0,56,0,41,99,0,0,59,0,37,99,0,0,62,0,34,98,0,0,64,0,31,98,0,0,67,0,28,97,0,0,69,0,24,96,0,0,72,0,21,95,0,0,74,0,17,94,0,0,77,0,14,93,0,0,79,0,10,91,0,0,81,0,7,90,0,0,83,0,3,88,0,0,85};


int max_volts = 95; // controls amplitude of the sin wave
int analog_volt = 1;

int value_pwm_1 = 0; // variable to keep the actual value_pwm_1
int array_tag_1 = 0; // where to get first value for phase 1 positive from array, first value in array is tagged at 0
int on_pulses_pin1 = 0; // counter for how many pulses pin 1 has been on

int value_pwm_2 = 0; // variable to keep the actual value_pwm_2
int array_tag_2 = 1; // where to get first value for phase 1 negative from array
int on_pulses_pin2 = 0;

int value_pwm_3 = 0; // variable to keep the actual value_pwm_2
int array_tag_3 = 4; // where to get first value for phase 2 positive from array
int on_pulses_pin3 = 0;

int value_pwm_4 = 0; // variable to keep the actual value_pwm_2
int array_tag_4 = 5; // where to get first value for phase 2 negative from array
int on_pulses_pin4 = 0;

int value_pwm_5 = 0; // variable to keep the actual value_pwm_2
int array_tag_5 = 2; // where to get first value for phase 3 positive from array
int on_pulses_pin5 = 0;

int value_pwm_6 = 0; // variable to keep the actual value_pwm_2
int array_tag_6 = 3; // where to get first value for phase 3 negative from array
int on_pulses_pin6 = 0;


void setup()

{
TIMSK0 = (1< // flag a (OCF0A) is written
TCCR0A = (0<TCCR0B = (0<OCR0A = 200; // this is the CTC value, this value gets changed to
// change the resolution of the counter
DDRC = 255; // this sets all of port C to outputs.
}


// This should be the routine called everytime the timer gets to the value of OCR0A
void callback()
{

if (freq >= freqmax)

{
freq = 0;
if (array_tag_1 < 1074) // 1074 is the last the last array tag for phase 1 postive, so below that we add 6 to each tag to get to the next spot for each phase in the array
{
array_tag_1 = array_tag_1 + 6;
array_tag_2 = array_tag_2 + 6;
array_tag_3 = array_tag_3 + 6;
array_tag_4 = array_tag_4 + 6;
array_tag_5 = array_tag_5 + 6;
array_tag_6 = array_tag_6 + 6;
}

else
{ // after 1074 we reset all the array tags to their original value
array_tag_1 = 0; // this resets the array counters back to zero
array_tag_2 = 1;
array_tag_3 = 4;
array_tag_4 = 5;
array_tag_5 = 2;
array_tag_6 = 3;
}
}

else
{
freq = freq + 1;
on_pulses_pin1 = (sinarray[array_tag_1] * freqmax / 100);
on_pulses_pin2 = (sinarray[array_tag_2] * freqmax / 100);
on_pulses_pin3 = (sinarray[array_tag_3] * freqmax / 100);
on_pulses_pin4 = (sinarray[array_tag_4] * freqmax / 100);
on_pulses_pin5 = (sinarray[array_tag_5] * freqmax / 100);
on_pulses_pin6 = (sinarray[array_tag_6] * freqmax / 100);
}

//PIN 1
if (on_pulses_pin1>freq) //these if's check to see if each pins counter has reached its max and then turns the pins on or off as needed
{
ledpin_1 = 1;
}
else
{
ledpin_1 = 0;
}
//PIN 2
if (on_pulses_pin2>freq) //these if's check to see if each pins counter has reached its max and then turns the pins on or off as needed
{
ledpin_2 = 1;
}
else
{
ledpin_2 = 0;
}
//PIN 3
if (on_pulses_pin3>freq) //these if's check to see if each pins counter has reached its max and then turns the pins on or off as needed
{
ledpin_3 = 1;
}
else
{
ledpin_3 = 0;
}
//PIN 4
if (on_pulses_pin4>freq) //these if's check to see if each pins counter has reached its max and then turns the pins on or off as needed
{
ledpin_4 = 1;
}
else
{
ledpin_4 = 0;
}
//PIN 5
if (on_pulses_pin5>freq) //these if's check to see if each pins counter has reached its max and then turns the pins on or off as needed
{
ledpin_5 = 1;
}
else
{
ledpin_5 = 0;
}
//PIN 6
if (on_pulses_pin6>freq) //these if's check to see if each pins counter has reached its max and then turns the pins on or off as needed
{
ledpin_6 = 1;
}
else
{
ledpin_6 = 0;
}


// Set all outputs
PORTC = (0<

}


void loop()

{

// pot_value = analogRead(analog_pin) / 100; // using a pot to control the frequency
// max_volts = analogRead(analog_volt) / 4; // changes the max voltage based on the second pot

pot_value = 100;


// port A looks like the analog inputs
// port B looks safe to play with
// port C looks safe to play with
// port D looks like it has the tx and rx pins

// Disable interrupts
// cli();
// Enable interrupts
// sei();

}

2 comments:

Unknown said...

Thanks for your interesting ac controller project ;) I am also thinking same kind of motor controller project for EV here in Finland. I tested you codes with arduino Duemilanove and got it work with some changes. I am thinking how torque control can be done but have no ideas yet. Can you share your formula for sin table creating? If like share your thoughts you can write izmopa'att'netti.fi

Unknown said...

Thanks for this intresting controller project for EV ;) I am planning same kind of controller in Finland. I tested your code with arduinoino Duemilanove and got it work with some changes. I have no idea for torgue control yet. I am thinking what kind of formula have you using to create sin table. If you like to share your thoughts write izmopa'att'netti.fi