PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Odometrie Problem [Hirn Fatal ERROR]



listner
03.04.2008, 21:41
Hi leute,
ich hab mich nun an die Odometrie gewagt um gleich entäuschung zu erleben :(
ich steh heute mit dem gesammten prggen iwie auf dem schlauch sry xD
hier der code:

#include "asuro.h" // Linienverfolgung auf die einfachste Art

unsigned int data[2];
unsigned char s[5] = "thze\0";

void PrintCharR(unsigned int x)
{
unsigned char einer, zehner, huni, tausend;
x = data[1];

einer=x%10;
zehner=(x-einer)/10;
huni=(x-(zehner*10+einer))/100; //nicht mit %, da "%" zu viel speicher brauch

if((x == 1000) || (x > 1000))
tausend= 1;
else
tausend= 0;

s[0]=huni+'0';
s[1]=zehner+'0';
s[2]=einer+'0';
s[3]=tausend+'0';

SerWrite(s,5);
}


int main(void)
{
Init();

unsigned char a[4];
int i=0;

while(1)
{
OdometrieData(data); // aktuelle Helligkeitswerte der Fototransistoren einlesen

SerWrite("Rechter Fototransistor: ",24); //Wert des Rechten Fototranistors Senden
PrintCharR(a);
SerWrite("\r\n\n",3);

for (i=0; i<2000; i++) //5 Sekunden Pause
{
Sleep(72);
}
}
return 0;

}

iwas passt nicht..

zwar: ich möchte zunächst die Odometrie von "von hand" testen. d.h. der asouro sol über serwrite alle paar sec. den odo wert über IR senden..

ich werde das rad von hand bewegen um schwarze bzw. weise fläche anzuzeigen...

iuch hoffe ihr könnt mir helfen.. und versteht was ich meinxD

gruß

Ceos
04.04.2008, 11:10
tausend = x/1000;
x = x%1000;
hunni = x/100;
x = x%100;
zehner = x/10;
x = x%10;
einer = x;

du arbeitest hier mit ganzahldivision also brauchste nachkomma net beachten

damaltor
04.04.2008, 16:43
diese prozedur dauert dafür SEHR lange und ist extrem speicherfressend...

listner
04.04.2008, 16:51
diese prozedur dauert dafür SEHR lange und ist extrem speicherfressend...

wenn Ceos' möglichkeit nicht so ideal ist, was für möglichkeiten gibt es dann noch??

plz help me :P

Ceos
04.04.2008, 17:07
das würede mich auch uinterssieren ... vor allem WAS ist so speicehrfressend ? das modulo ?

listner
04.04.2008, 17:10
das würede mich auch uinterssieren ... vor allem WAS ist so speicehrfressend ? das modulo ?

jap, das modul ist speicherfressend, aber es muss ja noch andere möglichkeiten geben, meine sollte eig. funktionieren. aber da ist irgendwo ein "Hintergrund fehler" drinne. ich steh zz auf dem schlauch *schnell mal hinsetz*

das mit dem modul wuste ich shcon, aus nem versuch der Linienfolgung (siehe anderer Tread von mir)

an was liegt das mein code nicht funzt?

damaltor
04.04.2008, 18:14
modulo benutzt fliesskomma-arithmetik. das dauert sehr lange und braucht speicher. funktionieren sollte es trotzdem, auch wenn eine bemerkbare pause an dieser stelle auftreten kann.

Sternthaler
04.04.2008, 18:18
Hallo listner,

wie wäre es einfach mit den Funktionen aus der LIB:


void UartPutc (
unsigned char zeichen)
{
UCSRB = 0x08; // enable transmitter
UCSRA |= 0x40; // clear transmitter flag
while (!(UCSRA & 0x20)) // wait for empty transmit buffer
;
UDR = zeichen;
while (!(UCSRA & 0x40)) // Wait for transmit complete flag (TXC)
;
}


void SerPrint (
unsigned char *data)
{
unsigned char i = 0;

while (data [i] != 0x00)
UartPutc (data [i++]);
}


void PrintInt (
int wert)
{
char text [7]; // "-12345"

itoa (wert, text, 10);
SerPrint (text);
}
Ist zwar auch nicht der winzigklein-Programmcode, aber im Moment scheint dein Programm ja noch nicht allzu lang zu sein ;-)

Du nutzt dann void "PrintInt (data[0]);" in deinem main(), und gut ist. Hoffe ich.

Gruß Sternthaler

Ceos
04.04.2008, 21:03
an dem sleep erkennt man das er nicht die 2.7er asurolib benutzt also wird er das vermutlich nicht haben

EDIT um diesem post noch einen sinn zu verleihen ... lad dir die asuro lib 2.71 installier sie und arbeite damit, da ist n haufen zeug bei was du brauchen kannst

listner
04.04.2008, 21:49
@ ceos
ich möchte gerne ohne die neuen libs arbeiten, dies ist der grund damit ich proggen besser leren. desshalb versuche ich "alles" selber zu schreiben
:P ich hoffe das ist i.o. ;)
kann mir noch jemand helfen :P

robo.fr
05.04.2008, 17:31
Eigentlich will ich gar nicht "Haare spalten", aber weil's mir so ins Auge sticht:


dies ist der grund damit ich proggen besser leren.

der Lehrer könnte dem Schüler etwas lehren,
der Schüler könnte viel mehr lernen

und später ein Flasche leeren

listner
05.04.2008, 18:37
@ robo.fr jop sry verschrieben hehe ;)

kann mir niemand helfen?

Sternthaler
06.04.2008, 01:54
Hallo zusammen


an dem sleep erkennt man das er nicht die 2.7er asurolib benutzt also wird er das vermutlich nicht haben

EDIT um diesem post noch einen sinn zu verleihen ... lad dir die asuro lib 2.71 installier sie und arbeite damit, da ist n haufen zeug bei was du brauchen kannst
Ja, das ist gut, dass du noch einen Sinn dranhängst.
Denn: Wenn du mal schaust, habe ich ja in meinem Post genau die benötigten Funktionen 'beigelegt'. ;-)

@robo.fr
Ich stimme für leeren.


iuch hoffe ihr könnt mir helfen.. und versteht was ich meinxD

kann mir niemand helfen?
Klar können wir helfen. Siehe den Beitrag von Ceos.
Aber ich für meinen Teil habe nicht verstanden wobei wir dir noch helfen sollen. Normalerweise gehen wir davon aus, dass du Hilfe zu deinem angegebene Programm willst. -> Hat Ceos vollbracht.
Erkläre hier doch mal was du genau von uns möchtest.

Hier mal Kleinigkeiten zu deinem Code, falls es das ist was du möchtest:

if((x == 1000) || (x > 1000))
tausend= 1;
else
tausend= 0;kannst du besser so schreiben:
if(x >= 1000)
tausend= 1;
else
tausend= 0;

Oder hier würde ich umsortieren:
s[0]=huni+'0';
s[1]=zehner+'0';
s[2]=einer+'0';
s[3]=tausend+'0';nach
s[0]=tausend+'0';
s[1]=huni+'0';
s[2]=zehner+'0';
s[3]=einer+'0';Zumindest passen nun die Variablen-NAMEN zur Stelle. Oder du musst deine Rechnung in andere Variablen schreiben, so dass der Name zur Stelle passt. (Wäre zumindest für andere Leser wie mich dann sehr, sehr hilfreich.)
Bei der Rechnung von Ceos kann man sich auf die Namen der Variablen verlassen.

Gruß Sternthaler

listner
15.04.2008, 13:53
hi leute, hab jetzt mein code bischen übersichtlicher gemacht (war ja ein schönes durcheinander oO)


#include "asuro.h" // Odometrie test
unsigned int data[2];
unsigned char s[5] = "thze\0";

void PrintCharR(unsigned int x)
{
unsigned char einer, zehner, huni, tausend;
x = data[1];

einer=x%10;
zehner=(x-einer)/10;
huni=(x-(zehner*10+einer))/100; //nicht mit %, da "%" zu viel speicher brauch

if(x >= 1000)
tausend= 1;
else
tausend= 0;

s[0]=tausend+'0';
s[1]=huni+'0';
s[2]=zehner+'0';
s[3]=einer+'0';


SerWrite(s,5);
}


int main(void)
{
Init();

unsigned char a[5];
int i=0;

while(1)
{
OdometrieData(data); // aktuelle "Position der Odometrie einlesen
a[5] = s[5];

SerWrite("Rechte Odometrie testen: ",24); //Wert der rechten Odometrie Senden
PrintCharR(a);
SerWrite("\r\n\n",3);

for (i=0; i<2000; i++) //5 Sekunden Pause
{
Sleep(72);
}
}
return 0;

}

dennoch funktioniert er immern och nicht, so wie er soll... er spukt über serwrite. "datenmüll" aus. hier mal ein auszug aus dem verlauft:



Rechte Odometrie testen:00M7

Rechte Odometrie testen:00M5

Rechte Odometrie testen:00M6

Rechte Odometrie testen:00M7

Rechte Odometrie testen:00M9

Rechte Odometrie testen:00N2

Rechte Odometrie testen:00N8

Rechte Odometrie testen:00N7

Rechte Odometrie testen:00N8

Rechte Odometrie testen:00N8

Rechte Odometrie testen:00N8

Rechte Odometrie testen:00N9

Rechte Odometrie testen:00N9

Rechte Odometrie testen:00N9

Rechte Odometrie testen:00O0

Rechte Odometrie testen:00O0

Rechte Odometrie testen:00O3

Rechte Odometrie te

Rechte Odometrie testen:00N7

Rechte Odometrie testen:00N8

Rechte Odometrie testen:00N8

Rechte Odometrie testen:00N8

Rechte Odometrie testen:00N8

Rechte Odometrie testen:00O3

Rechte Odometrie testen:00O1

Rechte Odometrie testen:00O4

Rechte Odometrie testen:00O2

Rechte Odometrie testen:00O2

Rechte Odometrie testen:00O2

Rechte Odometrie testen:00O2

Rechte Odometrie testen:00O2

Rechte Odometrie testen:00O2

Rechte Odometrie testen:00O2

Rechte Odometrie testen:00O0



kann mir jemand erklären, warum er an der stelle no den zehnern immer buchstaben schreibt, bzw, warum es einfach nicht so funktioniert, so wie ich mir das vorstelle :) ?

danke im vorraus :)

Ceos
15.04.2008, 14:07
a[5] = s[5];

SerWrite("Rechte Odometrie testen: ",24); //Wert der rechten Odometrie Senden
PrintCharR(a);
SerWrite("\r\n\n",3);
häh ??

a[5] = s[5]; deine arrays sind nur 5 bytes groß der index geht nur von 0 bis 4!!! ausserdem ist das 5te byte sodenn es existieren würde nicht initialisiert, würde also einen zufälligen wert haben

PrintCharR(a) aoll wohl heissen PrintCharR(Data[0 oder 1]) (...weis ncih ob rechts 0 oder 1 war :P)

dein zehner ist x - 4 / 10 bei x = 1234 wäre das also 1234 - 4 / 10 = 123 also kein sinnvoller wert ... zumal ich dir schonmal gesagt habe das du dir das subtrahieren sparen kannst weilö du ganzzahlen verwendest und die nachkommastelle einfach abgeschnitten wird ... in der rechnung mit meinem x würde dein hunni übrigenns 9 ergeben also iss deine rechnung reichlich vermurkst XD ich grübel grad auch über ne bessere lösung als das modulo gedönns, ich meld mich wenn cih was habe

listner
15.04.2008, 14:20
xD .. zuerst danke für die schnelle antwort^^ ;)

2. zu lib 2.7.seht ihr was ich meine mit programmieren lernen?? :P aus diesem grund will ich erst mal mit der jetzigen lib klaar kommen. danach auf die 2.7 wechseln.. denn durch ausprobieren lern ich mehr :)

hai1991
15.04.2008, 14:40
hallo zusammen

ich habe vl eine idee wie man die einzellnen stellen einer zahl ermitteln kann:

ich würde es versuchen mit den tauserndern anzufangen


int zahl; //hier wird die zu untersuchende zahl abgespeichert
int einer, zehner, huni, tausend;

//zerlegen der zahl:
tausend = zahl / 1000; // dividieren durch 1000 ==> tausenderstelle

huni = (zahl - 1000 * tausend) / 100; //subdrahieren der tausender, finden der huni

zehner = (zahl - 1000 * tausend - 100 * huni) / 10 //subdrahieren der tausender und huni, finden der einer

einer = zahl - 1000 * tausend - 100 * huni - 10 * zehner; //subdrahieren von tausender, huni, zehner ==> einerstelle


ich hoffe es funktionier, und entspricht dem, was ihr gesucht habt

mfg hai1991

Ceos
15.04.2008, 15:01
die idee hatte ich auch schon ist aber auch recht rechenintensiv, ich grübel grad mit maskierungen und so rum, es soll ja möglichst effektiv sein, nur leider denk ich verquer und bleib immer stecken XD ...

Sternthaler
16.04.2008, 02:34
Hallo listner, und natürlich auch ein Hallo an alle anderen die Bock haben das hier zu lesen,

deine Buchstaben berechnest du dir selber, da du bei der zehner-Berechnung, wie Ceos ja schon schrieb, noch nicht Fehlerfrei bist.
Prüfe daraufhin auch mal deine huni-Berechnung ;-)

Hier mal als Beispiel einen anderen Wert als den von Ceos, damit du siehst wie du auf das 'M' kommst:

Zahl X=297

einer 7 =X%10 einer + '0' = Zeichen '7'
zehner 29 =(X-einer)/10 zehner + '0' = Hier Zeichen '0' + 29
huni 0 =(X-(zehner*10+einer))/100 huni + '0' = Zeichen '0'
tausend 0 =WENN(X>=1000;1;0) tausend + '0' = Zeichen '0'

Wie du selber nachrechen kannst, kommt bei den Zehnern hier die 29 raus. Die aber auf den ASCII-'0'-Wert von dezimal 48 addiert ergibt dann 77. Das ist dann der Buchstabe 'M'.
Zum Nachrechnen in EXEL kannst du (bei einer deutschen Installation) den Befehl =REST(x;10) nutzen.

Finde ich übrigens sehr gut, dass du nicht 'Fertigfutter' nutzt, sondern erst einmal selber versuchst dem Rätsel auf die Spur zu kommen. \:D/ (Die LIB allerdings solltest du aber nicht aus den Augen verlieren da sie von vielen hier benutzt wird. Fehlt sie dir, kannst du die Programme aus dem Forum nicht runterladen und bei dir probieren.)

Um hier aber mal in die Pötte zu kommen, und damit du das auch (ganz bestimmt) komplett verstehst, hier mal ein Hergang, wie man es machen könnte.


In deinem Kommentar hinter "huni=(x-(zehner*10+einer))/100;" schreibst du, dass du den %-Befehl nicht nutzen möchtest, da er zu viel Speicher brauchen würde.
Du hast diesen Befehl aber schon bei der einer-Berechnung eingesetzt. Das bedeutet dann aber, dass der Programmspeicher für diesen Befehl schon benutzt/verbraucht wird. Dann macht es auch Sinn diese Funktion ruhig mehrfach zu benutzten.
=; Fazit: Entweder nie, oder möglichst häufig eine Funktion benutzen.


Und dann auch noch etwas zur Idee bei den Tausendern anzufangen:
Als erstes eine Frage: Was wäre, wenn in der Zahl Zehntausender drin wären? Upps, das Programm muss dann geändert werden. Nicht schlimm, aber auch nicht schön.

Also doch andersherrum:

Deinen Fehler bei der zehner-Berechnung werden wir gleich ausnutzen!!! Also nicht korrigieren ;-)

Wenn man sich das Ergebnis dieser fehlerhaften Berechnung anschaut, dann ist das ja die ursprüngliche Zahl ohne der letzten Stelle.
Nun ja, auch das ist nur eine Zahl, die wir ja auch noch zerlegen wollen. Auch hier soll die letzte Stelle ermittelt werden um sie danach aber auch wieder abzuschneiden.
Auch dann bleibt wieder nur irgendeine Zahl übrig, die wir schon wieder bearbeiten wollen.
usw. usw. (Hört sich nach einer Aufgabe für eine Schleife an)
Wann ist hier ein Ende in Sicht?
Klar, wenn nach dem Abschneiden der letzten Stelle nichts mehr übrig bleibt.

Kleine Zwischenüberlegung:
Wie viel Platz benötigen wir maximal im Textspeicher? (Deine Variable "unsigned char s[5] = "thze\0";")
Die Zahl x, die 'übersetzt' werden soll wird in deinem Programm in einer "unsigned int"-Variablen gespeichert.
int sind IMMER 16 Bit. Somit 2 ^ 16 - 1 = 65535 als Maximum. Das sind nun 5 Speicherstellen PLUS dem String-Ende-Zeichen '\0' sind somit 6 Speicherstellen, die wir maximal benötigen.
---> unsigned char s[6] = "thze\0";
Aus der Vorbelegung 'thze' machen wir '.....' (sollen 5 Leerzeichen sein), um alle Buchstaben aus der Variablen zu entfernen, da wir gleich in der Schleife nicht mehr alle Stellen bearbeiten werden.
Nun also
unsigned char s[6] = " \0";
Hier ist aber schon ein kleiner Fehlerteufel in C vergraben.
Wenn wir eine String-Variable mit einem in "" eingeschlossenem Text vorbelegen, dann kopieren wir hier eigentlich den Text zwischen den "" in die Variable. Der Text selber ist aber schon mit den doppelten "" eingeschlossen. Da es Text ist, wird automatisch ein '\n' angehängt.
Somit haben wir nun 5 Leerzeichen, das \n und das automatische \n. Das sind nun 7 Zeichen.

Also machen wir es nun richtig(er) mit:

unsigned char s[] = " ";
Wir lassen das \n weg und lassen auch die Größenangabe in der []-Klammer weg. Da kümmert sich der C-Compiler besser drum.

Und nun können wir mit der Schleife anfangen. Sie soll so lange rechnen, solange noch eine Zahl vorhanden ist:
unsigned char s[] = " ";

while (x > 0)
{
}
Oh, oh. Hier ist eine Stolperstelle.
Was ist, wenn wir die Zahl 0 senden wollen? Dann ist x ja von Anfang an schon nicht mehr größer als 0.
Kein Problem: Diesen Sonderfall initialisieren wir gleich in der String-Variablen mit einer 0 am Ende.

Da wir in der Schleife die letzte Stelle unserer Zahl x irgendwie an die richtige Position im Textspeicher schreiben wollen, benötigen wir noch einen Merker an welcher Stelle im Textspeicher wir diese letzte Stelle eintragen müssen. Dieser Merker wird in der Schleife dann bearbeitet, und muss aber vorher natürlich initialisiert werden.
Da wir hinten bei der Zahl x anfangen, muss dieser Merker 'am Ende' vom Textspeicher beginnen. ACHTUNG, nicht ganz am Ende, da das dort stehende '\n' natürlich nicht überschrieben werden darf.
unsigned char s[] = " 0";
unsigned char Position;

Position = sizeof (s) - 2;
while (x > 0)
{
Position--;
}
Dieses sizeof() verbraucht im übrigen keinen Programmspeicher und keine Rechenzeit, da es schon beim compilieren 'ausrechnet' wie groß deine Variable s ist.
Und warum werden 2 abgezogen?
sizeof() liefert den Speicherbedarf der Variablen. Das sind also unsere 4 Leerstellen und die Initialisierungs-0 PLUS dem '\n' = 6.
Wir wollen das '\n' ja nicht überschreiben: Also -1
Und da der Speicher mit der Zahl in der []-Klammer immer bei 0 beginnt zu zählen und somit bei 0 die erste Speicherstelle meint, müssen wir diese Diskrepanz auch noch berücksichtigen. Und das sind unsere -2

Nun ermitteln wir ohne den %-Befehl die letzte Stelle der Zahl x in einer Hilfsvariablen. Auch hier können wir Speicher sparen, und nehmen auch nur eine char-Variable:
unsigned char s[] = " 0";
unsigned char Position;
unsigned char LetzteStelle;

Position = sizeof (s) - 2;
while (x > 0)
{
Position--;
LetzteStelle = x - ( (int)(x / 10) * 10 );
}
So weit so gut. Aber halt! Da ist ein Fehler! Position wird ja schon vor der Schleife auf den letzten sinnvollen Platz im Textspeicher gesetzt. Wenn wir also in der Schleife als erstes da noch einen abziehen, ist die Position ja schon verschoben. Also werden wir das gleich korrigieren!

In diesem Schritt machen wir nun noch 3 Dinge. Zum einen nutzen wir nun deinen 'Fehler'. Dann speichern wir die letzte Stelle auch noch im Textspeicher. Und zu guter letzt 'pusten' wir das Ergebnis auf die Schnittstelle.

unsigned char s[] = " 0";
unsigned char Position;
unsigned char LetzteStelle;

Position = sizeof (s) - 2;
while (x > 0)
{
LetzteStelle = x - ( (int)(x / 10) * 10 );
x = ( x - LetzteStelle ) / 10; // Deinen Rechenfehler nutzen ;-)
s [Position] = LetzteStelle + '0';
Position--;
}
SerWrite (s, sizeof (s) - 1);


;-) Und das war es dann auch schon. ;-)


Und nach der Pflicht natürlich noch die Kür.
Warum funktioniert das Ausrechnen der letzten Stelle ist noch die große Frage?

Da müsste doch eigentlich bei x = 297 dann mit 297 - ( 297 / 10) * 10 ) auch wieder 297 rauskommen.
Der fiese C-Trick hier ist das kleine (int) in der Berechnung.
Das schneidet nämlich alle Nachkommastellen einfach weg. Wir zwingen den Compiler, dass er den Rechenschritt (x / 10) auf alle Fälle nur mit einem Ganzzahlergebnis berechnet. (War auch schon von Ceos angedeutet an anderer Stelle.)
Und dies ist auch das ganze Geheimnis der Funktion.


Wenn du jetzt noch Puste hast, können wir noch die Variable LetzteStelle wegoptimieren.

Was haben wir gerade für einen Trick mit dem (int) gesehen?
Die Rechnung (int)(x / 10) hatte ja schon 'von ganz alleine' die letzte Stelle abgeschnitten. Genau dies benötigen wir aber nun nur noch in deiner 'falschen' Rechnung.

Wenn wir also in der Zeile nur:
x = ( x ) / 10; // Deinen Rechenfehler nutzen
schreiben, dann schneidet auch diese Zeile die letzte Stelle weg, weil unsere Zielvariable x ja auch nur int-Zahlen speichern kann. Wir müssen uns die letzte Stelle hierfür somit nicht merken.

Auch das Speichern der berechneten letzten Stelle können wir schon in der Rechenzeile selber machen. Hier benötigen wir also diese Variable auch nicht mehr.
Und nun wirklich zu guter letzt, kann auch die Initialisierung der Variablen Position verschoben werden an die Stelle, wo wir die Variable 'erfinden'. Und das -- für die Position kann auch noch an anderer Stelle gemacht werden.

Daraus ergibt sich nun:

unsigned char s[] = " 0";
unsigned char Position = sizeof (s) - 2;

while (x > 0)
{
s [Position--] = x - ((int)(x / 10) * 10) + '0';
x /= 10;
}
SerWrite (s, sizeof (s) - 1);


Ach du meine Güte, ist das eine Minifunktion geworden. Und die ist so auch nicht mehr leicht zu verstehen. Wichtig hier ist also eine gute Kommentierung vom Code. (Lassen wir hier jetzt aber weg.)
Und du weißt nun wie man so etwas demnächst selber machen kann ;-). Zumindest hoffe ich das du mir folgen konntest.
Wenn nicht, dann frag natürlich und probiere auf alle Fälle weiterhin selber alles aus.

Gruß Sternthaler

pinsel120866
16.04.2008, 10:16
WOW Sternthaler,

ich möchte nicht wissen wie lange du für diesen ausführlichen Post gebraucht hast. Gratulation - wie immer hochintelligent und humorvoll erklärt, noch dazu um diese Uhrzeit!

[DENKBLASE] Ich wünschte mir würde auch mal einer beim meinem Problem mit der 2er IR-LED das so ausführlich erklären...

Sternthaler
17.04.2008, 01:52
Hallo pinsel120866,
vielen Dank für dein fettes Lob.

Ob das aber wirklich intelligent ist? Eher ein paar Jährchen Erfahrung.
Und nur das fehlt ja listner. Alter: 17. Alle Achtung für die Energie in diesem Alter. Dito bei hai1991 mit gerade 16 Jahren. Bei Ceos tippe ich eher ne Ecke höher?
listner, du schreibt ja, dass du gerne selber auf eine Lösung kommen willst.
Und da stellt sich mir dann die Frage, ob ihr überhaupt so einen Vortrag haben wollt?

Na, und wie lange ich da dran rumgetippert habe geht keinen etwas an ;-).
Wenn ich jetzt Gedanken lesen könnte, dann würde ich nach einem Link oder Titel fragen.

Gruß Sternthaler

Ceos
17.04.2008, 11:16
ich dachte ich hätt mein profil um die wichtigsten daten ergänzt :p sollte jetzt richtig sein!

pinsel120866
17.04.2008, 11:53
Hi Sternthaler,

also wenn du mich fragst ob ich deine Vorträge will, kann ich nur sagen: JA, GERNE!

Meine Gedanken drehen sich derzeit um dies:
https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=27368&start=22

listner
17.04.2008, 12:59
Hallo pinsel und hallo Sternthaler und die anderen natürlich auch :)
....

Gratulation - wie immer hochintelligent und humorvoll erklärt, noch dazu um diese Uhrzeit!

^^ dem stimm ich voll und ganz zu!!

...

nun zu deinem post sternthaler:

Alle Achtung für die Energie in diesem Alter

vielen dank!!


Und da stellt sich mir dann die Frage, ob ihr überhaupt so einen Vortrag haben wollt?

ja, dein post ist mir sehr wilkommen,
jedoch überschreitet er meine "programmiertechnische verständniss" aus- diesem grund möchte ich noch folgendes sagen, befor ich mit deiner idee rumexperimentiere:

zu:
In deinem Kommentar hinter "huni=(x-(zehner*10+einer))/100;" schreibst du, dass du den %-Befehl nicht nutzen möchtest, da er zu viel Speicher brauchen würde.
Du hast diesen Befehl aber schon bei der einer-Berechnung eingesetzt. Das bedeutet dann aber, dass der Programmspeicher für diesen Befehl schon benutzt/verbraucht wird. Dann macht es auch Sinn diese Funktion ruhig mehrfach zu benutzten.
Speak to the hand Fazit: Entweder nie, oder möglichst häufig eine Funktion benutzen.

d.h. is soll den modul befehl entweder garnix benutzen, oder ruhig mehrmals?? ... wird der benötigte speicher im IC nicht addiert?

zu:
Was wäre, wenn in der Zahl Zehntausender drin wären?
laut der Asuro Manual kann der wert nur im bereich 0-1023 liegen, aus diesem grund habe ich diese möglichkeit in erwägung gezogen...


nundenn. jetzt werde ich erst mal versuchen meinen asuro nach Sternthalers vorschlag zum laufen zu bringen.. wen einem noh etwas einfällt. bitte melden :) ich werde schreiben, sobald ich entweder niederschläge erleide, oder einen schritt weiter binn =)

gruß

listner
17.04.2008, 15:55
boaa. ich raffs einfach nicht. ich hab bestimmt 2 std lang dein post gelesen.. aber meine c fähigkeiten reichen einfach nicht aus, um dies zu verstehen xD

ausdiesem grund habe ich einfach mal die formeln zum berechnen der huni/zehner/einer usw. verändert. aber der gleiche ***** kommt raus.
hier der neue code:


#include "asuro.h" // Odometrie test
unsigned int data[2];
unsigned char s[5] = "thze\0";

void PrintCharR(unsigned int x)
{
unsigned char einer, zehner, huni, tausend;
x = data[1];

tausend=x/1000;
///////////huni
if(x>=1000)
huni=(x-1000)/100;
else
x/100;
zehner=(x-((tausend*1000)+(huni*100)))/10;
einer=x-((tausend*1000)+(huni*100)+(zehner*10));

s[0]=tausend+'0';
s[1]=huni+'0';
s[2]=zehner+'0';
s[3]=einer+'0';


SerWrite(s,5);
}


int main(void)
{
Init();

//unsigned char a[5];
int i=0;

while(1)
{
OdometrieData(data); // aktuelle "Position der Odometrie einlesen
//a[5] = s[5];

SerWrite("Rechte Odometrie testen: ",24); //Wert der rechten Odometrie Senden
PrintCharR(s);
SerWrite("\r\n\n",3);

for (i=0; i<2000; i++) //5 Sekunden Pause
{
Sleep(72);
}
}
return 0;

}

wäre nice, wenn mir das nochmal einer erklären könnte. wie ich das mit dem "m" weck kriege xD .. oder am besten wenn mir jemand die icq gibt. nicht dass das forum noch voll gespamt wird von mir mit (hilfe ich blicks nicht) trheads :P

danke xD

Ceos
17.04.2008, 23:10
zu dem modulo, wenn du einmal "etwas" benutzt wird der assemblercode auch nur einmal angelegt, und bei mehrfacher verwendung wird dann auch immer auf diesen "block" gesprungen, versuch die methode von hai1990 auf seite 1, die ist zwar auch etwas codeintensiv aber wenn du von den werten 0-1023 ausgehst isses in ordnung

listner
18.04.2008, 13:54
hi,
naja, so wie hai1990 habe ich es im prinzip im 2 versuch gemacht, es funktioniert dennoch nicht. ich habe beim besten willen keine ahnung, an was das liegne könnte :(
wenn jemand den fehler erkennt hatt, bitte sagen :)
gruß

Ceos
18.04.2008, 14:14
da steht noch IMMER
PrintCharR(s);

du willst aber entwerder
data[0] oder data[1] ausgeben .... ansonsten kannst du dir die if abfrage mit dem x >= 1000 sparen nimm lieber das exakte beispiel vom hai

also


tausend = x/1000;
hunni = (x-(tausend*1000))/100;
zenher = (x-(tausend*1000 + hunni*100))/10;
einer = (x-(tausend*1000 + hunni*100 + zehner*10))/10;


EDIT dieser post wurde unter stresseinfluss (ich hasse diesen compiler) geschrieben, eventuelle unfreundlich wirkende aussage sind nicht so gmeint wie sie wirken :p

listner
18.04.2008, 15:08
hi ceos und natürlich auch alle andere!!
ich habe deinen post natürlich gut aufgefasst :) jeder ist mal im stress

endlich habe ich das ergebnis bekommen, das ich so lange ersehnt habe =) :) *freu*

könnte jedoch mir nochmal einer erklären, wie die wertübergabe verläuft, damit serwrite nun endlich den richtigen wert ausgibt? also das berechnen habe ich verstanden. aber nochmal kurzzusammenfassen, wiso/weshalb/warum ich nich direkt die werte der odo ausgeben kann

hier der funktionierende code:

#include "asuro.h" // Odometrie test
unsigned int data[2];
unsigned char s[5] = "thze\0";

void PrintCharR(unsigned int x)
{
unsigned char einer, zehner, huni, tausend;
x = data[1];

tausend = x/1000;
huni = (x-(tausend*1000))/100;
zehner = (x-(tausend*1000 + huni*100))/10;
einer = (x-(tausend*1000 + huni*100 + zehner*10))/10;

s[0]=tausend+'0';
s[1]=huni+'0';
s[2]=zehner+'0';
s[3]=einer+'0';


SerWrite(s,5);
}


int main(void)
{
Init();

//unsigned char a[5];
int i=0;

while(1)
{
OdometrieData(data); // aktuelle "Position der Odometrie einlesen
//a[5] = s[5];

SerWrite("Rechte Odometrie testen: ",24); //Wert der rechten Odometrie Senden
PrintCharR(data[1]);
SerWrite("\r\n\n",3);

for (i=0; i<400; i++) //1 sec pause zwischen jedem erscheinen des odo-wertes
{
Sleep(72);
}
}
return 0;

}

Ceos
18.04.2008, 15:20
in deiner print methode hast du
x = data[1];

zu viel drinne,
das mit der wertübrgabe überlass ich jemand anderen, vll. schreib ich heut nachmittag was dazu aber im moment würde ich nur unverständliches gebrabbel statt ner handfesten erklärung hinbekommen

kurzfassung "data" ist ein array, der bezeicher "data" ist gleichzeitig ein pointer auf den anfang des array, mit den eckigen klammern dahinter greifst du auf die werte des array zu, ACHTUNG indizes starten bei 0 und hören bei n-1 auf wobei n die größe des array ist

deklariert wird ein array entweder
char meinarray[5]; damit habe ich ein array von 5 char index also 0-4

oder

char meinarray[] = "blabla"; hier legt der compiler die größe fest, und zwar 7 nicht 6 !!!! ein asgeschriebener string endet nämlich auf eine binäre 0, also hat "blabla" 7 zeichen
möchtest du die größe eines array erfahren kannst du

sizeof(meinarray);

aufrufen und erhälst die anzahl an speicherplätzen im array

wenn dein array aus word (2 bytes) besteht, bekommst du zwar für
word myarray[5];
sizeof(myarray);
eine 5 raus, aber im speicher liegen 10 byte!!!!
wenn du einen pointer auf das array holst

byte* mypointer = myarray;
wird der compiler zwar warnen weil mypointer byte ist udn myarray word aber erfolgreich compilieren
wenn du jetzt
*(myarray+1) ODER myarray[1]
aufrufst bekommst du den wert an dem index 1 (als an 2ter stelle)
wenn du aber jetzt
*(mypointer+1)
benutzt, bekommst du das highbyte von wert 0 und das lowbyte von wert 1 als neuen wert vorgerechnet

postscript: ih hoffe du hast verstanden was ich meine sonst editier ich das heut nachmittag wenn ich muse habe oder wer anders erklärts besser ^^

listner
23.04.2008, 14:09
ok, danke, ich bin mir zwar nicht sicher ob ich das verstanden habe,
aber die "x=data[1]" habe ich rausgekürzt undüberall wo x verwendet wurde direkt durch "data[1]" ersetzt.
hier der code:

#include "asuro.h" // Odometrie test
unsigned int data[2];
unsigned char s[5] = "thze\0";

void PrintCharR()
{
unsigned char einer, zehner, huni, tausend;

tausend = data[1]/1000;
huni = (data[1]-(tausend*1000))/100;
zehner = (data[1]-(tausend*1000 + huni*100))/10;
einer = (data[1]-(tausend*1000 + huni*100 + zehner*10))/10;

s[0]=tausend+'0';
s[1]=huni+'0';
s[2]=zehner+'0';
s[3]=einer+'0';

SerWrite(s,5);
}

int main(void)
{
Init();

int i=0;

while(1)
{
OdometrieData(data); // aktuelle "Position der Odometrie einlesen

SerWrite("Rechte Odometrie testen: ",24); //Wert der rechten Odometrie Senden
PrintCharR(data[1]);
SerWrite("\r\n\n",3);

for (i=0; i<400; i++) //1 sec pause zwischen jedem erscheinen des odo-wertes
{
Sleep(72);
}
}
return 0;

}

nun nochmals ein paar fragen, damit ich die funktionen allgemein verstehen:


void PrintCharR()
hier in den klammer muss nicht zwingend etwas drinn stehen??
muss die funktion zwingend mit "void" deklariert werden?


PrintCharR(data[1]);
zu was dient das "data[1]" in den klammern??

allgemein:
könnte mir jemand anhand von meinem beispiel versuchen zu erklären, wie der syntax einer funktion... funktioniert??

wäre no1. thx gruß listner

damaltor
23.04.2008, 14:48
ganz grob: zu erst wird die funktion deklariert. 3 beispiele:


void funktionsname(void){verschiedene aktionen};
// diese funktion gibt keinen wert zurück (Beispiel MotorDir();) und benötigt keine werte (Beispiel Init();).

int funktionsname(char wert){verschiedene aktionen; return x;}
//diese funktion gibt einen integer zurück (beispiel PollSwitch) und braucht einen wert um zu arbeiten (beispiel FrontLed();)

char funktionsname(char wert1, char wert2){verschiedene aktionen; return x}
//diese funktion gibt einen wert zurück und braucht zwei werte (Beispiel MotorSpeed();)


anstelle von "verschiedene aktionen" steht der eigentliche inhalt der funktion. hier dürfen dei übegebenen werte (in den beispielen wert, wert1, wert2) verwendet werden. bei funktionen mit rückgabe muss ein wert mit return zurückgegeben werden, dieser kann dann so verarbeitet werden wie zB der Wert von PollSwitch.

um die funktion dann aufzurufen, geht folgendes:


//funktion mit rückgabe, aber ohne übergabe:
variable = funktionsname();

//funktion ohne rückgabe, aber mit übergabe:
funktionsname(a,b);

//funktion mit rückgabe und mit übergabe:
variable = funktionsname(a);


ein komplettes beispiel: wir wollen zwei zahlen addieren. die zahlen werden übergeben und das ergebnis zurückgegeben:



//funktionsdeklaration:
int addieren(wert1, wert2){
int ergebnis = 0;
ergebnis = wert1 + wert2;
return ergebnis;
}

//jetzt ist die funktion definiert und darf in der main-funktion aufgerufen werden. dazu muss sie ÜBER der main funktion im quelltext stehen.

[...]
erstersummand = 4;
zweitersummand = 8;
summe = addieren(erstersummand, zweitersummand);
[...]


jetzt enthält "summe" den von addieren() zurückgegebenen wert.