Forum: Mikrocontroller und Digitale Elektronik Temperaturanzeige mit PIC16f872 und LCD display problem


von oliver M. (mysticalframe)


Angehängte Dateien:

Lesenswert?

Das war mein erster Schaltplan den ich selber gemacht habe und ebenso 
das C-Programm also nicht wundern wenn ihr dort komische Sachen sieht.
Kurz zur schaltung selber:
Die Temperatursensoren messen xx grad geben dann xx mV weiter und der OP 
verstärkt dieses dann und gibt dann x V an den PIC anschließend dann 
kommt das Signal an das Display
LM317 ist auf 5,120V eingestellt
4093 ist zum entprellen vom Taster zuständig der die Temperaturen 
weiterschaltet LO/LU/RO/RU
Der 5k Poti am display ist für die Helligkeit und der R7 47,5ohm ist für 
die Hintergrundbeleuchtung.
Hat extra kein AN/Aus schalter da es 24/7 laufen soll


Temperatursensor: 4x LM35DZ + 1,5m Lange kabel pro sensor
Feuchtigkeitssensor: HIH4031 + 1m langes kabel
PIC 16F872

Nun zum Problem selber:
Die schaltung und auch die Ausgabe funktioniert wunderbar, für 1 tag, 
dann sind für 2tage oder länger bis ich die schaltung ausschalte nur 
komische zeichen auf dem Display (Foto's folgen demnächst) und wenn ich 
die Schaltung wieder einschalte kommen entweder wieder komische Zeichen 
oder es funktioniert wunderbar, es kann auch mal vorkommen das es für 
2tage funktioniert

Fazit: Es kommen komische Zeichen auf meinem Display.

Woran kann das liegen ?



1
#define Vsupply 5.12
2
#define A1 6.2
3
#define A2 1054
4
#define A3 2.16
5
unsigned char txt[3];
6
unsigned short taster = 1, lcd, rh, Mittelwert, stop = 1;
7
unsigned int analog, test, ad, Mitte, LU, RU;
8
9
sbit LCD_RS at RC7_bit;
10
sbit LCD_EN at RC6_bit;
11
sbit LCD_D4 at RC3_bit;
12
sbit LCD_D5 at RC2_bit;
13
sbit LCD_D6 at RC1_bit;
14
sbit LCD_D7 at RC0_bit;
15
16
sbit LCD_RS_Direction at TRISC7_bit;
17
sbit LCD_EN_Direction at TRISC6_bit;
18
sbit LCD_D4_Direction at TRISC3_bit;
19
sbit LCD_D5_Direction at TRISC2_bit;
20
sbit LCD_D6_Direction at TRISC1_bit;
21
sbit LCD_D7_Direction at TRISC0_bit;
22
23
24
char *temp = "0000.0";               // Temperaturdarstellung
25
26
void main()
27
{
28
//Einstellen der I/O-Ports
29
30
31
TRISA = 255;
32
ADCON1 = 128;
33
PORTA = 0;
34
35
TRISB = 1;
36
PORTB = 0;
37
38
TRISC = 0;
39
PORTC = 0;
40
41
// Timer1 Einstellungen
42
43
PIR1.TMR1IF = 0;
44
PIE1.TMR1IE = 1;
45
46
TMR1H = 11;
47
TMR1L = 220;
48
T1CON.TMR1ON = 1;
49
T1CON.TMR1CS = 0;
50
T1CON.T1OSCEN = 0;
51
T1CON.T1CKPS0= 1;
52
T1CON.T1CKPS1= 1;
53
54
//Interrupt Einstellungen
55
56
Option_Reg.Intedg = 0;
57
INTCON.INTF = 0;
58
INTCON.INTE = 1;
59
INTCON.GIE = 1;
60
INTCON.PEIE = 1;
61
62
//Display initialisieren
63
64
Lcd_Init();
65
Lcd_Cmd(_LCD_CLEAR);
66
Lcd_Cmd(_LCD_CURSOR_OFF);
67
delay_ms(5);
68
69
//Hauptprogramm
70
71
while(1)
72
{
73
 ad = ADC_read(4);             // Luft
74
 ad = ad*5;
75
76
if(taster == 1) test = ADC_Read(0);         // Temperatur lo
77
if(taster == 2) test = ADC_Read(1);         // Temperatur lu
78
if(taster == 3) test = ADC_Read(2);         // Temperatur ro
79
if(taster == 4) test = ADC_Read(3);         // Temperatur ru
80
81
if(Stop == 4) {
82
83
 analog = test*10;
84
 temp[0] = ' ';
85
 temp[1] = ' ';
86
 temp[2] = (analog/1000)%10 + 48;       // Zehnerstelle
87
 temp[3] = (analog/100)%10 + 48;        // Kommastelle
88
 temp[5] = (analog/10)%10 + 48;         // Einerstelle
89
 Lcd_Out(1, 9, temp);                   // Temperatur auf dem Display ausgeben
90
 
91
92
 LU = ADC_Read(1);
93
 RU = ADC_Read(3);
94
 
95
 ad = ad/Vsupply;                // Rechnet
96
 ad = ad-160;                    // RH = ((Vout*5 /Vsupply ) - 160) / 6.2
97
 ad = ad/A1;                     // Sensor RH bei 25°C aus
98
99
 Mitte = (LU+RU)/2;              // Mittelwert von Temperatur Links + Rechts unten
100
 
101
 Mitte = Mitte;               //
102
 Mitte = A3*Mitte;               //
103
 Mitte = A2-Mitte;               //
104
 Mitte = Mitte/10;
105
 ad = ad*100;         // True RH =(Sensor RH)/(1,0546-0,00216*Temperatur)
106
 ad = ad/Mitte;                                // Geht über den Speicher
107
108
shorttoStr(ad, txt);            // Umwandeln
109
lcd_out(2,12,txt);              // Ausgeben
110
Lcd_Chr(2,16,'%');              //
111
112
delay_ms(1);
113
Lcd_Out(2,1,"Luftfeuchte:");
114
delay_ms(1);
115
Lcd_Chr(1,15,223);
116
delay_ms(1);
117
Lcd_Chr(1,16,'C');
118
if(taster == 1) Lcd_Out(1,1,"Temp LO:");
119
if(taster == 2) Lcd_Out(1,1,"Temp LU:");
120
if(taster == 3) Lcd_Out(1,1,"Temp RO:");
121
if(taster == 4) Lcd_Out(1,1,"Temp RU:");
122
if(taster == 0) Lcd_Out(1,1, "Error");
123
}
124
}
125
}
126
void interrupt()
127
{
128
if (INTCON.INTF == 1) {
129
taster = taster++;
130
if(taster == 5) taster = 1;
131
INTCON.INTF = 0;
132
}
133
if (PIR1.TMR1IF == 1) {
134
Stop = Stop++;
135
if(Stop == 5) Stop = 1;
136
TMR1H = 11;
137
TMR1L = 220;
138
PIR1.TMR1IF = 0;
139
}
140
}

Würde mich über Hilfe freuen :)

von Nico (nico123)


Lesenswert?

Was genau heißt "komische Zeichen"? Alle Zeichen, also Text und variable 
Zahlenwerte? Ändern sich die Zeichen trotzdem noch?

von Karl H. (kbuchegg)


Lesenswert?

Also das hier
1
char *temp = "0000.0";               // Temperaturdarstellung
2
3
....
4
5
 temp[0] = ' ';
6
 temp[1] = ' ';
7
 temp[2] = (analog/1000)%10 + 48;       // Zehnerstelle
8
 temp[3] = (analog/100)%10 + 48;        // Kommastelle
9
 temp[5] = (analog/10)%10 + 48;         // Einerstelle
10
....

darfst du grundsätzlich nicht tun.
"0000.0" ist ein Stringliteral und du darfst es nicht ändern.
1
char temp[] = "0000.0";

aber ich denke nicht, dass das jetzt dein eigentliches Problem ist. Denn 
wenn der Compiler den String als nicht änderbaren String ins Flash 
gelegt hätte, dann würdest du ihn überhaupt nicht ändern können. Und das 
hättest du sofort gesehen. Nichts desto trotz ist es ein Fehler und 
gehört geändert.



Was ist mit dem hier
1
unsigned char txt[3];

berücksichtigt
1
shorttoStr(ad, txt);            // Umwandeln
dass ad nur eine maximal 2 stellige Zahl sein darf?`Tut es das auch im 
Fehlerfall, wenn ad einen ungültigen Wert enthält?


Ich seh in deinem Code keine #includes oder Protoypen. Gibt es die 
überhaupt? Für alle Funktionen die du aufrufst?


Deine Symptome deuten in eine Richtung, dass an irgendeiner Stelle der 
Stack zerschossen wird.

von MaWin (Gast)


Lesenswert?

Das soll ein C-Programm sein ?

C ist schreibweisenabhängig, lcd_out keinesfalls dasselbe wie Lcd_Out.

Und das hier
taster = taster++;
Stop = Stop++;
ist ja wohl grober Unfug. Nach meiner Ansicht dürfte sich der Wert gar 
nicht ändern, aber dein Compiler sieht das wohl anders. Das Verhalten 
ist laut C zumindest undefiniert.

Der Unsinn, den Taster mit Hardware zu entprellen, dann per Interrupt 
auszuwerten, ohne daß die Werte taster und stop als volatile 
gekennzeichnet sind, ist auch daneben.

Und viel aufwändiger, als es gleich richtig zu machen, ohne Hardware, 
ohne Interrupt, mit nur einer Abfrage pro main while Schleifendurchlauf.
1
uint8_t taste,gedrueckt;
2
3
while(1) // deine Programm-Hauptschleife
4
{
5
  taste=PINB&1;
6
  gedrueckt=taste&~gedrueckt;
7
  if(gedrueckt)
8
  {
9
    taster=(taster%4+1);
10
  }
11
  // Rest deiner Hauptschliefe
12
  gedrueckt=taste;
13
}

Warum man
if(taster == 1) test = ADC_Read(0);         // Temperatur lo
if(taster == 2) test = ADC_Read(1);         // Temperatur lu
if(taster == 3) test = ADC_Read(2);         // Temperatur ro
if(taster == 4) test = ADC_Read(3);         // Temperatur ru
nicht zu
test = ADC_Read(taster-1);
verkürzt, ist auch schleierhaft.

von Karl H. (kbuchegg)


Lesenswert?

> nur komische zeichen auf dem Display

Wie komisch sind denn die Zeichen?
Könnten das japanische Zeichen sein?
Oder ist das eher in die Kategorie 'wirre Pixel' einzuordnen?

von oliver M. (mysticalframe)


Lesenswert?

Nico ... schrieb:
> Was genau heißt "komische Zeichen"? Alle Zeichen, also Text und variable
> Zahlenwerte? Ändern sich die Zeichen trotzdem noch?

Wie gesagt kommen komische zeichen "?0?(" Pfeile und diese ändern sich 
weiter also z.b wird aus einem ? eine 0 oder aus einem = ein ?
bekommen demnächst bilder wie genau das ausschaut und werde dann die 
Bilder hier hochstellen


Karl Heinz Buchegger schrieb:
> Also das hier
> char *temp = "0000.0";               // Temperaturdarstellung
>
> ....
>
>  temp[0] = ' ';
>  temp[1] = ' ';
>  temp[2] = (analog/1000)%10 + 48;       // Zehnerstelle
>  temp[3] = (analog/100)%10 + 48;        // Kommastelle
>  temp[5] = (analog/10)%10 + 48;         // Einerstelle
> ....
>
> darfst du grundsätzlich nicht tun.
> "0000.0" ist ein Stringliteral und du darfst es nicht ändern.
> char temp[] = "0000.0";

also müsste ich es ungefähr so programmieren ?
char temp[] = "";
oder komplett entfernen
da dachte ich mir halt das er am anfang 0000.0 reingeschreibt und diese 
Zeichen dann ersetzt
aber vielen dank :) werd ich mir merken


> aber ich denke nicht, dass das jetzt dein eigentliches Problem ist. Denn
> wenn der Compiler den String als nicht änderbaren String ins Flash
> gelegt hätte, dann würdest du ihn überhaupt nicht ändern können. Und das
> hättest du sofort gesehen. Nichts desto trotz ist es ein Fehler und
> gehört geändert.
>
>
>
> Was ist mit dem hierunsigned char txt[3];
>
> berücksichtigtshorttoStr(ad, txt);            // Umwandeln
> dass ad nur eine maximal 2 stellige Zahl sein darf?`Tut es das auch im
> Fehlerfall, wenn ad einen ungültigen Wert enthält?

Ja genau
Naja im Fehlerfall z.b. kein Sensor dann steht trotzdem ein wert dran 
(unterschiedlich)


> Ich seh in deinem Code keine #includes oder Protoypen. Gibt es die
> überhaupt? Für alle Funktionen die du aufrufst?

Da ich am anfang überhaupt keine Ahnung hatte, habe ich ein wenig Hilfe 
von einem Kollegen bekommen und der meinte da brauch ich nichts, nur 
leider weiß er nun auch nicht mehr weiter sonst hätte ich Ihn schon 
gefragt

>
> Deine Symptome deuten in eine Richtung, dass an irgendeiner Stelle der
> Stack zerschossen wird.

Das bedeutet was ?

Tut mir leid für so viele Fragen aber bin ein sehr neuer Frischling in 
solchen Sachen :)

MaWin schrieb:
> Das soll ein C-Programm sein ?
>
> C ist schreibweisenabhängig, lcd_out keinesfalls dasselbe wie Lcd_Out.
>
> Und das hier
> taster = taster++;
> Stop = Stop++;
> ist ja wohl grober Unfug. Nach meiner Ansicht dürfte sich der Wert gar
> nicht ändern, aber dein Compiler sieht das wohl anders. Das Verhalten
> ist laut C zumindest undefiniert.
>
> Der Unsinn, den Taster mit Hardware zu entprellen, dann per Interrupt
> auszuwerten, ohne daß die Werte taster und stop als volatile
> gekennzeichnet sind, ist auch daneben.
>
> Und viel aufwändiger, als es gleich richtig zu machen, ohne Hardware,
> ohne Interrupt, mit nur einer Abfrage pro main while Schleifendurchlauf.
> uint8_t taste,gedrueckt;
>
> while(1) // deine Programm-Hauptschleife
> {
>   taste=PINB&1;
>   gedrueckt=taste&~gedrueckt;
>   if(gedrueckt)
>   {
>     taster=(taster%4+1);
>   }
>   // Rest deiner Hauptschliefe
>   gedrueckt=taste;
> }
>
> Warum man
> if(taster == 1) test = ADC_Read(0);         // Temperatur lo
> if(taster == 2) test = ADC_Read(1);         // Temperatur lu
> if(taster == 3) test = ADC_Read(2);         // Temperatur ro
> if(taster == 4) test = ADC_Read(3);         // Temperatur ru
> nicht zu
> test = ADC_Read(taster-1);
> verkürzt, ist auch schleierhaft.

Tut mir ja leid das das mein erstes Programm war, und ich kein Profi 
bin.
Bin über Tipps dankbar, danke

EDIT: Das mit der Stop funktion ist drin damit das LCD-Display nur 1x 
jede Sekunde überschrieben wird ( war mein erstesr lösungsvorschlag ) 
aber hat nicht geklappt davor war nur der tasterinteruppt drin
hab mir das ganze mal mit der verkürzten version angeschaut und 
eigentlich ist es ja logisch :) danke war ein guter tipp


Karl Heinz Buchegger schrieb:
>> nur komische zeichen auf dem Display
>
> Wie komisch sind denn die Zeichen?
> Könnten das japanische Zeichen sein?
> Oder ist das eher in die Kategorie 'wirre Pixel' einzuordnen?

Man kann sagen wirre Pixel ja, mit buchstaben zahlen und sonderzeichen
ich denke morgen / Freitag habe ich die Bilder

von Karl H. (kbuchegg)


Lesenswert?

oliver Mayrock schrieb:

> Wie gesagt kommen komische zeichen "?0?(" Pfeile und diese ändern sich
> weiter also z.b wird aus einem ? eine 0 oder aus einem = ein ?
> bekommen demnächst bilder wie genau das ausschaut und werde dann die
> Bilder hier hochstellen

Das sind keine 'komische Zeichen' sondern da wird irgendein Text aufs 
Display geschrieben.

Ein komisches Zeichen wäre eines bei dem unmotiviert irgendwelche Pixel 
anstelle von regulären ASCII-Zeichen ausgegeben wird. 'komisch' ist kein 
definierter Terminus und hat in einer Fehlerbeschreibung nichts 
verloren.

>> "0000.0" ist ein Stringliteral und du darfst es nicht ändern.
>> char temp[] = "0000.0";
>
> also müsste ich es ungefähr so programmieren ?
> char temp[] = "";
> oder komplett entfernen

Ich hab dir doch hingeschrieben, wie es lauten muss.
1
char temp[] = "0000.0";


> da dachte ich mir halt das er am anfang 0000.0 reingeschreibt

da wird überhaupt nichts reingeschrieben.
MIt

char *temp

resiervierst du einen Pointer der auf einen Text zeigt. Und dieser 
Pointer zeigt auf ein Stringliteral, welches unveränderlich ist.

Mit
char temp[]

reservierst du hingegen ein Array, und der Arrayinhalt ist veränderbar. 
Der Arrayinhalt wird mit "0000.0" iniitialisiert aber danach kannst du 
die einzelnen Zeichen ändern soviel du lustig bist.

--->  C-Buch besorgen!


>> Was ist mit dem hierunsigned char txt[3];
>>
>> berücksichtigtshorttoStr(ad, txt);            // Umwandeln
>> dass ad nur eine maximal 2 stellige Zahl sein darf?`Tut es das auch im
>> Fehlerfall, wenn ad einen ungültigen Wert enthält?
>
> Ja genau
> Naja im Fehlerfall z.b. kein Sensor dann steht trotzdem ein wert dran
> (unterschiedlich)

Mit ist wurscht welchern Wert du da reingibst. Entscheidend ist, dass in 
ein Array der Länge 3 nur einen Text mit maximal 2 Zeichen unterbringst. 
Versuchst du da irgendwas größeres da drinn unterzubringen

   strcpy( txt, "Hallo Welt" );

dann -> Peng.

Und ja. Das umfasst auch den Fall, dass dies irrtümlich passiert, weil 
shorttoStr entweder selbst einen Fehler hat oder mit einem Wert 
aufgerufen wird, der größer als 99 oder kleiner als -9 ist (du hast doch 
negative Zahlen berücksichtigt oder nicht?)


> Da ich am anfang überhaupt keine Ahnung hatte, habe ich ein wenig Hilfe
> von einem Kollegen bekommen und der meinte da brauch ich nichts,

Der war gut.

-> Prototypen rein. Aber dalli dalli

von Karl H. (kbuchegg)


Lesenswert?

> Tut mir ja leid das das mein erstes Programm war, und ich kein
> Profi bin.

Das hat mit Profi recht wenig zu tun. Eher mit der Bereitschaft auch mal 
was zu 'riskieren' und einen Zusammenhang von 2 Zahlen in Form einer 
Berechnung auszudrücken.

von Karl H. (kbuchegg)


Lesenswert?

oliver Mayrock schrieb:

> Man kann sagen wirre Pixel ja, mit buchstaben zahlen und sonderzeichen
> ich denke morgen / Freitag habe ich die Bilder


Nein, kann man nicht.
Zahlen, Buchstaben, Sonderzeichen, das alles sind geordnete Pixelhaufen, 
die genau so angezeigt werden wie sie sollen. Das LCD kann ja nichts 
dafür, wenn es vom Programm die Anweisung bekommt, den 'Text' "0/&%"#?" 
anzuzeigen. Es tut das, was es soll und malt genau diese Zeichen hin. Da 
drann ist nichts komisch.

Wenn es aber so ein Zeichen hinmalt

   +---+---+---+---+---+
   |   | # |   |   |   |
   +---+---+---+---+---+
   |   |   |   |   | # |
   +---+---+---+---+---+
   |   | # |   |   |   |
   +---+---+---+---+---+
   | # |   |   |   |   |
   +---+---+---+---+---+
   |   |   | # | # | # |
   +---+---+---+---+---+
   |   |   |   |   |   |
   +---+---+---+---+---+
   |   |   | # |   |   |
   +---+---+---+---+---+


dann ist das ein komisches Zeichen. Denn dieses Zeichen existiert nicht 
im Zeichenvorrat des LCD. Taucht sowas trotzdem auf, dann gibt es 
irgendein Problem auf dem LCD (Kontroller abgestürzt oder Amok gelaufen, 
Verbindungsleitung abgerissen, Wackelkontakt oder sonstwas). >DAS< wäre 
ein "komisches" Zeichen.

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz Buchegger schrieb:

>> Da ich am anfang überhaupt keine Ahnung hatte, habe ich ein wenig Hilfe
>> von einem Kollegen bekommen und der meinte da brauch ich nichts,
>
> Der war gut.
>
> -> Prototypen rein. Aber dalli dalli

Und kauf dir ein C-Buch.
Davon hast du mehr als von einem Kollegen der selbst keine Ahnung hat.

von oliver M. (mysticalframe)


Lesenswert?

> Wenn es aber so ein Zeichen hinmalt
>
>    +---+---+---+---+---+
>    |   | # |   |   |   |
>    +---+---+---+---+---+
>    |   |   |   |   | # |
>    +---+---+---+---+---+
>    |   | # |   |   |   |
>    +---+---+---+---+---+
>    | # |   |   |   |   |
>    +---+---+---+---+---+
>    |   |   | # | # | # |
>    +---+---+---+---+---+
>    |   |   |   |   |   |
>    +---+---+---+---+---+
>    |   |   | # |   |   |
>    +---+---+---+---+---+
>
>
> dann ist das ein komisches Zeichen. Denn dieses Zeichen existiert nicht
> im Zeichenvorrat des LCD. Taucht sowas trotzdem auf, dann gibt es
> irgendein Problem auf dem LCD (Kontroller abgestürzt oder Amok gelaufen,
> Verbindungsleitung abgerissen oder sonstwas). >DAS< wäre ein "komisches"
> Zeichen.

Ich denke du meinst so ein rechteck mit kleinen freie punkte, die meine 
ich mit wirre Zeichen, solche sind auch auf dem Display drauf ,
Ich mein es funktioniert an sich schon nur ab und zu spackts halt rum
es ist auch schon 1 Woche ohne Fehler gelaufen dann kamm wieder der 
Fehler...

und wir lernen nun auch gerade in der Schule C-programmieren
Ok werd das mal mit Prototypen machen bzw ein Buch besorgen

von Karl H. (kbuchegg)


Lesenswert?

oliver Mayrock schrieb:

> Ich denke du meinst so ein rechteck mit kleinen freie punkte, die meine
> ich mit wirre Zeichen, solche sind auch auf dem Display drauf ,

OK.
Machen wirs kurz
Hier

http://de.wikipedia.org/wiki/HD44780#Schrift_und_Zeichensatz

ist der Vorrat an darstellbaren Zeichen, die dein LCD höchst 
wahrscheinlich kann (es gibt auch welche mit kyrillischen Zeichen, aber 
ich glaube nicht, dass du so eines hast). Beachte die rechte Hälfte. 
Sind deine 'komischen' Zeichen da dabei, oder nicht?
Alles was das LCD anzeigt und was sich in dieser Tabelle findet ist so 
erst mal in Ordnung.
Beunruhigend (aus Sicht des LCD) wird es erst dann, wenn auf deinem LCD 
sich Pixelhaufen finden, die es nicht in dieser Tabelle gibt. Denn dann 
rückt der Verdacht eines Hardware-Problems in den Vordergrund.

von Karl H. (kbuchegg)


Lesenswert?

oliver Mayrock schrieb:

> und wir lernen nun auch gerade in der Schule C-programmieren

Dann sollte dir dein Lehrer mal mit dem Zusatz 'äussere Form' ordentlich 
auf die Finger klopfen.

von oliver M. (mysticalframe)


Lesenswert?

Also bis jetzt sind es nur ganz normale Zeichen, (glaubt er zumindest) 
da dies nicht für mich war sondern für ein Kollege für sein Terarium.
Übernächste woche bekomme die Schaltung wieder zurück
und werd dann nochmal hier posten :)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.