Archiv verlassen und diese Seite im Standarddesign anzeigen : Probleme bei Programmierung
freekwave
10.12.2011, 17:50
Hi Leute,
ich hab mich mal wieder an meinen NIBO2 gewagt um etwas zu programmieren.
Das Programm, soll den Nibo solange geradeaus fahren lassen, bis der Wert des copro_distance[2] größer als 3 wird.
Aber, der Motor schaltet irgendwie nicht ab. (letztendlich geht es nur um den unteren teil des Programms).
#include <nibo/niboconfig.h>
#include <nibo/display.h>
#include <nibo/gfx.h>
#include <nibo/copro.h>
#include <nibo/delay.h>
#include <nibo/iodefs.h>
#include <nibo/bot.h>
#include <avr/interrupt.h>
#include <nibo/spi.h>
#include <stdio.h>
#include <nibo/leds.h>
#include <stdint.h>
#include <nibo/pwm.h>
int main() {
sei();
bot_init();
spi_init();
display_init();
leds_init ();
pwm_init ();
//-------------------------------------------------------
copro_ir_startMeasure();
//-------------------------------------------------------
leds_set_headlights (1024); //Frontlicht setzen
leds_set_status(LEDS_GREEN, 2);
leds_set_status(LEDS_GREEN, 3);
//-------------------------------------------------------
void blinker_links () { // Blinker Links definieren
int a = 1;
while (a<=10){
leds_set_status (LEDS_ORANGE, 0);
leds_set_status (LEDS_ORANGE, 1);
delay (100);
leds_set_status (LEDS_OFF, 0);
leds_set_status (LEDS_OFF, 1);
delay (100);
a++;
}
}
//-------------------------------------------------------
void blinker_rechts () {
int b = 1;
while(b<=10) // Blinker Rechts definieren
{
leds_set_status (LEDS_ORANGE, 4);
leds_set_status (LEDS_ORANGE, 5);
delay (100);
leds_set_status (LEDS_OFF, 4);
leds_set_status (LEDS_OFF, 5);
delay (100);
b++;
}
}
//-------------------------------------------------------
void warnblinker () {
int c = 1;
while(c<=10) // Warnblinker definieren
{
leds_set_status (LEDS_ORANGE, 0);
leds_set_status (LEDS_ORANGE, 1);
leds_set_status (LEDS_ORANGE, 4);
leds_set_status (LEDS_ORANGE, 5);
delay (100);
leds_set_status (LEDS_OFF, 0);
leds_set_status (LEDS_OFF, 1);
leds_set_status (LEDS_OFF, 4);
leds_set_status (LEDS_OFF, 5);
delay (100);
c++;
}
}
//-------------------------------------------------------
copro_ir_startMeasure();
copro_setSpeedParameters(5, 6, 7);
void motor_geradeaus (){
while(1==1){
copro_setSpeed(20, 20);
}
}
//-------------------------------------------------------
while(1==1){
delay(10);
char text[20]="-- -- -- -- --";
// Co-Prozessor
if (copro_update()) {
sprintf(text, "x x x x x",
(uint16_t)copro_distance[0]/256,
(uint16_t)copro_distance[1]/256,
(uint16_t)copro_distance[2]/256,
(uint16_t)copro_distance[3]/256,
(uint16_t)copro_distance[4]/256);
while(copro_distance[2]<3){
motor_geradeaus ();
}
}
}
return 0;
}
mfg freekwave
Ich kenn den NIBO2 zwar nicht aber die Programmiersprache ist ja C und du hast in dem Teil wo der Motor gesteuert wird folgendes stehen:
while(1==1){
copro_setSpeed(20, 20);
}
Die Schleife wird solange ausgeführt wie 1 = 1 ist, also die Bedingung wahr ist. Da 1 ein fester Wert ist und du nicht z.B. geschrieben hast Variable = 1, ändert sich dieser Wert im laufenden Programm nie und der Controller hängt quasi in einer Endlosschleife fest wo er den Befehl:
copro_setSpeed(20, 20);
andauernd ausführt.
Den selben Fehler hast du auch in dem Programmteil unter dem Motorteil gemacht, nur dieser Fehler macht sich noch(!) nicht bemerkbar, weil der Controller halt wie gesagt schon vorher in einer Endlosschleife festhängt.
Wenn du das korrigierst sollte es eigentlich funktionieren :)
Hier steht das nochmal auf Seite 12 erklärt:
http://download.nicai-systems.com/nibo/Nibo2Tutorial_20110909.pdf
freekwave
10.12.2011, 20:30
leider nicht, ich habe die zwei besagten while schleifen rausgenommen, aber es funktioniert iwi immoment komplett nicht. d.h. die Motoren gehen nach den einschalten sofort an, egal ob vor den sensoren etwas ist oder nicht.
Hast du den auch mal die Werte aus diesem Befehl entfernt:
while(1==1){
copro_setSpeed(20, 20);
}
?
Du musst die Werte denk ich mal auch aus dem Befehl löschen also z.B. wenn ein Hinderniss erkannt wird die Werte von 20 auf 0 umändern. Du hast ja in deinem Programm keine Bedingung unter welcher dieser Befehl ausgeführt werden soll. Da steht einfach nur das die Motoren sich mit einem Speed von 20, 20 drehen sollen und nicht
if(Bedingung)
{
Motor soll sich drehen
}
Wie gesagt ich kenn deinen Bot nicht und kann es leider auch nicht testen aber die Tatsache das sich die Motoren drehen deutet ja darauf hin das dieser Befehl andauernd ausgeführt wird. Was du machen könntest ist erstmal alles unnötige ausklammern und dann mit einfachen Print-Befehlen eine Art Debug-Schnittstelle zu machen, also das du nach jedem
copro_setSpeed(20, 20);
eine Ausgabe über UART machst. So siehst du wann der Befehl ausgeführt wird und ob der Befehl die ganze Zeit ausgeführt wird.
sourcecode
11.12.2011, 19:15
Um die Motoren zu stoppen ist lediglich ein _copro_stopImmediate();_ nötig.
Hero_123
12.12.2011, 14:57
Hallo freekwave
1.) "copro_setSpeed(20,20)" heißt, dass der NIBO2 mit ca 7cm/s (linkes Rad, rechtes Rad) fahren soll - und das macht er, bis er entweder einen Stopp-Befehl erhält oder man die Speed ("copro_setSpeed(0,0)" auf NULL setzt.
2.) Ich habe mir mal kurz Dein Programm angesehen - man sollte in der main keine Funktionen deklarieren, sondern sie nur verwenden; die Deklaration sollte außerhalbe der main erfolgen
3.) mit while(1==1) in einer Funktion zu arbeiten ist sehr gefährlich, da gibt es keine Abbruchbedingung => wird IMMER WEITER durchgeführt
4.) "while(copro_distance[2]<3){ motor_geradeaus (); }" => das fkt so nicht, denn: solange der Abstand < 3 ist, soll der NIBO geradeaus fahren => Du liest aber in der while-schleife NIE den neuen Abstand ein(copro_update!!):(
mfg
Hero_123
sourcecode
22.12.2011, 17:33
Hallo.
Ich hätte da auch mal eine Frage zur Programmierung und zwar würde ich gerne
Mittels nds3_get_dist(); ermittelte Werte über XBee versenden. Den ermittelten
Wert speicher ich wie folgt:
uint8_t dist_val1 = nds3_get_dist();
Über XBee lassen sich anscheinend nur Zeichen im Hex-Format versenden.
Mein Problem ist jetzt irgendwie den gespeicherten Wert in dist_val1 in
einzelne Hex Werte zu zerlegen. Mir wäre schon geholfen, wenn ich wüßte,
wie ich den Wert in dist_val1 in einen _array_ kriegen würde. Natürlich nicht
als _string_, sondern irgendwie in der Form array[0]=1; array[1]=8; array[2]=0;
Besser wäre natürlich noch array[0]=0x31; array[1]=0x38; array[2]=0x30;.
Vielen Dank.
Lieben Gruß
sourcecode
Hero_123
22.12.2011, 20:42
Hallo sourcecode
mal ein paar Fragen zu Deinen XBEEs - wie hast Du die denn konfiguriert, mit welcher Baudrate sendest Du, welches Terminalprogramm verwendest Du, wie hast du den FDT-Treiber konfiguriert?
Ich habe bei meinen XBEE Modulen ein seltsames Phänomen - ich verwende als Anzeige hterm, ein XBEE ist als Enddevice, das andere als Coordinator konfiguriert (hängt am PC - USB). Wenn ich nun das erste Mal das Modul am USB anstecke, hterm starte und den NIBO einschalte (der dann sofort das Senden beginnt), empfange ich die Daten am PC problemlos. Wenn ich das hterm beende ("disconnect" und Programm beenden) und dann wieder starte und connecte, empfange ich weiterhin Daten (soweit, so gut).
Wenn ich nun mich wieder disconnecte, den NIBO AUSSCHALTE und nach ca 3 min wieder EINSCHALTE und mit hterm wieder Daten empfangen will, fkt es nicht mehr - ich empfange einfach keine Daten mehr vom NIBO, obwohl er sendet; ich kann aber Daten an den NIBO senden. Erst wenn ich alles ausschalte (also auch den PC neu boote) kann ich wieder daten vom NIBO empfangen...
Hast Du dieses Phänomen auch schon mal gehabt, dass keine Daten mehr empfangen werden, wenn der NIBO aus- und dann nach ca 3 min wieder eingeschaltet wird???
Hero_123
sourcecode
22.12.2011, 22:08
Hallo Hero_123,
das Phänomen kann ich nur bestätigen. Passiert bei mir von Zeit zur Zeit auch.
Manchmal reicht es den XBee-Explorer (USB) aus zu stöpseln und wieder ein
zu stöpseln - manchmal muß ich auch komplett den Rechner neu starten.
Konfiguriert habe ich die XBee's ebenfalls als Coordinator und Enddevice. Baudrate 57600.
Als Terminalprogramm verwende ich X-CTU.
FTDI-Treiber Konfiguration: Senden/Empfangen 4096 Bytes
Wartezeit: 1ms
Timeouts Lesen/Schreiben: 0
sourcecode
Hero_123
22.12.2011, 22:34
Hallo sourcecode
Einerseits freuts mich, dass Du die gleichen Probleme hast wie ich ;) - anderseits ist das echt sch***:mad: - könnte mir vorstellen, dass es am FTDI-Treiber liegt, habe es mit dem "alten" und dem "neuesten" Treiber ausprobiert - kein Unterschied...werden wohl damit leben müssen (also den NIBO NICHT ausschalten)..mein Treiber ist wie Deiner konfiguriert; ein wirklich gutes Terminalprogramm ist hterm - läuft auch auf WIN 7!
Zu Deiner Frage - ich übertrage mit dem XBEE z.B die Drehzahl und lass sie mir im hterm als Dezimalwert anzeigen - dazu wandle ich den Wert und speicher ihn und schicke dann den Wert charweise über das XBEE-Modul: anbei einige Code-Schnipsel:
#define buf 80 /* Groesse Char-Buffer Wert einlesen - Empfangsbuffer */
char buf_ges[buf]; /* gesamter Buffer zum Werte rausschreiben */
char temp_buf[8]; /* temporaerer Buffer zum zwischenspeichern */
itoa((int8_t)copro_speed_l, temp_buf, 10); /* umwandeln und speichern der Speed links */
strcat(buf_ges, temp_buf);
usart_puts(buf_ges);
/* Funktion, um Character auf Terminal auszugeben */
extern void usart_putc(unsigned char c) {
while(!(UCSR1A & (1 << UDRE1))){
}
UDR1 = c;
}
/* Funktion, um String auf Terminal auszugeben */
extern void usart_puts(char *s) {
while (*s){ /* solange nicht Stringende erreicht */
usart_putc(*s); /* Aufruf Fkt usart_putc(*s) */
s++; /* Zeichen um 1 weiter zaehlen */
}
}
hoffe, das hilft ....
Hero_123
edit: habe vergessen zu erwähnen, dass bei mir über den UART1 gesendet wird (ich habe mir meine eigenen UART1-Fkt geschrieben), das XBEE Modul habe ich über SteckerX6 angeschlossen; verwendest Du das XBEE-Modul von nicai?
sourcecode
27.12.2011, 16:11
Hallo Hero_123,
vielen Dank für die Code Schnipsel. Momentan kann ich damit noch nicht sehr viel anfangen.
Ich denke bzw. hoffe das es für meine Problemlösung etwas einfacher gehen sollte/dürfte :-)
Werde mich die Tage nochmal damit beschäftigen.
sourcecode
Hero_123
27.12.2011, 21:40
Hallo sourcecode
Bei Unklarheiten/Fragen/Problemen => melden!
mfg
Hero_123
sourcecode
28.12.2011, 16:53
Hallo Hero_123,
mein Problem besteht natürlich nach wie vor.
Ich bin auch noch nicht wirklich firm in der C-Programmierung, weswegen wir
wohl dann auch ab und an mal Mittel und Wege zur Lösung fehlen.
Vielleicht ist meine _Denke_ in diesem Fall auch falsch :-/
Deine Lösung kommt mir im Moment noch etwas kryptisch vor :-) weswegen
ich mich da noch nicht ran traue und ich der Meinung bin (ohne es wirklich
zu wissen) das es für meine Problematik eine _einfacherer_ Lösung geben
müßte / sollte / könnte :-)
Nur mal so für mich zum Verständnis. Alle Werte (aller Sensoren z.B) werden
in einer Variable sicherlich _binär_ gespeichert, oder ?
Wie kriege ich die Werte dann in Hex umgewandelt. Nicht als Ausgabe mit
_printf_ sondern als Hex-Wert gespeichert in einer Variable. Diese Hex-Werte
wollte ich dann in einen Array schreiben, den ich dann später wieder auslesen
kann.
sourcecode
Genau genommen werden die Werte nicht in einer Variable gespeichert. Die Variable steht nur für eine stelle im Speicher wo die Werte binär gespeichert werden :)
Du musst die Werte nicht in Hex umwandeln. Einfach die Binärwerte anzeigen lassen. Terminals zeigen die Werte dann automatisch in Hexwerten an.
Du musst nur eine Umwandlung vornehmen wenn du den Wert in Dezimal angezeigt haben willst.
Hero_123
29.12.2011, 11:38
Hallo sourcecode
Ich versteh' nicht ganz, was Du da machen willst - weshalb willst Du den Wert dist_val1 = nds3_get_dist() in einen Hex-Wert umwandeln und dann in ein Array speichern? Gemäß NiboLib ist "nds3_get_dist()" die aktuell gemessene Distanz oder meinst Du uint8_t nds3_distances [181] - willst Du diese Werte in einem Array speichern und dann übertragen?
Du kannst doch problemlos den Wert dist_val1 in einen String umwandeln (muss ein String sein zum Senden) und dieses zyklisch senden...
Wie schon Kampi sagt - man kann in einem Terminalprogramm (z.B. hTerm http://www.der-hammer.info/terminal/, verwende ich, läuft auch problemlos unter WIN 7) sich die per XBEE übertragenen Werte als ASCII, HEX, BIN oder DEC anzeigen lassen. Es geht nur darum - wenn Du die Werte übertragen willst auf den PC - da mußte jeden Wert umwandeln in einen String und den Zeichenweise übertragen - dazu gibt's bei meinen Codeschnipseln die Funktionen:
- umwandeln eines int8_t wertes in einen String und diesen speichern in einem Char_buffer
- Funktion, um einen String auf Terminal auszugeben => diese Fkt ruft Funktion auf, um Char auf Terminal auszugeben
- Funktion, um Char auf Terminalauszugeben
Das Terminalprogramm macht dann aus den empfangenen Werten wieder eine "brauchbare" Anzeige - ich lass mir z.B die Motordrehzahlen, Abstand, Bodensensorenwerte, Motorströme auch per XBEE an den PC senden.
mfg
Hero_123
sourcecode
29.12.2011, 14:52
Hallo Kampi / Hero_123,
vielen Dank für Eure Antworten.
Langsam geht mir ein Lichtlein an :-)
Du hast das wohl richtig erkannt Hero_123. Ich möchte die ermittelten Werte aus uint8_t nds3_distance in ein Array schreiben und dann übertragen.
Ob die Werte dann wirklich in einen Array geschrieben werden müssen ist mir auch nicht ganz klar. Zumindest habe ich das bis jetzt so gelöst. Mit den
Distanzwerten habe ich das auch schon versucht, aber es kamen irgendwie nie die zeichen am Terminal an, die ankommen sollten.
Ich habe das bis jetzt so gemacht, das ich von vornherein nur Hex-Werte übertragen habe.
xbee_tx_buf[0] = 0x43;
xbee_tx_buf[1] = 0x45;
Da ich selbiges mit den ermittelten Werten von uint8_t nds3_distances gemacht habe und nie das
angekommen ist, was ankommen sollte, habe ich gedacht, ich müsse diese Werte erst in Hex
umwandeln. Leider kann ich meinen Code nicht posten, da ich momentan nicht daheim bin.
Morgen kann ich mal ein paar Schnipsel posten, wenn das vielleicht weiter hilft.
Ich versuche aber mal auf Grund der Antworten weiter zu kommen.
Vielen Dank.
sourcecode
Hero_123
29.12.2011, 22:11
Hallo sourcecode
Du nutzt offensichtlich die XBEE-Funktionen, die in der Lib sind - fkt die denn überhaupt korrekt? Ich hab' da auch mal mit rumprobiert, das hat aber bei mir ÜBERHAUPT nicht so geklappt, wie ich es wollte, habe mir deshalb selbst die Sende- / Empfangsroutinen für den UART1 geschrieben und verwende diese (d.h ich sende/empfange über UART1).
Jedenfalls - wenn Du uint8_t nds3_distances [181] übertragen willst, mußte Dir ein Array definieren, das diese Werte aufnehmen kann, ich denke aber nicht, dass Du alle Werte AUF EINMAL per XBEE senden kannst - irgendwo hab ich mal gelesen, dass man max 70 bytes/sendzyklus übertragen kann...
mfg
Hero_123
sourcecode
30.12.2011, 11:40
Hallo Hero_123,
ich benutze die XBEE Funftionen der lib. Wenn die natürlich nicht richtig funktionieren, könnte
das vielleicht auch mein Problem sein. Wie gesagt. Wenn ich konstante Werte / Zeichen
die ich vorher selber in Hex definiert habe übertrage funkioniert das ganz gut soweit.
Die ermittelten Werte des Distanzscanners habe ich versucht so zu übertragen:
xbee_tx_buf[0] = dist_val1;
xbee_tx_buf[1] = dist_val2;
xbee_tx_buf[2] = dist_val3;
Es kommt zwar dann auch was am Terminalprogramm an, aber nicht das, was ich
eigentlich erwarte. Wenn natürlich vielleicht an den Funktionen der lib etwas
nicht korrekt ist, kann man da als Laie natürlich auch mal anfangen zu verzweifeln :-)
Gruß
sourcecode
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.