www.elektronik.si Seznam forumov www.elektronik.si
Forum o elektrotehniki in računalništvu
 
 PomočPomoč  IščiIšči  Seznam članovSeznam članov  SkupineSkupine  StatisticsStatistika  AlbumAlbum  DatotekeFilemanager DokumentacijaDocDB LinksPovezave   Registriraj seRegistriraj se 
  PravilaPravila  LinksBolha  PriponkePriponke  KoledarKoledar  ZapiskiZapiski Tvoj profilTvoj profil Prijava za pregled zasebnih sporočilPrijava za pregled zasebnih sporočil PrijavaPrijava 

Program v 32bit načinu za arduino Atmel SAM3X8E
Pojdi na stran 1, 2, 3  Naslednja
 
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Programiranje embedded sistemov
Poglej prejšnjo temo :: Poglej naslednjo temo  
Avtor Sporočilo
Mikim
Član
Član



Pridružen-a: Ned 10 Okt 2010 1:11
Prispevkov: 141
Aktiv.: 0.86
Kraj: Brežice

PrispevekObjavljeno: Čet Maj 01, 2014 10:49 am    Naslov sporočila:  Program v 32bit načinu za arduino Atmel SAM3X8E Odgovori s citatom

Pozdravljeni,
imam napisan program za krmiljenje koračnega motorja iz dajalnika (encoder).
Vendar je napisan v ARM 8bit načinu. Iščem nekoga ki bi mi pomagal prevesti program da deluje v 32 bit načinu. AVR32

arm koda:


#define encoder_a 22
#define encoder_b 23
#define motor_step 53
#define motor_direction 52

volatile long motor_position, encoder;

void setup () {
pinMode(motor_step, OUTPUT);
pinMode(motor_direction, OUTPUT);

pinMode(encoder_a, INPUT);
pinMode(encoder_b, INPUT);
digitalWrite(encoder_a, HIGH);
digitalWrite(encoder_b, HIGH);

attachInterrupt(22, encoderPinChangeA, CHANGE);
attachInterrupt(23, encoderPinChangeB, CHANGE);
encoder = 0;
}

void loop() {
if (encoder > 0) {
digitalWrite(motor_direction, HIGH);
digitalWrite(motor_step, HIGH);
digitalWrite(motor_step, LOW);
delayMicroseconds(600);
motor_position++;
encoder = 0;
}
else if (encoder < 0) {
digitalWrite (motor_direction, LOW);
digitalWrite (motor_step, HIGH);
digitalWrite (motor_step, LOW);
delayMicroseconds(600);
motor_position--;
encoder = 0;
}
}

void encoderPinChangeA() {
if (digitalRead(encoder_a)==digitalRead(encoder_b)) {
encoder--;
}
else{
encoder++;
}
}

void encoderPinChangeB() {
if (digitalRead(encoder_a) != digitalRead(encoder_b)) {
encoder--;
}
else {
encoder++;
}
}
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Jaka57
Moderator
Moderator



Pridružen-a: Ned 12 Dec 2004 21:47
Prispevkov: 5766
Aktiv.: 25.97
Kraj: Grosuplje

PrispevekObjavljeno: Čet Maj 01, 2014 1:00 pm    Naslov sporočila:   Odgovori s citatom

Ne vem sicer od kje ti to, da je zgornji program pisan v ARM 8 bitnem načinu (???), kajti zgornji program je klasičen Arduino sketch (ki ne ve nič o 8 bitnem ali 32 bitnem načinu!), ki ga lahko v Arduino IDE prevedeš za katerikoli MCU, ki ga Arduino IDE podpira.
Pazit je potrebno le na definicije pinov, kajti nimajo vse ploščice (MCUji) vseh pinov na razpolago.
Razlika bo edino v naslednjih stavkih:
Koda:
#define encoder_a 22
#define encoder_b 23
#define motor_step 53
#define motor_direction 52


spremeni tudi attachInterupt(), saj so pini za enkoder že definirani zgoraj!
Koda:
void setup () {
.
.

.
.
.
.
attachInterrupt(enkoder_a, encoderPinChangeA, CHANGE);
attachInterrupt(enkoder_b, encoderPinChangeB, CHANGE);

Dobro bi bilo, če bi napisal za kakšen MCU bi rad prevedel to kodo!
Dobro bi bilo tudi, da bi šel na Arduino stran in si prebral, kaj Arduino je in iz tega ugotovil, kaj ni. Lahko pa pobrskaš malo po našem forumu, ker je o tem že tekla debata.

_________________
Lp, Jaka
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
Mikim
Član
Član



Pridružen-a: Ned 10 Okt 2010 1:11
Prispevkov: 141
Aktiv.: 0.86
Kraj: Brežice

PrispevekObjavljeno: Čet Maj 01, 2014 3:10 pm    Naslov sporočila:   Odgovori s citatom

Živijo Jakob,
hmm, bil sem na ardoino forumu, pa so dejali da imam napisan program v arm za večjo hitrost naj uporabim AVR z 32bit.
Pojasnilo: ko sem testiral arduino mini pro 16mhz mi je pri hitrem pomiku dajalnika izgubilo nekaj signalov in koračni motor ni sunkovito obrnil ampak počasneje. Če inkoder obračam počasi pa deluje vredu. Ko sem meril signal step mi je pri hitrem obratu prikazal manj pulzov kot bi ga obračal počasi. Ker mini ni tako hiter in deluje v 16Mhz taktu in 8 bitnem režimu sem kupil arduino DUE ker dela v 32bitnem režimu in ima 84MHz takt. Sem samo odstranil delay.h ker ga due ne podpira in spremenil sem pin za uporabo v DUE. Ko sem zadevo testiral mi deluje enako kot v mini, čeprav je DUE strojno precej hitrejši. Po tem sklepam da program ne deluje kot bi moral in kot sem opazil da pišejo program za due v tem smislu.

uint32_t pin_17 = (1u << 12); // mask for pin 17
uint32_t pin_20 = (1u << 12); // mask for pin 20

To ni klasičen arduino sketch.
Uporabljam Arduino 1.5.6 r2 platformo ampak, kako lahko prevedem codo, da mi deluje hitreje.
Tu sem vzel kodo, ker jo rabim za enako zadevo, da mi inkoder vozi koračni motor.
Ampak ne deluje dobro, saj prikazuje počaso vrtenje inkoderja.
https://www.youtube.com/watch?v=2dh6TIkN6jE
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
bostjan 2
Član
Član



Pridružen-a: Pon 05 Dec 2011 19:35
Prispevkov: 121
Aktiv.: 0.81
Kraj: Vače

PrispevekObjavljeno: Čet Maj 01, 2014 3:46 pm    Naslov sporočila:   Odgovori s citatom

Mikim, lahko od začetka?

Najprej, kak enkoder imaš ter kako je spojen na arduina. Število impulzov na sekundo ali obrat?
Shema, čeprav na Wc papir.
Kakšno hitrost impulzov dosegaš. 16 Mhz clock kot ga imaš na Arduinu ter glede na program kot ga imaš bi rekel da lahko generiraš cca 30.000 pin write/sekundo. Pa saj stepper motor najverjetneje tega ne zmore. Preglej ter posreduj podatke, lahko da sploh ni problem v arduinu..

LP Boštjan

_________________
Ja še vedno se ne da...
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Mikim
Član
Član



Pridružen-a: Ned 10 Okt 2010 1:11
Prispevkov: 141
Aktiv.: 0.86
Kraj: Brežice

PrispevekObjavljeno: Čet Maj 01, 2014 5:12 pm    Naslov sporočila:   Odgovori s citatom

Bostjan, mislim da je problem v programu.
Uporabljam enkoder iskra TGR10.4-05-T-DS-65-500.
Ko merim signal A in B iz inkoderja ima pravokotne signale če hitreje vrtim so bolj pogosti in počasneje je razmak signala daljši. To je ok. Ko pa merim puls so pri počasnem vrtenju razdalje impulsa enake, če pa inkoder hitro vrtim se impulzi gubijo. Kod da jih polovica manjka. Takrat se motor obrača bolj počasi kot bi moral.
Jaz pa rabim enakomerno hitrost, če so sunkoviti obrati na inkoderju mora tudi motor sunkovito obračat. Ni mi jasno že 2 meseca testiran in nikako mi ne uspe.
Program ima step in direct signal tu se pojavi napaka. Kot da arduino plošča ne more v tako kratkem času prebrati vseh impulzov inkoderja in jih poslati na step izhod. Zato sem nabavil DUE 32bit z 84MHz a žal dela enako kot MINI. Zato iščem codo ki podpira 32bit za DUE. To mi je še zadnja možnost. LP Miki
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
bostjan 2
Član
Član



Pridružen-a: Pon 05 Dec 2011 19:35
Prispevkov: 121
Aktiv.: 0.81
Kraj: Vače

PrispevekObjavljeno: Čet Maj 01, 2014 5:48 pm    Naslov sporočila:   Odgovori s citatom

Miki, še enkrat. Frekvenca oziroma koraki enkoderja. Je to 10, 100, 1000, 10000 na sekundo. Oziroma izmeri na osciloskopu periodo enkoderja, ko se začne izgubljati..
Lahko pa probaš z direktnim pisanjem na izhodni port, kar je cca 20x hitreje, če je res tu problem. Pa ne verjamem. Namesto:

digitalWrite(3, 1);
digitalWrite(3, 0);

je enako če napišeš:

PORTD |= 0x8;
PORTD &= ~0x8;

Samo dela pa 20x hitreje...

_________________
Ja še vedno se ne da...
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Mikim
Član
Član



Pridružen-a: Ned 10 Okt 2010 1:11
Prispevkov: 141
Aktiv.: 0.86
Kraj: Brežice

PrispevekObjavljeno: Čet Maj 01, 2014 6:46 pm    Naslov sporočila:   Odgovori s citatom

Koraki inkoderja 500 oz. število linij. Izhodna max freq. 300kHz. Te podatke imam. Imam pa stari osciloskop pa je težko točno določit frekvenco, ker nimam enakomernih obratov na inkoderju.
Ne vem kako misliš z direktnim pisanjem. Sem probal z codo brez inkoderja direkno napisani obrati pa deluje. Po moje je problem ko program bere iz enkoderja in ga pretvori v step in direction izhod. Step pulzi sem pa zmeril samo na digitalnem osciloskopi ki ga imamo na firmi. Moj stari 10mhz jih sploh ne vidi. LP Miki
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
bostjan 2
Član
Član



Pridružen-a: Pon 05 Dec 2011 19:35
Prispevkov: 121
Aktiv.: 0.81
Kraj: Vače

PrispevekObjavljeno: Čet Maj 01, 2014 7:24 pm    Naslov sporočila:   Odgovori s citatom

Dokler si ne razjasniš maksimalnih vrednosti ki jih moraš obdelovati ti je đabe 32 bit ali pa 100 Mhz!!!!
_________________
Ja še vedno se ne da...
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Mikim
Član
Član



Pridružen-a: Ned 10 Okt 2010 1:11
Prispevkov: 141
Aktiv.: 0.86
Kraj: Brežice

PrispevekObjavljeno: Čet Maj 01, 2014 9:43 pm    Naslov sporočila:   Odgovori s citatom

Bom izmeril frek. inkoderja ko začne gubiti puls. Ti sporočim.
LP Miki
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Mikim
Član
Član



Pridružen-a: Ned 10 Okt 2010 1:11
Prispevkov: 141
Aktiv.: 0.86
Kraj: Brežice

PrispevekObjavljeno: Pet Maj 02, 2014 12:07 pm    Naslov sporočila:   Odgovori s citatom

Živijo Boštjan,
po prvih izračunih imam takšne rezultate. Če zavrtim inkoder nekje 700, 800 microS je v redu, če pa pride na 300microS ali 0,3ms pa se motor ustavlja. Za test sem uporabil motor z 1300obratov z frekvenčno regulacijo obratov, pri najvišjih obratih mi je inkoder pošiljal podatke z kar 50microS. Se pravi če bi mi program pravilno bral do vsaj 150-100microS bi bil problem rešen. VSe to testiram na Arduino mini 16Mhz, bom pa še probal z direct manipulation port, če bo kakšne razlike.
Potem bom vse skupaj ponovil na arduino DUE in pošljem skupne rezultate.
LP Miki
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Mikim
Član
Član



Pridružen-a: Ned 10 Okt 2010 1:11
Prispevkov: 141
Aktiv.: 0.86
Kraj: Brežice

PrispevekObjavljeno: Pet Maj 02, 2014 1:17 pm    Naslov sporočila:   Odgovori s citatom

Žal so vsi rezultati enaki tako na mini kot na DUE, samo due ima manj prekinitev pri višjih obratih kot mini. Ampak pri ponovitvi sem imel še slabše rezultate že na 600microS so se pojavile prekinitve na koračnem motorju. Tudi pri uporabi code direct port manipulation ni velike spremembe, malenkost je boljša odzivnost ampak v vseh primerih nimam dobrih rezultatov. Če mi inkoder daje 50microS signalov potem je po vsej verjetnosti napaka v programu. LP Miki

Direct port manipulation program:

#define encoder_a 2 //keep this on and interrupt pin
#define encoder_b 3 //keep this on and interrupt pin
#define motor_step 4 //can be any pin
#define motor_direction 5 //can be any pin

#include <delay.h>
volatile long motor_position, encoder;

byte inputA;
byte inputB;

void setup () {
//set up the various outputs
pinMode(motor_step, OUTPUT);
pinMode(motor_direction, OUTPUT);

// then the encoder inputs
pinMode(encoder_a, INPUT);
pinMode(encoder_b, INPUT);

// enable pullup as we are using an open collector encoder
digitalWrite(encoder_a, HIGH);
digitalWrite(encoder_b, HIGH);

// encoder pin on interrupt 0 (pin 2)
attachInterrupt(0, encoderPinChangeA, CHANGE);
// encoder pin on interrupt 1 (pin 3)
attachInterrupt(1, encoderPinChangeB, CHANGE);
encoder = 0; //reseet the encoder position to 0
}

void loop() {
//do stuff dependent on encoder position here
//such as move a stepper motor to match encoder position
//if you want to make it 1:1 ensure the encoder res matches the motor res by dividing/multiplying
if (encoder > 0) {
//digitalWrite(motor_direction, HIGH);// move stepper in reverse
PORTD = PORTD | 0b00100000;
//digitalWrite(motor_step, HIGH);
PORTD = PORTD | 0b00010000;

//digitalWrite(motor_step, LOW);
PORTD = PORTD & 0b11101111;
delayMicroseconds(200); //_delay_us(200); //modify to alter speed
motor_position++;
encoder = 0; //encoder--;
}
else if (encoder < 0) {
//digitalWrite (motor_direction, LOW); //move stepper forward
PORTD = PORTD & 0b11011111;
//digitalWrite (motor_step, HIGH);
PORTD = PORTD | 0b00010000;
//digitalWrite (motor_step, LOW);
PORTD = PORTD & 0b11101111;
delayMicroseconds(200); //_delay_us(200); //modify to alter speed
motor_position--;
encoder = 0; //encoder++;
}
}

void encoderPinChangeA() {
inputA = (PIND & 0b00000100) >>2; // result is 0b00000001 if input is high, 0b00000000 if input is low.
inputB = (PIND & 0b00001000) >>3; //result is 0b00000001 if input is high, 0b00000000 if input is low.

//if (digitalRead(encoder_a)==digitalRead(encoder_b)) {
if (inputA == inputB){
encoder--;
}
else{
encoder++;
}
}

void encoderPinChangeB() {
inputA = (PIND & 0b00000100) >>2; // result is 0b00000001 if input is high, 0b00000000 if input is low.
inputB = (PIND & 0b00001000) >>3; // result is 0b00000001 if input is high, 0b00000000 if input is low.
//if (digitalRead(encoder_a) != digitalRead(encoder_b)) {
if (inputA != inputB){
encoder--;
}
else {
encoder++;
}
}
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Jaka57
Moderator
Moderator



Pridružen-a: Ned 12 Dec 2004 21:47
Prispevkov: 5766
Aktiv.: 25.97
Kraj: Grosuplje

PrispevekObjavljeno: Pet Maj 02, 2014 2:17 pm    Naslov sporočila:   Odgovori s citatom

Koliko časa porabi, da obdela interupt rutino?
_________________
Lp, Jaka
Nazaj na vrh
Skrit Poglej uporabnikov profil Pošlji zasebno sporočilo
Mikim
Član
Član



Pridružen-a: Ned 10 Okt 2010 1:11
Prispevkov: 141
Aktiv.: 0.86
Kraj: Brežice

PrispevekObjavljeno: Pet Maj 02, 2014 3:17 pm    Naslov sporočila:   Odgovori s citatom

Živijo Jaka,
kako pa lahko to izvedem. Z arduino sem se začel ukvarjat šele par mesecev.
Prej sem uporabljal krmilnike a so precej dražji kot arduino pa sem preskočil v to smer a mi dela preglavice.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
bostjan 2
Član
Član



Pridružen-a: Pon 05 Dec 2011 19:35
Prispevkov: 121
Aktiv.: 0.81
Kraj: Vače

PrispevekObjavljeno: Pet Maj 02, 2014 3:44 pm    Naslov sporočila:   Odgovori s citatom

600 mikro sekund je cca 1600 Hz. To mora delat. Ne bo pa delalo če imaš vmes vedno pauzo 200 mkirosekund..

Da ne vidim več v tvojem programu:
delayMicroseconds(200); //_delay_us(200); //modify to alter speed

Namreč program se tu ustavi za toliko časa.

V programu v glavnem loopu postavljaš vrednost :
motor_position--;
encoder = 0; //encoder++;

Ne glede na to koliko enkoder prešteje, ga ti po 1 stepu vržeš na nulo. Ali ne bi bilo boljše če bi si samo odšteval ali prišteval koliko korkaov si že naredil, kot npr:

motor_position--;
encoder --;

oziroma v drugem stavku;

motor_position++;
encoder ++;

Sedaj zelo hitro delaš stepe na motorju, brez pauze. Pauzo moraš naresti v ciklu Main loopa, kot npr.

Ko z enkoderjem šteješ impulze, prištevaj oziroma odštevaj dva impulza. Ko greš čez main loop pa odštevaj po enega, tako boš vedel, če je soda je High, liha je LOW, negativna je direction ena smer oziroma obratno.

Če pa meriš še čas med interrupti pa lahko v glavni zanki obdelavo delaš z istim timingom..

Je logično?


Lp Boštjan

_________________
Ja še vedno se ne da...
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Mikim
Član
Član



Pridružen-a: Ned 10 Okt 2010 1:11
Prispevkov: 141
Aktiv.: 0.86
Kraj: Brežice

PrispevekObjavljeno: Pet Maj 02, 2014 4:01 pm    Naslov sporočila:   Odgovori s citatom

Problem je ker potrebujem funkcijo delayMicroseconds(200); //_delay_us(200); //modify to alter speed
To sem testiral in ne dela napak. Če je nastavljeno na 200 potem se mi motor obrne 3x kot naredi inkoder en obrat. To obvezno potrebujem, da ne uporabljam zobniškega prenosa. Testiral sem tudi na 600, napake so enake samo da se motor in enkoder vrtita nekje sorazmerno.
Nazaj na vrh
Odsoten Poglej uporabnikov profil Pošlji zasebno sporočilo
Pokaži sporočila:   
Objavi novo temo   Odgovori na to temo   Printer-friendly version    www.elektronik.si Seznam forumov -> Programiranje embedded sistemov Časovni pas GMT + 2 uri, srednjeevropski - poletni čas
Pojdi na stran 1, 2, 3  Naslednja
Stran 1 od 3

 
Pojdi na:  
Ne, ne moreš dodajati novih tem v tem forumu
Ne, ne moreš odgovarjati na teme v tem forumu
Ne, ne moreš urejati svojih prispevkov v tem forumu
Ne, ne moreš brisati svojih prispevkov v tem forumu
Ne ne moreš glasovati v anketi v tem forumu
Ne, ne moreš pripeti datotek v tem forumu
Ne, ne moreš povleči datotek v tem forumu

Uptime: 48 dni


Powered by phpBB © 2001, 2005 phpBB Group