Oder du hättest das Einführungstutorial gelesen.
King tobi, wäre es dann nicht einfacher Du hättest den Link gepostet? Das Problem ist nur: auf der Webseite gibt es keiine Befehlsübersicht zum Download sondern - Bauanleitung, - Tutorial, - die erwähnte msi-Datei und - den Schaltplan.
Oder du hättest das Einführungstutorial gelesen.
Einen Zeitgeber Suche ich immernoch...
Ich habe das Tutorial zur Programmierung durchgearbeitet, einen Hinweis auf den Speicherort der Befehlsreferenz gibt es dort nicht.
Gibts denn vieleicht Jemanden, der kein Oberlehrer ist und sich über Programmbeispiele austauschen möchte?
Ich habe ein Programm gebastelt, welches den Nibobee im Kreis fahren lässt. Stösst er auf ein Hindernis oder bleibt er stecken (Motor steht still), so versucht er sich durch Rückwärtsfahren und Drehen zu befreien.
Code:/* NIBOBee fährt nach Fühleranstoß im Kreis. Stößt er an oder bleibt ein Motor hängen, so setzt er kurz zurück */ #include <nibobee/iodefs.h> #include <nibobee/sens.h> #include <nibobee/motpwm.h> #include <nibobee/led.h> #include <nibobee/delay.h> #include <nibobee/odometry.h> /* Funktionen zur Steuerung der Fahrt fahre(1) - im Uhrzeigersinn, fahre(-1) - gegen die Uhr, fahre(0) - rückwärts, rote Lampe leuchtet auf der Kurven- Innen- Seite */ int fahre(int8_t richtung) { switch(richtung) { case 1: { motpwm_setLeft(400); /* Kreis im Uhrzeigersinn */ motpwm_setRight(350); led_set(LED_L_RD, 0); led_set(LED_R_RD, 1); break; } case -1: { /* Kreis gegen die Uhr */ motpwm_setLeft(350); motpwm_setRight(400); led_set(LED_L_RD, 1); led_set(LED_R_RD, 0); break; } case 0: { /* volle Kraft zurück */ motpwm_setLeft(-1024); motpwm_setRight(-1024); led_set(LED_L_RD, 1); led_set(LED_R_RD, 1); delay(800); motpwm_setLeft(1000); /* und ein bischen drehen */ motpwm_setRight(-1000); delay(150); break; } } return 0; } */ Hauptprogramm */ int main() { motpwm_init(); sens_init(); enable_interrupts(); odometry_init(); int odo_l = 0; /* Variablen für die Odometriezählwerte */ int odo_l_merk = 0; int odo_r = 0; int odo_r_merk = 0; int loop = 0; /* Variable, die bei jedem Programmdurchlauf erhöht wird */ /* warte, bis ein Fühler betätigt wird */ while((sens_getLeft()==0) && (sens_getRight()==0)); /* jetzt gehts los! */ while(1==1) { /* Endlosschleife */ switch (sens_getLeft()) { /* linker Fühler */ case 1: fahre(1); break; case -1: fahre(0); /* bin angestoßen, also zurück */ delay(500); fahre(1); break; } switch (sens_getRight()) { /* rechter Fühler */ case 1: fahre(-1); break; case -1: fahre(0); /* bin angestoßen, also zurück */ delay(500); fahre(-1); break; } loop++; /* Programmdurchläufe zählen, als Ersatz für Zeitgeber */ odo_l = odometry_getLeft(0); /* Odometrie einlesen */ odo_r = odometry_getRight(0); /* prüfe bei jedem 10000sten Durchlauf ob der Odowert sich auch geändert hat, also der Motor noch drehen kann */ if (loop == 10000) { /* diesen Wert habe ich einfach ausprobiert */ if (odo_l == odo_l_merk) { /* linker Motor steht */ fahre(0); /* fahre rückwärts */ fahre(-1); } /* fahre weiter im Kreis */ odo_l_merk = odo_l; if (odo_r == odo_r_merk) { /* dito für den rechten Motor */ fahre(0); fahre(1); } odo_r_merk = odo_r; loop = 0; } ; if ((odo_l/10)%2) led_set(LED_L_YE, 1); /* laß die gelben Lampen blinken, je nach Odometer */ else led_set(LED_L_YE, 0); if ((odo_r/10)%2) led_set(LED_R_YE, 1); else led_set(LED_R_YE, 0); } return 0; }
Hallo
Was willst du mehr? Knapp einen Tag nach deinem Startposting hast du selbst eine brauchbare Lösung gefunden. Das Schleifenzählen war bei meinem Einstieg bei den Microkontrollern auch der erste Ansatz:
https://www.roboternetz.de/phpBB2/ze...g.php?p=242178
https://www.roboternetz.de/phpBB2/ze...g.php?p=242581
Vorbildiche Kommentare übrigends. Immer weiter so *Daumen Hoch*
Gruß
mic
Bild hier
Atmel’s products are not intended, authorized, or warranted for use
as components in applications intended to support or sustain life!
Bitte Schreibfehler im Codekommentar korrigieren:
*/ Hauptprogramm */ --> /* Hauptprogramm */
Zitat von KingTobi
Tach,
ich bin bei der Programmierung von AVRs ziemlich neu und hatte mir für Heute vorgenommen blockierte Räder zu detektieren. Auch ich hatte mir gedacht das ganze mit Hilfe eines Timers zu erledigen. Ich habe erst mal diverse Tutorials zu AVR-Timern im Netzt durchgelesen (hier und bei Mikrocontroller.net). Ein paar LEDs blinken schon fröhlich vor sich hin. Nu aber wo ich mich an der Roboter machen möchte stellen sich mir ein paar Fragen - vielleicht kann mir ja jemand weiterhelfen?
1.
Ich habe die Dokumentation vom NIBObee und das Tutorial durchsucht - leider finde ich da keine Hinweise auf die bereits verwendeten Timer/Counter. Die Odometrie läuft über INT0 und INT1 - sind also externe Interrupts und dürften mich nicht stören, oder? Über die PWM bin ich mir nicht schlüssig- laut Datenblatt liegt die An Timer/Counter1.
Heisst das für mich das ich die beiden 8Bit-Timer TCCR0 und TCCR1 frei für mich verwenden kann und trotzdem alle Bibliotheken vom NIBOBEE einbinden kann?
2.
Was ist beim detektieren von blockierten Rädern die geschickteste Variante? In Regelmäßigen Abständen schauen ob sich der Zählerstand geändert hat, falls dies nicht der Fall ist eine Globale Variable setzten damit meine Funktion die fürs Fahren zuständig ist reagieren kann? Das wäre das was mir als erstes dazu eingefallen ist...
noch nen schönen Sonntag
waschtl
Nach langer Zeit hab ich den nibobee wieder rausgekramt und ein wenig programmiert. Nachfolgendes Programm bewegt die Biene vorsichtig entlang der Dielenritzen. Ist sie blockiert oder stösst sie auf Hindernisse, so wendet sie. Start erfolgt durch Fühler.
Code:/* Die Biene bewegt sich vorsichtig entlang der Dielenritzen. Stößt sie an, wendet sie. Fährt sie sich fest, versucht sie sich zu befreien */ #include <nibobee/iodefs.h> #include <nibobee/sens.h> #include <nibobee/motpwm.h> #include <nibobee/led.h> #include <nibobee/line.h> #include <nibobee/delay.h> #include <nibobee/odometry.h> #include <avr/interrupt.h> int odo_l = 0; /* Variablen für die Odometriezählwerte */ int odo_l_merk = 0; int odo_r = 0; int odo_r_merk = 0; int loop = 0; /* Variable, die bei jedem Programmdurchlauf erhöht wird */ int motorblockt = 0; /* Variable, die von ISR gesetzt wird, wenn Motor steht */ /* Funktionen zur Steuerung der Fahrt fahre(1) - im Uhrzeigersinn, fahre(-1) - gegen die Uhr, fahre(0) - rückwärts, rote Lampe leuchtet auf der Kurven- Innen- Seite */ int fahre(int8_t richtung) { switch(richtung) { case 1: { motpwm_setLeft(400); /* Kreis im Uhrzeigersinn */ motpwm_setRight(150); led_set(LED_R_RD, 1); led_set(LED_L_RD, 0); break; } case -1: { /* Kreis gegen die Uhr */ motpwm_setLeft(150); motpwm_setRight(400); led_set(LED_L_RD, 1); led_set(LED_R_RD, 0); break; } case 0: { /* volle Kraft zurück */ motpwm_setLeft(-1024); motpwm_setRight(-1024); led_set(LED_L_RD, 1); led_set(LED_R_RD, 1); delay(500); motpwm_setLeft(1000); /* und ein bischen drehen */ motpwm_setRight(-1000); led_set(LED_L_RD, 0); led_set(LED_R_RD, 0); delay(300); loop = 0; /* setze Schleifenzähler zurück */ break; } } return 0; } /* diese Routine wird beim Timerinterrupt abgearbeitet */ ISR(TIMER0_OVF_vect) { static uint8_t count=0; count++; loop ++; if(count > 57) { count=0; if ((odo_l == odo_l_merk) || (odo_r == odo_r_merk)) motorblockt = 1; /* Motor steht */ odo_l_merk = odo_l; /* merke den odo- Stand*/ odo_r_merk = odo_r; } } /* Hauptprogramm */ int main() { motpwm_init(); sens_init(); odometry_init(); led_init(); line_init(); /* warte, bis ein Fühler betätigt wird */ while((sens_getLeft()==0) && (sens_getRight()==0)); TCCR0 = (1<<CS02) | (1<<CS00); /* Zeitgeber initialisieren, Danke mic */ TIMSK |= (1<<TOIE0); enable_interrupts(); /* jetzt gehts los! */ while(1==1) { /* Endlosschleife */ if (sens_getLeft() != 0) { /* linker Fühler */ fahre(0); /* bin angestoßen, also zurück */ } if (sens_getRight() != 0) { /* rechter Fühler */ fahre(0); /* bin angestoßen, also zurück */ } if (motorblockt == 1) /* Motor steht */ { fahre(0); /* fahre rückwärts */ motorblockt = 0; } odo_l = odometry_getLeft(0); /* Odometrie einlesen */ odo_r = odometry_getRight(0); /* bleib auf der Dielenritze */ if (line_get(LINE_L) > line_get(LINE_R)) fahre(1); else fahre(-1); /* sehr lange nicht angestoßen, fahr einfach mal zurück */ if (loop > 2280) fahre(0); } return 0; }
Lesezeichen