PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : NIBObee Programmbeispiele, Odometrie, Zeitgeber



gagu1
01.01.2010, 17:07
Nach erfolgreichem Aufbau und dem Abarbeiten des Tutorials bin ich nun beim Experimentieren mit den Codebeispielen.
Manchmal bleibt die Neebobee z.B. unter einem Möbel hängen ohne das die Fühler auslösen. Hier wäre es schön, wenn man den Moterstillstand über die Odometrie erkennen könnte um z.B. 2 Sekunden rückwärts zu fahren.
Dazu fehlt mir jedoch ein Zeitgeber um die Motorbewegung z.B. alle Sekunde abzufragen. Delay hift mir nicht weiter, weil ja sonst während der delay- Zeit die Fühler nicht reagieren.
Kennt jemand eine Lösung dafür? Gibt es außer dem Tutorial noch Codebeispiele und eine Beschreibung aller Befehle?

KingTobi
01.01.2010, 17:19
Kennt jemand eine Lösung dafür?
Ein Timer

gagu1
01.01.2010, 19:36
Eine (wenn auch nicht sehr elegante) Lösung habe ich gefunden:
Zunächst merke ich mir den Stand des Odometriezählers in einer Variable.
Bei jedem Programmdurchlauf zähle ich nun eine andere Variable hoch. Hat sie den Wert 10000 (ausprobiert) erreicht, schaue ich, ob der Odometerstand noch dergleiche ist. Ist dies der Fall, dann klemmt unser Freund irgendwo. Mit "voller Kraft zurück" kann ich ihn dann aus seiner mißlichen Lage befreien.
Danach setze ich die Variablen wieder zurück usw.

KingTobi
01.01.2010, 19:40
Ist doch nicht schlecht, aber das hochzählen würde ich über nen Timer machen!

gagu1
02.01.2010, 11:36
Sicherlich hat der nibobee irgendwo einen Timer. Aber mit welchem Befehl kann ich Ihn starten, abfragen oder auf die Timerereignisse reagieren? Überhaupt vermisse ich eine Übersicht der gelieferten Befehle.

KingTobi
02.01.2010, 12:07
Überhaupt vermisse ich eine Übersicht der gelieferten Befehle
Dann lern erstmal programmieren, wenn du dich nur auf die mitgelieferten Funktionen verlässt bist du selbst schuld

oberallgeier
02.01.2010, 13:28
... Überhaupt vermisse ich eine Übersicht der gelieferten Befehle ...Du bräuchtest nicht mal programmieren zu lernen - lesen können würde reichen. Denn die Leute von nicai systems haben das alles ziemlich perfekt zusammengetragen und zur Verfügung gestellt. Wie gesagt - man muss nur lesen . . . .

Da gibts die Liste der Dateien in der Library:

................http://oberallgeier.ob.funpic.de/NIBOdat.jpg

... und natürlich die Liste der Funktionen :

................http://oberallgeier.ob.funpic.de/NIBOfunc.jpg

... und noch viel, viel mehr. Mich machen solche Argumente "... Überhaupt vermisse ich ..." deswegen ärgerlich, weil einmal alles da und sehr sauber zusammengestellt ist und ausserdem der Umfang so groß ist, dass jedem klar sein muss, dass man das nicht auf einen klitzekleinen Zettel in einen einzigen Satz bekommt. Geht also nicht mit einem Quickinfo.

gagu1
02.01.2010, 15:20
Ich möchte mit anderen Nibobee- Einsteigern Erfahrungen und Programmbeispiele austauschen. Wenn ich mich abbügeln lassen will, wähle ich ein anderes Forum.
Also king tobi, natürlich möchte ich mich zunächst mit den mitgelieferten Funktionen befassen.
Und vielen Dank Oberallgeier lesen kann ich ein wenig, aber finden ist schwer. Ich kann diese Übersicht weder auf der mitgelieferten CD noch auf der Webseite http://www.nicai-systems.de/nibobee.html finden - wo stammt diese Übersicht her und wo kann ich sie bekommen?

KingTobi
02.01.2010, 15:26
Es ist unglaublich!
Du hast den Link dazu doch grad selbst gepostet... wenn du nicht bereit bis auch mal einen Satz zu lesen dann wird das nichts mit programmieren

gagu1
02.01.2010, 15:27
hab Dokumentation gefunden: steht nach der Installation von nibobeelib*.msi im Verzeichnis %programfiles%\nibobeelib\doc\html

gagu1
02.01.2010, 15:34
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.

KingTobi
02.01.2010, 15:36
Oder du hättest das Einführungstutorial gelesen.

gagu1
02.01.2010, 15:38
Einen Zeitgeber suche ich immernoch...

gagu1
02.01.2010, 16:00
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?

gagu1
02.01.2010, 16:06
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.



/* 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;
}

radbruch
02.01.2010, 16:56
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/zeigebeitrag.php?p=242178
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?p=242581

Vorbildiche Kommentare übrigends. Immer weiter so *Daumen Hoch*

Gruß

mic

gagu1
02.01.2010, 17:55
Bitte Schreibfehler im Codekommentar korrigieren:
*/ Hauptprogramm */ --> /* Hauptprogramm */

waschtl
03.01.2010, 16:14
Ist doch nicht schlecht, aber das hochzählen würde ich über nen Timer machen!


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

gagu1
31.10.2010, 14:00
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.


/* 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;
}