วันอังคารที่ 28 พฤศจิกายน พ.ศ. 2560

Arduino 3 phase induction motor variable frequency



Arduino 3 phase induction motor variable frequency

  
ดู 1,676 ครั้ง
เผยแพร่เมื่อ 8 พ.ย. 2016
http://www.avrfreaks.net/forum/3-phas...
/*โค๊ดนี้ได้มาจากชาวรัสเซียผู้มีใจอารีย์ท่านหนึ่งครับ...ขอบพระคุณ และ อนุโมทนา สาธุ ครับhttps://www.youtube.com/watch?v=Yqo87...
* VTx - transistors
*
  • หมวดหมู่

  • สัญญาอนุญาต

    • สัญญาอนุญาตมาตรฐานของ YouTube

ความคิดเห็น • 23 รายการ

Sompong Tungmepol 
Sompong Tungmepol1 เดือนที่ผ่านมาความคิดเห็นที่ไฮไลต์
สมพงศ์ อินดัสเตรียล อิเล็กทรอนิคส์ 
 ตรึงโดย Sompong Tungmepol
#ifndef _PGMSPACE_H
#define _PGMSPACE_H 1

#include <inttypes.h>

#define PROGMEM
#define PGM_P const char *
#define PSTR(str) (str)

typedef void prog_void;
typedef char prog_char;
typedef unsigned char prog_uchar;
typedef int8_t prog_int8_t;
typedef uint8_t prog_uint8_t;
typedef int16_t prog_int16_t;
typedef uint16_t prog_uint16_t;
typedef int32_t prog_int32_t;
typedef uint32_t prog_uint32_t;

#define strcpy_P(dest, src) strcpy((dest), (src))
#define strcat_P(dest, src) strcat((dest), (src))
#define strcmp_P(a, b) strcmp((a), (b))

#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define pgm_read_word(addr) (*(const unsigned short *)(addr))
#define pgm_read_dword(addr) (*(const unsigned long *)(addr))
#define pgm_read_float(addr) (*(const float *)(addr))

#define pgm_read_byte_near(addr) pgm_read_byte(addr)
#define pgm_read_word_near(addr) pgm_read_word(addr)
#define pgm_read_dword_near(addr) pgm_read_dword(addr)
#define pgm_read_float_near(addr) pgm_read_float(addr)
#define pgm_read_byte_far(addr) pgm_read_byte(addr)
#define pgm_read_word_far(addr) pgm_read_word(addr)
#define pgm_read_dword_far(addr) pgm_read_dword(addr)
#define pgm_read_float_far(addr) pgm_read_float(addr)

#endif
Venkatesh Hunter 
Can u pls send me the circuit diagram to my email id" venkateshmech.vm@gmail.com" thanks in advance...waiting for your reply:)
หมดเกิดหมดแก่หมดเจ็บหมดตาย 
#define UN (400.0) //napiecie znamionowe silnika
#define FN (50.0) //czestotliwosc znamionowa silnika
#define P (UN/FN) //wsp. okreslajacy proporcje napiecia do czestotliwoci znamionowej
#define T_PWM (0.000255) //okres sygnalu PWM - ustawiony przez preskaler w licznikach
#define T_MAX (4.0) //okreslenie maksymalnego okresu napiecia wyjsciowego
#define T_MIN (0.02) //minimalny okres napiecia wyjsciowego
#define K_MAX floor(T_MAX/T_PWM) //liczba wartosci okresu dla T_MAX
#define K_MIN ceil(T_MIN/T_PWM) //liczba wartosci okresu dla T_MIN

volatile static unsigned int dlugosc_tab_sin; //zmienna zawierajaca liczbe wartosci w pelnym
//okresie napiecia wyjsciowego
static unsigned int i = 0; //zmienna pomocniacza
volatile static unsigned int licznik_glowny = 0;//zmienna wystepujaca w przerwaniu czyklicznie
//^ co okres T_PWM zwiekszajaca swoja wartosc o 1
static unsigned int next_value_sin = 0; //zmienna ktora wartosc sin nalezy obliczyc
static double t_param=100; //parametr okreslajacy okres napiecia wyjsciowego
static float t = T_PWM; //T_PWM
static float omega_t; //pulsacja napiecia wyjsciowego pomnozona przez T_PWM
static float t_out; //okres wyjsciowy napiecia
static float U_o_param; //parametr okreslajacy wielkosc napiecie wyjsciowego
//^ obliczony na podstawie t_out i U_in
static unsigned int ocr0a, ocr0b, ocr1a;//zmienne pomocnicze do przechowywania obl. wypelnien
static unsigned int ocr1b, ocr2a, ocr2b;//^
static double sin_in; //zmienna zawierajaca parametr funkcji sin
static double blad = 1; //zmienna uzyta do zatrzymania generowania napiecia przy przeciazeniu
static unsigned int analog=0; //zmienna zawierajaca zmierzona wartosc
static double U_in = 0; //zmienna przechowuj¹ca pomiar napiecia ukladu posredniczacego
static double U_rms_max; //maksymalna aktualnie mozliwa do generacji wartosc skuteczna napiecia
static bool a=0; //zmienna logiczna do realizacji dwoch naprzemiennych pomiarow
int main()
{
io_init(); //inicjalizacja wejsc i wyjsc
timers_init(); //inicjalizacja licznikow PWM
adc_init(); //inicjalizacja przetwornika ADC
while(1) //nieskonczona petla z programem glownym
{
if(i==185) //warunek okreslajacy wejscie do funkcji zmiany
{ //parametrow napiecia wysjciowego, wywolanie co okolo 100ms
zmien_predkosc(); //funkcja zmiany parametrow napiecia wyjsciowego
i=0;
}
next_value_sin = licznik_glowny%dlugosc_tab_sin; //kolejna wartoϾ sinusa do obliczenia
sin_in=omega_t*next_value_sin;

/*obliczenie wartosci do rejestrow okreslajacych wypelnienie sygnalu wyjscioweg*/
ocr0a = round(blad*(U_o_param*(sin(sin_in)+1)*254/2)+1);//pin 6
ocr0b = ocr0a - 1;
ocr1a = round(blad*(U_o_param*(sin(sin_in-2.09)+1)*254/2)+1);//pin 9
ocr1b = ocr1a - 1;
ocr2a = round(blad*(U_o_param*(sin(sin_in+2.09)+1)*254/2)+1);//pin 11
ocr2b = ocr2a - 1;

/*uaktualnienie wartosci w rejestrach*/
cli(); //zabronienie na obsloge przerwan na wypadek gdyby
//podczas uaktualniania wystapilo przerwanie
OCR0A = ocr0a; //pin 6
OCR0B = ocr0b; //pin 5
OCR1AL = ocr1a; //pin 9
OCR1BL = ocr1b; //pin 10
OCR2A = ocr2a; //pin 11
OCR2B = ocr2b; //pin 3
sei(); //zezwolenie na obsloge przerwan
i++;
}
}
void adc_init()
{
ADCSRA |= _BV(ADEN);//uruchomienie przetwornika
ADCSRA |= _BV(ADPS2);//ustawienie preskalera
ADCSRA |= _BV(ADPS1);//^
ADCSRA |= _BV(ADPS0);//^
ADMUX |= _BV(REFS0);// napiecie odniesienia ustawione jako napiecie zasilania
ADMUX |= ADMUX &= 0b11110000; //wybranie wejscia ADC0 do pomiaru
}
void timers_init()
{
cli(); // obsloga przerwan zabroniona
//timer0 init
TCCR0A |= _BV(COM0A1) | _BV(COM0B0) | _BV(COM0B1) | _BV(WGM00);
TCCR0B |= _BV(CS01); //preskaler 8
TIMSK0 |= _BV(TOIE0); //flaga od wartosci 0 wlaczona
//timer1 init
TCCR1A |= _BV(COM1A1) | _BV(COM1B0) | _BV(COM1B1) | _BV(WGM10);
TCCR1B |= _BV(CS11); //preskaler 8
//timer2 init
TCCR2A |= _BV(COM2A1) | _BV(COM2B0) | _BV(COM2B1) | _BV(WGM20);
TCCR2B |= _BV(CS21); //preskaler 8
//zerowanie wartosci liczników
TCNT0 = 0;
TCNT1L = 0;
TCNT2 = 0;
/* licznik zlicza w góre do 255, nastepnie w dó³: /\/\/\
przy wartosci 255 jest przerwanie przy ktorym dokonuje sie
pomiarow napiec i pradow
*/
sei(); //zezwolenie na obsloge przerwan
}
void io_init()
{
pinMode(6, OUTPUT); //OC0A
pinMode(5, OUTPUT); //OC0B
pinMode(9, OUTPUT); //OC1A
pinMode(10, OUTPUT);//OC1B
pinMode(11, OUTPUT);//OC2A
pinMode(3, OUTPUT); //OC2B
pinMode(2, INPUT);
pinMode(4, INPUT);
pinMode(12, OUTPUT);
}
ISR(TIMER0_OVF_vect) //przerwanie przy wartosci 0 licznika0
{
analog = ADC;
if(a)
{
U_in = 0.0709*analog;
ADMUX |= _BV(MUX0); //wybranie wejscia ADC1 do pomiaru pradu
}
else
{
ADMUX |= ADMUX &= 0b11110000; //wybranie wejscia ADC0 do pomiaru napiecia
if(analog>579)
{
blad = 0; //jezeli przeciazenie wylaczenie generacji napiecia
digitalWrite(12, HIGH); //zapalenie diody
}
}
ADCSRA |= _BV(ADSC);//start odczytywania pomiaru
a=a^1; //bramka XOR neguje wartosc logiczna a
licznik_glowny++;
if(licznik_glowny>=dlugosc_tab_sin) licznik_glowny = 0;
}
void zmien_predkosc()
{
U_rms_max = U_in*0.62; //wartosc 0.62 wyzanczona eksperymentalnie
bool up; //zmienna logiczna, informuje o nacisnietym przycisku zwieksz czestotliwosc
bool down; //zmienna logiczna, informuje o nacisnietym przycisku zmiejsz czestotliwosc
t_param=map(analogRead(3),0,1023,0,100);
up = digitalRead(4); //odczyt: czy nacisniety przycisk zwieksz czestotliwosc
down = digitalRead(2); //odczyt: czy nacisniety przycisk zmiejsz czestotliwosc
if(up==1) t_param--; //jezeli nacisniety przycisk zwieksz czestotliwosc to zmiejsz okres
if(down==1) t_param++; //jezeli nacisniety przycisk zmniejsz czestotliwosc to zwieksz okres
if(t_param<0) t_param=0; //zabezpieczenie przekroczenia wartosci skrajnych
if(t_param>100) t_param=100;//^
dlugosc_tab_sin = ceil((K_MAX-K_MIN)*t_param/100+K_MIN);//ilosc wartosci wypelnien w jednym okresie
t_out = T_PWM*dlugosc_tab_sin; //obliczenie okresu napiecia wyjsciowego
omega_t = t*2*PI/t_out; //obliczenie pulsacji napiecia wyjsciowego
U_o_param = (P/t_out)/U_rms_max; //obliczenie parametru okreslajacego wielkosc napiecia wyjsciowego
if(t_out>1) U_o_param = 0.5*(18.5/U_rms_max); //napiêcie na wyjsciu przy niskiej czestotliwosci 10V
if(U_o_param>1) U_o_param=1; //zabezpieczenie przekroczenia wartosci skrajnych

blad = 1; //jezeli przeciazenie wylaczenie generacji napiecia
digitalWrite(12, LOW);
}
Sompong Tungmepol 
/*
Prorotype Code for 1-4MHz PWM 50% Duty Cycle
ICR1as TOP = crystal / (2*Prescale*Fpwm) in MODE 9


at 16000000MHz 64 Prescale PWM Fmax = 62.5KHz
at 16000000MHz 8 Prescale PWM Fmax = 500KHz
at 16000000MHz 1 Prescale PWM Fmax = 4MHz

*/


void setup(){

pinMode(9, OUTPUT); // OCR1A Output

pinMode(10, OUTPUT); // TEST Pin 10 as General purpose that can use after Enabling only OCR1A
digitalWrite(10, LOW);
delay(1000);
digitalWrite(10, HIGH);

//phase/frequency correct mode. SELECT THIS FOR INVERTED OUTPUTS.

TCCR1A = _BV(COM1A1); // Enable OCR1A none inverting mode
//TCCR1A = _BV(COM1A1) | _BV(COM1B1) ; // Enable OCR1A and OCAR1B and none inverting mode
// TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(COM1A0) | _BV(COM1B0);
//TCCR1B = _BV(WGM13) | _BV(CS11); // Set Prescale Clock 8 and Mode 9
TCCR1B = _BV(WGM13) | _BV(CS10); // Set Prescale Clock 1 and Mode 9
}

void loop(){
//ICR minimum 2 F = 16000000MHz No Change if using 14745600MHz

//make this variable as table
//ICR1 = 10,000; // 100Hz w/16MHz Prescale 8
//ICR1 = 5,000; // 200Hz w/16MHz Prescale 8
//ICR1 = 2; // 500KHz w/16MHz Prescale 8

ICR1 = analogRead (3); // Variable Frequency
OCR1A = ICR1 / 2; // 50 Duty of ICR1
}
Sompong Tungmepol 
Arduino - Map
https://www.arduino.cc/en/Reference/Map
แปลหน้านี้
The map() function uses integer math so will not generate fractions, when the math might indicate that ... int val = analogRead(0); val = map(val, 0, 1023, 0, 255);
Arduino - AnalogInOutSerial
https://www.arduino.cc/en/Tutorial/AnalogInOutSerial
แปลหน้านี้
29 ธ.ค. 2551 - Arduino has an analogRead range from 0 to 1023, and an analogWrite range only ... In order to convert this value, use a function called map():.
Arduino Map - Instructables
www.instructables.com/id/Arduino-Map/
แปลหน้านี้
int value=analogRead(A5);. value=map(value,0,1023,0,255);. if(A5 > hold). {. analogWrite(led, value);. Serial.println(value);. delay(10);. } // put your main code ...
[PDF]DFRduino Beginner Kit For Arduino V3 SKU ... - uri=media.digikey
https://media.digikey.com/pdf/Data%20Sheets/.../DFR0100_Web.pdf
แปลหน้านี้
delay(150);. digitalWrite(ledPin,LOW); .... colorRGB(random(0,255),random(0,255),random(0,255)); //R:0-255 G:0-255 B: 0-255 .... val = map(val, 0, 1023, 0, 179); // scale it to use it with the servo (val ... int potGreen = analogRead(potGreenPin);.
Joseph Samuels | Creative Computing Summer 2015
cc.droolcup.com/?author=4 - แปลหน้านี้
14 ส.ค. 2558 - sampleNum_scale= map(analogRead(0),0,1023,0,255);. gain_scale ..... 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163.
processing | Snebtor
snebtor.chiguiro.org/blog/category/processing/
แปลหน้านี้
4 ก.พ. 2559 - analogRead(0) from potentiometer, store it in a variable, map it // and write it arduino. ... mapvalgreen1=int(map (valgreen1, 0,1023,0,255));
MCU Arduino-based
mcu-arduino-based.blogspot.com/
... analog pin 0: int sensorValue = analogRead(A0); ... gridTextSize=14; color gridColor=150;//150; ... current = int(dataFreq);//int(map(inByte, 0, 1023, 0, height)); ..... Spin_speed = map(Spin_speed,0,1023,0,255);//((10000*Spin_speed)/255);
[PDF]Aulas de Arduino uno - Sites do IFGW
sites.ifi.unicamp.br/soares/files/2014/03/AulaArduino_uno.pdf
แปลหน้านี้
delay(150); // waits for 150ms .... By turning the knob, we can adjust the delay value between 0 and 1023 ... randomSeed(analogRead(0));. RGB1[0] ... Ans = constrain(Ans,0,255); ... int thisPitch = map(sensorReading, 400, 1000, 120, 1500);.
Stupid Pet Trick | ICM
https://itp.nyu.edu/classes/icm-dano-spring2014/.../3-stupid-pet-trick/
แปลหน้านี้
7 พ.ค. 2557 - int analogValue = analogRead(A0); .... lights = analogRead(A5); .... val = map(val, 0, 1023, 0, 179); //scale it to use with servo (0 and 180 ...
1.2.- Ejemplos – Arduino de Angel
https://arduinodeangel.wordpress.com/arduino-ide-ejemplos/
แปลหน้านี้
ReadAnalogVoltage Reads an analog input on pin 0, converts it to voltage, and prints ... read the input on analog pin 0: int sensorValue = analogRead(A0); // Convert the ..... outputValue=map(sensorValue,0,1023,0,255); pinMode(analogOutPin ..... Serial port; void setup() { size(256, 150); println("Available serial ports:"); // if ...
การค้นหาที่เกี่ยวข้องกับ map(analogRead(A5),0,1023,0,255));
arduino map function คือ
map arduino คือ
การใช้ map arduino
constrain arduino คือ
arduino analogread code
analogread pin
arduino sampling rate
analogread resolution
สมพงศ์ อินดัสเตรียล อิเล็กทรอนิคส์ 
/*
SparkFun Inventor's Kit
Example sketch 04

MULTIPLE LEDs

Make eight LEDs dance. Dance LEDs, dance!

Hardware connections:

You'll need eight LEDs, and eight 330 Ohm resistors
(orange-orange-brown).

For each LED, connect the negative side (shorter leg)
to a 330 Ohm resistor.

Connect the other side of the resistors to GND.

Connect the positive side (longer leg) of the LEDs
to Arduino digital pins 2 through 9.

This sketch was written by SparkFun Electronics,
with lots of help from the Arduino community.
This code is completely free for any use.
Visit http://learn.sparkfun.com/products/2 for SIK information.
Visit http://www.arduino.cc to learn about the Arduino.

Version 2.0 6/2012 MDG
*/


// To keep track of all the LED pins, we'll use an "array".
// An array lets you store a group of variables, and refer to them
// by their position, or "index". Here we're creating an array of
// eight integers, and initializing them to a set of values:

int ledPins[] = {2,3,4,5,6,7,8,9};

// The first element of an array is index 0.
// We've put the value "2" in index 0, "3" in index 1, etc.
// The final index in the above array is 7, which contains
// the value "9".

// We're using the values in this array to specify the pin numbers
// that the eight LEDs are connected to. LED 0 is connected to
// pin 2, LED 1 is connected to pin 3, etc.


void setup()
{
int index;

// In this sketch, we'll use "for() loops" to step variables from
// one value to another, and perform a set of instructions for
// each step. For() loops are a very handy way to get numbers to
// count up or down.

// Every for() loop has three statements separated by
// semicolons (;):

// 1. Something to do before starting
// 2. A test to perform; as long as it's true, keep looping
// 3. Something to do after each loop (increase a variable)

// For the for() loop below, these are the three statements:

// 1. index = 0; Before starting, make index = 0.
// 2. index <= 7; If index is less or equal to 7,
// run the following code.
// (When index = 8, continue with the sketch.)
// 3. index++ Putting "++" after a variable means
// "add one to it".
// (You can also use "index = index + 1".)

// Every time you go through the loop, the statements following
// the for() (within the brackets) will run.

// When the test in statement 2 is finally false, the sketch
// will continue.


// Here we'll use a for() loop to initialize all the LED pins
// to outputs. This is much easier than writing eight separate
// statements to do the same thing.

// This for() loop will make index = 0, then run the pinMode()
// statement within the brackets. It will then do the same thing
// for index = 2, index = 3, etc. all the way to index = 7.

for(index = 0; index <= 7; index++)
{
pinMode(ledPins[index],OUTPUT);
// ledPins[index] is replaced by the value in the array.
// For example, ledPins[0] is 2
}
}


void loop()
{
// This loop() calls functions that we've written further below.
// We've disabled some of these by commenting them out (putting
// "//" in front of them). To try different LED displays, remove
// the "//" in front of the ones you'd like to run, and add "//"
// in front of those you don't to comment out (and disable) those
// lines.

oneAfterAnotherNoLoop(); // Light up all the LEDs in turn

//oneAfterAnotherLoop(); // Same as oneAfterAnotherNoLoop,
// but with much less typing

//oneOnAtATime(); // Turn on one LED at a time,
// scrolling down the line

//pingPong(); // Light the LEDs middle to the edges

//marquee(); // Chase lights like you see on signs

//randomLED(); // Blink LEDs randomly
}


/*
oneAfterAnotherNoLoop()

This function will light one LED, delay for delayTime, then light
the next LED, and repeat until all the LEDs are on. It will then
turn them off in the reverse order.

This function does NOT use a for() loop. We've done it the hard way
to show you how much easier life can be when you use for() loops.
Take a look at oneAfterAnotherLoop() further down, which does
exactly the same thing with much less typing.
*/

void oneAfterAnotherNoLoop()
{
int delayTime = map (analogRead (A0),0,1023,0, 100); // time (milliseconds) to pause between LEDs
// make this smaller for faster switching

// turn all the LEDs on:

digitalWrite(ledPins[0], HIGH); //Turns on LED #0 (pin 2)
delay(delayTime); //wait delayTime milliseconds
digitalWrite(ledPins[1], HIGH); //Turns on LED #1 (pin 3)
delay(delayTime); //wait delayTime milliseconds
digitalWrite(ledPins[2], HIGH); //Turns on LED #2 (pin 4)
delay(delayTime); //wait delayTime milliseconds
digitalWrite(ledPins[3], HIGH); //Turns on LED #3 (pin 5)
delay(delayTime); //wait delayTime milliseconds
digitalWrite(ledPins[4], HIGH); //Turns on LED #4 (pin 6)
delay(delayTime); //wait delayTime milliseconds
digitalWrite(ledPins[5], HIGH); //Turns on LED #5 (pin 7)
delay(delayTime); //wait delayTime milliseconds
digitalWrite(ledPins[6], HIGH); //Turns on LED #6 (pin 8)
delay(delayTime); //wait delayTime milliseconds
digitalWrite(ledPins[7], HIGH); //Turns on LED #7 (pin 9)
delay(delayTime); //wait delayTime milliseconds

// turn all the LEDs off:

digitalWrite(ledPins[7], LOW); //Turn off LED #7 (pin 9)
delay(delayTime); //wait delayTime milliseconds
digitalWrite(ledPins[6], LOW); //Turn off LED #6 (pin 8)
delay(delayTime); //wait delayTime milliseconds
digitalWrite(ledPins[5], LOW); //Turn off LED #5 (pin 7)
delay(delayTime); //wait delayTime milliseconds
digitalWrite(ledPins[4], LOW); //Turn off LED #4 (pin 6)
delay(delayTime); //wait delayTime milliseconds
digitalWrite(ledPins[3], LOW); //Turn off LED #3 (pin 5)
delay(delayTime); //wait delayTime milliseconds
digitalWrite(ledPins[2], LOW); //Turn off LED #2 (pin 4)
delay(delayTime); //wait delayTime milliseconds
digitalWrite(ledPins[1], LOW); //Turn off LED #1 (pin 3)
delay(delayTime); //wait delayTime milliseconds
digitalWrite(ledPins[0], LOW); //Turn off LED #0 (pin 2)
delay(delayTime); //wait delayTime milliseconds
}
Sompong Tungmepol 
// DDS Sine Generator 3 phase ATMEGA 168 328P PWM 4KHZ + Danijel Gorupec, 2015
// Support 7 Segments Show Hz 15/07/2017
// Import SevSeg Library : https://playground.arduino.cc/Main/SevenSegmentLibrary

#include "arduino.h" //Store data in flash (program) memory instead of SRAM
#include "avr/pgmspace.h"
#include "avr/io.h"
#include "SevSeg.h"
SevSeg sevseg; //Instantiate a seven segment controller object

const byte sine256[] PROGMEM = {
127,130,133,136,139,143,146,149,152,155,158,161,164,167,170,173,176,178,181,184,187,190,192,195,198,200,203,205,208,210,212,215,217,219,221,223,225,227,229,231,233,234,236,238,239,240,
242,243,244,245,247,248,249,249,250,251,252,252,253,253,253,254,254,254,254,254,254,254,253,253,253,252,252,251,250,249,249,248,247,245,244,243,242,240,239,238,236,234,233,231,229,227,225,223,
221,219,217,215,212,210,208,205,203,200,198,195,192,190,187,184,181,178,176,173,170,167,164,161,158,155,152,149,146,143,139,136,133,130,127,124,121,118,115,111,108,105,102,99,96,93,90,87,84,81,78,
76,73,70,67,64,62,59,56,54,51,49,46,44,42,39,37,35,33,31,29,27,25,23,21,20,18,16,15,14,12,11,10,9,7,6,5,5,4,3,2,2,1,1,1,0,0,0,0,0,0,0,1,1,1,2,2,3,4,5,5,6,7,9,10,11,12,14,15,16,18,20,21,23,25,27,29,31,
33,35,37,39,42,44,46,49,51,54,56,59,62,64,67,70,73,76,78,81,84,87,90,93,96,99,102,105,108,111,115,118,121,124

};
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) //define a bit to have the properties of a clear bit operator
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))//define a bit to have the properties of a set bit operator
#define INPUT_DIR ((PINC&0x04)==0) // 00000010 = A2 //Control Direction


int PWM1= 9; //PWM1 output, phase 1
int PWM2 = 10; //PWM2 output, phase 2
int PWM3 = 11; //PWM3 output, phase 3


//int offset_1 = 85; //offset 1 is 120 degrees out of phase with previous phase, Refer to PWM to sine.xls
//int offset_2 = 170; //offset 2 is 120 degrees out of phase with offset 1. Refer to PWM to sine.xls
int offset_1; //offset 1 is 120 degrees out of phase with previous phase, Refer to PWM to sine.xls
int offset_2; //offset 2 is 120 degrees out of phase with offset 1. Refer to PWM to sine.xls
//int program_exec_time = A3; //monitor how quickly the interrupt trigger
int ISR_exec_time = A4; //monitor how long the interrupt takes
int INVERTOR_ENABLE = A1; //INVERTOR ENABLE

double ad_cel; //Manat Add Motor Acceleration, Deceleration
double spd_ref; //Manat Add
double spd_ref_max = 481; //60Hz Manat Add
double spd_ref_min = 20; //2.5Hz Manat Add
double speed; // Manat Add
unsigned char direction; // Manat Add rotation direction (0 forwared, 1 reverse)
unsigned char run; //Manat Add
int num = 0; // Manat Add for Hz Show 7-Segments

const double refclk=31376.6; // measured output frequency
//----------------------------------------------------------------------------
const int ledPin = A5; // the number of the LED pin
int ledState = LOW; // ledState used to set the LED
long previousMillis = 0; // will store last time LED was updated
long interval = 50000; // interval at which to blink (milliseconds)
//----------------------------------------------------------------------------

// variables used inside interrupt service declared as voilatile
volatile byte current_count; // Keep track of where the current count is in sine 256 array
volatile byte ms4_delay; //variable used to generate a 4ms delay
volatile byte c4ms; // after every 4ms this variable is incremented, its used to create a delay of 1 second
volatile unsigned long phase_accumulator; // pahse accumulator
volatile unsigned long tword_m; // dds tuning word m, refer to DDS_calculator (from Martin Nawrath) for explination.

void setup()
{
Serial.begin(9600); // Manat Add

pinMode(PWM1, OUTPUT); //sets the digital pin as output
pinMode(PWM2, OUTPUT); //sets the digital pin as output
pinMode(PWM3, OUTPUT); //sets the digital pin as output

pinMode(ledPin, OUTPUT); //Manat Add
pinMode(ISR_exec_time, OUTPUT); //sets the digital pin as output
pinMode(INVERTOR_ENABLE, OUTPUT); //sets the digital pin as output
digitalWrite(INVERTOR_ENABLE, LOW); //Manat Add



//sbi(PORTB,program_exec_time); //Sets the pin
//digitalWrite(program_exec_time, HIGH);

Setup_timer0();
Setup_timer1();
Setup_timer2();
//Disable Timer 1 interrupt to avoid any timing delays
//cbi (TIMSK0,TOIE0); //disable Timer0 !!! delay() is now not available
sbi (TIMSK2,TOIE2); //enable Timer2 Interrupt


tword_m=pow(2,32)*speed/refclk; //calulate DDS new tuning word

//----------SevenSegment------------
byte numDigits = 2;
byte digitPins[] = {13, 12};
byte segmentPins[] = {8, 7, 6, 5, 4, 3, 2};
bool resistorsOnSegments = false; // 'false' means resistors are on digit pins
byte hardwareConfig = COMMON_CATHODE; // See README.md for options
bool updateWithDelays = false; // Default. Recommended
bool leadingZeros = false; // Use 'true' if you'd like to keep the leading zeros

sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros);
sevseg.setBrightness(1);
//------------------------------------
digitalWrite(ledPin, HIGH);
WaitLoop(30000);
digitalWrite(ledPin, LOW);
}

void loop()
{
while(1)
{
ReadAnalogs();
unsigned long currentMillis = millis(); // For ledState

//--------Control Power IR2111---------------------------
if (speed > spd_ref_min){
offset_1 = 85;
offset_2 = 170;
run = 1;
digitalWrite(INVERTOR_ENABLE, HIGH);
}
else {
offset_1 = 0;
offset_2 = 0;
run = 0;
digitalWrite(INVERTOR_ENABLE, LOW);
}
//--------7 Segments Show Hz-----------------------------
num = (speed/8);
if(speed == spd_ref_min) num = 0;
sevseg.setNumber(num, 2);
sevseg.refreshDisplay();
//sbi(PORTC,program_exec_time); //Sets the pin
//digitalWrite(program_exec_time, HIGH);

//--------Monitor program--------------------------------
if((currentMillis - previousMillis) > (interval/(num+1))) {
// save the last time you blinked the LED
previousMillis = currentMillis;

// if the LED is off turn it on and vice-versa:
if (ledState == LOW)
ledState = HIGH;
else
ledState = LOW;

// set the LED with the ledState of the variable:
digitalWrite(ledPin, ledState);
}

//---------------------------------------------------------------

if (c4ms > 0) // c4ms = 4ms, thus 4ms *250 = 1 second delay
{
c4ms=0; //Reset c4ms
cbi (TIMSK2,TOIE2); //Disable Timer2 Interrupt
tword_m=pow(2,32)*speed/refclk; //Calulate DDS new tuning word
sbi (TIMSK2,TOIE2); //Enable Timer2 Interrupt

}

}
}

void WaitLoop(unsigned int time)
{
unsigned int i,j;
for (j=0;j<time;j++)
{
for (i=0;i<200;i++) //the ATmega is runs at 16MHz
if (PORTC==0xFF) DDRB|=0x02; //just a dummy instruction
}
}


void ReadAnalogs(void)
{
spd_ref=map(analogRead(0),0,1023,0,spd_ref_max); //Read voltage on analog 1 to see desired output frequency, 0V = 0Hz, 5V = 1.023kHz
ad_cel=map(analogRead(3),0,1023,1,200); // Manat Add

if(spd_ref > spd_ref_max) spd_ref = spd_ref_max; // Manat add maximum 60Hz
if(spd_ref < spd_ref_min) spd_ref = 0; // Manat Add minimum 2.5Hz


if (INPUT_DIR)
{
if (direction==0) spd_ref=spd_ref_min;
if (speed==spd_ref_min) direction=1; //only allow direction change at minimum speed

}

else
{
if (direction==1) spd_ref=spd_ref_min;
if (speed==spd_ref_min) direction=0; //only alow direction change at minimum speed

}

//if (spd_ref>speed) speed=speed+0.02; // Hz step
//if (spd_ref<speed) speed=speed-0.02;
if (spd_ref>speed) speed=speed+(1/ad_cel); // Hz step
if (spd_ref<speed) speed=speed-(1/ad_cel);
if (speed<spd_ref_min) speed=spd_ref_min;

}
Sompong Tungmepol 
#define UN (400.0) //napiecie znamionowe silnika
#define FN (50.0) //czestotliwosc znamionowa silnika
#define P (UN/FN) //wsp. okreslajacy proporcje napiecia do czestotliwoci znamionowej
#define T_PWM (0.000255) //okres sygnalu PWM - ustawiony przez preskaler w licznikach
#define T_MAX (4.0) //okreslenie maksymalnego okresu napiecia wyjsciowego
#define T_MIN (0.02) //minimalny okres napiecia wyjsciowego
#define K_MAX floor(T_MAX/T_PWM) //liczba wartosci okresu dla T_MAX
#define K_MIN ceil(T_MIN/T_PWM) //liczba wartosci okresu dla T_MIN

volatile static unsigned int dlugosc_tab_sin; //zmienna zawierajaca liczbe wartosci w pelnym
//okresie napiecia wyjsciowego
static unsigned int i = 0; //zmienna pomocniacza
volatile static unsigned int licznik_glowny = 0;//zmienna wystepujaca w przerwaniu czyklicznie
//^ co okres T_PWM zwiekszajaca swoja wartosc o 1
static unsigned int next_value_sin = 0; //zmienna ktora wartosc sin nalezy obliczyc
static double t_param=100; //parametr okreslajacy okres napiecia wyjsciowego
static float t = T_PWM; //T_PWM
static float omega_t; //pulsacja napiecia wyjsciowego pomnozona przez T_PWM
static float t_out; //okres wyjsciowy napiecia
static float U_o_param; //parametr okreslajacy wielkosc napiecie wyjsciowego
//^ obliczony na podstawie t_out i U_in
static unsigned int ocr0a, ocr0b, ocr1a;//zmienne pomocnicze do przechowywania obl. wypelnien
static unsigned int ocr1b, ocr2a, ocr2b;//^
static double sin_in; //zmienna zawierajaca parametr funkcji sin
static double blad = 1; //zmienna uzyta do zatrzymania generowania napiecia przy przeciazeniu
static unsigned int analog=0; //zmienna zawierajaca zmierzona wartosc
static double U_in = 0; //zmienna przechowuj¹ca pomiar napiecia ukladu posredniczacego
static double U_rms_max; //maksymalna aktualnie mozliwa do generacji wartosc skuteczna napiecia
static bool a=0; //zmienna logiczna do realizacji dwoch naprzemiennych pomiarow
int main()
{
io_init(); //inicjalizacja wejsc i wyjsc
timers_init(); //inicjalizacja licznikow PWM
adc_init(); //inicjalizacja przetwornika ADC
while(1) //nieskonczona petla z programem glownym
{
if(i==185) //warunek okreslajacy wejscie do funkcji zmiany
{ //parametrow napiecia wysjciowego, wywolanie co okolo 100ms
zmien_predkosc(); //funkcja zmiany parametrow napiecia wyjsciowego
i=0;
}
next_value_sin = licznik_glowny%dlugosc_tab_sin; //kolejna wartoϾ sinusa do obliczenia
sin_in=omega_t*next_value_sin;

/*obliczenie wartosci do rejestrow okreslajacych wypelnienie sygnalu wyjscioweg*/
ocr0a = round(blad*(U_o_param*(sin(sin_in)+1)*254/2)+1);//pin 6
ocr0b = ocr0a - 1;
ocr1a = round(blad*(U_o_param*(sin(sin_in-2.09)+1)*254/2)+1);//pin 9
ocr1b = ocr1a - 1;
ocr2a = round(blad*(U_o_param*(sin(sin_in+2.09)+1)*254/2)+1);//pin 11
ocr2b = ocr2a - 1;

/*uaktualnienie wartosci w rejestrach*/
cli(); //zabronienie na obsloge przerwan na wypadek gdyby
//podczas uaktualniania wystapilo przerwanie
OCR0A = ocr0a; //pin 6
OCR0B = ocr0b; //pin 5
OCR1AL = ocr1a; //pin 9
OCR1BL = ocr1b; //pin 10
OCR2A = ocr2a; //pin 11
OCR2B = ocr2b; //pin 3
sei(); //zezwolenie na obsloge przerwan
i++;
}
}
void adc_init()
{
ADCSRA |= _BV(ADEN);//uruchomienie przetwornika
ADCSRA |= _BV(ADPS2);//ustawienie preskalera
ADCSRA |= _BV(ADPS1);//^
ADCSRA |= _BV(ADPS0);//^
ADMUX |= _BV(REFS0);// napiecie odniesienia ustawione jako napiecie zasilania
ADMUX |= ADMUX &= 0b11110000; //wybranie wejscia ADC0 do pomiaru
}
void timers_init()
{
cli(); // obsloga przerwan zabroniona
//timer0 init
TCCR0A |= _BV(COM0A1) | _BV(COM0B0) | _BV(COM0B1) | _BV(WGM00);
TCCR0B |= _BV(CS01); //preskaler 8
TIMSK0 |= _BV(TOIE0); //flaga od wartosci 0 wlaczona
//timer1 init
TCCR1A |= _BV(COM1A1) | _BV(COM1B0) | _BV(COM1B1) | _BV(WGM10);
TCCR1B |= _BV(CS11); //preskaler 8
//timer2 init
TCCR2A |= _BV(COM2A1) | _BV(COM2B0) | _BV(COM2B1) | _BV(WGM20);
TCCR2B |= _BV(CS21); //preskaler 8
//zerowanie wartosci liczników
TCNT0 = 0;
TCNT1L = 0;
TCNT2 = 0;
/* licznik zlicza w góre do 255, nastepnie w dó³: /\/\/\
przy wartosci 255 jest przerwanie przy ktorym dokonuje sie
pomiarow napiec i pradow
*/
sei(); //zezwolenie na obsloge przerwan
}
void io_init()
{
pinMode(6, OUTPUT); //OC0A
pinMode(5, OUTPUT); //OC0B
pinMode(9, OUTPUT); //OC1A
pinMode(10, OUTPUT);//OC1B
pinMode(11, OUTPUT);//OC2A
pinMode(3, OUTPUT); //OC2B
pinMode(2, INPUT);
pinMode(4, INPUT);
pinMode(12, OUTPUT);
}
ISR(TIMER0_OVF_vect) //przerwanie przy wartosci 0 licznika0
{
analog = ADC;
if(a)
{
U_in = 0.0709*analog;
ADMUX |= _BV(MUX0); //wybranie wejscia ADC1 do pomiaru pradu
}
else
{
ADMUX |= ADMUX &= 0b11110000; //wybranie wejscia ADC0 do pomiaru napiecia
if(analog>579)
{
blad = 0; //jezeli przeciazenie wylaczenie generacji napiecia
digitalWrite(12, HIGH); //zapalenie diody
}
}
ADCSRA |= _BV(ADSC);//start odczytywania pomiaru
a=a^1; //bramka XOR neguje wartosc logiczna a
licznik_glowny++;
if(licznik_glowny>=dlugosc_tab_sin) licznik_glowny = 0;
}
void zmien_predkosc()
{
U_rms_max = U_in*0.62; //wartosc 0.62 wyzanczona eksperymentalnie
bool up; //zmienna logiczna, informuje o nacisnietym przycisku zwieksz czestotliwosc
bool down; //zmienna logiczna, informuje o nacisnietym przycisku zmiejsz czestotliwosc
t_param=map(analogRead(3),0,1023,0,100);
up = digitalRead(4); //odczyt: czy nacisniety przycisk zwieksz czestotliwosc
down = digitalRead(2); //odczyt: czy nacisniety przycisk zmiejsz czestotliwosc
if(up==1) t_param--; //jezeli nacisniety przycisk zwieksz czestotliwosc to zmiejsz okres
if(down==1) t_param++; //jezeli nacisniety przycisk zmniejsz czestotliwosc to zwieksz okres
if(t_param<0) t_param=0; //zabezpieczenie przekroczenia wartosci skrajnych
if(t_param>100) t_param=100;//^
dlugosc_tab_sin = ceil((K_MAX-K_MIN)*t_param/100+K_MIN);//ilosc wartosci wypelnien w jednym okresie
t_out = T_PWM*dlugosc_tab_sin; //obliczenie okresu napiecia wyjsciowego
omega_t = t*2*PI/t_out; //obliczenie pulsacji napiecia wyjsciowego
U_o_param = (P/t_out)/U_rms_max; //obliczenie parametru okreslajacego wielkosc napiecia wyjsciowego
if(t_out>1) U_o_param = 0.5*(18.5/U_rms_max); //napiêcie na wyjsciu przy niskiej czestotliwosci 10V
if(U_o_param>1) U_o_param=1; //zabezpieczenie przekroczenia wartosci skrajnych

blad = 1; //jezeli przeciazenie wylaczenie generacji napiecia
digitalWrite(12, LOW);
}
Sompong Tungmepol 
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#define UN (400.0) //napiecie znamionowe silnika
#define FN (50.0) //czestotliwosc znamionowa silnika
#define P (UN/FN) //wsp. okreslajacy proporcje napiecia do czestotliwoci znamionowej
#define T_PWM (0.000255) //okres sygnalu PWM - ustawiony przez preskaler w licznikach
#define T_MAX (4.0) //okreslenie maksymalnego okresu napiecia wyjsciowego
#define T_MIN (0.02) //minimalny okres napiecia wyjsciowego
#define K_MAX floor(T_MAX/T_PWM) //liczba wartosci okresu dla T_MAX
#define K_MIN ceil(T_MIN/T_PWM) //liczba wartosci okresu dla T_MIN

volatile static unsigned int dlugosc_tab_sin; //zmienna zawierajaca liczbe wartosci w pelnym
//okresie napiecia wyjsciowego
static unsigned int i = 0; //zmienna pomocniacza
volatile static unsigned int licznik_glowny = 0;//zmienna wystepujaca w przerwaniu czyklicznie
//^ co okres T_PWM zwiekszajaca swoja wartosc o 1
static unsigned int next_value_sin = 0; //zmienna ktora wartosc sin nalezy obliczyc
static double t_param=100; //parametr okreslajacy okres napiecia wyjsciowego
static float t = T_PWM; //T_PWM
static float omega_t; //pulsacja napiecia wyjsciowego pomnozona przez T_PWM
static float t_out; //okres wyjsciowy napiecia
static float U_o_param; //parametr okreslajacy wielkosc napiecie wyjsciowego
//^ obliczony na podstawie t_out i U_in
static unsigned int ocr0a, ocr0b, ocr1a;//zmienne pomocnicze do przechowywania obl. wypelnien
static unsigned int ocr1b, ocr2a, ocr2b;//^
static unsigned int ocr3a, ocr3b, ocr3c;//zmienne pomocnicze do przechowywania obl. wypelnien
static unsigned int ocr4a, ocr4b, ocr4c;//
static unsigned int ocr5a, ocr5b, ocr5c;//^
static double sin_in; //zmienna zawierajaca parametr funkcji sin
static double blad = 1; //zmienna uzyta do zatrzymania generowania napiecia przy przeciazeniu
static unsigned int analog=0; //zmienna zawierajaca zmierzona wartosc
static double U_in = 0; //zmienna przechowuj¹ca pomiar napiecia ukladu posredniczacego
static double U_rms_max; //maksymalna aktualnie mozliwa do generacji wartosc skuteczna napiecia
static bool a=0; //zmienna logiczna do realizacji dwoch naprzemiennych pomiarow
int main()
{
io_init(); //inicjalizacja wejsc i wyjsc
timers_init(); //inicjalizacja licznikow PWM
adc_init(); //inicjalizacja przetwornika ADC
while(1) //nieskonczona petla z programem glownym
{
if(i==185) //warunek okreslajacy wejscie do funkcji zmiany
{ //parametrow napiecia wysjciowego, wywolanie co okolo 100ms
zmien_predkosc(); //funkcja zmiany parametrow napiecia wyjsciowego
i=0;
}
next_value_sin = licznik_glowny%dlugosc_tab_sin; //kolejna wartoϾ sinusa do obliczenia
sin_in=omega_t*next_value_sin;

/*obliczenie wartosci do rejestrow okreslajacych wypelnienie sygnalu wyjscioweg*/
ocr0a = round(blad*(U_o_param*(sin(sin_in)+1)*254/2)+1);//pin 6
ocr0b = ocr0a-1;
ocr1a = round(blad*(U_o_param*(sin(sin_in-2.09)+1)*254/2)+1);//pin 9
ocr1b = ocr1a-1;
ocr2a = round(blad*(U_o_param*(sin(sin_in+2.09)+1)*254/2)+1);//pin 11
ocr2b = ocr2a-1;

ocr3a = round(blad*(U_o_param*(sin(sin_in)+1)*254/2)+1);//pin 6
ocr3b = ocr0a - 1;
ocr4a = round(blad*(U_o_param*(sin(sin_in-2.09)+1)*254/2)+1);//pin 3
ocr4b = ocr4a - 1;
ocr5a = round(blad*(U_o_param*(sin(sin_in+2.09)+1)*254/2)+1);//pin 11
ocr5b = ocr5a - 1;

ocr3c = round(blad*(U_o_param*(sin(sin_in)+1)*254/2)+1);
ocr4c = round(blad*(U_o_param*(sin(sin_in-2.09)+1)*254/2)+1);//pin 11
ocr5c = round(blad*(U_o_param*(sin(sin_in+2.09)+1)*254/2)+1);//pin 11

/*uaktualnienie wartosci w rejestrach*/
cli(); //zabronienie na obsloge przerwan na wypadek gdyby
//podczas uaktualniania wystapilo przerwanie
OCR0A = ocr0a; //pin 6
OCR0B = ocr0b; //pin 5
OCR1AL = ocr1a; //pin 9
OCR1BL = ocr1b; //pin 10
OCR2A = ocr2a; //pin 11
OCR2B = ocr2b; //pin 3

OCR3A = ocr3a; //pin 6
OCR3B = ocr3b; //pin 5
OCR3C = ocr3c; //pin 3
OCR4A = ocr4a; //pin 10
OCR4B = ocr4b; //pin 11
OCR4C = ocr4c; //pin 8

OCR5A = ocr5a; //pin 10
OCR5B = ocr5b; //pin 11
OCR5C = ocr5c; //pin 8

sei(); //zezwolenie na obsloge przerwan
i++;
}
}
void adc_init()
{
ADCSRA |= _BV(ADEN);//uruchomienie przetwornika
ADCSRA |= _BV(ADPS2);//ustawienie preskalera
ADCSRA |= _BV(ADPS1);//^
ADCSRA |= _BV(ADPS0);//^
ADMUX |= _BV(REFS0);// napiecie odniesienia ustawione jako napiecie zasilania
ADMUX |= ADMUX &= 0b11110000; //wybranie wejscia ADC0 do pomiaru
}
void timers_init()
{
cli(); // obsloga przerwan zabroniona
//timer0 init
TCCR0A |= _BV(COM0A1) | _BV(COM0B0) | _BV(COM0B1) | _BV(WGM00);
TCCR0B |= _BV(CS01)|1<< (CS00); //preskaler 8
TIMSK0 |= _BV(TOIE0); //flaga od wartosci 0 wlaczona
//timer1 init
TCCR1A |= _BV(COM1A1) | _BV(COM1B0) | _BV(COM1B1) | _BV(WGM10);
TCCR1B |= _BV(CS11)|1<< (CS10); //preskaler 8
//timer2 init
TCCR2A |= _BV(COM2A1) | _BV(COM2B0) | _BV(COM2B1) | _BV(WGM20);
TCCR2B |= _BV(CS22); //preskaler 8

//timer3 init
TCCR3A |= _BV(COM3A1) | _BV(COM3B0) | _BV(COM3B1) | _BV(WGM30);
TCCR3B |= _BV(CS31)|1<< (CS30);
TCCR3C |= _BV(CS31)|1<< (CS30);
//TCCR3C |= _BV(CS31);//;|(1 << CS00); //preskaler 8

cbi (TCCR3A, COM3C0);
sbi (TCCR3A, COM3C1);



//timer4 init
TCCR4A |= _BV(COM4A1) | _BV(COM4B0) | _BV(COM4B1) | _BV(WGM40);
TCCR4B |= _BV(CS41)|1<< (CS40);
TCCR4C |= _BV(CS41)|1<< (CS40);

cbi (TCCR4A, COM4C0);
sbi (TCCR4A, COM4C1); //preskaler 8



//timer5 init
TCCR5A |= _BV(COM5A1) | _BV(COM5B0) | _BV(COM5B1) | _BV(WGM50);
TCCR5B |= _BV(CS51)|1<< (CS50); //preskaler 8
TCCR5C |= _BV(CS51)|1<< (CS50);

cbi (TCCR5A, COM5C0);
sbi (TCCR5A, COM5C1);
//zerowanie wartosci liczników
TCNT0 = 0;
TCNT1L = 0;
TCNT2 = 0;

TCNT3 = 0;
TCNT4 = 0;
TCNT5 = 0;
/* licznik zlicza w góre do 255, nastepnie w dó³: /\/\/\
przy wartosci 255 jest przerwanie przy ktorym dokonuje sie
pomiarow napiec i pradow
*/
sei(); //zezwolenie na obsloge przerwan
}
void io_init()
{
pinMode(6, OUTPUT); //OC0A
pinMode(5, OUTPUT); //OC0B
pinMode(9, OUTPUT); //OC1A
pinMode(10, OUTPUT);//OC1B
pinMode(11, OUTPUT);//OC2A
pinMode(3, OUTPUT); //OC2B
pinMode(44, OUTPUT);
pinMode(45, OUTPUT);
pinMode(46, OUTPUT);
pinMode(53, INPUT);
pinMode(52, INPUT);
pinMode(53, INPUT);
pinMode(50, OUTPUT);

pinMode(2, OUTPUT); //OC0A
pinMode(4, OUTPUT); //OC0B
pinMode(7, OUTPUT); //OC1A
pinMode(8, OUTPUT);//OC1B
pinMode(12, OUTPUT);//OC2A
pinMode(13, OUTPUT); //OC2B

}
ISR(TIMER0_OVF_vect) //przerwanie przy wartosci 0 licznika0
{
analog = ADC;
if(a)
{
U_in = 0.0709*analog;
ADMUX |= _BV(MUX0); //wybranie wejscia ADC1 do pomiaru pradu
}
else
{
ADMUX |= ADMUX &= 0b11110000; //wybranie wejscia ADC0 do pomiaru napiecia
if(analog>579)
{
blad = 0; //jezeli przeciazenie wylaczenie generacji napiecia
digitalWrite(50, HIGH); //zapalenie diody
}
}
ADCSRA |= _BV(ADSC);//start odczytywania pomiaru
a=a^1; //bramka XOR neguje wartosc logiczna a
licznik_glowny++;
if(licznik_glowny>=dlugosc_tab_sin) licznik_glowny = 0;
}
void zmien_predkosc()
{
U_rms_max = U_in*0.62; //wartosc 0.62 wyzanczona eksperymentalnie
bool up; //zmienna logiczna, informuje o nacisnietym przycisku zwieksz czestotliwosc
bool down; //zmienna logiczna, informuje o nacisnietym przycisku zmiejsz czestotliwosc
up = digitalRead(52); //odczyt: czy nacisniety przycisk zwieksz czestotliwosc
down = digitalRead(53); //odczyt: czy nacisniety przycisk zmiejsz czestotliwosc
t_param=map(analogRead(3),0,1023,0,100);
if(up==1) t_param--; //jezeli nacisniety przycisk zwieksz czestotliwosc to zmiejsz okres
if(down==1) t_param++; //jezeli nacisniety przycisk zmniejsz czestotliwosc to zwieksz okres
if(t_param<0) t_param=0; //zabezpieczenie przekroczenia wartosci skrajnych
if(t_param>100) t_param=100;//^
dlugosc_tab_sin = ceil((K_MAX-K_MIN)*t_param/100+K_MIN);//ilosc wartosci wypelnien w jednym okresie
t_out = T_PWM*dlugosc_tab_sin; //obliczenie okresu napiecia wyjsciowego
omega_t = t*2*PI/t_out; //obliczenie pulsacji napiecia wyjsciowego
U_o_param = (P/t_out)/U_rms_max; //obliczenie parametru okreslajacego wielkosc napiecia wyjsciowego
if(t_out>1) U_o_param = 0.5*(18.5/U_rms_max); //napiêcie na wyjsciu przy niskiej czestotliwosci 10V
if(U_o_param>1) U_o_param=1; //zabezpieczenie przekroczenia wartosci skrajnych
blad = 1; //jezeli przeciazenie wylaczenie generacji napiecia
digitalWrite(50, LOW);
}
  

รายการถัดไป


2 ความคิดเห็น: