Forum: Mikrocontroller und Digitale Elektronik Appnote avr446 Atmega2560 (Arduino)


von mr.T (Gast)


Lesenswert?

Nabend in die Runde,
ich habe heute mal versucht das Programm aus der AppNote um zu
schreiben, damit es auf meinem Arduino Mega2560 läuft.

Erstmal liefert AVR Studio 6 einen Fehler bei den Berechnungen von A_SQ

integer constant is too large for 'long' type
1
#define T1_FREQ 2000000L
2
#define FSPR 200
3
#define SPR 200
4
#define ALPHA (long)(2*3.14159/SPR)                    // 2*pi/spr
5
#define A_T_x100 ((long)(ALPHA*T1_FREQ*100))     // (ALPHA / T1_FREQ)*100
6
#define T1_FREQ_148 ((long)((T1_FREQ*0.676)/100)) // divided by 100 and scaled by 0.676
7
#define A_SQ  (long)(ALPHA*2*10000000000)         // ALPHA*2*10000000000
8
#define A_x20000 (long)(ALPHA*20000)              // ALPHA*20000
das habe ich dann ausgelagert und in Excel von Hand berechnet und
eingetragen.
1
#define A_T_x100 6283180
2
#define T1_FREQ_148 13520
3
#define A_SQ 628318000
4
#define A_x20000 628

Dann lief es aber immer noch nicht, ich habe wohl noch ein Problem mit
dem Timer1
1
void speed_cntr_Init_Timer1(void)
2
{
3
  // Tells what part of speed ramp we are in.
4
  srd.run_state = STOP;
5
  // Timer/Counter 1 in mode 4 CTC (Not running).
6
  TCCR1B = (1<<WGM13); //Original WGM12
7
  // Timer/Counter 1 Output Compare A Match Interrupt enable.
8
  TIMSK1 = (1<<OCIE1A);
9
10
11
}

TCCR1B = (1<<WGM13);
habe ich geändert, eigentlich ist dort für CTC, WGM12, auch laut
Datenblatt, wenn ich nicht irre, aber dann Läuft das viel zu schnell.
Mit WGM13 kann ich meinen Schrittmotor nun verfahren.

mit den Werten verfahre ich zur Zeit
speed_cntr_Move(200,30000,30000,12000);

Aber irgend wie ist das doch so nicht richtig :(

#pragma vector=TIMER1_COMPA_vect
__interrupt void speed_cntr_TIMER1_COMPA_interrupt( void )

wurde ersetzt zu

ISR ( TIMER1_COMPA_vect )

http://atmel.no/webdoc/atmel.docs/atmel.docs.33085...
http://www.atmel.com/images/doc2549.pdf

grüße

von Stefan F. (Gast)


Lesenswert?

> #define SPR 200
> #define ALPHA (long)(2*3.14159/SPR)
> #define A_SQ  (long)(ALPHA*2*10000000000)

Das ergibt ALPHA=0,0314, aber da das Ergebnis als long Integer 
gespeichert wird, kommt dabei eine 0 heraus. Auch A_SQ=0.

So war das sicher nicht geplant.

von mr.T (Gast)


Lesenswert?

Ich glaube es wurde in der appnote ein IAR Compiler verwendet, 
vielleicht hat er die Rechenoperation ausgeführt.

Ich habe es jetzt erstmal am laufen auch mit der Richtigen 
Geschwindigkeit.

Folgendes habe ich in Excel errechnet und dann von Hand eingetragen.
1
#define T1_FREQ 2000000L // F_CPU/8 
2
#define FSPR 200 //Steps per round
3
#define SPR (FSPR*2) 
4
#define ALPHA (long)(2*3.14159/SPR)                    // 2*pi/spr
5
#define A_T_x100 ((long)(ALPHA*T1_FREQ*100))     // (ALPHA / T1_FREQ)*100
6
#define T1_FREQ_148 ((long)((T1_FREQ*0.676)/100)) // divided by 100 and scaled by 0.676
7
#define A_SQ  (long)(ALPHA*2*10000000000)         // ALPHA*2*10000000000
8
#define A_x20000 (long)(ALPHA*20000)              // ALPHA*20000

Die Timer1 Geschichte würde mich aber noch interessieren, und bei 
Falschen Kombinationen von Weg und Geschwindigkeit erwischt er die 
Bremsrampe nicht...

Die AppNote wird ja oft hier Verlinkt wenn nach Schrittmotoren gefragt 
wird, aber so richtig viele Beispiele hab ich dennoch nicht gefunden wo 
es dann auch benutzt wurde :/.

von mr.T (Gast)


Angehängte Dateien:

Lesenswert?

Hier mal die *.ino

von mr.T (Gast)


Lesenswert?

Hab es glaube ich gefunden :)

das
1
accel_lim = ((long)step*accel_stepper) / (accel_stepper+accel_stepper);

geändert in
1
accel_lim = ((long)step*accel_stepper) / ((long)accel_stepper+accel_stepper);

bleibt noch die Frage mit dem Timer
1
void speed_cntr_Init_Timer1(void)
2
{
3
  // Tells what part of speed ramp we are in.
4
  srd.run_state = STOP;
5
  // Timer/Counter 1 in mode 4 CTC (Not running).
6
  TCCR1B = (1<<WGM13);  /***************** Original WGM12 ?!?!? *****************/
7
  // Timer/Counter 1 Output Compare A Match Interrupt enable.
8
  TIMSK1 = (1<<OCIE1A);
9
}

von spess53 (Gast)


Lesenswert?

Hi

>TCCR1B = (1<<WGM13); /******** Original WGM12 ?!?!? *****************/

Weshalb ist das geändert?

TCCR1B = (1<<WGM13)  -> PWM, Phase Correct
TCCR1B = (1<<WGM12)  -> CTC mit OCR1A als Top

MfG Spess

von mr.T (Gast)


Lesenswert?

Ich hab das mehr durch "Zufall" geändert, weil meine Signale viel zu 
schnell gekommen sind :/.

Erklären kann ich mir das leider auch noch nicht. Nur das es so nun 
Funktioniert ;).
Mit den Kalkulierten werten wie oben passen die Steps und die Frequenz 
auf dem Oszi. So wie es soll :)

Mein Vermutung ist das ich irgendetwas übersehen habe beim Timer1, oder 
die Doku Falsch ist...? Das glaube ich aber eigentlich weniger.

Nur Warum passen dann die Werte so gut? ;).

errechnet habe ich 666,54 Hz, mein Oszi zeigt 666,6 Hz für 200rpm, und 
200 Schritte pro Umdrehung.

grüße

von spess53 (Gast)


Lesenswert?

Hi

>Ich hab das mehr durch "Zufall" geändert, weil meine Signale viel zu
>schnell gekommen sind :/.

Da hast du wahrscheinlich noch etwas anderes geändert. Bei gleichem 
OCR1A-Wert ist, bei beiden Modes, der Abstand der OC1A-Interrupts 
identisch.

MfG Spess

von mr.T (Gast)


Lesenswert?

Hi,
meine Ansteuerungen der Motoren ist nun ja Step/Dir, das habe ich noch 
geändert. Komisch ist das ich bei der Berechnung, obwohl Vollschritt, 
mit SPR = FSPR*2 berechne.

das ist das Original.
1
/*! \Brief Frequency of timer1 in [Hz].
2
 *
3
 * Modify this according to frequency used. Because of the prescaler setting,
4
 * the timer1 frequency is the clock frequency divided by 8.
5
 */
6
// Timer/Counter 1 running on 3,686MHz / 8 = 460,75kHz (2,17uS). (T1-FREQ 460750)
7
#define T1_FREQ 460750
8
9
//! Number of (full)steps per round on stepper motor in use.
10
#define FSPR 200
11
12
#ifdef HALFSTEPS
13
  #define SPR (FSPR*2)
14
  #pragma message("[speed_cntr.c] *** Using Halfsteps ***")
15
#endif
16
#ifdef FULLSTEPS
17
  #define SPR FSPR
18
  #pragma message("[speed_cntr.c] *** Using Fullsteps ***")
19
#endif
20
#ifndef HALFSTEPS
21
  #ifndef FULLSTEPS
22
    #error FULLSTEPS/HALFSTEPS not defined!
23
  #endif
24
#endif

Das habe ich noch zu IAR gefunden...

http://www.nongnu.org/avr-libc/user-manual/porting.html

und entsprechend geändert. Aber irgendwo ist noch der Wurm drin auch 
wenn es Funktioniert :D...

von spess53 (Gast)


Lesenswert?

Hi

>// Timer/Counter 1 running on 3,686MHz / 8 = 460,75kHz (2,17uS).

Hast du einen anderen Quarz verbaut? Meines Wissens laufen die Arduino 
Mega 2560 mit einem 16MHz Quarz.

MfG Spess

von mr.T (Gast)


Lesenswert?

Jab,
das hab ich alles angepasst,Extern umgerechnet und dann die festen Werte 
eingetragen. Der IAR Compiler konnte das anscheinend rechnen. AVR Studio 
6 so nicht. Da hatte ich ja den oben beschriebenen Fehler.

errechnet
1
Steps/round  200
2
T1_FREQ  2000000
3
  
4
SPR  400
5
  
6
Alpha  0.015707963267949
7
A_T_x100  3,141,592.65358979
8
T1_FREQ_148  13,520
9
A_SQ  314,159,265.358979
10
A_x20000  314.159265358979

so ins Programm übertragen...
1
#define A_T_x100 3141592
2
#define T1_FREQ_148 13520
3
#define A_SQ 314159265
4
#define A_x20000 314

original
1
/*! \Brief Frequency of timer1 in [Hz].
2
 *
3
 * Modify this according to frequency used. Because of the prescaler setting,
4
 * the timer1 frequency is the clock frequency divided by 8.
5
 */
6
// Timer/Counter 1 running on 3,686MHz / 8 = 460,75kHz (2,17uS). (T1-FREQ 460750)
7
#define T1_FREQ 460750
8
9
//! Number of (full)steps per round on stepper motor in use.
10
#define FSPR 200
11
12
#ifdef HALFSTEPS
13
  #define SPR (FSPR*2)
14
  #pragma message("[speed_cntr.c] *** Using Halfsteps ***")
15
#endif
16
#ifdef FULLSTEPS
17
  #define SPR FSPR
18
  #pragma message("[speed_cntr.c] *** Using Fullsteps ***")
19
#endif
20
#ifndef HALFSTEPS
21
  #ifndef FULLSTEPS
22
    #error FULLSTEPS/HALFSTEPS not defined!
23
  #endif
24
#endif
25
26
// Maths constants. To simplify maths when calculating in speed_cntr_Move().
27
#define ALPHA (2*3.14159/SPR)                    // 2*pi/spr
28
#define A_T_x100 ((long)(ALPHA*T1_FREQ*100))     // (ALPHA / T1_FREQ)*100
29
#define T1_FREQ_148 ((int)((T1_FREQ*0.676)/100)) // divided by 100 and scaled by 0.676
30
#define A_SQ (long)(ALPHA*2*10000000000)         // ALPHA*2*10000000000
31
#define A_x20000 (int)(ALPHA*20000)              // ALPHA*20000

Ohne das würde meine Geschwindigkeit ja nicht so exakt passen... der 
Motor läuft auch 1A... nur komme ich nicht hinter das Problem :(... also 
warum es so Funktioniert aber mit WGM12 nicht...

meine Step/Dir Ansteuerung sieht zur zeit so aus, die Verschleifung mit 
sm_driver_StepOutput() hab ich gelassen weil da noch was zu kommt.
1
void sm_driver_StepCounter(signed char inc)
2
{
3
       sm_driver_StepOutput();
4
}
5
6
7
void sm_driver_StepOutput()
8
{  
9
  
10
    if (srd.dir == CW){      
11
      digitalWrite(dirpin, LOW);   
12
    digitalWrite(steppin, LOW);     
13
    stepPosition++;
14
    }
15
    else{
16
      stepPosition--;
17
    digitalWrite(dirpin, HIGH);    
18
    digitalWrite(steppin, LOW);       
19
    }
20
  digitalWrite(steppin, HIGH);   
21
22
}

danke für dein Hilfe

grüße

von rene z (Gast)


Lesenswert?

hallo!

frage, hast du/oder jemand das jetzt fertig für den mega 2560 arduino 
portiert?. ich hab grade die ino getestet und es funktioniert, aber is 
ein wenig unüberschaubar.

suche nämlich eine einfache lösung für eine rampensteuerung für meinen 
delta roboter. der läuft mit nema 17 motoren derweil ohne rampe und der 
schaukelt sich auf deswegen ganz schön auf.

lg rene

von Hubbsi (Gast)


Lesenswert?

Da fehlt die glcd.h und die die allfonts.h... Kann die bitte jemand 
uppen?

von Mike (Gast)


Lesenswert?

mr.T schrieb:
> Die AppNote wird ja oft hier Verlinkt wenn nach Schrittmotoren gefragt
> wird, aber so richtig viele Beispiele hab ich dennoch nicht gefunden wo
> es dann auch benutzt wurde :/.

Wieso auch. Einbauen und läuft ...

von Jonas H. (delta_b)


Lesenswert?

rene z schrieb:
> hallo!
>
> frage, hast du/oder jemand das jetzt fertig für den mega 2560 arduino
> portiert?. ich hab grade die ino getestet und es funktioniert, aber is
> ein wenig unüberschaubar.
>
> suche nämlich eine einfache lösung für eine rampensteuerung für meinen
> delta roboter. der läuft mit nema 17 motoren derweil ohne rampe und der
> schaukelt sich auf deswegen ganz schön auf.
>
> lg rene

Hallo Rene,

hast du bereits eine Lösung mit Rampensteuerung für deinen delta Roboter 
gefunden?

Grüße

von Louis (Gast)


Lesenswert?

Ist ein uralter Thread, ich weiß. Aber diese Schrittmotoransteuerung ist 
sehr gut, wer sich das auf den Arduino holen will findet oben die .ino 
Datei.

Es war aber ein Problem dass es nur mit
TCCR1B = (1<<WGM13)  -> PWM, Phase Correct
lief, nicht wie in der Appnote mit
TCCR1B = (1<<WGM12)  -> CTC mit OCR1A als Top

Einfache Abhilfe: TCCR1A mit 0 initialisieren, da steht offenbar etwas 
anderes drin nach dem Reste des  Arduino:

 TCCR1A = 0;


void speed_cntr_Init_Timer1(void)
{
  // Tells what part of speed ramp we are in.
  srd.run_state = STOP;
  // TTCR1A init with zero.
  TCCR1A = 0;
  // Timer/Counter 1 in mode 4 CTC (Not running).
  TCCR1B = (1 << WGM12);
  // Set Timer/Counter to divide clock by 8
    TCCR1B |= ((0<<CS12)|(1<<CS11)|(0<<CS10));
  // Timer/Counter 1 Output Compare A Match Interrupt enable.
  TIMSK1 = (1 << OCIE1A);
}

Dann läuft es perfekt :-)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.