PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : UART Interrupt und Time kommen sich in die Quere???



jagdfalke
14.12.2005, 21:17
Hi,
ich will nun beide meine Testprogramme vereinen. Das eine Bewegt 4 Servos gleichzeitig. Das ganze ist Timer-Interrupt-gesteuert. Der andere Teil in ein RX-Complete Interrupt, der Eingaben speichert bis das Stoppzeichen kommt und dann den String an eine Methode weitergibt, die ihn verarbeitet.. Es sollen z.B. Strings wie "s1100" empfangen werden, was bedeutet "Bewege Servo 1 (s1) zur Position 100".
Das ganze klappt aber nicht so. Wenn ich die Befehle zum Bewegen der Servos auskommentiere funktioniert der Empfang, ansonstem eben nicht.

Das Prinzip soll folgendes sein: Der Controller vergleicht ständig die aktuelle Position und die Soll-Position. Wenn sie nicht übereinstimmen bewegt er sie. Durch den Empfang des Befehls sollen neue Positionen vergeben werden können. Der Controller bewegt dann automatisch die Servos in die gewünschte Position.

Hier ist der Code für das ganze:


#define F_CPU 8000000
#define BAUD_RATE 9600

#include <avr/delay.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <avr/io.h>
#include <avr/sfr_defs.h>


#define stopsign '!'
#define startsign '&'
char inStr[500];
int inCnt = 0;

// -- METHODEN DEKLARATIONEN
void keep_moving(void);
void move(int servo, int pos);
void calc_steps(void);
int putChar(char c);
int signum(int val);
void uart_init(int tx, int rx);
uint8_t uart_readChar(void);
void parseInput(void);



// -- SERVO VARIABLES
volatile uint8_t servo_flag = 0;

volatile float shoulder_pos = 127.0;
volatile float elbow_pos = 127.0;
volatile float wrist_pos = 127.0;
volatile float gripper_pos = 127.0;

volatile uint8_t shoulder_dest = 255;
volatile uint8_t elbow_dest = 1;
volatile uint8_t wrist_dest = 127;
volatile uint8_t gripper_dest = 250;

volatile float shoulder_step = 0;
volatile float elbow_step = 0;
volatile float wrist_step = 0;
volatile float gripper_step = 0;


int main (void) {

//TIMER-IINTERRUPT AN
TCCR0 |= (1<<CS01) | (1<<CS00);
TIMSK |= (1<<TOIE0);

//UART-INTERRUPT AN
UCSRB |= (1<<RXCIE);

//UART INITIALISIEREN (RX UND TX ANSCHALTEN)
uart_init(1, 1);

//GLOBAL INTERRUPT AN
sei();


//PRINTF FÜR AUSGABE KONFIGURIEREN
fdevopen(putChar,NULL,0);
printf("\n\n\rSTART !!!\n\r");

//HAUPTSCHLEIFE
while(1)
{
//NUR AUFRUFEN, WENN EIN TIMER INTERUPT DA WAR
if(servo_flag == 1) {
cli();
calc_steps();
keep_moving();
sei();
}
}
return 0;
}


// -- METHODEN ZUM BEWEGEN DER SERVOS
void keep_moving() {

//CALCULATE NEW POSITIONS
shoulder_pos = shoulder_pos + shoulder_step;
elbow_pos = elbow_pos + elbow_step;
wrist_pos = wrist_pos + wrist_step;
gripper_pos = gripper_pos + gripper_step;

//SET STEP=0 IF DEST. POSITION WAS REACHED
if( (int)(shoulder_pos) == shoulder_dest){ shoulder_step = 0; }
if( (int)(elbow_pos) == elbow_dest) { elbow_step = 0; }
if( (int)(wrist_pos) == wrist_dest) { wrist_step = 0; }
if( (int)(gripper_pos) == gripper_dest) { gripper_step = 0; }

//POSITIONEN SCHICKEN
move(1, (int)shoulder_pos);
move(2, (int)shoulder_pos);
move(3, (int)elbow_pos);
move(4, (int)wrist_pos);
move(5, (int)gripper_pos);

servo_flag = 0;
}
void calc_steps(void) {
float shoulder_to_go = shoulder_dest - shoulder_pos;
float elbow_to_go = elbow_dest - elbow_pos;
float wrist_to_go = wrist_dest - wrist_pos;
float gripper_to_go = gripper_dest - gripper_pos;

float shoulder_absolute = abs(shoulder_to_go);
float elbow_absolute = abs(elbow_to_go);
float wrist_absolute = abs(wrist_to_go);
float gripper_absolute = abs(gripper_to_go);

shoulder_step = 1;
elbow_step = 1;
wrist_step = 1;
gripper_step = 1;


//GET GREATEST VALUE
uint8_t largest_way_servo = shoulder_absolute;
if(elbow_absolute > largest_way_servo) { largest_way_servo = elbow_absolute; }
if(wrist_absolute > largest_way_servo) { largest_way_servo = wrist_absolute; }
if(gripper_absolute > largest_way_servo) { largest_way_servo = gripper_absolute; }

//SET STEP DEPENDING ON GREATEST VALUE (BIGGEST STEP=1)
shoulder_step = (shoulder_absolute/largest_way_servo) * signum(shoulder_to_go);
elbow_step = (elbow_absolute/largest_way_servo) * signum(elbow_to_go);
wrist_step = (wrist_absolute/largest_way_servo) * signum(wrist_to_go);
gripper_step = (gripper_absolute/largest_way_servo) * signum(gripper_to_go);

}
void move(int servo, int pos){
loop_until_bit_is_set(UCSRA, UDRE);
UDR = '#';
loop_until_bit_is_set(UCSRA, UDRE);
UDR = 's';
loop_until_bit_is_set(UCSRA, UDRE);
UDR = servo;
loop_until_bit_is_set(UCSRA, UDRE);
UDR = pos;
}


// INPUT PARSEN
void parseInput(void) {
if(inStr[0] == 's') {
if(inStr[1] == '1') {
int hundred = 100 * ((int)inStr[2] - 48);
int ten = 10 * ((int)inStr[3] - 48);
int one = (int)inStr[4] - 48;
int pos = hundred + ten + one;
elbow_dest = pos;
}
}
}

//SIGNUM WIRD NUR IN calc_steps BENÖTIGT
int signum(int val) {
if(val != 0) {
return val/abs(val);
} else {
return 0;
}
}

//INTERRUPTS
SIGNAL (SIG_OVERFLOW0){
servo_flag = 1;
}
SIGNAL(SIG_USART_RECV) {
cli();
inStr[inCnt] = uart_readChar();

switch (inStr[inCnt])
{
case (stopsign):
parseInput();
inCnt=0;
break;
case (startsign):
inCnt=0;
break;
default:
inCnt++;
break;
}
sei();
}

// -- UART METHODEN
void uart_init(int tx, int rx) {
UBRRL = (F_CPU/(BAUD_RATE*16l)-1);
if(tx == 1) {
UCSRB |= (1<<TXEN);
}
if(rx == 1) {
UCSRB |= (1<<RXEN);
}
}
int putChar(char c){
while ( !( UCSRA & (1<<UDRE)) );
UDR=c;
return 0;
}
uint8_t uart_readChar(void) {
loop_until_bit_is_set(UCSRA, RXC);
return UDR;
}



Aber irgendwas stimmt nicht.. Er reagiert nicht auf Eingaben. Wenn ich die Zeilen mit move() auskommentiere klappt der Empfang.

Wäre super nett wenn sich das jemand anschauen würde. Es ist viel weniger als es aussieht. Ihr könnt ja die methoden keep_moving() und calc_steps komplett auslassen. Sie funktionieren ja einwandfrei.

mfg
jagdfalke

askazo
15.12.2005, 07:57
Hi!

Zuerst mal wundere ich mich ein wenig über dieses Konstrukt:

//NUR AUFRUFEN, WENN EIN TIMER INTERUPT DA WAR
if(servo_flag == 1) {
cli();
calc_steps();
keep_moving();
sei();

Warum machst Du das über ein Flag und schreibst nicht den ganzen Kram in die Interrupt-Routine?

Was Dein Empfangs-Problem angeht - das wird wohl ein Timing-Problem sein. Der Empfangs-Interrupt bekommt einfach nicht genügend Zeit zum arbeiten.

Versuche doch mal
- Den Timer langsamer laufen zu lassen
- Die Interrupts während der Positionierung nicht global zu deaktivieren.

askazo

jagdfalke
15.12.2005, 16:57
Ich habe irgendwo gelesen, dass man größere Rechenoperationen nicht in die Interruptroutiene schreiben soll, sondern es mit so einem Flag in der Hauptschleife machen soll. Ich glaube es ging darum, dass während der eine Interrupt in Bearbeitung ist sonst alle anderen blockiert werden oder so ähnlich. Aber mit dem cli() und sei() hast du natürlich Recht wenn ich mir das jetzt so überlege. Dadurch ist ja nichts anders als wenn ich es direkt reinschreibe.
Timer langsamer laufen lassen ist schlecht, weil sich sonst die Servos zu langsam bewegen. Dann müsste ich die Steps erhöhen was dann zu starkem rückeln führen würde.
Ich werde das mal testen und dann bescheid sagen, was daraus geworden ist.
Thx
jagdfalke

jagdfalke
15.12.2005, 17:18
Also ich habs jetzt mal so geschrieben (verkürzte Form):


int main (void) {
//TIMER-IINTERRUPT AN
TCCR0 |= (1<<CS01) | (1<<CS00);
TIMSK |= (1<<TOIE0);
//UART-INTERRUPT AN
UCSRB |= (1<<RXCIE);
//UART INITIALISIEREN (RX UND TX ANSCHALTEN)
uart_init(1, 1);
//GLOBAL INTERRUPT AN
sei();
//PRINTF FÜR AUSGABE KONFIGURIEREN
fdevopen(putChar,NULL,0);
printf("\n\n\rSTART !!!\n\r");
//HAUPTSCHLEIFE
while(1)
{
//NUR AUFRUFEN, WENN EIN TIMER INTERUPT DA WAR
if(servo_flag == 1) {
calc_steps();
keep_moving();
}
if(char_flag == 1) {
input();
}
}
return 0;
}

void input(void) {
inStr[inCnt] = uart_readChar();
printf("\nCHAR RECEIVED: %c\n\r", inStr[inCnt]);
switch (inStr[inCnt])
{
case (stopsign):
//parseInput();
inCnt=0;
break;
case (startsign):
inCnt=0;
break;
default:
inCnt++;
break;
}
char_flag = 0;
}

SIGNAL (SIG_OVERFLOW0){
servo_flag = 1;
}
SIGNAL(SIG_USART_RECV) {
char_flag = 1;
}


Die keep_moving()-Methode ist noch fast die selbe. Ich habe nur mal statt dem CoController die Werte zu schicken eine Ausgabe über UART draus gemacht, die einem die momentanen Positionen der Servos angibt.
Die bekomme jetzt auch immer schön regelmäßig Informationen zu den Servopositionen. Wenn ich jetzt ein Zeichen schicke kommt auch "CHAR RECEIVED" allerdings stimmt das Zeichen nie. Entweder piept der PC nur oder es kommt > oder + oder # (das dürften so sie gängigsten sein :D)

Weiß jemand woran das liegt?


mfg
jagdfalke

PicNick
15.12.2005, 18:34
gönne den beiden ein "volatile", nutzt vielleicht nix, schad aber auch nicht
volatile char inStr[500];
volatile int inCnt = 0;

jagdfalke
15.12.2005, 18:36
es hat sich nichts geändert. Was ich aber herausgefunden habe ist, dass Großbuchstaben zwar ankommen, aber immernoch der Piep-Ton vom PC ertönt.

PicNick
15.12.2005, 18:46
mmmhhh.
In einer Uart-Receive ISR Routine ist das mindestens überflüssig
loop_until_bit_is_set(UCSRA, RXC);
du wirst ja aufgerufen WEIL ein Zeichen da ist.

Sind die Zeichen, die du kriegst, überhaupt alle druckbar ? binäre Zeichen < 32 treiben ein Terminal in den Wahnsinn
(bei 0x07 z.B. piepst er )

jagdfalke
15.12.2005, 19:00
wenn ich die Zeile
printf("CHAR RECEIVED: %c\n\r", inStr[inCnt]);
in
printf("CHAR RECEIVED: %i\n\r", (int)inStr[inCnt]);
ändere kommt bei einem kleinen a die Zahl 97. Für b 98 für c 99 usw. Ein großes A bringt 65. Sollte doch stimmen oder?

PicNick
15.12.2005, 19:09
Ganz genau. passt eh alles.
Zum test kannst du ja unterscheiden
if (inStr[inCnt]) < 32)
printf("CHAR RECEIVED: %i\n\r", (int)inStr[inCnt]);
else
printf("CHAR RECEIVED: %c\n\r", inStr[inCnt]);

jagdfalke
15.12.2005, 19:12
aber kleine Buchstaben gehen überhaupt nicht.

PicNick
15.12.2005, 19:17
Das is strange. dann mach mal

if ( (inStr[inCnt]) < 32) || (inStr[inCnt]) > 96) )
printf("CHAR RECEIVED: %i\n\r", (int)inStr[inCnt]);
else
printf("CHAR RECEIVED: %c\n\r", inStr[inCnt]);


Edit: ausgebessert . muh muh !

PicNick
15.12.2005, 19:19
Nochwas: ich bin dann weg. bis morgen !

jagdfalke
15.12.2005, 19:21
immernoch: bei kleinen Buchstaben andere Zeichen oder Piepsen. Bei Großbuchstaben der entsprechende int-Wert, bei Zahlen auch der entsprechende int-Wert.

jagdfalke
15.12.2005, 21:42
Ahh,
sowas ist doch ätzend: scheinbar hat sich das terminal durch die Zeichen aufgehängt, die zur Servobewegung gesendet wurden. Sobald ich das bewegen weg lasse klappt alles.
Dh. irgendwer müsste mir jetzt doch mal beibringen, wie ich TX auf einen anderen Pin verlege, damit das nicht über die selbe Leitung geht, die zur Kommunikation mit dem PC verwendet wird. Gibts da eine Tutorial oder so?

Danke, dass ihr euch den Code angeschaut habt. War ja auch einiges Überflüssiges drin.

mfg
jagdfalke

PicNick
16.12.2005, 07:00
Bei bestimmten Zeichen hängt sich das Terminal auf. ich kann dir aber zeigen, wie du das vermeidest, auch ohne eigene Leitung. ich muß nur vorher einige Wege machen.
Wie ist das mit den kleinbuchstaben gelaufen ?

jagdfalke
16.12.2005, 11:05
Seit dem Neustart des Terminals geht alles wunderbar. Von Großbuchstaben über Kleinbuchstaben bis zu Sonderzeichen geht alles.
Wie kann ich das vermeiden? Ich habe aber gelesen, dass diese avrlibs einen Software UART bereitstellen.

mfg
jagdfalke

PicNick
16.12.2005, 11:18
Wenn du NACH dem senden der Servo-Message (oder sonst was binäres)
schick folgendes, das beruhigt die Nerven vom Terminal wieder
Print "{015}{017}";
Das ist ein <SI> und sicherheitshalber ein <XON>

Ich hatte das gleiche Problem, is damit gelöst.

jagdfalke
16.12.2005, 12:24
bist du dir sicher, dass ich
[code]
printf("{015}{017}");
[/code}
schreiben muss? Du hast ja print ".."; geschrieben. Ist das ne Mischung aus Bascom und C ? Also was muss ich jetzt senden lassen?

PicNick
16.12.2005, 12:33
Mein Fehler,
[code]
print "{015}{017}"; 'BASCOM
printf (%c%c", 15, 17); 'C (= 0x0F, 0x11)
[/code}

jagdfalke
16.12.2005, 12:44
Also irgendwie kommt immer nur noch Müll dabei raus. Das was jetzt dabei raus kommt macht irgendwie überhaupt keinen Sinn und ein Muster ist auch nicht zu erkennen:


#define F_CPU 8000000
#define BAUD_RATE 9600

#include <avr/delay.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <avr/io.h>
#include <avr/sfr_defs.h>


#define stopsign '!'
#define startsign '&'
volatile char inStr[500];
volatile int inCnt = 0;

// -- METHODEN DEKLARATIONEN
void keep_moving(void);
void move(int servo, int pos);
void calc_steps(void);
int putChar(char c);
int signum(int val);
void uart_init(int tx, int rx);
uint8_t uart_readChar(void);
void parseInput(void);
void input(void);


volatile uint8_t char_flag = 0;

// -- SERVO VARIABLES
volatile uint8_t servo_flag = 0;

volatile float shoulder_pos = 127.0;
volatile float elbow_pos = 127.0;
volatile float wrist_pos = 127.0;
volatile float gripper_pos = 127.0;

volatile uint8_t shoulder_dest = 255;
volatile uint8_t elbow_dest = 1;
volatile uint8_t wrist_dest = 127;
volatile uint8_t gripper_dest = 250;

volatile float shoulder_step = 0;
volatile float elbow_step = 0;
volatile float wrist_step = 0;
volatile float gripper_step = 0;


int main (void) {
//TIMER-IINTERRUPT AN
TCCR0 |= (1<<CS01) | (1<<CS00);
TIMSK |= (1<<TOIE0);
//UART-INTERRUPT AN
UCSRB |= (1<<RXCIE);
//UART INITIALISIEREN (RX UND TX ANSCHALTEN)
uart_init(1, 1);
//GLOBAL INTERRUPT AN
sei();
//PRINTF FÜR AUSGABE KONFIGURIEREN
fdevopen(putChar,NULL,0);
printf("\n\n\rSTART !!!\n\r");
//HAUPTSCHLEIFE
while(1)
{
//NUR AUFRUFEN, WENN EIN TIMER INTERUPT DA WAR
if(servo_flag == 1) {
calc_steps();
keep_moving();
}
if(char_flag == 1) {
cli();
input();
sei();
}
}
return 0;
}

void parseInput(void) {
// ANZAHL DER ZEICHEN: inCnt
// INDEX DES LETZTEN ZEICHENS inCnt-1
cli();
printf("\n\rPARSING %s ...\n\r", inStr);
int cnt = 0;
if(inStr[0] == 's') {
printf("SERVO COMMAND FOUND\n\r");
int hundreds = (int)inStr[2]-48;
int tens = (int)inStr[3]-48;
int ones = (int)inStr[4]-48;
int number = hundreds*100 + tens*10 + ones;
printf("NUMBER: %i\n\r", number);
int servo = (int)inStr[1] - 48;
switch(servo) {
case(1):
shoulder_dest = number;
printf("\n\rSHOULDER_DEST CHANGED\n\r");
break;
case(2):
elbow_dest = number;
printf("\n\rELBOW_DEST CHANGED\n\r");
break;
case(3):
wrist_dest = number;
printf("\n\rWRIST_DEST CHANGED\n\r");
break;
case(4):
gripper_dest = number;
printf("\n\rGRIPPTER_DEST CHANGED\n\r");
}
}
sei();
}

void input(void) {
inStr[inCnt] = uart_readChar();

switch (inStr[inCnt])
{
case (stopsign):
parseInput();
inCnt=0;
break;
case (startsign):
inCnt=0;
break;
default:
inCnt++;
break;
}

char_flag = 0;
}


// -- METHODEN ZUM BEWEGEN DER SERVOS
void keep_moving() {

//CALCULATE NEW POSITIONS
shoulder_pos = shoulder_pos + shoulder_step;
elbow_pos = elbow_pos + elbow_step;
wrist_pos = wrist_pos + wrist_step;
gripper_pos = gripper_pos + gripper_step;

//SET STEP=0 IF DEST. POSITION WAS REACHED
if( (int)(shoulder_pos) == shoulder_dest){ shoulder_step = 0; }
if( (int)(elbow_pos) == elbow_dest) { elbow_step = 0; }
if( (int)(wrist_pos) == wrist_dest) { wrist_step = 0; }
if( (int)(gripper_pos) == gripper_dest) { gripper_step = 0; }

//POSITIONEN SCHICKEN
move(1, (int)shoulder_pos);
move(2, (int)shoulder_pos);
move(3, (int)elbow_pos);
move(4, (int)wrist_pos);
move(5, (int)gripper_pos);
printf("%c%c", 15, 17);

printf("POSITION:\tSHOULDER:%i \tELBOW:%i \tWRIST:%i \t GRIPPER:%i\n\r", (int)shoulder_pos,(int)elbow_pos,(int)wrist_pos,(i nt)gripper_pos);


servo_flag = 0;
}
void calc_steps(void) {
float shoulder_to_go = shoulder_dest - shoulder_pos;
float elbow_to_go = elbow_dest - elbow_pos;
float wrist_to_go = wrist_dest - wrist_pos;
float gripper_to_go = gripper_dest - gripper_pos;

float shoulder_absolute = abs(shoulder_to_go);
float elbow_absolute = abs(elbow_to_go);
float wrist_absolute = abs(wrist_to_go);
float gripper_absolute = abs(gripper_to_go);

shoulder_step = 1;
elbow_step = 1;
wrist_step = 1;
gripper_step = 1;


//GET GREATEST VALUE
uint8_t largest_way_servo = shoulder_absolute;
if(elbow_absolute > largest_way_servo) { largest_way_servo = elbow_absolute; }
if(wrist_absolute > largest_way_servo) { largest_way_servo = wrist_absolute; }
if(gripper_absolute > largest_way_servo) { largest_way_servo = gripper_absolute; }

//SET STEP DEPENDING ON GREATEST VALUE (BIGGEST STEP=1)
shoulder_step = (shoulder_absolute/largest_way_servo) * signum(shoulder_to_go);
elbow_step = (elbow_absolute/largest_way_servo) * signum(elbow_to_go);
wrist_step = (wrist_absolute/largest_way_servo) * signum(wrist_to_go);
gripper_step = (gripper_absolute/largest_way_servo) * signum(gripper_to_go);

}
void move(int servo, int pos){
loop_until_bit_is_set(UCSRA, UDRE);
UDR = '#';
loop_until_bit_is_set(UCSRA, UDRE);
UDR = 's';
loop_until_bit_is_set(UCSRA, UDRE);
UDR = servo;
loop_until_bit_is_set(UCSRA, UDRE);
UDR = pos;
}


//SIGNUM WIRD NUR IN calc_steps BENÖTIGT
int signum(int val) {
if(val != 0) {
return val/abs(val);
} else {
return 0;
}
}

//INTERRUPTS
SIGNAL (SIG_OVERFLOW0){
servo_flag = 1;
}
SIGNAL(SIG_USART_RECV) {
char_flag = 1;
}

// -- UART METHODEN
void uart_init(int tx, int rx) {
UBRRL = (F_CPU/(BAUD_RATE*16l)-1);
if(tx == 1) {
UCSRB |= (1<<TXEN);
}
if(rx == 1) {
UCSRB |= (1<<RXEN);
}
}
int putChar(char c){
while ( !( UCSRA & (1<<UDRE)) );
UDR=c;
return 0;
}
uint8_t uart_readChar(void) {
return UDR;
}

PicNick
16.12.2005, 12:55
Du, werd' das abend zu Hause einfach mal probieren.
Sag mir kurz, was ich eingeben muß
"&s1NNN|"
& start
| end
s Kennzeichen
1 servonummer 0-9
NNN eine Position

stimmt das ?

jagdfalke
16.12.2005, 13:03
ja zB "s1001" heißt, dass er Servo 1 zur Position 001 also 1 bewegen soll. Startzeichen ist "&", Stopzeichen ist "!".
Danke!

PicNick
17.12.2005, 14:08
hallo, spät, aber doch !
Leider bin ich in der Vorweihnachtszeit nicht Herr meiner selbst, tut leid.

Anbei gezippt das Projekt. Vorsicht: ich hab mega32 mit 8 MHZ also ev. ausbessern.

Das tut jetzt, was es soll.

Damit ich was sehen kann, hab ich ein paar Terminal steuerungen eingebaut, du mußt etweder dein terminal auf VT100-Mode einstellen oder das Zeugs rauslöschen.
Ein paar sachen hab ich hin- und hergeschoben, aber du solltest dein Programm noch erkennen können

jagdfalke
18.12.2005, 16:37
Hi,
ich hab auch atmega32 und 8MHz also sollte das schon stimmen. Ich hab im Makefile mal meinen Programmer auf stk200 angepasst und /dev/parport0 statt com1 angegeben. Man kann es auch hochlagen auf den Controller. Das ganze Programm funktioniert auch wunderbar, solange man kein Terminal anschaltet. Wenn ich es anhabe springen die Servopositionen ab und zu mal hin und her. Eingaben von mir haben überhaupt keine Auswirkung. Was soll eigentlich der Spaß mit dem clear screen und terminal cursor? Und was ist VT100? Vielleicht liegts ja daran.

mfg
jagdfalke

jagdfalke
18.12.2005, 17:25
Ahh, ich musste das Terminal auf ANSI stellen. Weiß zwar nicht warum aber es geht jetzt. Nur ein Problem gibts noch: Die Servos bewegen sich jetzt nur seeehr langsam. Hängt das mit den vielen Zeichen zusammen, die z.B. für dieses clear screen gesendet werden müssen? Hab schon den Timer auf CPU-Takt gesetzt, hat aber auch nicht viel geholfen. Man könnte doch die Baud-Rate erhöhen oder? Aber da spielt der Servotreiber wieder nicht mit :(
Naja, jetzt hab ich ja schonmal was vorzeigbares. Danke für die Hilfe !

WOW, hab grad noch was bemerkt: Wärend ich Zeichen sende, setzen die Servos machmal aus. Also die brechen für ne 10tel Sekunde komplett zusammen und sind dann wieder auf der gewünschten Position. Kann es sein, dass sich der CoController mit dem Servotreiber kurz aufhängt und sich selber ein RESET gibt?

mfg
jagdfalke

PicNick
19.12.2005, 08:32
Die Servos bewegen sich jetzt nur seeehr langsam.
Während ich Zeichen sende, setzen die Servos machmal aus.
Kann es sein, dass sich der CoController mit dem Servotreiber kurz aufhängt und sich selber ein RESET gibt?

Der CoController RNS1 od. RNSX macht die Servosteuerung selbstätig und Interruptgesteuert. Solche Effekte sind da eher nicht möglich.
Wenn sich die Servos zu langsam bewegen, dann sind wahrscheinlich die Schritte zu klein.
Denk mal: Du kannst einem Servo höchstens 50 Positionen in einer Sekunde übermitteln. (alle 20mS eine neue) das Übertragen EINER Position bei 9600 dauert ~ 4mS d.h. das reicht locker.

Du mußt jetzt deine Positions- und Schrittberechnung insgesamt mal genau anschauen.

jagdfalke
19.12.2005, 14:47
Das Zucken lag daran, dass ich nicht überprüft habe, ob der neue Wert zwischen 1 und 255 liegt.
Jetzt gehts gut!


Du musst jetzt deine Positions- und Schrittberechnung insgesamt mal genau anschauen.
Ich hab es jetzt anders gemacht: Der Betrag vom Step ist immer 1 und de Richtung wird bestimmt indem ich den signum-Wert dranmultipliziere.
Jetzt ist es schon ein wenig schneller. Aber immernoch nicht zufriedenstellend. Klar ich könnte den Schritt standardmäßig auf 2 oder höher stellen aber aber dann ruckelts wahrscheinlich sehr, oder? Bevor ich mir die Arbeit mache die Probleme, die durch einen 2er-Schritt zustandekommen, zu lösen, wollte ich erstmal Fragen ob das die einzige Methode ist um das ganze schneller zu bekommen.
Nur damit ihr wisst um welche langsame Geschwindigkeit es sich hier handelt: Um von 1 bis 255 zu laufen braucht er ca 27 Sekunden :S

mfg
jagdfalke

jagdfalke
19.12.2005, 18:03
Frage: Wie kommen denn solce Outputs im Terminal zustande ???


POSS DESTT
200 2007
127 127!
1277 127
1>7 1277
#sOA<#soA<

Da baut er irgendwie Mist, wenn ich was eingeben. Bei solchen Dingern kommen dann auch diese Zuckungen zustande.

"POSS" == "POS"
"DESTT" == "DEST"
manchmal kommt aber auch ein anderer Buchstabenmix raus.
Die Nummern sollten eigentlich so aussehen:
200 200
127 127
127 127
127 127

mfg
jagdfalke

PicNick
19.12.2005, 18:38
Ja, kommt daher, daß das Programm besonders im output-bereich ein absoluter Schnellschuss war(ist). da wird kreuz und quer "printf" oder UDR= gemacht, ohne sich aufeinander abzustimmen. Ist mehr Arbeit und Gefummel, als man meinen möchte.
Perfekterweise, wenn man beim Terminal-output bleibt, macht man auf kariertem Papier ein Konzept, was wo und wie lang auf dem Schirm stehen soll, und dann fummelt man halt rum.

Zuerst müßt mal auch mal alle "Kontroll" printf rausnehmen, die ja nur zeigen sollten, was und wo das Programm sich grad rumtreibt. das wissen wir ja jetzt so ziemlich, jetzt gehören andere Dinge gecheckt und herzgezeigt

jagdfalke
19.12.2005, 19:49
Zu dem Zeitpunkt als der gepostetet output gekommen ist hatte ich schon alle printfs entfernt.
Dieses "#sOA<#soA<" zeigt doch eigentlich, dass irgendwas dazwischen gefprintet wird wärend er die Servoposition übermittelt, oder? Soll ich da einfach cli()-sei() drum rum machen? Aber dann könnte es wieder sein, dass er Eingaben nicht registriert. Damn.

Zur Geschwindigkeit: Wenn ich das printf, das die Positionen ausgibt weglasse, ist er mind. doppelt so schnell. Naja, wäre trotzdem gut wenn wir ne andere Möglichkeit finden würden das schneller zu machen, denn irgendwann sollen die Daten vom PC empfangen werden.

Im Anhang nochmal der modifizierte Code

PicNick
20.12.2005, 10:40
So, ich hab ein wenig umgerührt und "streamlined"

Was auf jeden Fall den Schirm stört, ist das Echo vom Inky. Hab ich mal auskommentiert, wir wissen ja, daß es geht.

Die Input-Prüfung und verteilung hab ich gleich in die ISR reingegeben, is einfacher und man muß bei der Position nicht mehr führende Nullen eingeben.

Ich kann es im Moment hier mangels AVR zwar kompilieren, aber nicht testen.

jagdfalke
20.12.2005, 17:50
Danke, aber du kannst es nicht ausprobieren und ich nicht kompilieren :O


linux:/home/mathias/makefile und load/roboterarm steuerung/Falke # make all
.dep/falke.o.d:1: *** Mehrfache Target-Muster. Schluss.


mfg
jagdfalke

PicNick
20.12.2005, 18:17
Da steht wohl in der makefile irgendein Brimsen drinnen ?
"Mehrfache Targetmuster" ?
ich kenne z.B. tapeten-muster, was meint er ?
Na ich schau' mal.

PicNick
20.12.2005, 18:56
Na ich hab kompiliert und inzwischen schon getestet
Geht pipifein ! kein problem mit make ??????
nimm einfach den ganzen projektkrempel aus der Zip, ist alles aktuell

Man muß zwar blind eingeben, weil kein Echo mehr da ist.
Ich hab' drei Servos angehängt, die bewegen sich auch.

Lad einfach das Hex !

jagdfalke
20.12.2005, 21:07
Also ich entpacke einfach nur das File und mach make program in dem Ordner. Aber immernoch exakt die selbe Fehlermeldung :(

PicNick
21.12.2005, 06:53
Na dann mach doch eine neu makefile, das kann's ja nicht sein

SprinterSB
21.12.2005, 15:06
Lösch das falke.o.d

jagdfalke
21.12.2005, 15:30
Tatsächlich, das wars. Einfach das falke.o.d weg und schon gehts.
Kannst du auch erklären warum? Ich versteh das nämlich nicht,

mfg
jagdfalke

PicNick
21.12.2005, 15:45
Ich hab's aufgegeben, Computer verstehen zu wollen. Mir reicht's, wenn er mich versteht, sonst gibt's eins auf die Glocke.

jagdfalke
21.12.2005, 15:48
So kann mans natürlich auch sehen. Allerdings liegt es leider immer an menschlicher Unvollkommenheit wenn was nicht funktioniert.

Naja, jedenfalls danke, dass du dir so viel Mühe gemacht hast. Sag mal, wo ist eigentlich beschrieben, was man an ein Terminal senden muss, damit z.B ein "clear screen" gemacht wird?

mfg
jagdfalke

PicNick
21.12.2005, 15:50
Da schau, da hab' ich mir die Finger wund geschrieben.

https://www.roboternetz.de/wissen/index.php/Terminals#Terminalsteuerung_ANSII

jagdfalke
21.12.2005, 15:52
Wow, das werde ich mir mal reinziehn. Thx,

jagdfalke
23.12.2005, 10:05
Hab noch ne Frage: Wenn ich in dem .c-File was ändere und versuche es neu zu kompilieren kommt das hier:


linux:/home/mathias/makefile und load/roboterarm steuerung # make all

-------- begin --------
avr-gcc (GCC) 4.0.2
Copyright (C) 2005 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Size before:
falke.elf :
section size addr
.text 3788 0
.data 38 8388704
.bss 19 8388742
.noinit 0 8388761
.eeprom 0 8454144
.stab 7008 0
.stabstr 3505 0
.debug_aranges 20 0
.debug_pubnames 440 0
.debug_info 780 0
.debug_abbrev 216 0
.debug_line 710 0
.debug_str 415 0
Total 16939




Compiling: falke.c
avr-gcc -c -mmcu=atmega32 -I. -gdwarf-2 -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=falke.lst -std=gnu99 -MD -MP -MF .dep/falke.o.d falke.c -o falke.o
falke.c:1: error: target system does not support the "dwarf-2" debug format
make: *** [falke.o] Fehler 1



Was zum Henker soll das?

mfg
jagdfalke

PicNick
23.12.2005, 10:16
Irgendwo in der Makefile steht "DEBUG = dwarf-2"
das macht ihn offenbar nervös.
Beim Makefileprogram mußt du dir bei "DEBUG Format" was anderes aussuchen. wahrscheinlich probieren, ich weiss auch nix besseres.

https://www.roboternetz.de/wissen/index.php/Avr-gcc

Schau mal, vielleicht steht da was

jagdfalke
23.12.2005, 10:19
ahja, habs in "stabs" geändert. jetzt gehts.
Thx.