die asuro bücher nutzen die lib von der cd. tie timebase ist da nicht 36khz, sondern 72 khz was alles zeitkritischen dinge versuat
Druckbare Version
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...
die ausgabe:Code: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);
}
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? ](*,)Code: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
3*941*100=282300!Zitat:
int batt_1,batt_2, batt_3, spannung;
...
spannung=(batt_3 + batt_2 + batt_1)*100/535;
(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
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.
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:
Es sollte aber so aussehen:Code:spannung_1=(batt_3 + batt_2 + batt_1)/535.1;
spannung=(batt_3 + batt_2 + batt_1)*100/535;
Zähler und Nenner mal 10, dann stimmts auch mit dem Komma im Ergebniss...Code:spannung_1=(batt_3 + batt_2 + batt_1)/535.1;
spannung=(batt_3 + batt_2 + batt_1)*10/5351;
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:
micCode:spannung_1=(batt_3 + batt_2 + batt_1)/535.1;
spannung=(int) spannung_1*100;
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... :(
Hallo inka,
das LCD aus dem Asuro Buch II funktioniert erst, wenn man im Header FileZitat:
was habe ich bei der initialisierung des lcd vergessen? Zumindest in der lcd.c habe ich weiter nichts gefunden?
i2c.h die beiden Defines für den I2C Bus folgendermaßen ändert.
De AsuroLib und die Programme müssen dann natürlich anschließend neu übersetzt werden.Code:#define SDA PC2
#define SCL PC3
hi m.a.r.v.i.n.
damit habe ich wohl immer noch probleme: mit AVR studio heisst "neu übersetzen":Zitat:
Zitat von m.a.r.v.i.n
- ändern
- rebuilt all
- flash...???
ausser dass die status-led beim starten von asuro von gelb in grün wechselt passiert aber leider nix :-(
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 :-(
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:
Die LCD Funktionen der AsuroLib sind leider aller vor Erscheinen des Asuro Buches entstanden.Code:////// 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
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?
Code: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?
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...:-)
Hallo inka,
Eigentlich beides. Den Code um zu sehen wie man die Funktionen anwendet, und auf dem Display sollte man verfolgen, wie das ganze dann aussieht.Zitat:
oder war es so gemeint, dass man sich den code anschauen kann?
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/uploa.../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?
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.
Nachteil dabei ist. Die IR Kommunikation und die rote Status LED funktionieren damit nicht mehr.Code: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
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?
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?
Code: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
???
}
Hallo inka,
nicht so ganz, aber fast. So könnte es vielleicht gehen. Ich kann das aber erst heute abend testen.
Code:#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:
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...Zitat:
nicht so ganz, aber fast.
Hallo inka,
das stimmt natürlich. :oops:Zitat:
key |= (PIND&LCD_KEY_RED); //PINB in PIND
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.Zitat:
DDRD &= ~((0<<PD2)|(0<<PD6));
DDRB &= ~(0<<PB3);
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:
ist es nicht so, dass ich bei allen drei pins mit einer "1" auf eingang schalte und mit einer "0" auf ausgang?Zitat:
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
bei dem hier:
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...Zitat:
DDRD &= ~((0<<PD2)|(0<<PD6));
DDRB &= ~(0<<PB3);
das verstehe ich nicht: oben im ersten umstellen wird doch mit 3 "1" auf eingang geändert? Oder verwechsle ich da was?Zitat:
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.
Hallo inka,
ich Schussel. Um die Pins als Ausgang zu schalten, müssen diese natürlich gesetzt werden, nicht gelöscht.
Zum näheren Verständnis siehe hier:Zitat:
DDRD |= ((1<<PD2)|(1<<PD6));
DDRB |= (1<<PB3);
http://www.mikrocontroller.net/artic...eiben_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.