von
jan (Gast)
06.02.2015 15:15
Folgender code funktioniert: 1 while ( 1 )
2 {
3
4 if ( calculateRpm )
5 {
6 if ( rpmTemp > 0 )
7 {
8 //6 steps per revolution
9 //time per tick 32 us
10
11 rpmTemp *= 6 * 32 ; //get periodtime for one revolution
12 //period time in us
13
14 rpmTemp = 10000000 / rpmTemp ;
15 //temp is now 1/10 rpm;
16 rpmTemp *= 60 ;
17 lastRpms [ lastRpmsPos ] = rpmTemp & 0xFFFF ;
18 }
19 else
20 {
21 lastRpms [ lastRpmsPos ] = 0x00 ;
22 }
23
24
25
26 lastRpmsPos ++ ;
27 if ( lastRpmsPos >= lastRpmsSize )
28 {
29 lastRpmsPos = 0 ;
30 }
31
32 tempU32 = 0 ;
33 for ( counter = 0 ; counter < lastRpmsSize ; counter ++ )
34 {
35 tempU32 += lastRpms [ counter ];
36 }
37 rpmAverage = tempU32 / lastRpmsSize ;
38
39 if ( sendRpm == 1 )
40 {
41
42 rpm_to_string ( rpmString , rpmAverage , motor . direction );
43 UART_send_blocking_string ( rpmString );
44
45 sendRpm = 0 ;
46 }
47
48 calculateRpm = 0 ;
49 lockRpm = 0 ;
50 }
51
52 }
In diesem Fall bekomme ich am RS232 Terminal am pc "-0300.0".
jedoch bei dieser Version:
1 int main ( void )
2 {
3 uint32_t tempU32 ;
4 uint8_t counter ;
5
6 init ();
7
8
9
10 while ( 1 )
11 {
12
13 if ( calculateRpm )
14 {
15 if ( rpmTemp > 0 )
16 {
17 //6 steps per revolution
18 //time per tick 32 us
19
20 rpmTemp *= 6 * 32 ; //get periodtime for one revolution
21 //period time in us
22
23 rpmTemp = 10000000 / rpmTemp ;
24 //temp is now 1/10 rpm;
25 rpmTemp *= 60 ;
26 lastRpms [ lastRpmsPos ] = rpmTemp & 0xFFFF ;
27 }
28 else
29 {
30 lastRpms [ lastRpmsPos ] = 0x00 ;
31 }
32
33
34
35 lastRpmsPos ++ ;
36 if ( lastRpmsPos >= lastRpmsSize )
37 {
38 lastRpmsPos = 0 ;
39 }
40
41 tempU32 = 0 ;
42 for ( counter = 0 ; counter < lastRpmsSize ; counter ++ )
43 {
44 tempU32 += lastRpms [ counter ];
45 }
46 rpmAverage = tempU32 / lastRpmsSize ;
47
48 if ( sendRpm == 1 )
49 {
50
51 rpm_to_string ( rpmString , rpmAverage , motor . direction );
52 UART_send_blocking_string ( rpmString );
53
54 sendRpm = 0 ;
55 }
56
57
58 calculateRpm = 0 ;
59 lockRpm = 0 ;
60 }
61 }
62 }
Kommt am Terminal nur -0.000 an. Meine rpm_to_string Funktion und meine
UART_send_blocking_string Funktion funktioniert ja.
Variablen Definitionen (global): 1 volatile uint8_t motorDirection = 0 , motorRPM = 0 ;
2 volatile uint8_t readyToSend = 0 ;
3 volatile uint8_t timer0_overflows = 0 , timer0_overflow_error = 0 ;
4
5 uint32_t rpmTemp = 0 ;
6
7 #define lastRpmsSize 12
8 uint16_t lastRpms [ lastRpmsSize ] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 };
9 uint8_t lastRpmsPos = 0 ;
10 volatile uint16_t rpmAverage ;
11
12 volatile uint8_t calculateRpm = 0 , lockRpm = 0 , sendRpm = 0 ;
13 volatile uint8_t rpmString [ 8 ] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 };
Versuch jetzt schon seit einer Stunde das Problem zu beheben, doch
leider finde ich keinen Fehler. Ich hoffe ihr könnt mir helfen.
MfG
Jan
von
Peter II (Gast)
06.02.2015 15:19
jan schrieb:
> jedoch bei dieser Version:
beide Versionen sind doch gleich? (ich kann zumindest kein unterschied
finden)
von
jan (Gast)
06.02.2015 15:25
Sry hatte beim zweiten das falsche kopiert.
Das richtige 2. Beispiel:
1 int main ( void )
2 {
3 uint32_t tempU32 ;
4 uint8_t counter ;
5
6 init ();
7
8
9
10 while ( 1 )
11 {
12
13 if ( calculateRpm )
14 {
15 if ( rpmTemp > 0 )
16 {
17 //6 steps per revolution
18 //time per tick 32 us
19
20 rpmTemp *= 6 * 32 ; //get periodtime for one revolution
21 //period time in us
22
23 rpmTemp = 10000000 / rpmTemp ;
24 //temp is now 1/10 rpm;
25 rpmTemp *= 60 ;
26 lastRpms [ lastRpmsPos ] = rpmTemp & 0xFFFF ;
27 }
28 else
29 {
30 lastRpms [ lastRpmsPos ] = 0x00 ;
31 }
32
33
34
35 lastRpmsPos ++ ;
36 if ( lastRpmsPos >= lastRpmsSize )
37 {
38 lastRpmsPos = 0 ;
39 }
40
41 tempU32 = 0 ;
42 for ( counter = 0 ; counter < lastRpmsSize ; counter ++ )
43 {
44 tempU32 += lastRpms [ counter ];
45 }
46 rpmAverage = tempU32 / lastRpmsSize ;
47
48 calculateRpm = 0 ;
49 lockRpm = 0 ;
50 }
51 //sendRpm = 1;
52 if ( sendRpm == 1 )
53 {
54
55 rpm_to_string ( rpmString , rpmAverage , motor . direction );
56 UART_send_blocking_string ( rpmString );
57
58 sendRpm = 0 ;
59 }
60
61 }
62 }
Übrigens: wenn ich das //sendRpm = 1; einkommentiere, bekomm ich auch
die richtigen Werte.
von
Peter II (Gast)
06.02.2015 15:29
1 volatile uint8_t calculateRpm = 0 , lockRpm = 0 , sendRpm = 0 ;
2 [ c ]
3 ich bin mir nicht sicher ob das volatile wirklich f ü r alle Variabel gilt .
4
5 schreibe es doch gleich lesbar .
6
7 [ c ]
8 volatile uint8_t calculateRpm = 0 ;
9 volatile uint8_t lockRpm = 0 ;
10 volatile uint8_t sendRpm = 0 ;
hätte sogar den Vorteil da man noch Kommentare für die Variablen
verwenden kann.
von
jan (Gast)
06.02.2015 15:36
Hab das bei allen Variablen gemacht, brachte keinen Unterschied.
Wie gesagt bei dieser Form funktioniert es ja:
1 int main ( void )
2 {
3 uint32_t tempU32 ;
4 uint8_t counter ;
5
6 init ();
7
8
9
10 while ( 1 )
11 {
12
13 if ( calculateRpm )
14 {
15 .....
16 }
17
18 sendRpm = 1 ;
19 if ( sendRpm == 1 )
20 {
21
22 rpm_to_string ( rpmString , rpmAverage , motor . direction );
23 UART_send_blocking_string ( rpmString );
24
25 sendRpm = 0 ;
26 }
27
28 }
29 }
Deswegen denke ich das der Fehler nicht am volatile liegt.
Zur Sicherheit noch meine Funktionen: 1 #define digit_to_char(digit) '0' + digit
2
3 void rpm_to_string ( volatile uint8_t * string , volatile uint16_t rpms , uint8_t direction )
4 {
5 uint8_t thousands , hundreds , tens , ones , tenths ;
6
7 thousands = rpms / 10000 ;
8 rpms = rpms % 10000 ;
9 hundreds = rpms / 1000 ;
10 rpms = rpms % 1000 ;
11 tens = rpms / 100 ;
12 rpms = rpms % 100 ;
13 ones = rpms / 10 ;
14 rpms = rpms % 10 ;
15 tenths = rpms ;
16
17 if ( direction == 1 )
18 * string = '-' ;
19 else
20 * string = '+' ;
21
22 string ++ ;
23 * string = digit_to_char ( thousands );
24 string ++ ;
25 * string = digit_to_char ( hundreds );
26 string ++ ;
27 * string = digit_to_char ( tens );
28 string ++ ;
29 * string = digit_to_char ( ones );
30 string ++ ;
31 * string = '.' ;
32 string ++ ;
33 * string = digit_to_char ( tenths );
34 string ++ ;
35 * string = 0 ;
36
37 }
38
39 uint8_t UART_send_blocking_string ( volatile uint8_t * data )
40 {
41 if ( UCSRA & ( 1 << UDRE )) //ready to send
42 {
43 while ( 1 )
44 {
45 if ( * data == 0x00 )
46 break ;
47
48 UART_send_blocking ( * data );
49 data ++ ;
50 }
51
52 return UART_success ;
53 }
54
55 return UART_failed ;
56 }
57
58 uint8_t UART_send ( uint8_t data )
59 {
60 if ( UCSRA & ( 1 << UDRE )) //ready to send
61 {
62 UDR = data ;
63 return UART_success ;
64 }
65
66 return UART_failed ;
67 }
Der Unterschied deiner 2 Varianten ist doch folgender:
1. Variante (die wohl geht):
rpm_to_string und UART_send_blocking_string wird nur ausgeführt, wenn
calculateRpm != 0 ist, und damit auch rpmAverage berechnet wurde.
Im 2. Fall hast du rpm_to_string und UART_send_blocking_string
ausserhalb von if(calculateRpm) plaziert, so dass es beim ersten
Durchlauf wohl so ist, dass rpmAverage 0 ist, und dies wird dann auch
auf den UART geschickt.
Wenn doch die 1. Variante geht, warum benutzt du dann nicht einfach
diese?
von
jan (Gast)
06.02.2015 15:53
Joe F. schrieb:
> Der Unterschied deiner 2 Varianten ist doch folgender:
> 1. Variante (die wohl geht):
> rpm_to_string und UART_send_blocking_string wird nur ausgeführt, wenn
> calculateRpm != 0 ist, und damit auch rpmAverage berechnet wurde.
>
> Im 2. Fall hast du rpm_to_string und UART_send_blocking_string
> ausserhalb von if(calculateRpm) plaziert, so dass es beim ersten
> Durchlauf wohl so ist, dass rpmAverage 0 ist, und dies wird dann auch
> auf den UART geschickt.
>
> Wenn doch die 1. Variante geht, warum benutzt du dann nicht einfach
> diese?
Komischerweise funktioniert der zweite Fall ja wenn ich "if(sendRpm =
1).." oder "sendRpm = 1; if(sendRpm)..." ja, das heist rpmAverage ist
nicht 0....
und ich kann die ersten Variante nicht verwenden weil calculateRpm nur
eins wird wenn ein neuer Wert reinkommt d.h. eine Flanke am encoder...
um Rechenleistung zu sparen. Und ich will ja die die Rpm's ja auch
senden können wenn der Motor steht ;).
Und weiter wird auf rpmAverage nur im main code zugegriffen, daher
wüsste ich nicht warum der Wert auf einmal 0 sein sollte.
Trotzdem Danke schonmal an eure Hilfe!
von
jan (Gast)
06.02.2015 16:27
So jetzt funktionierts:
1 int main ( void )
2 {
3 uint32_t tempU32 ;
4 uint8_t counter ;
5 uint16_t plsSendMeForGodsSake = 0 ;
6 init ();
7
8
9
10 while ( 1 )
11 {
12
13 if ( calculateRpm )
14 {
15 if ( rpmTemp > 0 )
16 {
17 //6 steps per revolution
18 //time per tick 32 us
19
20 rpmTemp *= 6 * 32 ; //get periodtime for one revolution
21 //period time in us
22
23 rpmTemp = 10000000 / rpmTemp ;
24 //temp is now 1/10 rpm;
25 rpmTemp *= 60 ;
26 lastRpms [ lastRpmsPos ] = rpmTemp & 0xFFFF ;
27 }
28 else
29 {
30 lastRpms [ lastRpmsPos ] = 0x00 ;
31 }
32
33
34
35 lastRpmsPos ++ ;
36 if ( lastRpmsPos >= lastRpmsSize )
37 {
38 lastRpmsPos = 0 ;
39 }
40
41 tempU32 = 0 ;
42 for ( counter = 0 ; counter < lastRpmsSize ; counter ++ )
43 {
44 tempU32 += lastRpms [ counter ];
45 }
46 rpmAverage = tempU32 / lastRpmsSize ;
47 plsSendMeForGodsSake = ( uint16_t ) rpmAverage ;
48 calculateRpm = 0 ;
49 lockRpm = 0 ;
50 }
51
52 //sendRpm = 1;
53 if ( sendRpm )
54 {
55 rpm_to_string (( uint8_t * ) rpmString , plsSendMeForGodsSake , motor . direction );
56 UART_send_blocking_string ( rpmString );
57 sendRpm = 0 ;
58 }
59 }
60 }
aber ich versteh noch immer nicht warum es mit Bsp. 2 nicht funktioniert
hatte.
Vielleicht findet irgendjemand das Problem, würde mich interessieren was
ich falsch hatte.
von
asdfasd (Gast)
06.02.2015 23:37
Mal davon abgesehen, dass die gesamte Programmlogik ziemlich konfus
aussieht, in dieser Funktion:
1 > uint8_t UART_send_blocking_string ( volatile uint8_t * data )
2 > {
3 > if ( UCSRA & ( 1 << UDRE )) //ready to send
4 > {
5 > while ( 1 )
6 > {
7 > if ( * data == 0x00 )
8 > break ;
9 >
10 > UART_send_blocking ( * data );
11 > data ++ ;
12 > }
13 >
14 > return UART_success ;
15 > }
16 >
17 > return UART_failed ;
18 > }
sieht das "if" falsch und überflüssig aus. Entweder "blocking" oder
nicht. Du scheisst den ganzen String weg, wenn noch ein Byte im
Transmitter ist.
Das volatile ergibt auch keinen Sinn. Übrig bleibt:
1 void UART_send_blocking_string ( uint8_t * data )
2 {
3 while ( * data )
4 UART_send_blocking ( * data ++ );
5 }
PS: Die Richtung solltest du in deinem Moving-Average evtl
mitberücksichtigen...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.