Arduino kontrola rotacije

Ako ste početnik ovo je pravo mjesto za vas. Sva opšta diskusija o elektronici i/ili elektrotehnici se treba odvijati ovdje.

Moderators: stojke369, pedja089, [eDo], trax, LAF

Post Reply
jugav
Posts: 7
Joined: 11-06-2010, 14:09

Arduino kontrola rotacije

Post by jugav »

Pozdrav da li je izvodljivo da arduino proverava(hall senzorom) obrtaje recimo 4 (ili više) osovina, i zvočno(sevtlosno pojedinačno za sve 4) javlja kada padne broj obrtaja(u zadatom rangu)(sa ili bez lcd-a)?
User avatar
Black
Odlično uznapredovao
Odlično uznapredovao
Posts: 981
Joined: 17-12-2008, 15:44

Re: Arduino kontrola rotacije

Post by Black »

Izvodljivo je
jugav
Posts: 7
Joined: 11-06-2010, 14:09

Re: Arduino kontrola rotacije

Post by jugav »

sad sam malo kombinovao i stigao sad do ovog koda :
// read RPM

volatile int rpmcount = 0;//see http://arduino.cc/en/Reference/Volatile
int rpm = 0;
int zuj = 3;
unsigned long lastmillis = 0;

void setup(){
pinMode (zuj, OUTPUT);
Serial.begin(9600);

}

void loop(){
if (millis() - lastmillis == 1000){ /*Uptade every one second, this will be equal to reading frecuency (Hz).*/
rpm = rpmcount * 60; /* Convert frecuency to RPM, note: this works for one interruption per full rotation. For two interrups per full rotation use rpmcount * 30.*/

Serial.println(rpm); // print the rpm value.

rpmcount = 0; // Restart the RPM counter
lastmillis = millis(); // Uptade lasmillis
attachInterrupt(0, rpm_fan, FALLING); //enable interrupt
}
}
void rpm_fan(){ /* this code will be executed every time the interrupt 0 (pin2) gets low.*/
rpmcount++;
if (rpm<100){
tone (zuj, 1000);
delay(1000);
}
if (rpm>200){
noTone(zuj);
}
}
da li bi trebalo nesto izmeniti?
User avatar
Black
Odlično uznapredovao
Odlično uznapredovao
Posts: 981
Joined: 17-12-2008, 15:44

Re: Arduino kontrola rotacije

Post by Black »

Treba sve :lol: :lol: ,nece to ic bas tako zgodno.
Za mjerit okretaje četiriju osovina potrebno je koristit tajmere i direkno upravljanje registrima(portovima)
Ja ti mogu napisat program al tek tamo nekad sljedeći tjedan
jugav
Posts: 7
Joined: 11-06-2010, 14:09

Re: Arduino kontrola rotacije

Post by jugav »

Black wrote:Treba sve :lol: :lol: ,nece to ic bas tako zgodno.
Za mjerit okretaje četiriju osovina potrebno je koristit tajmere i direkno upravljanje registrima(portovima)
Ja ti mogu napisat program al tek tamo nekad sljedeći tjedan
Ovaj kod radi merenje sa jednim senzorom i javlja ok
Ok, nije mi hitno ;) sacekacu, hvala :)
Maki
Odlično uznapredovao
Odlično uznapredovao
Posts: 766
Joined: 02-07-2012, 12:54

Re: Arduino kontrola rotacije

Post by Maki »

A koj arduino koristiš ?
jugav
Posts: 7
Joined: 11-06-2010, 14:09

Re: Arduino kontrola rotacije

Post by jugav »

Uno
Maki
Odlično uznapredovao
Odlično uznapredovao
Posts: 766
Joined: 02-07-2012, 12:54

Re: Arduino kontrola rotacije

Post by Maki »

Sam arduino uno ima dva vanjska prekida, međutim može se probati upotrijebiti prekid koji se aktivira promjenom stanja na nekom od arduino pinova (točnije mikrokontrolera ATmega328). Mislim na ovo https://playground.arduino.cc/Main/PinChangeInterrupt
Nedostatak takvog prekida je što ne znaš koji pin je uzrokovao prekid, stoga moraš spremati prethodna stanja i uspoređivat sa trenutnim. Također taj prekid će se događat svake poluperiode ondnosno kad se dogodi promjena stanja na jednom od pinova.
Tu se postavlja pitanje što ako hall senzor, točnije signal generiran od hall senzora bude oblika koji odgovara pravokuntom signalu gdje pozitivna poluperioda traje 10%, a ostalo bude 0V. I recimo da ti sama prekidna petlja traje duže od 10% poluperiode...
Ili recimo da se prekidi događaj jedni za drugim u trajanju kraćem od trajanja prekidne petlje :idea:
Još mi pada na pamet da možeš probat upotrijebiti pored dva vanjska prekida i prekid sa analognim komparatorom. Nisam siguran jel ATmega328 ima dva ili jedan pa možda odatle iskopat još ta dva prekida.

Nisam siguran kako je Black to zamislio pa najbolje da njega pričekaš. Ovu su više moja razmišljanja, nadam se će možda pomoć.

Također ako je kojim slučajem omjer trajanja poluperioda 1:1 odnosno 50% traje jedinica, 50% traje nula možeš probati upotrijebiti neki pretvarač frekvencije u napon, tipa LM331 pa mjeriš napon sa ADC-om. Te poslje obrađuješ te podatke. Ako upotrijebiš i LM331, ne trebaš nužno arduino jer zujalicu možeš nparaviti sa NE555, a aktivaciju pištanja sa nekim komparatorom s histerezom. Naravno to zahtijeva više dodatnih komponenata od arduina... I to je samo ideja...
jugav
Posts: 7
Joined: 11-06-2010, 14:09

Re: Arduino kontrola rotacije

Post by jugav »

pade mi na pamet, da li je moguće da za uslov alarma ne bude tacno određen broj obrtaja, nego recimo da on odredi maksimalnu brzinu prvih 15 sek.pri uključenju i od toga kada patne 15% od te maksimalne da uključi zvuk i ukljuci lampicu?
jer će u nekim slučajevima biti recimo 1000 obrtaja osovine,a nekad 300...
Maki
Odlično uznapredovao
Odlično uznapredovao
Posts: 766
Joined: 02-07-2012, 12:54

Re: Arduino kontrola rotacije

Post by Maki »

Moguće je, ali prvo treba probat kako radi mjerene 4 frekvencije.
Znam da je kolega Black reko da će on napisat kod, ali eto ja sam nekaj napisao :roll:
Hoće li raditi, ne znam, moraš probati pa mi javiti povratnu informaciju.
Što se di spaja piše u kodu.
Držim fige da radi :lol:

Code: Select all

/*
Program za mjerenje 4 fkrevencije koje ispisuje preko serijskog porta.
Na ulaze D2-D5 dovode se mjerni signali, na svaki pin moraš staviti jedan pull up otpornik.
U varijablama frekv, frekv1, frekv2 i frekv3 nalaze se frekvencije pojedinih signala.
Bilo bi dobro kad bi signali kasnili 90° fazno međusobno.
Probna verzija V1.0.0
*/


volatile unsigned long Prosli, Prosli1, Prosli2, Prosli3 ,Period, Period_us,Period1, Period1_us,Period2, Period2_us,Period3, Period3_us;
const byte ulaz = 2, ulaz1 = 3, ulaz2=4, ulaz3=5;
volatile byte br1 = 0, br2=0, trenutno_stanje=0, proslo_stanje=0, br=0,br3=0;
volatile byte zastavica1=0, zastavica2=0, zastavica3=0,zastavica=0;
float frekv=0, frekv1=0, frekv2=0, frekv3=0;


void pciSetup(byte pin)
{
    *digitalPinToPCMSK(pin) |= bit (digitalPinToPCMSKbit(pin));  // enable pin 
    PCIFR  |= bit (digitalPinToPCICRbit(pin)); // clear any outstanding interrupt
    PCICR  |= bit (digitalPinToPCICRbit(pin)); // enable interrupt for the group
}

void resetiraj_timer1(){
  TCCR1A = 0;
  TCCR1B = 0;
  TCCR1C = 0;
  TIMSK1 = 0;
  TCNT1 = 0;
}
void postavi_timer1(){
  TCCR1B |= 0x02;
  TIMSK1|= 1;
}
void setup(){
  resetiraj_timer1();
  postavi_timer1();
  Serial.begin(9600);
  pinMode(ulaz, INPUT);//Ulaz 0 na D0
  pinMode(ulaz1, INPUT); //Ulaz 1 na D1
  pinMode(ulaz2, INPUT); //Ulaz 2 na D2
  pinMode(ulaz3, INPUT); //Ulaz 3 na D3
  proslo_stanje = PIND;
  pciSetup(ulaz);
  pciSetup(ulaz1);
  pciSetup(ulaz2);
  pciSetup(ulaz3);
  sei();
}

void loop(){
  
  Period_us = Period/2; 
  Period2_us = Period2/2;
  Period3_us = Period3/2;
  Period1_us = Period1/2;
  if(Period_us != 0) frekv = 1/Period_us;
  if(Period1_us != 0) frekv = 1/Period1_us;
  if(Period2_us != 0) frekv = 1/Period2_us;
  if(Period3_us != 0) frekv = 1/Period3_us;
  
  
  Serial.print("Frekvencije 1 - 4:");
  Serial.print(frekv);
  Serial.print("\t");
  Serial.print(frekv1);
  Serial.print("\t");
  Serial.print(frekv2);
  Serial.print("\t");
  Serial.print(frekv3);
}

ISR(TIMER1_OVF_vect){//}
  br++;
  br1++;
  br2++;
  br3++;
  if(br1>30){
    br1=0;
    frekv1 = 0;
  }
  if(br2>30){
    br2=0;
    frekv = 0;
  }
  if(br>30){
    br=0;
    frekv = 0;
  }
  if(br3>30){
    br3=0;
    frekv3 = 0;
  }
}

ISR (PCINT2_vect) // handle pin change interrupt for D0 to D7 here
 {
  //D2-D5 = PORTD2 - PORTD5
  trenutno_stanje = PIND;
  trenutno_stanje =trenutno_stanje>>2; //makni prva dva bita
  trenutno_stanje &=0x0F; //očisti gornja 4 bita
  
  if(trenutno_stanje^proslo_stanje){ //Ispitaj jel doslo do promjene
      //Doslo je do promjene
      if(trenutno_stanje&0x01){ //Na prvom pinu D2
        unsigned int trenutno = TCNT1;
          if(zastavica==2){ // došlo je do druge promjene (za 1 period)
              
              if(br){  //Ako je došlo do prelejva kod timera
                Period = ((unsigned long)br*65535-Prosli) + trenutno;
                br=0;
              }
               else{
                Period = trenutno - Prosli;
              }
              zastavica1=0;
            }
         else{
            zastavica++;
            if(zastavica==1) Prosli = trenutno;
          }
      }
        
    
       if(trenutno_stanje&0x02){ //Na drugom pinu D3
        unsigned int trenutno = TCNT1;
          if(zastavica1==1){ // došlo je do druge promjene (za 1 period)
              
              if(br1)
              {  //Ako je došlo do prelejva kod timera
                Period1 = ((unsigned long)br1*65535-Prosli1) + trenutno;
                br1=0;
              }
              else
              {
                Period1 = trenutno - Prosli1;
              }
              zastavica1=0;
            }
         else
          {
          zastavica1++;
          if(zastavica1==1)Prosli1 = trenutno;
          }
       }


       if(trenutno_stanje&0x04){ //Na trecem pinu D4
        unsigned int trenutno = TCNT1;
          if(zastavica2==2)
              { // došlo je do druge promjene (za 1 period)
                
                if(br2)
                {  //Ako je došlo do prelejva kod timera
                  Period2 = ((unsigned long)br2*65535-Prosli2) + trenutno;
                  br2=0;
                }
                else
                {
                  Period2 = trenutno - Prosli2;
                }
                zastavica2=0;
            }
          else
            {
              zastavica2++;
              if(zastavica2==1)Prosli2 = trenutno;
            }
       }


       if(trenutno_stanje&0x08){ //Na cetvertom pinu D2
        unsigned int trenutno = TCNT1;
          if(zastavica3==2){ // došlo je do druge promjene (za 1 period)
              if(br3)
              {  //Ako je došlo do prelejva kod timera
                Period3 = ((unsigned long)br3*65535-Prosli3) + trenutno;
                br3=0;
              }
           else
              {
                Period3 = trenutno - Prosli3;
              }
              zastavica3=0;   
            }
          else  
          {
            zastavica3++;
            if(zastavica3==1) Prosli3 = trenutno;
          }
      }
    
    
    
    }    
 
 
 
 }  
Edit:
Ako ne bude radilo, banana :| :roll: :lol:
Maki
Odlično uznapredovao
Odlično uznapredovao
Posts: 766
Joined: 02-07-2012, 12:54

Re: Arduino kontrola rotacije

Post by Maki »

Ne bude radilo :lol:
Skužio sam da sam krivo ispitivao promjene stanja na pojedinom pinu i nisam pamtio proslo stanje :roll:
Evo probaj ovako.

Code: Select all

/*
Program za mjerenje 4 fkrevencije.
Na ulaze D2-D5 dovode se mjerni signali. Dodaje pullup na svaki od ulaza.
U varijablama frekv, frekv1, frekv2 i frekv3 nalaze se frekvencije pojedinih signala.
Bilo bi dobro kad bi signali kasnili 90° fazno međusobno.
Probna verzija V1.0.1
*/


volatile unsigned long Prosli, Prosli1, Prosli2, Prosli3 ,Period, Period_us,Period1, Period1_us,Period2, Period2_us,Period3, Period3_us;
const byte ulaz = 2, ulaz1 = 3, ulaz2=4, ulaz3=5;
volatile byte br1 = 0, br2=0, trenutno_stanje=0, proslo_stanje=0, br=0,br3=0;
volatile byte zastavica1=0, zastavica2=0, zastavica3=0,zastavica=0;
float frekv=0, frekv1=0, frekv2=0, frekv3=0;
volatile byte t1=0,t2=0,t3=0,t=0;


void pciSetup(byte pin)
{
    *digitalPinToPCMSK(pin) |= bit (digitalPinToPCMSKbit(pin));  // enable pin 
    PCIFR  |= bit (digitalPinToPCICRbit(pin)); // clear any outstanding interrupt
    PCICR  |= bit (digitalPinToPCICRbit(pin)); // enable interrupt for the group
}

void resetiraj_timer1(){
  TCCR1A = 0;
  TCCR1B = 0;
  TCCR1C = 0;
  TIMSK1 = 0;
  TCNT1 = 0;
}
void postavi_timer1(){
  TCCR1B |= 0x02;
  TIMSK1|= 1;
}
void setup(){
  resetiraj_timer1();
  postavi_timer1();
  Serial.begin(9600);
  pinMode(ulaz, INPUT);//Ulaz 0 na D0
  pinMode(ulaz1, INPUT); //Ulaz 1 na D1
  pinMode(ulaz2, INPUT); //Ulaz 2 na D2
  pinMode(ulaz3, INPUT); //Ulaz 3 na D3
  proslo_stanje = PIND;
  pciSetup(ulaz);
  pciSetup(ulaz1);
  pciSetup(ulaz2);
  pciSetup(ulaz3);
  sei();
}

void loop(){
  
  Period_us = Period/2; 
  Period2_us = Period2/2;
  Period3_us = Period3/2;
  Period1_us = Period1/2;
  if(Period_us != 0) frekv = 1/Period_us;
  if(Period1_us != 0) frekv = 1/Period1_us;
  if(Period2_us != 0) frekv = 1/Period2_us;
  if(Period3_us != 0) frekv = 1/Period3_us;
  
  
  Serial.print("Frekvencije 1 - 4:");
  Serial.print(frekv);
  Serial.print("\t");
  Serial.print(frekv1);
  Serial.print("\t");
  Serial.print(frekv2);
  Serial.print("\t");
  Serial.print(frekv3);
}

ISR(TIMER1_OVF_vect){//}
  br++;
  br1++;
  br2++;
  br3++;
  if(br1>30){
    br1=0;
    frekv1 = 0;
  }
  if(br2>30){
    br2=0;
    frekv = 0;
  }
  if(br>30){
    br=0;
    frekv = 0;
  }
  if(br3>30){
    br3=0;
    frekv3 = 0;
  }
}

ISR (PCINT2_vect) // handle pin change interrupt for D0 to D7 here
 {
  //D2-D5 = PORTD2 - PORTD5
  trenutno_stanje = PIND;
  trenutno_stanje =trenutno_stanje>>2; //makni prva dva bita
  trenutno_stanje &=0x0F; //očisti gornja 4 bita
  
  if(trenutno_stanje^proslo_stanje){ //Ispitaj jel doslo do promjene
      //Doslo je do promjene
      t = (trenutno_stanje^proslo_stanje)&0x01;
      t1 = (trenutno_stanje^proslo_stanje)&0x02;
      t2 = (trenutno_stanje^proslo_stanje)&0x04;
      t3 = (trenutno_stanje^proslo_stanje)&0x08;
      if(t!=(proslo_stanje&0x01)){ //Na prvom pinu D2
        unsigned int trenutno = TCNT1;
          if(zastavica==2){ // došlo je do druge promjene (za 1 period)
              
              if(br){  //Ako je došlo do prelejva kod timera
                Period = ((unsigned long)br*65535-Prosli) + trenutno;
                br=0;
              }
               else{
                Period = trenutno - Prosli;
              }
              zastavica1=0;
            }
         else{
            zastavica++;
            if(zastavica==1) Prosli = trenutno;
          }
      }
        
    
       if(t!=(proslo_stanje&0x02)){ //Na drugom pinu D3
        unsigned int trenutno = TCNT1;
          if(zastavica1==1){ // došlo je do druge promjene (za 1 period)
              
              if(br1)
              {  //Ako je došlo do prelejva kod timera
                Period1 = ((unsigned long)br1*65535-Prosli1) + trenutno;
                br1=0;
              }
              else
              {
                Period1 = trenutno - Prosli1;
              }
              zastavica1=0;
            }
         else
          {
          zastavica1++;
          if(zastavica1==1)Prosli1 = trenutno;
          }
       }


       if(t!=(proslo_stanje&0x04)){ //Na trecem pinu D4
        unsigned int trenutno = TCNT1;
          if(zastavica2==2)
              { // došlo je do druge promjene (za 1 period)
                
                if(br2)
                {  //Ako je došlo do prelejva kod timera
                  Period2 = ((unsigned long)br2*65535-Prosli2) + trenutno;
                  br2=0;
                }
                else
                {
                  Period2 = trenutno - Prosli2;
                }
                zastavica2=0;
            }
          else
            {
              zastavica2++;
              if(zastavica2==1)Prosli2 = trenutno;
            }
       }


       if(t!=(proslo_stanje&0x08)){ //Na cetvertom pinu D2
        unsigned int trenutno = TCNT1;
          if(zastavica3==2){ // došlo je do druge promjene (za 1 period)
              if(br3)
              {  //Ako je došlo do prelejva kod timera
                Period3 = ((unsigned long)br3*65535-Prosli3) + trenutno;
                br3=0;
              }
           else
              {
                Period3 = trenutno - Prosli3;
              }
              zastavica3=0;   
            }
          else  
          {
            zastavica3++;
            if(zastavica3==1) Prosli3 = trenutno;
          }
      }
    
    
    
    }    
 
 proslo_stanje = trenutno_stanje;
 
 }  
User avatar
Black
Odlično uznapredovao
Odlično uznapredovao
Posts: 981
Joined: 17-12-2008, 15:44

Re: Arduino kontrola rotacije

Post by Black »

Nemam još kad napisat kompletan kod al evo malo za razmišljanje

while(uzimam_RPM_osovina1 == 1) program ne radi ništa drugo nego se 'koncentrira' na jednu osovinu sve dok ne izmjeri okretaje
{

if((PINB & (1<<PB4)) == 0) //čita dali je port LOW, PB4 je port D12
{
staro_stanje_pick_up=0;
stanje_pick_up=0;
}
else
{
stanje_pick_up=1;
}

if(staro_stanje_pick_up != stanje_pick_up) //ako se port promjenio sa LOW na HIGH uzmi period
{
staro_stanje_pick_up=stanje_pick_up; //stavi predhodnu petlju u FALSE da ne ulazi u nju do
ponovne promjene stanja
if(corak_signal == 1) //ćorak signal da resetira timer da nema greške dok je u ulazio u while
{
TCNT0=0;
corak_signal=0;
}
else {
osovina1period=TCNT0; //uzmi vrijeme perioda i resetiraj timer
uzimam_RPM_osovina1=0; //izlaz iz while petlje da može preć na sljedeću osovinu
}

}
}
corak_signal=0; //opet upali ćorak da kod ponovnog ulaska u while petlju može resetirat timer



neznam koliko je ovaj kod razumljiv al da objasnim ukratko o čemu se radi:
Napravi se jedna while petlja gdje kada proghram uđe samo čita dali se stanje porta mjenja, ako se port promjene(period počinje) resetira timer i opet čeka promjenu porta. Kada se to desi uzima vrijeme perioda i izlazi iz te while petlje i tako može mjerit sljedeću osovinu.

Kada se sve 4 osovine izmjere na kraju se napiše još jedna petlja gdje provjerava kakve su brzine i treba li alarm palit i za koju osovinu.

Koliko portova toliko osovina možeš mjerit,a maximalna greška je oko 2-3uS i nema straha da će mjerenje jedne osovine utjecat na neku drugu. Dali je signal 10 ili 90% dutya isto nije bitno očitanja će bit ista jer program mjeri od rising edge-a do rising edgea
https://image.ibb.co/ejQWAQ/atmega168a_pwm_02_lrg.jpg
označeno sa period na ovoj slici

Pošto se radi o 4 osovine trebam se skoncentrirat šta pišem i još u intereuptima postavit ako se neka osovina ne okreće da tu izbaci 0 RPM.
Maki
Odlično uznapredovao
Odlično uznapredovao
Posts: 766
Joined: 02-07-2012, 12:54

Re: Arduino kontrola rotacije

Post by Maki »

Slažem s s tobom, samo što treba onda ograničiti vrijeme čekanja idućeg brida jer se možda niti ne pojavi.
Nek proba ovo što sam napisao, ako radi super, ako ne onda je nabolje tu tvoju ideju primjeniti.

Kolega jugav javi kak prođe test ovog gore programa što sam napisao.
jugav
Posts: 7
Joined: 11-06-2010, 14:09

Re: Arduino kontrola rotacije

Post by jugav »

Pozdrav nisam još stigao da probam kod" :( (sezona poljoprivrede)
Čim ovih dana ugrabim vremena javljam se šta sam uradio ... ;)
Maki
Odlično uznapredovao
Odlično uznapredovao
Posts: 766
Joined: 02-07-2012, 12:54

Re: Arduino kontrola rotacije

Post by Maki »

Samo polako :)
Evo ja sam skužio da sam napravio još nekoliko grešaka u kod-u.Prepravio sam ih.
Ako ne bude radilo, napravit ću samo za mjerenje 1 frekvencije istom metodom, ako će to raditi, polako ćemo dodavati i druge ulaze u igru.

Prepravljeni kod:

Code: Select all

/*
Program za mjerenje 4 fkrevencije.
Na ulaze D2-D5 dovode se mjerni signali. Dodaje pullup na svaki od ulaza.
U varijablama frekv, frekv1, frekv2 i frekv3 nalaze se frekvencije pojedinih signala.
Bilo bi dobro kad bi signali kasnili 90° fazno međusobno. 
Na računalu će se ispisivati frekvencija svakog ulaza.
Probna verzija V1.0.2
*/


volatile unsigned long Prosli, Prosli1, Prosli2, Prosli3 ,Period, Period_us,Period1, Period1_us,Period2, Period2_us,Period3, Period3_us;
const byte ulaz = 2, ulaz1 = 3, ulaz2=4, ulaz3=5;
volatile byte br1 = 0, br2=0, trenutno_stanje=0, proslo_stanje=0, br=0,br3=0;
volatile byte zastavica1=0, zastavica2=0, zastavica3=0,zastavica=0;
float frekv=0, frekv1=0, frekv2=0, frekv3=0;
volatile byte t1=0,t2=0,t3=0,t=0;


void pciSetup(byte pin)
{
    *digitalPinToPCMSK(pin) |= bit (digitalPinToPCMSKbit(pin));  // enable pin 
    PCIFR  |= bit (digitalPinToPCICRbit(pin)); // clear any outstanding interrupt
    PCICR  |= bit (digitalPinToPCICRbit(pin)); // enable interrupt for the group
}

void resetiraj_timer1(){
  TCCR1A = 0;
  TCCR1B = 0;
  TCCR1C = 0;
  TIMSK1 = 0;
  TCNT1 = 0;
}
void postavi_timer1(){
  TCCR1B |= 0x02;
  TIMSK1|= 1;
}
void setup(){
  resetiraj_timer1();
  postavi_timer1();
  Serial.begin(9600);
  pinMode(ulaz, INPUT);//Ulaz 0 na D2
  pinMode(ulaz1, INPUT); //Ulaz 1 na D3
  pinMode(ulaz2, INPUT); //Ulaz 2 na D4
  pinMode(ulaz3, INPUT); //Ulaz 3 na D5
  proslo_stanje = PIND;
  pciSetup(ulaz);
  pciSetup(ulaz1);
  pciSetup(ulaz2);
  pciSetup(ulaz3);
  sei();
}

void loop(){
  
  Period_us = Period/2; 
  Period2_us = Period2/2;
  Period3_us = Period3/2;
  Period1_us = Period1/2;
  if(Period_us != 0) frekv = 1/Period_us;
  if(Period1_us != 0) frekv = 1/Period1_us;
  if(Period2_us != 0) frekv = 1/Period2_us;
  if(Period3_us != 0) frekv = 1/Period3_us;
  
  
  Serial.print("Frekvencije 1 - 4:");
  Serial.print(frekv);
  Serial.print("\t");
  Serial.print(frekv1);
  Serial.print("\t");
  Serial.print(frekv2);
  Serial.print("\t");
  Serial.print(frekv3);
}

ISR(TIMER1_OVF_vect){//}
  br++;
  br1++;
  br2++;
  br3++;
  if(br1>30){
    br1=0;
    frekv1 = 0;
  }
  if(br2>30){
    br2=0;
    frekv2 = 0;
  }
  if(br>30){
    br=0;
    frekv = 0;
  }
  if(br3>30){
    br3=0;
    frekv3 = 0;
  }
}

ISR (PCINT2_vect) // handle pin change interrupt for D0 to D7 here
 {
  //D2-D5 = PORTD2 - PORTD5
  trenutno_stanje = PIND;
  trenutno_stanje =trenutno_stanje>>2; //makni prva dva bita
  trenutno_stanje &=0x0F; //očisti gornja 4 bita
  int pomocna=trenutno_stanje;
  trenutno_stanje ^=proslo_stanje;
  
  if(pomocna!=trenutno_stanje){ //Ispitaj jel doslo do promjene
      //Doslo je do promjene
      t = trenutno_stanje&0x01;
      t1 = trenutno_stanje&0x02;
      t2 = trenutno_stanje&0x04;
      t3 = trenutno_stanje&0x08;
      if(t!=(proslo_stanje&0x01)){ //Na prvom pinu D2
        unsigned int trenutno = TCNT1;
          if(zastavica==2){ // došlo je do druge promjene (za 1 period)
              
              if(br){  //Ako je došlo do prelejva kod timera
                Period = ((unsigned long)br*65535-Prosli) + trenutno;
                br=0;
              }
               else{
                Period = trenutno - Prosli;
              }
              zastavica1=0;
            }
         else{
            zastavica++;
            if(zastavica==1) Prosli = trenutno;
          }
      }
        
    
       if(t1!=(proslo_stanje&0x02)){ //Na drugom pinu D3
        unsigned int trenutno = TCNT1;
          if(zastavica1==2){ // došlo je do druge promjene (za 1 period)
              
              if(br1)
              {  //Ako je došlo do prelejva kod timera
                Period1 = ((unsigned long)br1*65535-Prosli1) + trenutno;
                br1=0;
              }
              else
              {
                Period1 = trenutno - Prosli1;
              }
              zastavica1=0;
            }
         else
          {
          zastavica1++;
          if(zastavica1==1)Prosli1 = trenutno;
          }
       }


       if(t2!=(proslo_stanje&0x04)){ //Na trecem pinu D4
        unsigned int trenutno = TCNT1;
          if(zastavica2==2)
              { // došlo je do druge promjene (za 1 period)
                
                if(br2)
                {  //Ako je došlo do prelejva kod timera
                  Period2 = ((unsigned long)br2*65535-Prosli2) + trenutno;
                  br2=0;
                }
                else
                {
                  Period2 = trenutno - Prosli2;
                }
                zastavica2=0;
            }
          else
            {
              zastavica2++;
              if(zastavica2==1)Prosli2 = trenutno;
            }
       }


       if(t3!=(proslo_stanje&0x08)){ //Na cetvertom pinu D2
        unsigned int trenutno = TCNT1;
          if(zastavica3==2){ // došlo je do druge promjene (za 1 period)
              if(br3)
              {  //Ako je došlo do prelejva kod timera
                Period3 = ((unsigned long)br3*65535-Prosli3) + trenutno;
                br3=0;
              }
           else
              {
                Period3 = trenutno - Prosli3;
              }
              zastavica3=0;   
            }
          else  
          {
            zastavica3++;
            if(zastavica3==1) Prosli3 = trenutno;
          }
      }
    
    
    
    }    
 
 proslo_stanje = pomocna;
 
 }  
jugav
Posts: 7
Joined: 11-06-2010, 14:09

Re: Arduino kontrola rotacije

Post by jugav »

pozdrav,odavno nisam navracao naforum...i ono malo sto sam znao zaboravio sam :( ...
probao sam kod ali u serial monitoru sve u jednom redu brzo ide sledeca stavka pa se ne vidi nista :( ..
da li u kodu ima za zujalicu...?
Post Reply