radbruch
07.01.2007, 03:32
Hallo,
bisher kannte ich PWM berufsbedingt nur bei Motoren mit mehreren KW Leistung. Nachdem ich mich nun ein wenig in die Materie eingelesen habe und die Umsetzung in ein c-Programm auch halbwegs funktioniert sollte ich ja eigentlich zufrieden sein. Aber leider bin ich mit diesen neuen Kenntnissen auch in der Lage zu erkennen, das der asuro die PWM schon serienmässig eingebaut hat ( den Hinweis darauf habe ich im asuro-wiki (https://www.roboternetz.de/wissen/index.php/Pulsweitenmodulation) nicht gefunden). Aber egal, ich wollte ja was lernen, hier noch mein bisheriger Code:
/* asuro fährt endlos drehend in zwei Richtungen mit selbstgebauter
Pulsweitenmodulation und Sanftanlauf
mic 6.1.2006
*/
#include <asuro.h>
unsigned long step_delay,loop_count;
unsigned char run_flag, step;
unsigned char pwm_tick_l, pwm_duty_l, pwm_bit_l, pwm_speed_l;
unsigned char pwm_tick_r, pwm_duty_r, pwm_bit_r, pwm_speed_r;
unsigned long pwm_rampe_l; pwm_rampe_r;
int pwm(void) {
StatusLED(OFF);
if ((loop_count > pwm_rampe_l) && (pwm_speed_l != pwm_duty_l)) {
if (pwm_duty_l < pwm_speed_l) {
pwm_duty_l++;
} else {
pwm_duty_l--;
}
pwm_rampe_l=loop_count+500; // Steilheit Rampe
StatusLED(RED);
}
if ((loop_count > pwm_rampe_r) && (pwm_speed_r != pwm_duty_r)) {
if (pwm_duty_r < pwm_speed_r) {
pwm_duty_r++;
} else {
pwm_duty_r--;
}
pwm_rampe_r=loop_count+500;
StatusLED(RED);
}
pwm_tick_l++; pwm_tick_r++;
if (pwm_tick_l >= 255) pwm_tick_l=0;
if (pwm_tick_r >= 255) pwm_tick_r=0;
if ((pwm_duty_l) && (pwm_tick_l <= pwm_duty_l)) pwm_bit_l=255; else pwm_bit_l=0;
if ((pwm_duty_r) && (pwm_tick_r <= pwm_duty_r)) pwm_bit_r=255; else pwm_bit_r=0;
MotorSpeed(pwm_bit_l,pwm_bit_l); // verflucht, rechte Seite funzt nicht
BackLED(pwm_bit_l,pwm_bit_r);
}
void Motor(unsigned char speed_l, unsigned char speed_r) {
pwm_speed_l=speed_l;
//pwm_duty_l=speed_l; // ohne Sanftanlauf
pwm_speed_r=speed_r;
//pwm_duty_r=speed_r;
step_delay=loop_count+100000;
}
int main(void) {
Init();
run_flag=1; step=0; loop_count=0;
pwm_duty_l=0; pwm_speed_l=0; pwm_rampe_l=0; pwm_tick_l=0;
pwm_duty_r=0; pwm_speed_r=0; pwm_rampe_r=0; pwm_tick_r=0; // oder Tick=128 für Phasenverschiebung l/r
SerWrite("\nHallo\nBatterie: ",17);
PrintInt(Batterie());
MotorSpeed(0,0);
MotorDir(BREAK,BREAK);
do {
loop_count++;
if (loop_count > step_delay)
switch (step) {
case 0: MotorDir(FWD,RWD); step++; break;
case 1: Motor(150,150); step++; break;
case 2: Motor(0,0); step++; break;
case 3: MotorDir(RWD,FWD); step_delay=loop_count+200; step++; break;
case 4: Motor(150,150); step++; break;
case 5: Motor(0,0); step=0; break;
case 6: MotorDir(BREAK,BREAK); step++; break;
case 7: run_flag=0; break;
}
pwm();
}while (run_flag);
StatusLED(RED);
MotorSpeed(0,0);
MotorDir(BREAK,BREAK);
while (1);
return 0;
}
Kann man natürlich noch viel optimieren, aber da es völlig unnötig ist werde ich mich jetzt auf die Weg- und Geschwindigkeitsmessung stürtzen. Übrigens fährt mein asuro beim Testen fast immer im Kreis ;-)
Gruß
mic
bisher kannte ich PWM berufsbedingt nur bei Motoren mit mehreren KW Leistung. Nachdem ich mich nun ein wenig in die Materie eingelesen habe und die Umsetzung in ein c-Programm auch halbwegs funktioniert sollte ich ja eigentlich zufrieden sein. Aber leider bin ich mit diesen neuen Kenntnissen auch in der Lage zu erkennen, das der asuro die PWM schon serienmässig eingebaut hat ( den Hinweis darauf habe ich im asuro-wiki (https://www.roboternetz.de/wissen/index.php/Pulsweitenmodulation) nicht gefunden). Aber egal, ich wollte ja was lernen, hier noch mein bisheriger Code:
/* asuro fährt endlos drehend in zwei Richtungen mit selbstgebauter
Pulsweitenmodulation und Sanftanlauf
mic 6.1.2006
*/
#include <asuro.h>
unsigned long step_delay,loop_count;
unsigned char run_flag, step;
unsigned char pwm_tick_l, pwm_duty_l, pwm_bit_l, pwm_speed_l;
unsigned char pwm_tick_r, pwm_duty_r, pwm_bit_r, pwm_speed_r;
unsigned long pwm_rampe_l; pwm_rampe_r;
int pwm(void) {
StatusLED(OFF);
if ((loop_count > pwm_rampe_l) && (pwm_speed_l != pwm_duty_l)) {
if (pwm_duty_l < pwm_speed_l) {
pwm_duty_l++;
} else {
pwm_duty_l--;
}
pwm_rampe_l=loop_count+500; // Steilheit Rampe
StatusLED(RED);
}
if ((loop_count > pwm_rampe_r) && (pwm_speed_r != pwm_duty_r)) {
if (pwm_duty_r < pwm_speed_r) {
pwm_duty_r++;
} else {
pwm_duty_r--;
}
pwm_rampe_r=loop_count+500;
StatusLED(RED);
}
pwm_tick_l++; pwm_tick_r++;
if (pwm_tick_l >= 255) pwm_tick_l=0;
if (pwm_tick_r >= 255) pwm_tick_r=0;
if ((pwm_duty_l) && (pwm_tick_l <= pwm_duty_l)) pwm_bit_l=255; else pwm_bit_l=0;
if ((pwm_duty_r) && (pwm_tick_r <= pwm_duty_r)) pwm_bit_r=255; else pwm_bit_r=0;
MotorSpeed(pwm_bit_l,pwm_bit_l); // verflucht, rechte Seite funzt nicht
BackLED(pwm_bit_l,pwm_bit_r);
}
void Motor(unsigned char speed_l, unsigned char speed_r) {
pwm_speed_l=speed_l;
//pwm_duty_l=speed_l; // ohne Sanftanlauf
pwm_speed_r=speed_r;
//pwm_duty_r=speed_r;
step_delay=loop_count+100000;
}
int main(void) {
Init();
run_flag=1; step=0; loop_count=0;
pwm_duty_l=0; pwm_speed_l=0; pwm_rampe_l=0; pwm_tick_l=0;
pwm_duty_r=0; pwm_speed_r=0; pwm_rampe_r=0; pwm_tick_r=0; // oder Tick=128 für Phasenverschiebung l/r
SerWrite("\nHallo\nBatterie: ",17);
PrintInt(Batterie());
MotorSpeed(0,0);
MotorDir(BREAK,BREAK);
do {
loop_count++;
if (loop_count > step_delay)
switch (step) {
case 0: MotorDir(FWD,RWD); step++; break;
case 1: Motor(150,150); step++; break;
case 2: Motor(0,0); step++; break;
case 3: MotorDir(RWD,FWD); step_delay=loop_count+200; step++; break;
case 4: Motor(150,150); step++; break;
case 5: Motor(0,0); step=0; break;
case 6: MotorDir(BREAK,BREAK); step++; break;
case 7: run_flag=0; break;
}
pwm();
}while (run_flag);
StatusLED(RED);
MotorSpeed(0,0);
MotorDir(BREAK,BREAK);
while (1);
return 0;
}
Kann man natürlich noch viel optimieren, aber da es völlig unnötig ist werde ich mich jetzt auf die Weg- und Geschwindigkeitsmessung stürtzen. Übrigens fährt mein asuro beim Testen fast immer im Kreis ;-)
Gruß
mic