rtek1000:
Does it work?
void io_init()
{
pinMode(13, OUTPUT); // OC0A Arduino Mega2560 pin 13
pinMode(4, OUTPUT); // OC0B Arduino Mega2560 pin 4
pinMode(11, OUTPUT); // OC1A Arduino Mega2560 pin 11
pinMode(12, OUTPUT); // OC1B Arduino Mega2560 pin 12
pinMode(10, OUTPUT); // OC2A Arduino Mega2560 pin 10
pinMode(9, OUTPUT); // OC2B Arduino Mega2560 pin 9
pinMode(14, INPUT_PULLUP); // up Arduino Mega2560 14
pinMode(15, INPUT_PULLUP); // dn Arduino Mega2560 15
pinMode(16, OUTPUT); // Arduino Mega2560 16
}
digitalWrite(16, HIGH); // lighting the diode
up = digitalRead(14); // read: if you press the button, increase the frequency
#define UN (400.0) // motor rated voltage
#define FN (50.0) // motor nominal frequency
#define P (UN/FN) // associate Determining the ratio of voltage to nominal frequency
#define T_PWM (0.000255) // PWM signal period - set by the prescaler in the counters
#define T_MAX (4.0) // Specify the maximum output voltage period
#define T_MIN (0.02) // minimum output voltage
#define K_MAX floor (T_MAX/T_PWM) // number of period values for T_MAX
#define K_MIN ceil (T_MIN/T_PWM) // number of period values for T_MIN
volatile static unsigned int length_tab_sin; // variable containing the number of values in the full // period of the output voltage
static unsigned int i = 0; // auxiliary variable
volatile static unsigned int main_counter = 0; // variable in the interrupt
// ^ every T_PWM period increasing its value by 1
static unsigned int next_value_sin = 0; // variable which value sin should be calculated
static double t_param = 50; // parameter specifying the period of the output voltage
static float t = T_PWM; // T_PWM
static float omega_t; // pulsation of the output voltage multiplied by T_PWM
static float t_out; // output voltage period
static float U_o_param; // parameter specifying the size of the output voltage
// ^ calculated on the basis of t_out and U_in
static unsigned int ocr0a, ocr0b, ocr1a; // auxiliary variables to store obl. fillings
static unsigned int ocr1b, ocr2a, ocr2b; // ^
static double sin_in; // variable containing the parameter of the function sin
static double error = 1; // variable used to stop generating voltage when overloaded
static unsigned int analog = 0; // variable containing the measured value
static double U_in = 0; // variable holding the voltage measurement of the intermediate system
static double U_rms_max; // maximum currently possible to generate the effective voltage value
static bool a = 0; // logical variable for the implementation of two alternating measurements
//void setup()
//{
// Serial.begin(57600);
//}
int main()
{
io_init(); // initiate entry and exit
timers_init(); // initialization of PWM meters
adc_init(); // initialization of the ADC transducer
while (1) // infinite loop with the main program
{
if (i == 185) // condition specifying the entry to the change function
{ // parameter of the discharge voltage, calling approx. 100ms
chang_para(); // function to change the parameters of the output voltage
i = 0;
}
next_value_sin = main_counter % length_tab_sin; // the next sine value to be calculated
sin_in = omega_tnext_value_sin;
// calculating the value to registers specifying the completion of the output signal /
ocr0a = round(error * (U_o_param * (sin(sin_in) + 1) * 254 / 2) + 1); // pin
ocr0b = ocr0a - 1;
ocr1a = round (error * (U_o_param * (sin(sin_in - 2.09) + 1) * 254 / 2) + 1); // pin
ocr1b = ocr1a - 1;
ocr2a = round(error * (U_o_param * (sin(sin_in + 2.09) + 1) * 254 / 2) + 1); // pin
ocr2b = ocr2a - 1;
// updating values in registers /
cli(); // prohibition on obsloge interruptions in case if
// an interrupt occurred during the upgrade
OCR0A = ocr0a; // pin
OCR0B = ocr0b; // pin
OCR1AL = ocr1a; // pin
OCR1BL = ocr1b; // pin
OCR2A = ocr2a; // pin
OCR2B = ocr2b; // pin
sei(); // allow for interruption obsloge
i++;
}
}
void adc_init()
{
ADCSRA |= _BV(ADEN); // start the transmitter
ADCSRA |= _BV(ADPS2); // setting the prescaler
ADCSRA |= _BV(ADPS1); // ^
ADCSRA |= _BV(ADPS0); // ^
ADMUX |= _BV(REFS0); // reference voltage set as power supply
ADMUX |= ADMUX &= 0b11110000; // choose the ADC0 input for measurement
}
void timers_init()
{
cli(); // interrupt handler is forbidden
// timer0 init
TCCR0A |= _BV(COM0A1) | _BV(COM0B0) | _BV(COM0B1) | _BV(WGM00);
TCCR0B |= _BV(CS01); // preskaler 8 | _BV(WGM02)
TIMSK0 |= _BV (TOIE0); // flag from value 0 enabled //
// timer1 init
TCCR1A |= _BV(COM1A1) | _BV(COM1B0) | _BV(COM1B1) | _BV(WGM10);
TCCR1B |= _BV (CS11); // preskaler 8 // | _BV(WGM02)
// timer2 init
TCCR2A |= _BV(COM2A1) | _BV(COM2B0) | _BV(COM2B1) | _BV(WGM20);
TCCR2B |= _BV(CS21); // preskaler 8 | _BV(WGM02)
// resetting counter values
TCNT0 = 0;
TCNT1L = 0;
TCNT2 = 0; / the counter counts in g3re to 255, then in d3 ณ: / \ / \ /
at the value of 255 there is an interruption at which it occurs
voltage and current measurements
*/
sei(); // allow for interruption obsloge
}
void io_init()
{
pinMode(13, OUTPUT); // OC0A Arduino Mega2560 pin 13
pinMode(4, OUTPUT); // OC0B Arduino Mega2560 pin 4
pinMode(11, OUTPUT); // OC1A Arduino Mega2560 pin 11
pinMode(12, OUTPUT); // OC1B Arduino Mega2560 pin 12
pinMode(10, OUTPUT); // OC2A Arduino Mega2560 pin 10
pinMode(9, OUTPUT); // OC2B Arduino Mega2560 pin 9
pinMode(14, INPUT_PULLUP); // up Arduino Mega2560 14
pinMode(15, INPUT_PULLUP); // dn Arduino Mega2560 15
pinMode(16, OUTPUT); // Arduino Mega2560 16
}
ISR(TIMER0_OVF_vect) // interrupt at 0 counter 0
{
analog = ADC;
if (a)
{
U_in = 0.0709 * analog;
ADMUX |= _BV(MUX0); // choose the ADC1 input to measure the current
}
else
{
ADMUX |= ADMUX &= 0b11110000; // select the ADC0 input to measure the voltage
if (analog > 579)
{
error = 0; // if the overload turn off the voltage generation
digitalWrite(16, HIGH); // lighting the diode
}
}
ADCSRA |= _BV(ADSC); // start reading the measurement
a = a ^ 1; // the XOR gate negates the logical value a
main_counter++;
if (main_counter >= length_tab_sin) main_counter = 0;
}
void chang_para()
{
t_param = map(analogRead(3), 0, 102, 0, 100);
U_rms_max = U_in * 0.62; // value 0.62 experimentally limited
bool up; // logical variable, informs you that the button has been pressed to increase the frequency
bool down; // logical variable, informs you that the button has been pressed to decrease the frequency
up = digitalRead(14); // read: if you press the button, increase the frequency
down = digitalRead(15); // read: if you press the button you will decrease the frequency
if (!up) t_param--; // if you press the button to increase the frequency then you will decrease the period
if (!down) t_param ++; // if the button you press decreases the frequency, it will increase the period
if (t_param < 0) t_param = 0; // protection of exceeding the extreme values
if (t_param > 100) t_param = 100; // ^
length_tab_sin = ceil((K_MAX - K_MIN) * t_param / 500 + K_MIN); // amount of values filled in one period
t_out = T_PWM * length_tab_sin; // calculate the period of the output voltage
omega_t = t * 2 * PI / t_out; // calculate the output voltage pulsation
U_o_param = (P / t_out) / U_rms_max; // calculate the parameter determining the value of the output voltage
if (t_out > 1) U_o_param = 0.5 * (18.5 / U_rms_max); // voltage at the output at low frequencies of 10v
if (U_o_param > 1) U_o_param = 1; //protection of exceeding the extreme values
error = 1; //if the overload turn off the voltage generation
//digitalWrite(13, HIGH); //diode lighting
//if the overload turn off the voltage generation
digitalWrite(16, LOW); //diode lighting
// Serial.println(t_param);
}
Thank you for your kind modifications, my board is Arduino mega 2560. I am out for few days and will test your codes on Arduino mega 2560 ASP and report you back the results.