Arduino kontrola rotacije
Moderators: pedja089, stojke369, [eDo], trax, LAF
Arduino kontrola rotacije
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)?
Re: Arduino kontrola rotacije
Izvodljivo je
Re: Arduino kontrola rotacije
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?
// 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?
Re: Arduino kontrola rotacije
Treba sve ,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
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
Re: Arduino kontrola rotacije
Ovaj kod radi merenje sa jednim senzorom i javlja okBlack wrote:Treba sve ,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
Ok, nije mi hitno sacekacu, hvala
Re: Arduino kontrola rotacije
A koj arduino koristiš ?
Re: Arduino kontrola rotacije
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
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...
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
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...
Re: Arduino kontrola rotacije
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...
jer će u nekim slučajevima biti recimo 1000 obrtaja osovine,a nekad 300...
Re: Arduino kontrola rotacije
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
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
Edit:
Ako ne bude radilo, banana
Znam da je kolega Black reko da će on napisat kod, ali eto ja sam nekaj napisao
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
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;
}
}
}
}
Ako ne bude radilo, banana
Re: Arduino kontrola rotacije
Ne bude radilo
Skužio sam da sam krivo ispitivao promjene stanja na pojedinom pinu i nisam pamtio proslo stanje
Evo probaj ovako.
Skužio sam da sam krivo ispitivao promjene stanja na pojedinom pinu i nisam pamtio proslo stanje
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;
}
Re: Arduino kontrola rotacije
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.
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.
Re: Arduino kontrola rotacije
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.
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.
Re: Arduino kontrola rotacije
Pozdrav nisam još stigao da probam kod" (sezona poljoprivrede)
Čim ovih dana ugrabim vremena javljam se šta sam uradio ...
Čim ovih dana ugrabim vremena javljam se šta sam uradio ...
Re: Arduino kontrola rotacije
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:
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;
}
Re: Arduino kontrola rotacije
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...?
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...?