Johann schrieb:> könnte das so funktionieren.
vermutlicht nicht, denn wenn by nicht 75 und nicht -45 passiert nichts.
Warum testest du es nicht einfach?
Nicht so ganz.
Du machst folgendens:
---------------
Nur wenn die Variable by den Wert 75 hat wird by 76
Nur wenn die Variable by den Wert -45 hat wird by 44
Augabe des Wertes
-------------
Sonnst passiert nichts im Code
if ( by == 75 ) --> bedeute ja mache was wenn genau gleich wie die
angegebene Zahl
Was möchtest du denn überhaupt machen?
Deine Abfragen könnte man natürlich richtig machen:
Wenn BY ==75 Flag=1
Wenn BY==-45 Flag=0
Wenn Flag=1 BY--
ansonsten BY++
So ungefähr
Grüße Michael
Was ich machen möchte ist erstmal nur das vergleichen der Negativen
werte hier -45 und das ausgen des negativen wertes, da stehe ich derzeit
bischen auf'n Schlauch.
Meine Ausgabe ist nicht -45 sonder 210.
Zeig doch bitte deinen richtigen, kompletten Code.
Nicht irgendwelchen Code, den du fürs Forum zurecht gemacht hast.
Denn wie Daniel schon richtig eingewendet hat: Der Code, den du (um
15:55) gepostet hast, gibt gar nichts aus.
Und selbst wenn er etwas ausgeben würde, dann ganz sicher nicht 210. Die
müssen also von wo anders herkommen.
bei dem letzen code wird immer 75 oder -45 ausgegeben - das ist
bestimmt nicht was du willst.
Teste doch bitte dein code einfach mal im simulator oder auf dem PC.
Dann sieht doch doch selber was passiert.
wozu brauchst du 2 Funktionen, die komplett das gleiche machen? Sowas
verwirrt nur.
Du brauchst eine Funktion die einen 'int' ausgibt. Ob dieser int dann
ein Wert oder eine Kanalnummer ist, ist ja der Funktion wieder wurscht.
Die kriegt einen int, und den gibt sie aus.
Karl Heinz Buchegger schrieb:>> void outtgValue( uint8_t x1,uint8_t x2, uint8_t x3,> uint8_t y1,uint8_t y2,>> uint8_t valuetg )> *******>> das steckt der Übeltäter.
vielen Dank,wenn jemand anders drüberschaut ist es schnell gefunden
> Abgesehen davon> void outtgValue( uint8_t x1,uint8_t x2, uint8_t x3,uint8_t y1,uint8_t y2,
uint8_t valuetg )
>> void outtgchan( uint8_t x1,uint8_t x2,uint8_t x3, uint8_t y1,uint8_t y2, uint8_t
chantg )
>> wozu brauchst du 2 Funktionen, die komplett das gleiche machen? Sowas> verwirrt nur.> Du brauchst eine Funktion die einen 'int' ausgibt. Ob dieser int dann> ein Wert oder eine Kanalnummer ist, ist ja der Funktion wieder wurscht.> Die kriegt einen int, und den gibt sie aus.
Ja stimmt ist Doppelt-gemoppelt
vielen Dank nochmals
mfg
Rein aus Neugier:
Kann es sein, dass du nicht verstanden hast, dass man eine Zahl auch
programmtechnisch in High-Byte und Low-Byte zerlegen kann und zwar in
einer möglichst tiefen Ausgabeschicht, damit derjenige der die
Ausgabefunktionen benutzen will, sich nicht damit abplagen muss, mit dem
Taschenrechner das zu tun?
Anders kann ich mir deine x und y Koordinaten nämlich nicht erklären.
Und warum es da 3 x Koordinaten aber nur 2 y Koordinaten gibt, schon
gleich gar nicht.
Johann schrieb:> Karl Heinz Buchegger schrieb:>>> void outtgValue( uint8_t x1,uint8_t x2, uint8_t x3,>> uint8_t y1,uint8_t y2,>>>> uint8_t valuetg )>> *******>>>> das steckt der Übeltäter.> vielen Dank,wenn jemand anders drüberschaut ist es schnell gefunden
Eben.
Und jetzt vergleich mal diesen Fehler mit dem was du ursprünglich
gepostet hast :-) Absolut kein Zusammenhang.
Karl Heinz Buchegger schrieb:> Rein aus Neugier:> Kann es sein, dass du nicht verstanden hast, dass man eine Zahl auch> programmtechnisch in High-Byte und Low-Byte zerlegen kann und zwar in> einer möglichst tiefen Ausgabeschicht, damit derjenige der die> Ausgabefunktionen benutzen will, sich nicht damit abplagen muss, mit dem> Taschenrechner das zu tun?>> Anders kann ich mir deine x und y Koordinaten nämlich nicht erklären.> Und warum es da 3 x Koordinaten aber nur 2 y Koordinaten gibt, schon> gleich gar nicht.
Es handelt sich um ein 640x480Pixel LCD SW welches von einenm ATmega128
Gesteuert wird.
outtgValue( 255,1,69, 23,1, TempgWert[12] );
Das heißt in X=255+255+69=579, setze den ersten Pixel in X bei 579
und in Y=255+23=278,setze den ersten Pixel in Y bei 278.
Da ich ja in 8Bit nur bis 255 zählen kann,Daher dieses Konstruct.
mfg
Johann schrieb:> Das heißt in X=255+255+69=579, setze den ersten Pixel in X bei 579> und in Y=255+23=278,setze den ersten Pixel in Y bei 278.> Da ich ja in 8Bit nur bis 255 zählen kann,Daher dieses Konstruct.
Es ist ja nicht in Stein gemeisselt, dass die Stringausgabefunktion nur
uint8_t Werte als Argumente haben darf :-)
Mach halt uint16_t draus, dann brauchst du beim Aufruf nicht selber die
Bytes zu zerlegen, das kann die Stringausgabefunktion ganausogut auch
selber erledigen.
outtgValue( 175, 279, TempgWert[0] );
outtgValue( 175, 299, TempgWert[1] );
outtgValue( 175, 319, TempgWert[2] );
outtgValue( 175, 399, TempgWert[3] );
...
liest sich doch gleich viel besser als
outtgValue( 175,0,0, 23,1, TempgWert[0] );
outtgValue( 175,0,0, 43,1, TempgWert[1] );
outtgValue( 175,0,0, 63,1, TempgWert[2] );
...
und ausserdem ermöglicht es dir dann auch, dass du die Werte errechnen
kannst.
for( i = 0; i < 6; i++ )
outtgValue( 175, 279 + i * 20, TempgWert[i] );
Dasselbe nochmal für x (eine Formel finden) und noch ein bischen
umformen und dein ganze "halbseitige" Ausgabefunktion dampft sich auf
einen 3-Zeiler ein, bei dem #garantiert# ist, dass die Abstände immer
gleich sind, auch ohne dass du 20 Minuten mit dem Taschenrechner
händisch rumrechnest.
Es lohnt nicht, bei den untersten Schichten faul zu sein. Du verschiebst
damit Detailprobleme immer nur zum Aufrufer und machst dem mehr Arbeit
als notwendig. Ganz abgesehen davon, dass sowas meistens Flexibilität
kostet. So wie hier.
Sorg dir 'unten' für Komfort. Noch dazu, wo er wie in deinem Fall so
einfach zu erreichen ist. Einen 16 Bit Wert in 2 Stück 8 Bit Werte zu
zerlegen ist doch trivial.
uint_16_t Wert = 279;
uint8_t HighByte = Wert >> 8;
uint8_t LowByte = Wert;
Du musst dir Funktionen immer so schreiben, dass sie einfach zu benutzen
sind! Und nicht die Argumente so wählen, dass du die Funktion einfach
implementieren kannst. Denn damit verlagerst du die Arbeit nur an eine
andere Stelle (im schlimmsten Fall an den Programmierer, und das ist die
schlechteste aller Möglichkeiten)
ich habe nochmal eine Frage,
ich möchte 2 ARRAYs vergleichen
in TempWert steht meine Temperratur mit vorzeichen drin allerdings in
ASCII
und in TempgWert mein Grenzwert in Dezimal,
Vielleicht kann mir jemand von ihnen weiterhelfen
mfg
Umrechnung ASCII-Dezimal: '0' (<--das ist für den Compiler eine Zahl!)
von jeder Ziffer abziehen.
if ( TempWert[0]=='+' && TempWert[1]-'0'==TempgWert[1] &&
TempWert[2]'0'==TempgWert[2] )
Desweiteren:
-ordentlich einrücken
-du brauchst ein putstring:
void putstring (char * c)
{
for(;*c,c++)
uart_putc(*c);
}
> in TempWert steht meine Temperratur mit vorzeichen drin> allerdings in ASCII
An dieser Stelle musst du dich schon mal fragen: Warum?
Warum hast du eine Stringrepräsentierung für eine Zahl und versuchst mit
der weiterzuarbeiten.
Wenn du Zahlen hast, und Temperaturen sind zweifellos welche, dann
speichere sie auch als Zahlen und nicht als Strings. Denn dann wird
alles plötzlich wieder trivial: Zahlen kann man leicht auf größer oder
kleiner vergleichen.
Das ist im Grunde wieder genau das gleiche wie weiter oben: Du machst
dir selbst das Leben schwer, weil du an den falschen Stellen ansetzt.
Wenn du die Temperatur von irgendeinem Sensor oder von einer
Benutzereingabe in Textform bekommst, dann wandle dir die beim Einlesen
SOFORT in eine Zahl um. Zögerst du das hinaus, dann wirds nur in
weiterer Folge aufwendiger, aber gewonnen hast du nichts dabei. Selbst
wenn es auf den ersten Blick so aussehen mag als ob, weil du ja so toll
den Wert vom Sensor gleich auf ein LCD ausgeben kannst. Das du dich
dabei bei der Verarbeitung des Zahlenwertes in Textform selbst
behinderst, übersiehst du dabei geflissentlich. Dabei hättest du auch
noch so eine schöne Ausgabefunktion, mit der du so einen int wieder ganz
leicht ausgeben kannst, d.h. der Vorteil von zuerst ist in Wirklichkeit
gar keiner, weil dich die Temperatur in einem int gespeichert nämlich
überhaupt nicht bei der Ausgabe behindert.
Also: Wo kommt diese Temepratur her, die du nur in Textform hast. Dort
ist dein Ansatzpunkt. Den String, der den Wert hält, den wirfst du raus
und ersetzt ihn durch ebenfalls einen int. Und plötzlich wird alles ganz
einfach.
ich habe hier das kommplette Programm welches die Temperratur
einliesst,Ausgibt und wo ich mein Grenzwert für jeden Sensor einstelle.
Das Temperratur-EEinlesen ist vielleicht nicht die beste lösung.
im Anhang das Programm welches die Temperratur sendet.
mfg
1
signedintTempgWert[18];//Grenzwerte für 18 DS18S20
troll schrieb:> Für den Rest des Programms gilt vermutlich das selbe...
tut es.
Puuuh. Wo soll man da blos anfangen?
Copy&Paste ist nun mal kein Ersatz für fehlendes Wissen bzw.
Kreativität.
Johann.
Dein ganzer bisheriger Code lässt sich auf weniger als eine
Bildschirmseite programmieren.
Ich bin schon fast versucht zu sagen: Schmeiss ihn weg. Das taugt nix.
Hol dir ein Einsteigerbuch für C und mach um Gottes Willen die ersten
paar Kapitel durch!
ich hatte ja schon gesagt das mann dass sicher besser machen kann,
meine Werte vom Temperraturmodul kommen jetzt nicht mehr als ASCII.
Ich brauche doch 2ARRAYs einmal der Tempwert und einmal der Grenzwert
oder irre ich mich da.
Mein Problem ist j wie ich die 2 Werte miteinander vergleiche.
Das War ja meine Frage.
Mfg
Johann schrieb:> ich hatte ja schon gesagt das mann dass sicher besser machen kann,
Nicht'kann' - MUSS
> meine Werte vom Temperraturmodul kommen jetzt nicht mehr als ASCII.> Ich brauche doch 2ARRAYs einmal der Tempwert und einmal der Grenzwert> oder irre ich mich da.
Genau.
> Mein Problem ist j wie ich die 2 Werte miteinander vergleiche.
Du hast das falsche Problem.
Dein Problem ist, wie kann ich den Wert, den ich vom Sensor bekomme und
der eine Textrepräsentierung einer Zahl ist, in eine Zahl umwandeln.
atoi macht das
Aber erst mal muss dein Code restrukturiert werden. So wie der jetzt
ist, kann das nicht bleiben. Da kannst du keine Änderungen vornehmen,
ohne dass du dich zu Tode editierst.
OK.
Erst mal musst du den Prozess des Einlesens der Werte von den Sensoren
von deren Anzeige trennen.
Dann musst du für die Werte, die du vom Sensor bekommt Variablen
anlegen.
Fangen wir mit letzterem an.
Ich nenne die dafür notwendigen 18 Stück INteger einfach mal Temperatur.
Die Variable int TempWert[96]; brauchst du nicht mehr. Lösch sie gleich
raus.
1
// Grenzwerte
2
signedintTempgWert[18];//Grenzwerte für 18 DS18S20
3
intactiveTempgWert=1;
4
5
// aktuelle Temperaturwerte aller Sensoren
6
intTemperature[18];
to be continued (muss mich erst mal weiter orientieren, wies weiter
geht)
OK.
Der erste Streich.
Das Einlesen eines Sensorwertes funktioniert offenbar so, dass da ein
Text daherkommt, desen erstes Zeichen '1'..'9' 'A'..'H' den Sonsor
identifiziert und danach kommt der Sensorwert
Dafür machen wir gleich mal eine Funktion, die eine Zeile einliest und
anhand des ersten Zeichens entscheidet um welchen Sensor es sich handelt
und den gelesenen Wert als Zahl(!) in den richtigen Array Eintrag im
Temperatur Array schreibt.
1
voidgetSensor()
2
{
3
charinLine[20];
4
charc;
5
uint8_ti;
6
uint8_tsensorNr;
7
8
// eine Zeile komplett einlesen
9
c=uart_getchar();
10
while(c!='\r'&&i<sizeof(inLine)-2){
11
if(c!='\n'&&c!=' ')
12
inLine[i++]=c;
13
}
14
inLine[i]='\0';
15
16
// das erste Zeichen sagt aus, welcher Sensor das ist
17
if(inLine[0]>='0'&&inLine[0]<='9')
18
sensorNr=inLine[0]-'0';
19
elseif(inLine[0]>='A'&&inLine[0]<='H')
20
sensorNr=inLine[0]-'A'+10;
21
else
22
sensorNr=255;
23
24
// wenn es sich um eine gültige Sensor Nummer handelt
25
// dann wandle den Rest des Strings in eine Zahl um
26
// und speichere sie im Temperatur Array zum korrekten Sensor
27
if(sensorNr!=255){
28
intmessWert=atoi(&inLine[1]);
29
Temperatur[sensorNr]=messWert;
30
}
31
}
Fertig. Diese Funktion handhabt schon mal jegliche Eingabe von der UART.
Da du eine schöne Funktion hast, die einen int anzeigen kann, kannst du
dir damit schon mal alle Sensorwerte am LCD ausgeben lassen.
An dem Müll, wie du Positionen am LCD identifizierst, musst du noch
arbeiten! Das ist immer noch der gleiche Unsinn.
gotoxy(175,0,0, 98,0 );
so kommst du nicht weiter.
Dein µC kann rechnen! Der tut nichts lieber als das.
Wenn du das hast, kannst du nämlich dann benutzen:
Deine x bzw. y Positionen am LCD lassen sich ganz leicht ausrechnen,
wenn du die Sensornummer hast. Aber dazu musst du die Ausgabe vernünftig
machen!
Du willst gotoxy so benutzen können, dass du x und y angibst. Und zwar
ohne dass du sich um Bytegrenzen kümmern musst. Du willst x direkt als
Wert von 0 bis 639 angeben können. Und du willst y als Wert von 0 bis
379 angeben können!
Denn dann kannst du dir aus der Sensornummer die x Koordinate errechnen
x = 175 + sensorNr / 6 * 247;
und du kannst dir aus der Sensornummer die y Koordinate errechnen
y = 98 + sensorNr % 6 * 21;
Deine ganze Ausgabeorgie dampft sich damit ein zu
1
voidoutputSensor(uint8_tsensorNr)
2
{
3
intx=175+sensorNr/6*247;
4
inty=98+sensorNr%6*21;
5
6
outtgValue(x,y,Temperatur[sensorNr]);
7
8
if(Temperatur[sensorNr]>TempgWert[sensorNr]){
9
gotoxy(x-50,y);
10
uart_puts("O");
11
}
12
else{
13
gotoxy(x-50,y);
14
uart_puts("m");
15
}
16
}
Fertig. Diese paar Codezeilen (dieser Post und der vorhergehende)
ersetzen die ganze komplizierte "Orgie" die du da hattest.
Aber du musst anfangen zu programmieren und nicht einfach nur COde zu
duplizieren! Dein µC kann rechnen! Benutze das. UNd wenn dir Funktionen
dafür nicht passen (wie zb die gotoxy) dann musst du sie dir eben
passend machen!
Hallo Karl Heinz Buchegger,
vielen vielen Dank das hätte ich in so kurzer zeit nicht Geschaft.
Um die Pixelposition so wie von Ihnen vorgeschlagen muss ich den
LCD-Controller noch Umschreiben.
Vom Temperratur-Modul kommen die Werte wie folgt:
SensorNummer, Vorzeichen, 2stellen vorm Punkt, Punkt,1 stellen nachdem
Punkt
zb.+18.4
Im Display wird mir 29127 angezeigt.
mfg
Johann schrieb:> SensorNummer, Vorzeichen, 2stellen vorm Punkt, Punkt,1 stellen nachdem> Punkt> zb.+18.4
Das Vorzeichen wäre kein Problem. atoi würde damit klarkommen.
Aber der Dezimalpunkt.
Du hast überall nur int vorgesehen, daher bin ich davon ausgegangen,
dass es keine Nachkommastellen gibt.
Aber ist kein Problem. Dann wird eben im int immer das 10-fache des
Temperaturwertes gespeichert. Die Zeile muss dann etwas anders zerlegt
werden um die Zahl als Zahl zu erhalten.
> Im Display wird mir 29127 angezeigt.
Dann geht mit der Übertragung was schief. Lass durch doch mal die
empfangene Zeile auf deinem LCD ausgeben, nachdem sie zusammengesetzt
wurde.
ich habe beim Tempmodul Testweise erstmal nur die ersten 4 Zeichen
ausgeben lassen,1+22 für einen Sensor.
Bekomme leider immernoch null angezeigt.
Sende ich die Zeichen zum Terminal in ASCII wirds mir korrekt angezeigt.
mfg
Johann schrieb:> So nun gehts :)> eine Frage hät ich noch, wie kann ich mit atoi mein Vorzeichen mit> ausgeben.> kann mir bitte einer von ihnen weiterhelfen
Du kannst ja bei der Ausgabe zb prüfen, ob deine Zahl >= 0 ist und wenn
ja, erst mal ein '+' ausgeben.
(Andere Möglichkeit wäre sprintf zu benutzen. Das kann man auch anweisen
auf jeden Fall ein Vorzeichen zu erzeugen)