Archiv verlassen und diese Seite im Standarddesign anzeigen : projekt: asuro sucht selbständig seine ladestation
hi allerseits,
der anfang ist gemacht, das ladegerät als solches funktioniert, wird aber aufgrund von warnungen - die ich allerdings noch hinterfragen möchte - nur beim abgeschalteten asuro verwendet...
Hallo
Sieht gut aus! Das Ladegerät von E-Zahnbürsten ist genauso. Wie soll er die station später finden?
Anderes Thema aber wie kann man Plexi biegen?
mfg palermo
damaltor
15.05.2007, 13:33
lexi vorsichtig erwärmen, und dann vorsichtig biegen. wenn du es zu schnell biegst oder zu stark erwärmst, wird es matt.
das ist ein e-zahnbürsten-ladegerät.
Asuro-n00b
15.05.2007, 16:37
Ja ein Haarföhn bringt da nix.
Aber Plexiglas ist so spröde, dass es nur sehr schwer zu bearbeiten ist.
Bei ner einfachen Bohrung kann es schon zerspringen.
Besser ist Makrolon, das hat bessere Eigenschaften zum zerspannen und biegen, ist allerdings ziemlich genau doppelt so teuer wie Plexiglas.
@damaltor:
naja, wenns nur matt werden würde wäre es ja nicht so schlimm. Aber nach dem "ganz fest" kommt ja bekanntlich "ganz locker"...
@palermo:
ich föne mir die haare nicht (hab schon zu wenig dafür) :-(
um die station zu finden sehe ich mehrere möglichkeiten:
- IR bake orten
- wärme des ladegerätes orten
- position (kompas)
- odometrie
- ......?
aber eines nach dem anderen...
Jetzt muss erstmal geklärt werden was passiert, wennn er meinetwegen 24h am ladegerät hängt obwohl der akku voll ist, weil irgendwelche überwachung versagt hat... :-(
Ja ein Haarföhn bringt da nix.
Aber Plexiglas ist so spröde, dass es nur sehr schwer zu bearbeiten ist.
Bei ner einfachen Bohrung kann es schon zerspringen.
Besser ist Makrolon, das hat bessere Eigenschaften zum zerspannen und biegen, ist allerdings ziemlich genau doppelt so teuer wie Plexiglas.
und wo zu bekommen? Ich habe schon ein paar sachen aus plexiglas gemacht, man muss es halt vorsichtig bearbeiten. Zum biegen eignet sich hervorragend das mini schweissgerät von conrad, kostet blos ein paar euro...
Asuro-n00b
15.05.2007, 16:44
tolles Projekt! :) Sieht sehr gut aus. Bin gespannt, was draus wird. O:)
Ich bin von der Linienverfolgung über die Taster jetzt gerade zur Odometrie gekommen. Die macht mir durch die neue Lib noch etwas Kopfzerbrechen. :-s Nebenbei lese ich noch Asuro Band I und II. Die Bücher gefallen mir sehr gut und den dritten Teil werd ich mir auch noch kaufen. Da wird es um den Einstieg in die Regelungstechnik gehen. 8-[
Asuro-n00b
15.05.2007, 16:48
Bei E-bay bietet ab und zu mal jemand Reststücke an...
ja, die bücher sind spitze. Im 2ten band ist auch ein programm zu odometrie, muss schon sagen so gerade ist mein asuro noch nie gefahren...
Asuro-n00b
15.05.2007, 18:40
Aber bei dem Programm aus dem Buch seh ich nicht, wo er die Odometrie aktiviert. Muss man das nicht vorher, bevor man es auslesen kann?
Vielleicht hängt das damit zusammen, dass im Buch die Original Library verwendet wird.
radbruch
15.05.2007, 20:34
wird aber aufgrund von warnungen ... nur beim abgeschalteten asuro verwendet
Ich hoffe, das bezieht sich nicht auf meinen ängstlichen Beitrag über das Laden von eingebauten Akkus. Denn da hätte ich jetzt bei deiner Ladekonstruktion überhaupt keine Bedenken. Wegen der geringen Leistung die übertragen wird und wegen der galvanischen Trennung ist es sicher ungefährlich für den Kleinen.
naja, ein bischen schiss habe ich schon bekommen...
ich habe vor einer stunde den braun-service bemüht und nach dem prinzip gefragt nach dem die arbeiten. Wenn da einfach nur strom reingepowert werden würde ohne rücksicht auf den ladezustand wäre die lebesdauwer der akkus (wer legt die bürste schon neben der ladestation hin!) nicht sehr hoch. Mal schauen was sie mir antworten...
Paar kleine Anmerkung zum Wiederfinden da Ladestation von mir:
- Wärme Ortung ist nicht geeignet (viel zu störanfällig)
- Odometrie ist auch sehr ungenau, vor allem wenn du eine weile rumgefahren bist
- Kompass alleine wird nicht aureichend
Ich finde die beste Variante (die auch schon oft benutzt wurde) ist eine Bake an der Ladestation aufzustellen. Daran kann der Roboter sich grob orientieren. Auf dem Boden um die Bake hast du noch einen Streifen für die Linienfolgesensoren, damit Asuro exakt andocken kann.
Fast wie der Leitstrahl, den Flugzeuge benutzen um sicher zu landen.
MfG Marcus
damaltor
15.05.2007, 22:44
plexiglas lässt sich mit einem heissluftfön (also kein haarfön) ganz fein biegen. vorsichtig halt...
ich habe immer mal wieder mit "bastelglas" gearbeitet. etwa halb so teuer wie plexiglas, aber von den eigenschaften recht ähnlich.
überhaupt wäre zB eine art kreis um die ladestation nicht schlecht, so dass der asuro nur ungefähr peilen muss und sich dann im kreis orientieren kann.
hi allerseits,
warscheinlich weil ich so lange offline war wurde ich per pm gefragt wie weit ich nun mit der automatischen ladestation bin...
noch nicht sehr weit, aber es wird daran - zumindest theorethisch - gearbeitet...
H3llGhost
05.09.2007, 17:02
Ich selber würde gerne helfen, aber leider bin ich noch nicht sehr weit fortgeschritten in der Asuro-Welt, aber ich werde trotzdem mal meine Idee zur Wiederfindung posten ...
Dazu gefällt mir die Idee von Acu ganz gut ...
[...]
Ich finde die beste Variante (die auch schon oft benutzt wurde) ist eine Bake an der Ladestation aufzustellen. Daran kann der Roboter sich grob orientieren. Auf dem Boden um die Bake hast du noch einen Streifen für die Linienfolgesensoren, damit Asuro exakt andocken kann.
[...]
Die Bake kann ja ähnlich wie ein Leuchtturm sein, nur das der auf Infrarotbassis einen bestimmten Impuls sendet, wenn der Asuro nun mit dem Infrarot-Entfernungsmesser ausgerüstet ist und man den Asuro so programmiert, dass er auch auf den Impuls des "Leuchtturms" reagiert, müsste er doch auf diesen Punkt zufahren können und ab einer gewissen Entfernung die Linienfolgesensoren aktivieren, um die Leitstreifen zum Andocken zu finden.
Ist doch möglich oder?
so ähnlich habe ich es mir auch gedacht. Nur muss sich mein asuro auch noch um 180° drehen und zumindest die letzte strecke rückwärts hinfahren weil die vorrichtung zum andocken hinten ist.
Momentan bin ich dabei das auslesen der akkus zu testen, er soll ja bei einer bestimmten spannung seine tätigkeit (welche auch immer) abbrechen und energie holen.
so sieht mein programm aus:
#include "asuro.h"
#include "inka.h"
int wert, i;
int main (void)
{
Init();
WaitforStart();
while(1)
{ //start programm
wert = Batterie (); //Abfrage batterispannung
EncoderInit ();
for (i = 0; i < 4; i++) //start eigentliches programm
{
Go (200, 150);
StatusLED(GREEN);
Msleep(500);
Turn (90, 150);
StatusLED(YELLOW);
Msleep(500);
if (wert < 700) // 810 entsprechen ca. 4,455 Volt
{
StatusLED(RED);
PrintInt(wert);
break; //statt break dann sprung zu ir-suchprogramm
}
SerWrite("\r ",4);
PrintInt(wert);
}
} //ende programm
return 0;
}
was mich dabei wundert ist /sind die unterschiede bzw. die schwankungen der ausgelesenen werte (vonn 800 bis 950, wenn ich den asuro hochbocke, kann ich es am monitor ausgeben)
bis anfang der nächsten woche komme ich überhaupt nicht dazu weiterzumachen :-(, weil ich etwas dringendes übersetzen muss...:-) - schliesslich bring das geld...
eine andere frage:
könnte es sein, dass das US-modul die genauigkeit der odometrie beeinflusst? jedenfalls sind die quadrate, die der suro ohne fährt viel genauer, die turn funktion macht wirklich 90°...
H3llGhost
05.09.2007, 17:59
Kleine Frage am Rande:
Was ist das US-Modul?
b2t:
Ich würde es vielleicht so machen, dass er die Linie folgt und diese geht an der Station vorbei und fängt an heller zu werden bzw. ist dann heller als die andere. Dann kann ja der Asuro merken oh ... andere Intensität ... => Rückwärtsgang und dieser Linie folgen ...
Müsste doch möglich sein oder?
damaltor
05.09.2007, 19:57
evtl wäre das auch ein einsatzgebiet für die barcodes. der die linie wird einfach gestrichelt zum ende hin.
eigentlich sollte das us modul den rest nicht beeinflussen... =)
H3llGhost
06.09.2007, 20:27
Was ist nun eigentlich das US-Modul?
damaltor
06.09.2007, 21:48
ultraschall-entfernungsmessung. das ist eine erweiterungsplatine, welche in dem buch für den asuro beschrieben wird.
hi allerseits,
ich versuche mich wieder mal an meinem projekt, mit der batteriespannung und dem aussortieren der ausreisser bin ich eigentlich zufrieden, obwohl man es sicher elegenter machen kann:
/*ladestation_anfahren*/
#include "asuro.h"
#include "inka.h"
#include "stdio.h"
unsigned int batt_1;
unsigned int batt_2;
unsigned int batt_3;
double u_batt;
int main (void)
{
Init();
WaitforStart();
while(1)
{
(batt_1)=Batterie();
(batt_2)=Batterie();
(batt_3)=Batterie();
if ((batt_1)<((batt_2)-(batt_2)/100)) (batt_1)=Batterie();
if ((batt_2)<((batt_3)-(batt_3)/100)) (batt_2)=Batterie();
if ((batt_3)<((batt_1)-(batt_1)/100)) (batt_3)=Batterie();
(u_batt)= 0,0055*Batterie();
SerWrite("\r\n batt_1: ",11);
PrintInt(batt_1);
SerWrite(" batt_2: ",9);
PrintInt(batt_2);
SerWrite(" batt_3: ",9);
PrintInt(batt_3);
SerWrite(" u_batt: ",9);
printf ("%5f", (u_batt));
SerWrite(" [V]",4);
{
EncoderInit();
if (PollSwitch()>0) {
StatusLED(RED);
Go (-100, 150);
}
else {
Go (200, 150);
StatusLED(GREEN);
Msleep(500);
}
if (PollSwitch()>0) {
StatusLED(RED);
Go (-100, 150);
}
else {
Turn (90, 150);
StatusLED(YELLOW);
Msleep(500);
}
}
}
return 0;
}
ich wollte mir aber zu den Batterie() werten auch noch die daraus errechnete spannung ausgeben, was ich auch mache, wo und wonach ich auch suche, es wird einfach nix im terminal ausgegeben...
auszug aus dem oberen code:
PrintInt(batt_3);
SerWrite(" u_batt: ",9);
printf ("%5f", (u_batt));
SerWrite(" [V]",4);
was stimmt da nicht?
m.a.r.v.i.n
22.09.2007, 11:39
Hallo inka,
printf alleine funktioniert so nicht. Dazu müßtest du die Ausgabe (STDOUT) auf die serielle Schnittstelle umleiten. Alternativ könntest du sprintf verwenden, dann ist das Ziel ein String. Den könntest du dann mit SerWrite ausgeben.
Wie das geht, steht im mikrocontroller.net Tutorial (http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Die_Nutzung_von_printf)
Für Floating Point Ausgaben benötigts du zudem noch eine AVR Lib, die du im Makefile hinzufügen mußt, siehe
http://www.mikrocontroller.net/articles/FAQ#Aktivieren_der_Floating_Point_Version_von_spri ntf_beim_WinAVR_mit_AVR-Studio
Allerdings fiunktioniert die Umleitung von STDOUT, so wie im Tutorial beschrieben, mit neueren AVR-GCC Compilern wohl nicht mehr.
hi allerseits,
dank Printfloat bin ich wieder ein kleines stückchen im projekt weitergekommen, jetzt kann ich am monitor den stand der batterieladung überprüfen. Schön wäre es allerdings, wenn ich jetzt noch ein schritt weiterkäme - den batteriestand in Volt auf der LCD erweiterungsplatine anzuzeigen. dazu muss ich die am monitor ausgegebene floatvariable wieder in einen string umwandeln um sie dann "pixel für pixel" auszugeben. Ist das so? Ich habe im asuro-band II nämlich keine funktion gefunden, die es möglich macht irgendwelche, wie auch immer geartete variable auszugeben. Nur text und pixel...
damaltor
21.11.2007, 14:28
text ist schonmal nicht schelcht.
ich hab mal nen ansatz zum nachdenken für dich:
du hast eine zahl die den batteriezusatnd beschreibt. am besten wäre ein int oder ein char.
wenn du aus diesem die einzelnen ziffern extrahierst (dazu unten mehr), macht das die sache einfacher. beispiel: aus 123 wird 1 und 2 und 3
jetzt such n dem display-zeichensatz nach der position der null. direkt dahinter kommen 1,2,3... usw. wenn du jetzt den positionswert der null zu einer zahl die du so extrahiert hast addierst, kommst du automatisch auf das richtige, auszugebende zeichen. beispiel: wir nehmen an, dass die null den wert 48 (oder 0x30) hat. jetzt wollen wir die zahl 140 ausgeben:
zuerst zerlegen: 1 4 0
jetzt die eins ausgeben:
48 + 1 = 49 --> wert für eine eins auf dem display
48 + 4 = 52 --> wert für eine vier auf dem display
48 + 0 = 48 --> wert für eine null auf dem display
jetzt brauchen wir nur noch eine methode, um die ziffern aus der ganzen zahl rauszubekommen. diese die ich dir jetzt zeige geht nur für ganzzahlen, also chars und ints. in diesem falle nehme ich einen char als beispiel, die integer funktionieren genauso (bloss dass die zahlen zwei stellen mehr haben).
Beispiel: 246
zuerst wollen wir die hunderterstelle haben.
unsigned char hunderter(unsigned char zahl){
return zahl/100;
}
das war schonmal recht einfach. die zahl wird durch 100 geteilt, der rest fällt weg, und die hunderter bleiben. 246 / 100 = 2
jetzt die zehner:
unsigned char zehner(unsigned char zahl){
return (zahl - (100 * hunderter(zahl)))/10;
}
zuerst wird hundert mal die hunderterstelle abgezogen und dann der rest durch 10 geteilt.
246 - 100*2 = 46
46 / 10 = 4
jetzt nur noch die einerstelle:
unsigned char einer(unsigned char zahl){
return zahl - (100*hunderter(zahl)) - (10*zehner(zahl));
}
es werden erst hundert mal die hunderterziffer, und dann zehn mal die zehner-ziffer abgezogen.
246 - 100*2 - 10*4 = 6
und dann kannst du das so machen wie oben beschreiben. den zeichenwert der null addieren ("offset") und ans display ausgeben.
hi damaltor,
danke erstmal, die erkklärung zu den stellen im display so weit verstandan...
frage noch dazu:
(bloss dass die zahlen zwei stellen mehr haben).
was bedeutet das konkret?
Beispiel: 246
zuerst wollen wir die hunderterstelle haben.
unsigned char hunderter(unsigned char zahl){
return zahl/100; }
in diesem beispiel ist "unsigned char hunderter" eine vorher noch zu definierende variable, die nach der ausführung der berechnung im o.g. beispiel den wert 2 hat?
"(unsigned char zahl)" entspricht im beispiel der zahl 246 (die ja auch noch zugewiesen werden muss? Könnte dort die zahl vor dem komma aus dem spannungswert der batterie übernommen werden (natürlich die einserstelle incl. der berechnung)?
mit "{ return zahl/100;}" wird das ergebnis hunterter berechnet und wo ausgegeben?
radbruch
22.11.2007, 11:09
Hallo
Das Thema "PrintChar()" hatten wir grad in einem anderen Thread. Das Ergebniss ist eine geile Funktion von izaseba weiter unten im Thread:
https://www.roboternetz.de/phpBB2/viewtopic.php?p=328202#328202
mic
damaltor
22.11.2007, 15:28
unsigned char hunderter ist die funktion, welche aus dem "unsigned char zahl" die hunderterstelle extrahiert und mit return zurückgibt.
beispiel:
hunnis = hunderter(batteriespannung)
zehnis = zehner(batteriespannung)
einis = einer(batteriespannung)
jetzt ist in jeder der drei variablen ein byte gespeichert, das die jeweilige stelle reräsentiert, bei 246 also:
hunnis = 2
zehnis = 4
einis = 6
das sind also keine variablen, sondern funktionen :P
radbruch: es geht nicht um das senden ans terminal, sondern um das senden an ein lcd display...
hi damaltor,
du hast es nicht einfach mit mir :-(
dieser code:
int main(void)
{
Init();
unsigned int zahl;
zahl=Batterie();
unsigned int hunderter(unsigned int zahl){
return zahl/100;
}
SerWrite("\r\n hunderter: ",14);
PrintInt(hunderter);
return 0;
}
liefert diese warnunge, bzw. fehlermeldungen:
../lcd_ausgabe.c:21: warning: passing arg 1 of `PrintInt' makes integer from pointer without a cast
../lcd_ausgabe.c:24: internal compiler error: trampolines not supported
leider verstehe ich weder das eine noch das andere
damaltor
22.11.2007, 18:43
mach mal PrintInt(*hunderter)
eigentlich muss nämlich eine zahl in den klammern stehen und nicht eine variable =) den zweiten fehler würd ich mal ignorieren, evtl verschwindet der dann von allein.
was auch gehen könnte ist:
PrintInt(Hunderter(zahl));
die zweite lösung wars:
hunderter: 9 zehner: 0 einer: 6
:-) danke
damaltor
22.11.2007, 19:09
sehr gut. und so ähnlich müsste es auch mit dem display klappen, indem du den offset addierst und dann ausgibst.
AARGH:
mir fällt grad was auf. das sollte durchaus so funktionieren wie vorher (PrintInt(hunderter);) ABER du hast die funktion INNERHALB der main-funktion deklariert. dieser absatz
unsigned int hunderter(unsigned int zahl){
return zahl/100;
}
MUSS ÜBER DER MAIN-FUNKTION STEHEN und nicht mittendrin :P
ich habe es jetzt so abgeändert:
#include "asuro.h"
#include "lcd.h"
#include "i2c.h"
int zahl=246;
//int zahl=Batterie();
int hunderter( int zahl){
return zahl/100;
}
int zehner( int zahl){
return (zahl - (100 * hunderter(zahl)))/10;
}
int einer( int zahl){
return zahl - (100*hunderter(zahl)) - (10*zehner(zahl));
}
int main(void)
{
Init();
SerWrite("\r\n hunderter: ",14);
PrintInt(hunderter);
SerWrite(" zehner: ",9);
PrintInt(zehner(zahl));
SerWrite(" einer: ",8);
PrintInt(einer(zahl));
return 0;
}
die auskomentierte zeile mit batterie hat er angemeckert, weil keine konstante, kommt später dran. Die warnung wg. der geänderten zeile PrintInt(hunderter);
kommt aberr wieder:
../lcd_ausgabe.c:30: warning: passing arg 1 of `PrintInt' makes integer from pointer without a cast
hallo,
mit diesem code
#include "asuro.h"
#include "lcd.h"
#include "i2c.h"
int zahl;
unsigned int batt_1, batt_2, batt_3;
float spannung;
/************hunderter**********/
int hunderter( int zahl){
return zahl/100;
}
/*************zehner************/
int zehner( int zahl){
return (zahl - (100 * hunderter(zahl)))/10;
}
/*************einer*************/
int einer( int zahl){
return zahl - (100*hunderter(zahl)) - (10*zehner(zahl));
}
/************************batterieabfrage*********** **************************/
void batt_abfrage(void)
{
(batt_1)=Batterie();
(batt_2)=Batterie();
(batt_3)=Batterie();
if ((batt_1)<((batt_2)-(batt_2)/100)) (batt_1)=Batterie();
if ((batt_2)<((batt_3)-(batt_3)/100)) (batt_2)=Batterie();
if ((batt_3)<((batt_1)-(batt_1)/100)) (batt_3)=Batterie();
spannung=(batt_3 + batt_2 + batt_1)/535.1;
}
int main(void)
{
Init();
zahl=Batterie();
batt_abfrage();
SerWrite("\r\n hunderter: ",14);
PrintInt(hunderter(zahl));
SerWrite(" zehner: ",9);
PrintInt(zehner(zahl));
SerWrite(" einer: ",8);
PrintInt(einer(zahl));
SerWrite(" spg: ",6);
PrintFloat(spannung,1,5);
return 0;
}
habe ich bereits die größe des hexfiles erreicht die in den atmega8 nicht mehr reinpasst, bzw. eine fehlermeldung beim flashen ausgegeben wird...
Kann das sein, oder ist da irgendwo ein fehler? Ich habe mit staunen festgestellt, dass das Printfloat mit dem einbinden von printf.c eine vergrößerung der hexdatei von 18,235k auf 22,237k bewirkt. Eine printzeile! Da muss ich wohl um mein ziel zu erreichen noch was tun...
damaltor
23.11.2007, 10:12
tja.. floats sind halt echt tückisch. da gehen einige kilobyes flöten... deshalb behilft man sich soweit es geht mit ints oder am besten sogar chars.
du teilst auch durch 535.1, was ja auch ein float ist. evtl solltest du durch 535 teilen, und versuchen alles auf integer zu bringen. das würde den code deutlich verkleinern.
warum setzt du batt_1 ,2 ,3 in klammern? geht auch ihne denke ich, könnte sein dass der compiler hier ein paar unnötige bytes produziert.
was evtl ein problem sein könnte, ist dass die unsigned int bis zu 5 stellen haben können. deshalb wird die zahl der hunderter nicht korrekt berechnet, da alle stellen über der dritten mit in die hnderterstelle eingefügt werden.
du brauchst also, wenn du größere zahlen als 999 bearbeitest, noch eine funktion für tausender, und wenn du größere zahlen als 9999 bearbeitest, auch eine für 10tausender.
schönen guten morgen...
ein anderes thema, hängt aber auch mit der ausgabe am lcd zusammen. Folgender code:
#include "asuro.h"
#include "lcd.h"
int main(void)
{
Init(); //Initialisiert ASURO
InitLCD();
PrintAlignLCD (LEFT, 1, "Ich bin");
PrintAlignLCD (RIGHT, 2, "asuro");
// for(;;);
return 0;
}
lässt sich problemlos compilieren, am lcd tut sich aber nix...
was habe ich übersehen?
du teilst auch durch 535.1, was ja auch ein float ist. evtl solltest du durch 535 teilen, und versuchen alles auf integer zu bringen. das würde den code deutlich verkleinern.
das mit den klammern habe ich geändert, aber beim teilen durch 535 werden alle nachkommastellen durch nullen ersetzt :-(
damaltor
25.11.2007, 11:29
hmm das ist wahr. aber wenn du die zhal vorher mit 100multiplizierst, und dann bei der ausgabe darauf achtest das komma an die richtige stelle zu setzen, hast du trotzdem zwei nackommastellen... =)
10 / 8 = 0.125 -> kommazahlen
10 * 100 / 8 = 125 -> keine kommazahlen
ok,
das habe ich glaube ich verstanden, werde ich ausprobieren...
der beitrag weiter oben - was habe ich bei der initialisierung des lcd vergessen? Zumindest in der lcd.c habe ich weiter nichts gefunden? Ist es eigentlich so, dass mit der lcd.c aus der 2.7.1 lib jetzt alle programme aus dem band II nicht funktionieren?
damaltor
25.11.2007, 13:20
die asuro bücher nutzen die lib von der cd. tie timebase ist da nicht 36khz, sondern 72 khz was alles zeitkritischen dinge versuat
hi damaltor,
ich habe jetzt die ausgabe in der funktion geändert, schlau werde ich daraus nicht...
void batt_abfrage(void)
{
int batt_1,batt_2, batt_3, spannung;
float spannung_1;
batt_1=Batterie();
batt_2=Batterie();
batt_3=Batterie();
if (batt_1<(batt_2-batt_2/100)) batt_1=Batterie();
if (batt_2<(batt_3-batt_3/100)) batt_2=Batterie();
if (batt_3<(batt_1-batt_1/100)) batt_3=Batterie();
spannung_1=(batt_3 + batt_2 + batt_1)/535.1;
spannung=(batt_3 + batt_2 + batt_1)*100/535;
SerWrite("\r\n batt_1: ",11);
PrintInt(batt_1);
SerWrite(" batt_2: ",9);
PrintInt(batt_2);
SerWrite(" batt_3: ",9);
PrintInt(batt_3);
SerWrite(" spannung: ",11);
PrintInt(spannung);
SerWrite(" spannung_1: ",13);
PrintFloat(spannung_1, 1, 5);
}
die ausgabe:
batt_1: 941 batt_2: 940 batt_3: 940 spannung: 37 spannung_1: 5.27191
batt_1: 941 batt_2: 941 batt_3: 941 spannung: 37 spannung_1: 5.27564
batt_1: 940 batt_2: 940 batt_3: 941 spannung: 37 spannung_1: 5.27191
batt_1: 941 batt_2: 941 batt_3: 941 spannung: 37 spannung_1: 5.27564
batt_1: 941 batt_2: 941 batt_3: 941 spannung: 37 spannung_1: 5.27564
batt_1: 941 batt_2: 940 batt_3: 941 spannung: 37 spannung_1: 5.27378
batt_1: 940 batt_2: 941 batt_3: 940 spannung: 37 spannung_1: 5.27191
batt_1: 941 batt_2: 941 batt_3: 940 spannung: 37 spannung_1: 5.27378
batt_1: 940 batt_2: 939 batt_3: 940 spannung: 36 spannung_1: 5.26817
batt_1: 940 batt_2: 940 batt_3: 940 spannung: 37 spannung_1: 5.27004
batt_1: 939 batt_2: 940 batt_3: 940 spannung: 36 spannung_1: 5.26817
wie erkenne ich woher bei der spannung die 37, bzw. 36 kommen? ich dachte es werden dann (auch wenn evtl. di falschen) aber immerhin ein paar stellen von dem float spannung_1 ausgegeben? ](*,)
radbruch
25.11.2007, 14:12
int batt_1,batt_2, batt_3, spannung;
...
spannung=(batt_3 + batt_2 + batt_1)*100/535;
3*941*100=282300!
(282300-4*65536)/535=(282300-242144)/535=37,67476635514018691588785046729
spannung muss float sein
[Edit]
ach Quatsch, die Formel ist falsch:
spannung=(batt_3 + batt_2 + batt_1)*10/535;
3*941*10/535=28230/535=52(,76635514018691588785046728972)
mic
damaltor
25.11.2007, 14:14
hmm da stimmt irgendwas nich so ganz... so hab ich das nicht gemeint =)
versuch mal: spannung=(batt_3 + batt_2 + batt_1)*1000/5351;
das sollte 2 kommastellen ergeben. das ziel war, von der 535.1 das komma zu entfernen, da wir jetzt durch 5351 teilen würde das ergebnis nur 1/10 der wirklcihen spannung darstellen. also nur zahlen hinter dem komma, das wäre nicht das ziel gewesen da die komma stellen ja abgeschnitten werden.
wenn wir die zahl jedoch vorher mit 1000 multiplizieren, bekommen wir anstatt 0.527 jetzt 527, also 5,27 volt.
batt_1 = 941
batt_2 = 941
batt_3 = 940
batt_1+2+3 = 2822
2822*1000 = 2822000 (...hier könnte ganz evtl ein problem mit dem int überlauf entstehen... probiers trotzdem mal)
2822000 / 5351 = 527.37806
dabvei wird 527 gespeichert, also 5.27 volt. das kannst du dann entweder bei der ausgabe beachten dass an passender stelle ien punkt eingefügt wird, oder du arbeitest einfach mit diesem wert und sparst dir den umstand.
radbruch
25.11.2007, 14:31
Natürlich gibt die erste Version mit Faktor 100 einen Int-Überlauf, habe ich doch oben vorgerechnet. Die Formel für spannung sieht so aus:
spannung_1=(batt_3 + batt_2 + batt_1)/535.1;
spannung=(batt_3 + batt_2 + batt_1)*100/535;
Es sollte aber so aussehen:
spannung_1=(batt_3 + batt_2 + batt_1)/535.1;
spannung=(batt_3 + batt_2 + batt_1)*10/5351;
Zähler und Nenner mal 10, dann stimmts auch mit dem Komma im Ergebniss...
Ach, ich Depp, ihr wollt doch gar keine Kommas haben, blöd wenn man nicht alles liest. Sorry. Wäre vielleicht das die richtige Lösung:
spannung_1=(batt_3 + batt_2 + batt_1)/535.1;
spannung=(int) spannung_1*100;
mic
damaltor
25.11.2007, 15:18
die erst elösung hilft nicht, weil keine kommastellen gewollt sind, ist wahr. und die zweite lösung hilft auch nicht, wel in der zwischenvariable spannung_1 trotzdem wieder kommas sind =) es geht darum die floats völlig zu vermeiden. mehr ideen? das problem ist wenn man erst teilt und dann mit 100 multipliziert ohne floats zu nutzen, bekommt man nur ne null... :(
m.a.r.v.i.n
25.11.2007, 15:24
Hallo inka,
was habe ich bei der initialisierung des lcd vergessen? Zumindest in der lcd.c habe ich weiter nichts gefunden?
das LCD aus dem Asuro Buch II funktioniert erst, wenn man im Header File
i2c.h die beiden Defines für den I2C Bus folgendermaßen ändert.
#define SDA PC2
#define SCL PC3
De AsuroLib und die Programme müssen dann natürlich anschließend neu übersetzt werden.
hi m.a.r.v.i.n.
#define SDA PC2
#define SCL PC3
De AsuroLib und die Programme müssen dann natürlich anschließend neu übersetzt werden.
damit habe ich wohl immer noch probleme: mit AVR studio heisst "neu übersetzen":
- ändern
- rebuilt all
- flash...???
ausser dass die status-led beim starten von asuro von gelb in grün wechselt passiert aber leider nix :-(
damaltor
25.11.2007, 16:23
rebuild all =) alle neu aufbauen
ok,
hatte noch einen fehler drinn, immerhin kann ich jetzt die hintergrundbeleuchtung des diaplays einschalten, ausschalten geht komischerweise mit "BacklightLCD(OFF);" nicht :-(
m.a.r.v.i.n
25.11.2007, 19:01
Hallo inka,
ich sehe gerade, das auch die Belegung der PCF8574 Pins in der AsuroLib anders ist, als für das LCD aus dem AsuroBuch II.
Deswegen muß auch die lcd.h geändert werden:
////// PCF8574p PINS
#define LD4 4 // Pin to Data Bus 4
#define LD5 5 // Pin to Data Bus 5
#define LD6 6 // Pin to Data Bus 6
#define LD7 7 // Pin to Data Bus 7
#define LRS 0 // Pin to RS Pin (Register Select)
#define LRW 1 // Pin to Read/Write Pin
#define LEN 2 // Pin to Enable Pin
#define LBL 3 // Backlight Pin
Die LCD Funktionen der AsuroLib sind leider aller vor Erscheinen des Asuro Buches entstanden.
hi m.a.r.vi.n.
jetzt gehts, zumindest das was ich bisher ausprobiert habe...
danke
hi allerseits,
die ausgabe der spannung auf dem LCD display funktioniert nun :-)
jetzt habe ich eine bitte:
gibt es vielleicht etwas genauere erklärungen zu den folgenden LCD-funktionen?
in der docu 2.7.1 fand ich nicht viel mehr als in den beiden dateien lcd.c und lcd.h, leider sind mir aus den funktionen allein die bedeutungen einzelner begriffe nicht klar...
Für andere befehle wurden fast immer schöne beispiele angegeben, gibt es sowas zu dem LCD auch?
void InitLCD(void)
ist soweit klar, funktioniert bei mir auch offensichtlich.
-------------------------
void BacklightLCD(unsigned char state)
parameter sollten wohl ON/OFF sein, funktioniert bei mir nicht...
----------------------------
void SetCursorLCD(unsigned char cursor, unsigned char line)
LCD-ausgabe wird wohl mit cursor/line auf position gesetzt...
---------------------------------
void CommandLCD(unsigned char command)
welche commands?
----------------------------
void ClearLCD(void)
ist klar...
-------------------------------
void WriteLCD(unsigned char data)
wie könnte der unsigned char denn aussehen?
char a=46 gibt einen "." aus?
-------------------------------
void PrintLCD(char *string, unsigned char wrap)
wrap steht wohl für zeilenumbruch? ON/OFF?
*string?
-------------------------------
void PrintSetLCD(unsigned char cursor, unsigned char line, char *string)
LCD wird auf position cursor/line gesetzt, *string?
-------------------------------
void PrintIntLCD(int value)
wie könnte int value aussehen?
-----------------------------
void PrintAlignLCD(unsigned char alignment, unsigned char line, char *string)
alignment, line sind klar *string?
m.a.r.v.i.n
27.11.2007, 20:02
Hallo inka,
ja, die Doku der LCD Funktionen ist noch lückenhaft.
Im examples Ordner gibt es auch das Beispielprojekt (I2CLCD). Dort sieht man zumindest, was bei den einzelnen Funktionen so passiert.
hi m.a.r.v.i.n,
hat das schon jemand ausprobiert? Die datei lässt sich flashen, beim einschalten ändert die status-led die farbe von gelb auf grün, aber sonst passiert nix :-(
oder war es so gemeint, dass man sich den code anschauen kann?
hhuuurrrraaa!!!
die hintergrundbeleuchtung lässt sich tatsächlich abschlaten, wenn man auf den trichter kommt, dass eine 1 eigentlich eine 0 ist:
BacklightLCD(1);
da kann ich nur mit dem kopf schütteln...:-)
m.a.r.v.i.n
28.11.2007, 22:55
Hallo inka,
oder war es so gemeint, dass man sich den code anschauen kann?
Eigentlich beides. Den Code um zu sehen wie man die Funktionen anwendet, und auf dem Display sollte man verfolgen, wie das ganze dann aussieht.
Das Testprojekt funktioniert natürlich auch mit dem LCD aus dem Asuro Buch 2, mit den oben genannten Änderungen.
Wie das ganze aussieht, kann man in einem kleinen Video verfolgen:
http://www.asurowiki.de/pmwiki/uploads/Main/asuro-lcd.wmv
hi m.a.r.v.i.n,
so weit so gut, danke, ich werde die verschiedenen funktionen nun testen. Noch eine frage:
die taster auf der LCD platine werden mit hilfe in der lcd.h definierten makros abgefragt:
---------------------------------
// Makros für die drei Taster
#define LCD_KEY_YELLOW (PIND&(1<<PD6))
#define LCD_KEY_RED (PIND&(1<<PD2))
#define LCD_KEY_BLUE (PINB&(1<<PB3))
-------------------------------
so stehen die makros in der ursprünglichen lcd.h. Wenn ich sie so wie sie sind in die neue datei übertrage, gibt es bei z.b.
-------------------------------
while(!LCD_KEY_RED);
while(LCD_KEY_RED);
-----------------------------
keine reaktion. Ich habe ein hinweis in den anderen dateien auf diese makros gesucht, aber leider nicht gefunden... Stimmen die makros noch so? Oder müssen sie bei der neuen lib noch irgendwo eingetragen werden?
m.a.r.v.i.n
29.11.2007, 11:39
Hallo inka,
damit die Taster vom LCD Modul funktionieren, müssen die entsprechenden Prozessor Pins auch als Input definiert werden.
In der lcd_init Funktion müßte man dazu folgende Zeilen einfügen.
TCCR2 = (1 << WGM21) | (1 << CS20); // OC2 PIN deaktivieren, aber 36kHz Timer weiterlaufen lassen (z.B. für Sleep(void) )
DDRD &= ~((1<<PD2)|(1<<PD6)); // roten und gelben Taster als Eingang definieren
DDRB &= ~(1<<PB3); // blauen Taster als Eingang definieren
Nachteil dabei ist. Die IR Kommunikation und die rote Status LED funktionieren damit nicht mehr.
danke marvin,
ist es auch möglich diese aktivierung der prozessorpinns immer vor der ausgabe am display, besser gesagt in dem moment, wo die ausgabe erwartet wird, also immer wieder nach der berechnung der werte zu aktivieren, um diese dann unmittelbar nach der ausgabe wieder zurück zu ändern? Verstehst du was ich meine, oder habe ich das zu verdreht ausgedrückt? Müssen die zeilen bestandteil der initialisierung des displays sein, oedr geht das auch separat davon?
m.a.r.v.i.n
29.11.2007, 20:03
Hallo inka,
ich verstehe schon was du meinst. Dazu müßte man eine Funktion ähnlich der PollSwitch Funktion mit folgenden Aufgaben bauen:
* Taster Pins auf Input schalten
* Taster abfragen
* Taster Pins auf Output schalten
* Tasterwert zurückgeben
hi m.a.r.v.i.n,
bin ich da auf dem richtigen weg?
int LED_PollSwitch (void)
{
int yellow, blue, red;
//makrodefinitionen der taster
#define LCD_KEY_YELLOW (PIND&(1<<PD6))
#define LCD_KEY_RED (PIND&(1<<PD2))
#define LCD_KEY_BLUE (PINB&(1<<PB3))
//taster pins auf input schalten
TCCR2 = (1 << WGM21) | (1 << CS20); // OC2 PIN deaktivieren, aber 36kHz Timer weiterlaufen lassen (z.B. für Sleep(void) )
DDRD &= ~((1<<PD2)|(1<<PD6)); // roten und gelben Taster als Eingang definieren
DDRB &= ~(1<<PB3); // blauen Taster als Eingang definieren
//taster abfragen
yellow=(LCD_KEY_YELLOW);
red=(LCD_KEY_RED);
blue=(LCD_KEY_BLUE);
//taster pins auf output schalten
TCCR2 = (0 << WGM21) | (1 << CS20); OC2 PIN aktivieren
DDRD &= ~((0<<PD2)|(0<<PD6)); // roten und gelben Taster als ausgang definieren
DDRB &= ~(0<<PB3); // blauen Taster als ausgang definieren
//tasterwert zurückgeben
???
}
m.a.r.v.i.n
30.11.2007, 10:06
Hallo inka,
nicht so ganz, aber fast. So könnte es vielleicht gehen. Ich kann das aber erst heute abend testen.
#include "asuro.h"
#include "lcd.h"
#include "i2c.h"
//makrodefinitionen der taster
#define LCD_KEY_YELLOW (1<<PD6)
#define LCD_KEY_RED (1<<PD2)
#define LCD_KEY_BLUE (1<<PB3)
int LCDPollSwitch (void)
{
int key = 0;
//taster pins auf input schalten
TCCR2 = (1 << WGM21) | (1 << CS20); // OC2 PIN deaktivieren, aber 36kHz Timer weiterlaufen lassen (z.B. für Sleep(void) )
DDRD &= ~((1<<PD2)|(1<<PD6)); // roten und gelben Taster als Eingang definieren
DDRB &= ~(1<<PB3); // blauen Taster als Eingang definieren
//taster abfragen
key |= (PIND&LCD_KEY_YELLOW);
key |= (PINB&LCD_KEY_RED);
key |= (PINB&LCD_KEY_BLUE);
//taster pins auf output schalten
TCCR2 = (1 << WGM20) | (1 << WGM21) | (1 << COM20) | (1 << COM21) | (1 << CS20);
DDRD &= ~((1<<PD2)|(0<<PD6)); // roten und gelben Taster als ausgang definieren
DDRB &= ~(1<<PB3); // blauen Taster als ausgang definieren
//tasterwert zurückgeben
return key;
}
int main(void)
{
int keys;
Init();
InitI2C();
InitLCD();
while(1)
{
keys = LCDPollSwitch();
if (keys & LCD_KEY_YELLOW)
{
PrintSetLCD(0,0,"Yellow");
}
else if (keys & LCD_KEY_RED)
{
PrintSetLCD(0,0,"Red");
}
else if (keys & LCD_KEY_BLUE)
{
PrintSetLCD(0,0,"Blue");
}
Msleep(1000);
}
return 0;
}
hi m.a.r.v.i.n,
danke, hast mir sehr geholfen. habe ein bischen mit dem code experimentiert, folgendes noch geändert:
key |= (PIND&LCD_KEY_RED); //PINB in PIND
und bei der umstellung in outputpins:
DDRD &= ~((0<<PD2)|(0<<PD6));
DDRB &= ~(0<<PB3);
überall 0 eingesetzt...
Jetzt kann es wieder ein bischen weitergehen...
btw:
nicht so ganz, aber fast.
darüber habe ich mich richtig gefreut. Wenn ich ein paar monate zurückdenke, heute konnte ich sogar die meisten änderungen von Dir nachvollziehen und verstehen...
m.a.r.v.i.n
01.12.2007, 12:55
Hallo inka,
key |= (PIND&LCD_KEY_RED); //PINB in PIND
das stimmt natürlich. :oops:
DDRD &= ~((0<<PD2)|(0<<PD6));
DDRB &= ~(0<<PB3);
Das stimmt so leider nicht. Zum löschen von Bits wird eine 1 an die entsprechende Stelle geschoben. Dann wird das ganze bitweise negiert und mit dem aktuellen Wert UND-verknüft.
Assonsten funtkioniert das Programm bei mir ganz gut (Wenn man die Wartezeit auf 100ms verkürzt).
hi m.a.r.v.i.n,
so stand es in deinem code:
DDRD &= ~((1<<PD2)|(1<<PD6)); // roten und gelben Taster als Eingang definieren
DDRB &= ~(1<<PB3); // blauen Taster als Eingang definieren
DDRD &= ~((1<<PD2)|(0<<PD6)); // roten und gelben Taster als ausgang definieren
DDRB &= ~(1<<PB3); // blauen Taster als ausgang definieren
ist es nicht so, dass ich bei allen drei pins mit einer "1" auf eingang schalte und mit einer "0" auf ausgang?
bei dem hier:
DDRD &= ~((0<<PD2)|(0<<PD6));
DDRB &= ~(0<<PB3);
wie kann ich an der hardware erkennen, dass es nicht richtig ist? Also dass der pin 2 und 3 - da habe im gegensatz zu deiner version ja die nullen eingesetzt - nun nicht als ausgänge definiert sind? Eine (irgendwelche) fehlermeldung beim compilieren, oder eine fehlfunktion konnte ich nicht beobachten...
Zum löschen von Bits wird eine 1 an die entsprechende Stelle geschoben. Dann wird das ganze bitweise negiert und mit dem aktuellen Wert UND-verknüft. das verstehe ich nicht: oben im ersten umstellen wird doch mit 3 "1" auf eingang geändert? Oder verwechsle ich da was?
m.a.r.v.i.n
01.12.2007, 13:45
Hallo inka,
ich Schussel. Um die Pins als Ausgang zu schalten, müssen diese natürlich gesetzt werden, nicht gelöscht.
DDRD |= ((1<<PD2)|(1<<PD6));
DDRB |= (1<<PB3);
Zum näheren Verständnis siehe hier:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Schreiben_von_Bits
Edit:
Ob die Ports dann wieder korrekt sind, kann man am einfachsten überprüfen, in dem man in das Programm eine serielle Ausgabe einbaut.
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.