Čitanje podataka sa hall sensora preko PC-a

Forum o svemu i svačemu, ALI vezanim za elektroniku.

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

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

Re: Čitanje podataka sa hall sensora preko PC-a

Post by Maki »

Evo probaj ovo, kopiraj cijeli jer sam dodao nešto i u prekidnim petljama. Samo trenutno nisam stavljao da je frekvecnija nula, to si ti dodaj u ovom dolje programu (imaš predviđeno mjesto za to). Jer da je period 0 onda, a frekvencija je 1/perido što ne štima. Period za slobodan kraj mora bti beskonačno.

Code: Select all

volatile int Prosli, Prosli2 ,Period, Period_us,Period2, Period2_us;
volatile unsigned long zadnjemjerenje1=0, zadnjemjerenje2=0;
const byte ulaz1 = 2, ulaz2 = 3;

void resetiraj_timer1(){
  TCCR1A = 0;
  TCCR1B = 0;
  TCCR1C = 0;
  TIMSK1 = 0;
  TCNT1 = 0;
}
void postavi_timer1(){
  TCCR1B |= 0x02;
}
void setup(){
  resetiraj_timer1();
  postavi_timer1();
  Serial.begin(9600);
  pinMode(ulaz1, INPUT_PULLUP); //interruptPin = 2, na pin 2 spajas signal.
  pinMode(ulaz2, INPUT_PULLUP); // na pin 3 ide drugi signal
  attachInterrupt(digitalPinToInterrupt(ulaz1), prekid1, RISING);
  attachInterrupt(digitalPinToInterrupt(ulaz2), prekid2, FALLING);
}

void loop(){
  //Tu radiš kaj oćeš, u varijablama Period i Period2 su ti periodi, ali da ih skaliraš na us, moraš podjeli s 2
  Period_us = Period/2; //Timer broji svakih 500ns pa to treba podjelit sa 2 da bi doil us, skaliranje
  Period2_us = Period2/2;
  Serial.print("Periodi 1 i 2:");
  Serial.print(Period_us);
  Serial.print("\t");
  Serial.print(Period2_us);
  if((millis()-zadnjemjerenje1)>1000){
    //Tu postaviš frekv1 = 0, a period1 na beskonačno
    //To mora ostat u glavnoj petlji
    }
  if((millis()-zadnjemjerenje2)>1000){
    //Tu postaviš frekv2 = 0, a period2 na beskonačno
    //To mora ostat u glavnoj petlji
    }
}
void prekid1(){
  int trenutno = TCNT1;
  if(TIFR1&1){  //Ako je došlo do prelejva
    Period = (65535-Prosli) + trenutno;
  }
  else{
    Period = trenutno - Prosli;
  }
  Prosli = trenutno;
  zadnjemjerenje1=millis();
}

void prekid2(){
  int trenutno = TCNT1;
  if(TIFR1&1){  //Ako je došlo do prelejva
    Period2 = (65535-Prosli2) + trenutno;
  }
  else{
    Period2 = trenutno - Prosli2;
  }
  Prosli2 = trenutno;
  zadnjemjerenje2=millis();
}
User avatar
Black
Odlično uznapredovao
Odlično uznapredovao
Posts: 981
Joined: 17-12-2008, 15:44

Re: Čitanje podataka sa hall sensora preko PC-a

Post by Black »

hvala još jednom nisam probao al da te nešto pitam. Znači ovi timeri su potpuno neovisni od glavnog programa i onoga što radi procesor? Kao da sam upotrjebio neke vanjske timere a arduino je taj koji šalje podatke na komjuter
Maki
Odlično uznapredovao
Odlično uznapredovao
Posts: 766
Joined: 02-07-2012, 12:54

Re: Čitanje podataka sa hall sensora preko PC-a

Post by Maki »

Molim :)
Da, recimo. Glavni program je neovisan od tih tajmera. Ono što se događa je da glavni program bude isprekidan, ali to ne utječe na njegovo izvršavanje jer on pamti gdje je stao.
Zbog ovakve upotrebe timera nemaš 2 PWM kanala.
Glavni program je isprekidan dvama prekidima. Odnosno oni se događaju svaki period.
Ovime si si oslobodio resurse procesora jer nemoraš čekat dok izmjeri.
Više informativno kako program radi.
Upalim štopericu/timer i ona/on broji sa rezolucijom od 500nS. Kad se na ulaznom signalu dogodi promjena iz logičke 0 u logičku 1 očita se vrijednost timera te se oduzme od prošlog prekida (prelaza iz 0 u 1). Ta razlika je period. To je ko na štoperici oni lap-ovi. Njihova razlika je period :wink:.
A ti prijelazi signala iz 0 u 1 aktiviraju prekid, koda netko zuji (radi nekaj drugo) nad štopericom i onda ga neki signal (vizualni, zvuk) prekine da očita vrijeme.
A ovo novo da kad nema signala ispisuje 0 radi na sličnom principu, ali bez prekida i surađuje sa glavnom petljom. U prekidnim petljama očita trenutno vrijeme s millis, a ako u glavnoj petlji razlika izmeđ zadnjeg prekidnog trenutka i trenutnog u glavnoj petlji bude prevelika (cca. 1sec) stavi frekvenciju na 0.
Malo sam smotao, ali nadam se da si razumio.
Ali da, procesor je oslobođen djela tereta. Samo da napomenem ti timeri su na mikrokontroleru koji je "srce" Arduina.
User avatar
Black
Odlično uznapredovao
Odlično uznapredovao
Posts: 981
Joined: 17-12-2008, 15:44

Re: Čitanje podataka sa hall sensora preko PC-a

Post by Black »

ajmo reć da kužim, mislim zato se i zove interupt da prekine sve kad dođe signal. Ali ja sam u ovaj tvoj program dodavao delay a on idalje točno mjeri. Mislim što se tiče ovog programa to je to, al gledam za budući projekt. Dali je moguće da ovaj mikrokontroler čita temp preko db20s, dva-tri analog ulaza i još dva signala (s tim da će jedan bit i do 5 hZ) ali od ta dva signala nesmje propustit niti jedan prijelaz iz logičkog stanja 0,1, znači svaki mora zabilježit
Maki
Odlično uznapredovao
Odlično uznapredovao
Posts: 766
Joined: 02-07-2012, 12:54

Re: Čitanje podataka sa hall sensora preko PC-a

Post by Maki »

Da nebi pomislio, procesor ne radi paralelne radnje. On jednostavno očita timer kad je potrebno i pretvori u mikrosekunde. Zato ti imaš za to vrijeme dok još period traje mogućnost iskoristi procesor za nešto drugo. Kad se dogodi prekid procesor skače na taj prekid i izvršava njega, a ono što je prethodno u glavnom programu radio ostavlja na miru. Potom kad je obradio prekid skače natrag gdje je stao.
Stoga delay koji ti staviš u glavnu petlju on (prekid) može u nekom trenutku prekinut. Ako ga prekine, delay zapravo ne traje više isto nego nešto duže. Primjer planiraš jesti 10min, ali te netko svaku minutu prekine i zadrži te pola minute. Ukupno ćeš duže jesti od 10min, negdje oko 15min. To se događa i kod delay naredbe i ostalih koje su softverski riješene.
Uglavnom, da moguće je s trenutnim programom očitavat analogne ulaze, može komunicirat sa drugim čipom, ali ovisi o komunikaciji. Ako je komunikaicja koja je podržana od strane harvera Arduina (Atmega328) onda nema problema. Komunikacije koje su rješene na softverskoj bazi (programski) vrlo vjerovatno neće raditi dobro. Npr. 1-Wire komunikacija nije podržana od strane ATmega328 stoga vrlo vjerovatno u ovom programu neće raditi kako spada. Više od dva signala teško da ćeš moći mjeriti tako da ne znam što si želio reći sa "...još dva signala (s tim da će jedan bit i do 5 hZ) ali od ta dva signala nesmje propustit niti jedan prijelaz iz logičkog stanja 0,1, znači svaki mora zabilježit...".
Komunikacija sa računalom je rješena na hardverskom nivou stoga to radi dobro u ovom programu.
User avatar
Black
Odlično uznapredovao
Odlično uznapredovao
Posts: 981
Joined: 17-12-2008, 15:44

Re: Čitanje podataka sa hall sensora preko PC-a

Post by Black »

ok to sve jasno ko dan sad, a za ove signale. Konkretno board com na autu dakle na ekranu prikazuje vanjsku temp,napon akumlator i tako dalje, a na ovim atach interupt ima dva signala jedan za brzinu vozila i drugi za potrošnju i ta dva signala mora stalno zabilježavat kako bi očitanje bilo točno. Razumiješ sad o čemu pričam. Ali kako si mi sad objasnio vidim da je to moguće odradit s ovim kontrolerom
User avatar
Black
Odlično uznapredovao
Odlično uznapredovao
Posts: 981
Joined: 17-12-2008, 15:44

Re: Čitanje podataka sa hall sensora preko PC-a

Post by Black »

I nemogu skužit zašto na periodu dužem od 16000uS krene ići u minus? zar nebi trebao na 32000 uS?
Maki
Odlično uznapredovao
Odlično uznapredovao
Posts: 766
Joined: 02-07-2012, 12:54

Re: Čitanje podataka sa hall sensora preko PC-a

Post by Maki »

Problem je u ovom: "On the Arduino Uno (and other ATMega based boards) an int stores a 16-bit (2-byte) value. This yields a range of -32,768 to 32,767 (minimum value of -2^15 and a maximum value of (2^15) - 1). ", sa: https://www.arduino.cc/en/Reference/Int
A timer je isto 16 bitini, ali on ima raspon od 0 do 65535. To su oni signed i unsigned brojevi, odnosno s predznakom i bez perdznaka.
Umjesto int stavi unsigned int ili long, ali bolje unsigned int. To bi trebalo riješit problem :wink:
User avatar
Black
Odlično uznapredovao
Odlično uznapredovao
Posts: 981
Joined: 17-12-2008, 15:44

Re: Čitanje podataka sa hall sensora preko PC-a

Post by Black »

A da tako je int nemože ići dalje, ja sve gledam kako okrivit brojač jer je 16-bitni.
A šta da ti kažem puno ti hvala na svemu, kad budem trebao one niže frekfencije opet te zovem upomoć :D ali neće to još skoro mislim
Maki
Odlično uznapredovao
Odlično uznapredovao
Posts: 766
Joined: 02-07-2012, 12:54

Re: Čitanje podataka sa hall sensora preko PC-a

Post by Maki »

Molim, drago mi je da radi :)
Kad sam već u štosu, evo probaj ovo za niže frekvencije. Sad je dodan još jedan prekid. Inače prekidi ponekad i nisu baš naj naj opcija. Jer ono redovito izvršavanje progrmama se prekida. Ako su učestali prekidi i dugi onda postoji mogućnost da ti se glavna petlja jako sporo izvršava, ali i prekidne petlje nisu aktivne kad bi doista trebale jer se npr. izvršava neki drugi prekid. U kodu ti piše gdje trebaš postavit frekvenciju na 0 za frekvencije veće od 1Hz.

Code: Select all

volatile unsigned int Prosli, Prosli2 ,Period, Period_us,Period2, Period2_us;
const byte ulaz1 = 2, ulaz2 = 3;
volatile byte br1 = 0, br2=0;

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(ulaz1, INPUT_PULLUP); //interruptPin = 2, na pin 2 spajas signal.
  pinMode(ulaz2, INPUT_PULLUP); // na pin 3 ide drugi signal
  attachInterrupt(digitalPinToInterrupt(ulaz1), prekid1, RISING);
  attachInterrupt(digitalPinToInterrupt(ulaz2), prekid2, FALLING);
  sei();//Omogući globanle prekide, ali mislim da ih je već on sa gornjom instrukcijom 
}

void loop(){
  Period_us = Period/2; 
  Period2_us = Period2/2;
  Serial.print("Periodi 1 i 2:");
  Serial.print(Period_us);
  Serial.print("\t");
  Serial.print(Period2_us);
}

ISR(TIMER1_OVF_vect){//}
  br1++;
  br2++;
  if(br1>30){ 
    br1=0;
    //Tu staviš frekvencija1 = 0 za periode dulje od sek
    //Tu budi što kraći tak da ne uzimaš puno vremena
  }
  if(br2>30){
    br2=0;
    //Tu staviš frekecenija2 = 0 za periode dulje od sek
    //Tu budi što kraći tak da ne uzimaš puno vremena
  }
}
void prekid1(){
  int trenutno = TCNT1;
  if(br1){  //Ako je došlo do prelejva
    Period = (br1*65535-Prosli) + trenutno;
    br1=0;
  }
  else{
    Period = trenutno - Prosli;
  }
  Prosli = trenutno;
}

void prekid2(){
  int trenutno = TCNT1;
  if(br2){  //Ako je došlo do prelejva
    Period2 = (br2*65535-Prosli2) + trenutno;
    br2=0;
  }
  else{
    Period2 = trenutno - Prosli2;
  }
  Prosli2 = trenutno;
}
Maki
Odlično uznapredovao
Odlično uznapredovao
Posts: 766
Joined: 02-07-2012, 12:54

Re: Čitanje podataka sa hall sensora preko PC-a

Post by Maki »

Sad sam se sjetio. U postu iznad umjesto ovog

Code: Select all

volatile unsigned int Prosli, Prosli2 ,Period, Period_us,Period2, Period2_us;
stavi ovo

Code: Select all

volatile unsigned long Prosli, Prosli2 ,Period, Period_us,Period2, Period2_us;
Jer budu brojevi veći od 65535.
User avatar
Black
Odlično uznapredovao
Odlično uznapredovao
Posts: 981
Joined: 17-12-2008, 15:44

Re: Čitanje podataka sa hall sensora preko PC-a

Post by Black »

kad stavim int onda točno mjeri, kad stavim long onda gluposti izbacuje

Image


Ista stvar se i gore dešavala u onom programu sa int mogao je mjerit do 60 hz, sa unsigned int do 30 hz, a kad bi stavio long ovako bi gluposti ispisivalo
Maki
Odlično uznapredovao
Odlično uznapredovao
Posts: 766
Joined: 02-07-2012, 12:54

Re: Čitanje podataka sa hall sensora preko PC-a

Post by Maki »

Probaj ovako:

Code: Select all

volatile unsigned long Prosli, Prosli2 ,Period, Period_us,Period2, Period2_us;
const byte ulaz1 = 2, ulaz2 = 3;
volatile byte br1 = 0, br2=0;

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(ulaz1, INPUT_PULLUP); //interruptPin = 2, na pin 2 spajas signal.
  pinMode(ulaz2, INPUT_PULLUP); // na pin 3 ide drugi signal
  attachInterrupt(digitalPinToInterrupt(ulaz1), prekid1, RISING);
  attachInterrupt(digitalPinToInterrupt(ulaz2), prekid2, FALLING);
  sei();
}

void loop(){
  //Tu radiš kaj oćeš, u varijablama Period i Period2 su ti periodi, ali da ih skaliraš na us, moraš podjeli s 2
  Period_us = Period/2; //Timer broji svakih 500ns pa to treba podjelit sa 2 da bi doil us, skaliranje
  Period2_us = Period2/2;
  Serial.print("Periodi 1 i 2:");
  Serial.print(Period_us);
  Serial.print("\t");
  Serial.print(Period2_us);
}

ISR(TIMER1_OVF_vect){//}
  br1++;
  br2++;
  if(br1>30){ 
    br1=0;
    //Tu staviš frekvencija1 = 0 za periode dulje od sek
    //Tu budi što kraći tak da ne uzimaš puno vremena
  }
  if(br2>30){
    br2=0;
    //Tu staviš frekecenija2 = 0 za periode dulje od sek
    //Tu budi što kraći tak da ne uzimaš puno vremena
  }
}
void prekid1(){
  unsigned int trenutno = TCNT1;
  if(br1){  //Ako je došlo do prelejva
    Period = ((unsigned long)br1*65535-Prosli) + trenutno;
    br1=0;
  }
  else{
    Period = trenutno - Prosli;
  }
  Prosli = trenutno;
}

void prekid2(){
  unsigned int trenutno = TCNT1;
  if(br2){  //Ako je došlo do prelejva
    Period2 = ((unsigned long)br2*65535-Prosli2) + trenutno;
    br2=0;
  }
  else{
    Period2 = trenutno - Prosli2;
  }
  Prosli2 = trenutno;
}
User avatar
Black
Odlično uznapredovao
Odlično uznapredovao
Posts: 981
Joined: 17-12-2008, 15:44

Re: Čitanje podataka sa hall sensora preko PC-a

Post by Black »

To je to :D :D :D neznam kako da ti zahvalim radi kao sat
User avatar
Black
Odlično uznapredovao
Odlično uznapredovao
Posts: 981
Joined: 17-12-2008, 15:44

Re: Čitanje podataka sa hall sensora preko PC-a

Post by Black »

program ti je odličan, jako mi se sviđa kako si ga izveo tek sad vidim kad ga ubacujem u svoj kod. Vrlo koristan program, a najbolje od svega da je jednostavan i ne opterećuje ostatak koda doslovno se mogu igrat.
Kad god korisitm neke od kodova s interneta uvijek sam nečim ograničen, ovo je napravljeno baš onako kako volim jednostavno i funkcionalno. kapa do poda
Maki
Odlično uznapredovao
Odlično uznapredovao
Posts: 766
Joined: 02-07-2012, 12:54

Re: Čitanje podataka sa hall sensora preko PC-a

Post by Maki »

Hvala :)
Drago mi je da ti koristi :wink:
User avatar
Black
Odlično uznapredovao
Odlično uznapredovao
Posts: 981
Joined: 17-12-2008, 15:44

Re: Čitanje podataka sa hall sensora preko PC-a

Post by Black »

Maki pomagaj
Trebam izmjeriti koliko traje jedan puls. puls traje od 2.5 do 15 mS. A razmak između pulsova se mjenja od 20 do 100mS

Program treba zbrojiti trajanje svih pulsova sveukupno u jednoj ili dvije sekunde


Image


Primjer u slici: 6 pulsova u 1 sec po 3 mS . Sveukupno trajanje 18mS
Samo što to neće biti ovako idealno i stalno će se mjenjat, a program treba uhvatiti svaki puls i njegovu dužinu za precizno mjerenje

Hoće li to bit moguće isprogramirat?
User avatar
Black
Odlično uznapredovao
Odlično uznapredovao
Posts: 981
Joined: 17-12-2008, 15:44

Re: Čitanje podataka sa hall sensora preko PC-a

Post by Black »

Zeleno pje signal filtriran za arduino

Code: Select all

volatile unsigned long Prosli, Prosli2 ,Period, Period_us,Period2, Period2_us,frek[200];
const byte ulaz1 = 2, ulaz2 = 3;
volatile byte br1 = 0, br2=0;
int i=0;
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(ulaz1, INPUT_PULLUP); //interruptPin = 2, na pin 2 spajas signal.
  pinMode(ulaz2, INPUT_PULLUP); // na pin 3 ide drugi signal
  attachInterrupt(digitalPinToInterrupt(ulaz1), prekid1, CHANGE);
  //attachInterrupt(digitalPinToInterrupt(ulaz2), prekid2, FALLING);
  sei();
}

void loop(){
  //Tu radiš kaj oćeš, u varijablama Period i Period2 su ti periodi, ali da ih skaliraš na us, moraš podjeli s 2
 /* Period_us = frek[i]/2; //Timer broji svakih 500ns pa to treba podjelit sa 2 da bi doil us, skaliranje
  Period2_us = Period/2;
  /*Serial.print("Periodi 1 i 2:");
  Serial.print(Period_us);
  Serial.print("\t");
  Serial.println(Period2_us);
  */
  if(i==100)
  {
    for(i=0;i<100;i++)
    {
      Serial.print("i== ");
      Serial.print(i);
      Serial.print("frek = ");
      Serial.println(frek[i]/2);
    }
    i=0;
    Serial.println("+++++++STOP++++++++");
  }
  
}

ISR(TIMER1_OVF_vect){//}
  br1++;
  br2++;
  if(br1>30){ 
    br1=0;
    //Tu staviš frekvencija1 = 0 za periode dulje od sek
    //Tu budi što kraći tak da ne uzimaš puno vremena
  }
  if(br2>30){
    br2=0;
    //Tu staviš frekecenija2 = 0 za periode dulje od sek
    //Tu budi što kraći tak da ne uzimaš puno vremena
  }
}
void prekid1(){
  unsigned int trenutno = TCNT1;
  if(br1){  //Ako je došlo do prelejva
    Period = ((unsigned long)br1*65535-Prosli) + trenutno;
    br1=0;
    
  }
  else{
    Period = trenutno - Prosli;
    
  }
  i++;
  frek[i] = Period;
  
  Prosli = trenutno;
}

void prekid2(){
  unsigned int trenutno = TCNT1;
  if(br2){  //Ako je došlo do prelejva
    Period2 = ((unsigned long)br2*65535-Prosli2) + trenutno;
    br2=0;
  }
  else{
    Period2 = trenutno - Prosli2;
  }
  Prosli2 = trenutno;
}
Probao sma nešto na ovu foru

ALi mi u niz 2-3 puta upiše istu informaciju(a trebalo bi ići nasumično jedna pa druga)
Imageimage post
Maki
Odlično uznapredovao
Odlično uznapredovao
Posts: 766
Joined: 02-07-2012, 12:54

Re: Čitanje podataka sa hall sensora preko PC-a

Post by Maki »

Ovako na prvu mi djeluje ok. Razlog ponavljanja nemora biti u loše očitavanju. Problem je u tom što ti ne šalješ informaciju računalu kad je signal doista očitan već uzastopno ono što je u buffer-u. Postavi si da kad je gotov sa očitanjem postavi neku varijablu npr. u 1. Kad ispišeš vrijednost, varijablu vrati u 0. I tako u krug. Znaći ispisuješ kad je varijabla u jedinici i onda ju resetiraš i čekaš ponovno kraj očitanja (varijabla je u jedinici). Malo sam zbunjujuće to napisao :roll:
User avatar
Black
Odlično uznapredovao
Odlično uznapredovao
Posts: 981
Joined: 17-12-2008, 15:44

Re: Čitanje podataka sa hall sensora preko PC-a

Post by Black »

ali gdje to trebam postavit? Probao sam tako radit u glavnom programu ali samo mi je prvi put učita, kasnije stalno ispisuje 0.
Post Reply