hallo botty,

Zitat von
botty
aus Deinem Beispiel mit den mehreren Motoren hast folgende Variablen definiert gehabt:
Code:
AF_DCMotor motor_1(1);
AF_DCMotor motor_2(2);
AF_DCMotor motor_3(3);
AF_DCMotor motor_4(4);
die Zahl n, die Du hier in motor_x(n) benutzt hast, muß in der ersten Spalte des Arrays in AF_DCMotor(n) eingetragen werden.
so?
Code:
struct motor motoren[M_MAX] =
{
{ AF_DCMotor(1), 4, 18, 0, 0 }, // M_VL
{ AF_DCMotor(2), 1, 19, 0, 0 }, // M_HL
{ AF_DCMotor(3), 3, 20, 0, 0 }, // M_VR
{ AF_DCMotor(4), 2, 21, 0, 0 } // M_HR
};

Zitat von
botty
Probier doch bitte mal aus,wenn Du die Initialisierung von oben nimmst, ob
Code:
void loop() {
motoren[M_VL].mot.setSpeed(130);
motoren[M_VL].mot.run(FORWARD);
delay(3000);
motoren[M_VL].mot.setSpeed(0);
motoren[M_VL].mot.run(RELEASE);
delay(3000);
}
den linken vorderen Motor alle drei Sekunden an bzw aus schaltet.
der - so wie ich Dich verstanden habe geänderte code sieht so aus:
Code:
#include <AFMotor.h>
/*
* Benamte Indexe. Wichtig: Alle Schleifen basieren auf der
* Annahme, dass M_VL das erste Element und mit 0 initialisiert
* ist. M_MAX muss ausserdem _immer_ das letzte Element sein da
* es die Groesse des Arrays s.u. bestimmt.
*/
enum motoren_e
{
M_VL = 0, // Motor vorne links
M_HL,
M_VR,
M_HR,
M_MAX
};
/*
* Infos zu einem Motor zusammenfassen.
*/
struct motor
{
AF_DCMotor mot;
uint8_t enc_pin;
// volatile damit der Compiler keine 'dummen' Optimierung macht.
volatile uint32_t ticks;
unsigned long start_time;
unsigned long stop_time;
};
/*
* Hier werden die PWM Channel - Encoder Pin Paare gesetzt.
* Restliche Elemente muessen ebenfalls initialisiert werden.
* Werte pruefen ob sie zu den Namen oben passen.
* Fuer die externen Interrupts sind die Pins 2,5,18-21
* erlaubt. Hardware anpassen.
*/
struct motor motoren[M_MAX] =
{
{ AF_DCMotor(1), 4, 18, 0, 0 }, // M_VL
{ AF_DCMotor(2), 1, 19, 0, 0 }, // M_HL
{ AF_DCMotor(3), 3, 20, 0, 0 }, // M_VR
{ AF_DCMotor(4), 2, 21, 0, 0 } // M_HR
};
// Anzahl der Encoderstriche fuer eine Umdrehung
const static double ticks_per_rev = 40;
const static double durchmesser = 6.5; // in cm;
const static double u_per_tick = (3.1415926535897932384626433832795 * durchmesser) / ticks_per_rev;
/*
* Interruptroutinen mit der gleichen Namenskonvention wie
* oben.
*/
void motor_isr_m_vl(void) { motoren[M_VL].ticks++; }
void motor_isr_m_vr(void) { motoren[M_VR].ticks++; }
void motor_isr_m_hl(void) { motoren[M_HL].ticks++; }
void motor_isr_m_hr(void) { motoren[M_HR].ticks++; }
void setup()
{
//Serial.begin(115200);
Serial.begin(9600);
for(uint8_t idx = M_VL; idx < M_MAX; idx++)
{
pinMode(motoren[idx].enc_pin, INPUT_PULLUP);
// motor_init_pos(idx);
}
/*
* Hier wird die Verbindung hergestellt zwischen Pin und Interruptroutine.
* Die Namen muessen zueinander passen.
* Durch CHANGE werden beide Uebergaenge beruecksichtigt.
*/
attachInterrupt(digitalPinToInterrupt(motoren[M_VL].enc_pin), motor_isr_m_vl, CHANGE);
attachInterrupt(digitalPinToInterrupt(motoren[M_HL].enc_pin), motor_isr_m_hl, CHANGE);
attachInterrupt(digitalPinToInterrupt(motoren[M_VR].enc_pin), motor_isr_m_vr, CHANGE);
attachInterrupt(digitalPinToInterrupt(motoren[M_HR].enc_pin), motor_isr_m_hr, CHANGE);
}
/*
* Alle Motoren an, bis eine Umdrehung erreicht ist. Es wird alle
* halbe Sekunde der Zustand der Ticks pro Motor ausgeben.
*/
void loop() {
motoren[M_VL].mot.setSpeed(130);
motoren[M_VL].mot.run(FORWARD);
delay(3000);
motoren[M_VL].run(RELEASE);
delay(3000);
}
/*
void loop()
{
unsigned long log_time = 0;
unsigned long ticks_tmp = 0;
unsigned long all_ticks_tmp[M_MAX] = { 0, 0, 0, 0 };
String out_s = "";
bool alle_aus = false;
// Alle Motoren an.
for(uint8_t idx = M_VL; idx < M_MAX; idx++)
{
if( ! motor_laeuft(idx) )
motor_start(idx, 200/2+3, FORWARD);
}
while( ! alle_aus )
{
// Wenn die Anzahl der Ticks fuer eine Umdrehung
// erreicht ist - Motor aus.
for(uint8_t idx = M_VL; idx < M_MAX; idx++) {
if(motor_laeuft(idx) && motor_hole_ticks(idx) >= ticks_per_rev)
{
motor_stop(idx);
}
}
// Ticks und Strecke ausgeben
static const int wtime = 250;
if(log_time + wtime <= millis() )
{
out_s = "";
out_s += millis() + ": ";
for(uint8_t idx = M_VL; idx < M_MAX; idx++)
{
out_s += idx + " ";
out_s += motoren[idx].ticks + " "; // Hier koennte jetzt ein Interrupt unterbrechen!
out_s += motor_strecke_gefahren(idx);
ticks_tmp = 0;
motor_ticks_per_milli(idx, &ticks_tmp);
out_s += " " + ticks_tmp;
if(idx == M_MAX - 1)
out_s += "\n";
else
out_s += ", ";
}
for(uint8_t idx = 0; idx < M_MAX; idx++)
all_ticks_tmp[idx] = 0;
motor_ticks_per_milli_fuer_alle(all_ticks_tmp, M_MAX);
for(uint8_t idx; idx < M_MAX; idx++)
out_s += all_ticks_tmp[idx] + " ";
Serial.println(out_s);
log_time = wtime + millis();
}
// pruefen ob alle Motoren aus sind.
for(uint8_t idx = M_VL, alle_aus = true; alle_aus && idx < M_MAX; idx++)
{
alle_aus = alle_aus && ( ! motor_laeuft(idx) );
}
}
while(1);
// Oder nach 2sec geht's von vorne los.
// delay(2000);
}*/
/*
* Faehrt den Motor auf den ersten HIGH Level des Encoderpins.
* Falls er schon HIGH ist wird erst in ein LOW gefahren und
* beim naechsten HIGH gestoppt.
*/
void motor_init_pos(uint8_t idx)
{
if(idx >= M_MAX)
return;
if(motor_laeuft(idx))
motor_stop(idx);
// Wenn wir bereits eine 1 haben, dann fahren wir erstmal bis zur
// naechsten 0.
if(digitalRead(motoren[idx].enc_pin))
{
motoren[idx].mot.setSpeed(255/3);
motoren[idx].mot.run(FORWARD);
while(digitalRead(motoren[idx].enc_pin));
}
// Wir sind in ner 0, wissen aber nicht ob sich der Motor schon dreht.
if( ! digitalRead(motoren[idx].enc_pin) )
{
motoren[idx].mot.setSpeed(255/4);
motoren[idx].mot.run(FORWARD);
while( ! digitalRead(motoren[idx].enc_pin) );
motoren[idx].mot.setSpeed(0);
motoren[idx].mot.run(RELEASE);
// Bremsen evtl. nicht noetig oder muss angepasst werden.
/*
delayMicroseconds(75);
motoren[idx].mot.setSpeed(255/5);
motoren[idx].mot.run(BACKWARD);
delayMicroseconds(100);
motoren[idx].mot.setSpeed(0);
motoren[idx].mot.run(RELEASE);
*/
}
}
/*
*
*/
bool motor_laeuft(uint8_t idx)
{
if(idx >= M_MAX)
return false;
return motoren[idx].start_time > 0 && motoren[idx].start_time == motoren[idx].stop_time;
}
/*
* idx - der Motor Index
* pwm und dir wie in AF_DCMotor.
*/
void motor_start(uint8_t idx, uint8_t pwm, uint8_t dir)
{
if(idx >= M_MAX)
return;
motor_setze_ticks(idx, 0);
motoren[idx].start_time = motoren[idx].stop_time = millis();
motoren[idx].mot.setSpeed(pwm);
motoren[idx].mot.run(dir);
}
/*
* Fuer den Fall das zwischen motor_start und motor_stop die pwm nicht
* geaendert wird liesse sich aus der Zeit und der Strecke s.u. grob die
* Geschwindigkeit ermitteln (Be- und Entschleunigung vernachlaessgt).
*/
void motor_stop(uint8_t idx)
{
if(idx >= M_MAX)
return;
motoren[idx].mot.setSpeed(0);
motoren[idx].mot.run(RELEASE);
motoren[idx].stop_time = millis();
}
/*
* Liesst den ticks Wert interrupt safe.
*/
inline uint32_t motor_hole_ticks(uint8_t idx)
{
if(idx >= M_MAX)
return 0;
noInterrupts();
uint32_t tmp = motoren[idx].ticks;
interrupts();
return tmp;
}
/*
* Setzt den ticks Wert interrupt safe.
*/
inline void motor_setze_ticks(uint8_t idx, uint32_t val)
{
if(idx >= M_MAX)
return;
noInterrupts();
motoren[idx].ticks = val;
interrupts();
}
/*
*
*/
void motor_ticks_per_milli(uint8_t idx, unsigned long *res)
{
if(idx >= M_MAX)
{
*res = 0;
return;
}
*res = motor_hole_ticks(idx) / (millis() - motoren[idx].start_time);
}
/*
* Zu _einem_ Zeitpunkt werden alle Ticks/Milli ausgerechnet.
*/
void motor_ticks_per_milli_fuer_alle(unsigned long *res, uint8_t n)
{
unsigned long *b = 0;
unsigned long tstamp = 0;
if(n != M_MAX)
return;
b = res;
noInterrupts();
tstamp = millis();
while(b < res + n)
{
*b = motoren[b - res].ticks;
b++;
}
interrupts();
for(b = res; b < res + n; b++) {
*b = *b / (tstamp - motoren[b - res].start_time);
}
}
/*
* Rechnet die gefahrenen Zentimeter anhand der Ticks aus.
*/
double motor_strecke_gefahren(uint8_t idx)
{
if(idx >= M_MAX)
return 0.0;
return motor_hole_ticks(idx) * u_per_tick;
}
/*
* Rechnet fuer alle Motoren zu _einem_ Zeitpunkt die Strecke
* aus.
*/
void motor_strecke_fuer_alle(double *res, int n)
{
if(n != M_MAX)
return;
double *b = 0;
unsigned long tmps[M_MAX];
uint8_t idx = 0;
noInterrupts();
while(idx < M_MAX) {
tmps[idx] = motoren[idx].ticks;
idx++;
}
interrupts();
for(b = res; b < res + n; b++)
{
*b = tmps[b-res] * u_per_tick;
}
}
und lässt sich nicht kompilieren (ich sagte es schon, sehr sportlich der code für meine programmierkünste
)
Arduino: 1.6.6 (Linux), Board: "Arduino Mega ADK"
Code:
/home/georg/Arduino/sainsmart_car/fahren_mit timer/botty_4_motoren_1/botty_4_motoren_1.ino: In function 'void loop()':
botty_4_motoren_1:95: error: 'struct motor' has no member named 'run'
motoren[M_VL].run(RELEASE);
^
exit status 1
'struct motor' has no member named 'run'
Dieser Report hätte mehr Informationen mit
"Ausführliche Ausgabe während der Kompilierung"
aktiviert in Datei > Einstellungen.
Lesezeichen