Nachrichten
Sie sind nicht eingeloggt.
Site-Statistic
7433 private projects
378 public projects
16180353 lines compiled
58212 builds
mifritscher
OFFLINE
Expert Boarder
Beiträge: 153
Ich werde hier zukünftig meine Patches für die nibobeelib posten.
Ich möchte die lib nur ungern forken, da dann der Rückfluss der Verbesserungen deutlich schwieriger wird. Ich werde versuchen die Kompatibilität soweit möglich zu erhalten.
mifritscher
OFFLINE
Expert Boarder
Beiträge: 153
--- src/ nibobee/ motpid. c. org 2010 - 07 - 10 17 : 21 : 36.000000000 + 0200
+++ src/ nibobee/ motpid. c 2013 - 05 - 15 07 : 55 : 54.416067720 + 0200
@@ - 56 , 7 + 56 , 16 @@
// PS = 1
// freq = 15Mhz/1022 = 14.677 kHz
// call PID with 100 Hz:
- #define MOTPID_CALL_CNT 147
+ #if F_CPU == 15000000
+ #define MOTPID_CALL_CNT 147
+ #else
+ #if F_CPU == 200000000
+ #define MOTPID_CALL_CNT 196
+ #else
+ #error "Frequency unknown!"
+ #define MOTPID_CALL_CNT 100
+ #endif
+ #endif
/*! PID will be called with 100 Hz */
#define MOTPID_FREQ 100
Sorgt dafür, dass auch bei 20 MHz Takt die Taktgeber passen
Alternative:
--- src/ nibobee/ motpid. c. org 2010 - 07 - 10 17 : 21 : 36.000000000 + 0200
+++ src/ nibobee/ motpid. c 2013 - 05 - 15 07 : 55 : 54.416067720 + 0200
@@ - 56 , 7 + 56 , 16 @@
// PS = 1
// freq = 15Mhz/1022 = 14.677 kHz
// call PID with 100 Hz:
- #define MOTPID_CALL_CNT 147
#define MOTPID_CALL_CNT (uint8_t)((F_CPU / 1022) + 50 / 100)
/*! PID will be called with 100 Hz */
#define MOTPID_FREQ 100
Dann funktioniert es für (fast) jeden Takt. (+50 fürs bessere Runden)
workwind
OFFLINE
Administrator
Beiträge: 573
Prima, zweite Variante übernommen!
mifritscher
OFFLINE
Expert Boarder
Beiträge: 153
Dieser Patch räumt ein paar Dinge in der Zeitrechnung auf:
* die Verwaltung des Timer1 obliegt nun der clock.c - dadurch kann auf die motpid (oder manuelle ISRs) verzichtet werden, was bei motpid 1,2 KB Flash und ein wenig RAM einspart
* die 1,022ms sind nicht mehr hart codiert, sodern werden in Abhängigkeit von der Taktfrequenz berechnet
* motpid hat nun genau 1 Konstante für die Frequenz
* 1ms-frequenzhook eingefügt
Wurde mit einem ATMEGA128-20 getestet, die Zeitberechnung wurde zusätzlich mit 15 MHz nachgerechnet, wo exakt die 1022µs rauskamen.
diff - u nibobee. org/ base. c nibobee/ base. c
--- nibobee. org/ base. c 2013 - 05 - 15 08 : 38 : 41.000000000 + 0200
+++ nibobee/ base. c 2013 - 05 - 21 17 : 47 : 02.000000000 + 0200
@@ - 54 , 6 + 54 , 7 @@
uint16_t nibobee_getMillivolt( ) {
uint16_t voltage = analog_getValue( ANALOG_VOLT) ;
+ //voltage *= ((2560 * 2) / 1024); //Referenz: 2560 mV, 10 bit, *2 wegen Spannungsteiler
voltage = ( 4 * 12480U) / voltage;
voltage *= 25 ;
return voltage;
diff - u nibobee. org/ base. h nibobee/ base. h
--- nibobee. org/ base. h 2013 - 05 - 15 08 : 38 : 41.000000000 + 0200
+++ nibobee/ base. h 2013 - 05 - 21 19 : 10 : 38.551256519 + 0200
@@ - 57 , 6 + 57 , 7 @@
NIBOBEE_ANALOG_INITIALIZED = 0x01 ,
NIBOBEE_MOTPWM_INITIALIZED = 0x02 ,
NIBOBEE_I2C_INITIALIZED = 0x04 ,
+ NIBOBEE_CLOCK_INITIALIZED = 0x08 ,
} ;
/*!
diff -u nibobee.org/clock.c nibobee/clock.c
--- nibobee.org/clock.c 2013-05-15 08:38:41.000000000 +0200
+++ nibobee/clock.c 2013-05-21 21:04:17.573286156 +0200
@@ -40,7 +40,9 @@
#include <avr/sleep.h>
#include <util/atomic.h>
#include "nibobee/iodefs.h"
+#include "nibobee/base.h"
#include "nibobee/clock.h"
+#include "nibobee/motpwm.h"
#ifdef __cplusplus
@@ -58,11 +60,55 @@
void clock_sec_irq_hook() {
}
+void clock_ms_irq_hook() __attribute__((weak));
+
+void clock_ms_irq_hook() {
+}
+
void clock_hundredth_irq_hook() __attribute__((weak));
void clock_hundredth_irq_hook() {
}
+void clock_irq_hook() __attribute__((weak));
+void clock_irq_hook() {
+}
+
+void (*pid_irq_hook)() = 0;
+
+
+ISR(TIMER1_OVF_vect) {
+ static uint8_t counter=0;
+ static uint8_t running=0;
+ counter++;
+ if (running) {
+ return;
+ }
+ running=1;
+ if (counter>=CLOCK_PRESCALER_SOFTWARE) {
+ counter-=CLOCK_PRESCALER_SOFTWARE;
+ clock_inc_irq(CLOCK_MS_PART, CLOCK_US_PART);
+ }
+
+ clock_irq_hook();
+ running = 0;
+}
+
+void clock_set_pid_irq_hook(void new_pid_irq_hook()) {
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+ pid_irq_hook = new_pid_irq_hook;
+ }
+}
+
+void clock_init() {
+ if (!(nibobee_initialization & NIBOBEE_CLOCK_INITIALIZED)) {
+ nibobee_initialization |= NIBOBEE_CLOCK_INITIALIZED;
+ PWM_TIMER_CCRA = PWM_TIMER_CCRA_INIT;
+ PWM_TIMER_CCRB = PWM_TIMER_CCRB_INIT;
+ PWM_TIMER_IMSK |= PWM_TIMER_IMSK_INIT;
+ PWM_TIMER_IMSK |= PWM_TIMER_IMSK_OIE;
+ }
+}
void clock_inc_irq(uint8_t ms, uint16_t us) {
clock_us += us;
@@ -73,12 +119,17 @@
if (clock_waitms) {
clock_waitms--;
}
+ if (pid_irq_hook != 0) {
+ pid_irq_hook();
+ }
+ clock_ms_irq_hook();
}
clock_10ms+=ms;
if (clock_10ms>=10) {
clock_10ms-=10;
clock_hundredth_irq_hook();
+
}
clock_ms+=ms;
diff -u nibobee.org/clock.h nibobee/clock.h
--- nibobee.org/clock.h 2013-05-15 08:38:41.000000000 +0200
+++ nibobee/clock.h 2013-05-21 21:13:32.046730393 +0200
@@ -47,9 +47,57 @@
extern "C" {
#endif
+#define PWM_TIMER_MAX 511
+
+#define PWM_TIMER_CNT TCNT1
+#define PWM_TIMER_CCRA TCCR1A
+#define PWM_TIMER_CCRA_INIT _BV(COM1A1) | _BV(COM1A0) | _BV(COM1B1) | _BV(COM1B0) | _BV(WGM11)
+#define PWM_TIMER_CCRB TCCR1B
+#define PWM_TIMER_CCRB_INIT _BV(CS10)
+#define PWM_TIMER_OCRA OCR1A
+#define PWM_TIMER_OCRA_INIT 0
+#define PWM_TIMER_OCRB OCR1B
+#define PWM_TIMER_OCRB_INIT 0
+#ifndef TIMSK
+# define PWM_TIMER_IMSK TIMSK1
+#else
+# define PWM_TIMER_IMSK TIMSK
+#endif
+#define PWM_TIMER_IMSK_INIT 0
+#define PWM_TIMER_IMSK_CMPA _BV(OCIE1A)
+#define PWM_TIMER_IMSK_CMPB _BV(OCIE1B)
+
+#define PWM_TIMER_IMSK_OIE _BV(TOIE1)
+
+
+// PS = 1
+// Mode 2: PWM, Phase Correct, 9-bit
+// freq = F_CPU Mhz/(2*(512-1)) = 14.677 kHz (bei F_CPU=15000000)
+
+//#define fF_CPU 15000000
+#define CLOCK_PRESCALER_HARDWARE (2*(512-1))
+#define CLOCK_PRESCALER_SOFTWARE 15
+#define CLOCK_TIMER_US (((long long)1000000 * CLOCK_PRESCALER_HARDWARE * CLOCK_PRESCALER_SOFTWARE) / F_CPU)
+
+#define CLOCK_MS_PART CLOCK_TIMER_US / 1000
+#define CLOCK_US_PART CLOCK_TIMER_US % 1000
+
+/*!
+ * Wird vom pid-Modul verwendet, um sich einzuhooken.
+ *
+ * @internal
+ */
+ void clock_set_pid_irq_hook( void new_pid_irq_hook( ) ) ;
+
+ /*!
+ * Initialisiert den Clock-IRQ.
+ */
+ void clock_init( ) ;
+
/*!
- * Funktion zum Aufruf durch den IRQ. Wird bei Verwendung des PID Reglers
- * automatisch alle 1.022 ms aufgerufen. Falls dieser nicht verwendet wird, muss die Funktion
+ * Funktion zum Aufruf durch den IRQ. Wird bei clock_init oder bei Verwendung des PID Reglers
+ * automatisch alle 1.022 ms (bei 15 MHz, ansonsten entsprechend angepasst) aufgerufen.
+ * Falls keiner dieser Funktionen verwendet wird muss die Funktion
* regelmäßig von einem eigenen Timer-Interrupt aus aufgerufen werden.
*/
void clock_inc_irq( uint8_t ms, uint16_t us) ;
Nur in nibobee: clock. h~.
diff - u nibobee. org/ motpid. c nibobee/ motpid. c
--- nibobee. org/ motpid. c 2013 - 05 - 21 21 : 10 : 55.000000000 + 0200
+++ nibobee/ motpid. c 2013 - 05 - 21 21 : 07 : 23.025795880 + 0200
@@ - 44 , 25 + 44 , 12 @@
#include "nibobee/motpwm.h"
#include "nibobee/motpid.h"
- #ifndef TIMSK
- # define PWM_TIMER_IMSK TIMSK1
- #else
- # define PWM_TIMER_IMSK TIMSK
- #endif
-
- #define PWM_TIMER_IMSK_OIE _BV(TOIE1)
-
- // call PID with 100 Hz:
- #define MOTPID_CALL_CNT ((uint8_t)((F_CPU / 1022) + 50 / 100))
- // Example for 15 MHz:
- // Clock = 15 Mhz, (PS = 1)
- // freq = 15Mhz/1022 = 14.677 kHz
- // -> MOTPID_CALL_CNT = 147
-
/*! PID will be called with 100 Hz */
#define MOTPID_FREQ 100
+ #define MOTPID_CALL_CNT 1000 / MOTPID_FREQ
+
#define MOTPID_KP 5
#define MOTPID_KI 6
#define MOTPID_KD 7
@@ - 194 , 19 + 181 , 7 @@
}
- ISR( TIMER1_OVF_vect) {
- static uint8_t counter= 0 ;
- static uint8_t running= 0 ;
- counter++;
- if ( running) {
- return ;
- }
- running= 1 ;
- if ( counter>= 15 ) {
- counter-= 15 ;
- clock_inc_irq( 1 , 22 ) ;
- }
-
+ void clock_irq_motpid_hook( ) {
motpid_cnt++;
if ( motpid_cnt>= MOTPID_CALL_CNT) {
motpid_left_timer_int( ) ;
@@ - 216 , 7 + 191 , 6 @@
//comdata_signal();
motpid_cnt= 0 ;
}
- running = 0 ;
}
@@ - 224 , 7 + 198 , 8 @@
if ( ! ( nibobee_initialization& NIBOBEE_MOTPWM_INITIALIZED) ) {
motpwm_init( ) ;
}
- PWM_TIMER_IMSK |= PWM_TIMER_IMSK_OIE;
+ clock_init( ) ;
+ clock_set_pid_irq_hook( clock_irq_motpid_hook) ;
motpid_reset( ) ;
motpid_mode = MOTPID_MODE_OFF;
}
diff - u nibobee. org/ motpwm. c nibobee/ motpwm. c
--- nibobee. org/ motpwm. c 2013 - 05 - 15 08 : 38 : 41.000000000 + 0200
+++ nibobee/ motpwm. c 2013 - 05 - 21 19 : 51 : 32.601151189 + 0200
@@ - 40 , 32 + 40 , 9 @@
#include <util/atomic.h>
#include "nibobee/iodefs.h"
#include "nibobee/base.h"
+ #include "nibobee/clock.h"
+
- // Clock = 15 Mhz
- // PS = 1
- // Mode 2: PWM, Phase Correct, 9-bit
- // freq = 15Mhz/(2*(512-1)) = 14.677 kHz
-
-
- #define PWM_TIMER_MAX 511
-
- #define PWM_TIMER_CNT TCNT1
- #define PWM_TIMER_CCRA TCCR1A
- #define PWM_TIMER_CCRA_INIT _BV(COM1A1) | _BV(COM1A0) | _BV(COM1B1) | _BV(COM1B0) | _BV(WGM11)
- #define PWM_TIMER_CCRB TCCR1B
- #define PWM_TIMER_CCRB_INIT _BV(CS10)
- #define PWM_TIMER_OCRA OCR1A
- #define PWM_TIMER_OCRA_INIT 0
- #define PWM_TIMER_OCRB OCR1B
- #define PWM_TIMER_OCRB_INIT 0
- #ifndef TIMSK
- # define PWM_TIMER_IMSK TIMSK1
- #else
- # define PWM_TIMER_IMSK TIMSK
- #endif
- #define PWM_TIMER_IMSK_INIT 0
- #define PWM_TIMER_IMSK_CMPA _BV(OCIE1A)
- #define PWM_TIMER_IMSK_CMPB _BV(OCIE1B)
#ifdef __cplusplus
extern "C" {
@@ - 84 , 9 + 61 , 7 @@
nibobee_initialization |= NIBOBEE_MOTPWM_INITIALIZED;
set_output_group( IO_MOTOR) ;
activate_output_group( IO_MOTOR) ;
- PWM_TIMER_CCRA = PWM_TIMER_CCRA_INIT;
- PWM_TIMER_CCRB = PWM_TIMER_CCRB_INIT;
- PWM_TIMER_IMSK |= PWM_TIMER_IMSK_INIT;
+ clock_init( ) ;
}
mifritscher
OFFLINE
Expert Boarder
Beiträge: 153
Kleiner Patch, der das Senden von Strings über die COM vereinfacht.
--- nibobee. org/ usart. h 2013 - 05 - 15 08 : 38 : 41.000000000 + 0200
+++ nibobee/ usart. h 2013 - 05 - 22 23 : 01 : 27.937160878 + 0200
@@ - 88 , 6 + 88 , 11 @@
/*!
+ * Schreibt einen 0-terminierten String.
+ */
+ void usart_putstring( char* data) ;
+
+ /*!
* Liefert true wenn der Empfangspuffer leer ist.
*/
static inline char usart_rxempty( ) {
--- nibobee. org/ usart. c 2013 - 05 - 15 08 : 38 : 41.000000000 + 0200
+++ nibobee/ usart. c 2013 - 05 - 22 23 : 01 : 04.972598513 + 0200
@@ - 103 , 6 + 103 , 13 @@
return c;
}
+ void usart_putstring( char* data) {
+ while ( * data != '\0' ) {
+ while ( usart_txfull( ) ) ;
+ usart_putchar( * data) ;
+ data++;
+ }
+ }
static char usart_tx_getchar( ) {
uint8_t result = usart_txbuf[ usart_txbuf_begin] ;
mifritscher
OFFLINE
Expert Boarder
Beiträge: 153
Dieses Mal hat es die niboprot erwischt
Zum einen passt die Beschreibung der Register für die Biene nicht (in der niboprot_reg.h), ich habe folgendes eruiert:
#define NSP_REGISTER_TEXT \
"Registers:\n " \
"=========\n " \
" 0: BOT ID\n " \
" 1: Version\n " \
" 2: Supply Voltage [mV]\n " \
" 3: LEDs\n " \
" 4: Sensors\n " \
" 6: Motor Mode (0=stop, 1=unstop, 2=pwm, 3=pid) \n " \
" 7: Motor PWM/PID L \n " \
" 8: Motor PWM/PID R \n " \
"13: Odometry L \n " \
"14: Odometry R \n " \
"16: Line C\n " \
"17: Line L\n " \
"18: Line R\n " \
"\n "
Zum anderen habe ich die Unterstützung für negative Zahlen beim Setzen von Registern eingefügt - ist manchmal ganz praktisch. Die Variable bleibt ein uint16_t, sodass sich nichts ändert, nur wenn ein Minuszeichen vorkommt wird der Wert so verschoben, dass wenn man diesen als int16_t betrachtet das richtige herauskommt.
--- niboprot. c. org 2013 - 06 - 01 20 : 52 : 07.745293167 + 0200
+++ niboprot. c 2013 - 06 - 01 20 : 50 : 13.855473944 + 0200
@@ - 57 , 21 + 57 , 29 @@
static uint16_t parse_dec( ) {
uint16_t result= 0 ;
+ uint8_t negativ= 0 ;
while ( length) {
char c = * data;
if ( ( c>= '0' ) && ( c<= '9' ) ) {
data++; length--;
result = result* 10 + ( c- '0' ) ;
+ } else if ( c == '-' ) { //Trick, um negative Zahlen zu erfassen (muss bei Verwendung natuerlich als int16_t angesehen werden)
+ data++; length--;
+ negativ = 1 ;
} else {
- return result;
+ break ;
}
}
- return result;
+ if ( negativ)
+ return ( ~result) + 1 ;
+ else
+ return result;
}
static uint16_t parse_hex( ) {
uint16_t result= 0 ;
+ uint8_t negativ= 0 ;
while ( length) {
char c = * data;
if ( ( c>= '0' ) && ( c<= '9' ) ) {
@@ - 80 , 11 + 88 , 17 @@
} else if ( ( c>= 'a' ) && ( c<= 'f' ) ) {
data++; length--;
result = result* 16 + ( c- ( 'a' - 10 ) ) ;
+ } else if ( c == '-' ) { //Trick, um negative Zahlen zu erfassen (muss bei Verwendung natuerlich als int16_t angesehen werden)
+ data++; length--;
+ negativ = 1 ;
} else {
- return result;
+ break ;
}
}
- return result;
+ if ( negativ)
+ return ( ~result) + 1 ;
+ else
+ return result;
}
Letzte Änderung: 10 Jahre 10 Monate her von mifritscher .