Anfängerfrage: Wert umwandeln

Gast #2361281
Lesenswert?

Hallo,

ich bin nicht sehr erfahren beim programmieren also verzeiht mir bitte 
den Diletantismus.

Ich habe mal mit einem Bekannten etwas gebaut und programmiert das einen 
DS18S20 One Wire Temperatursensor ausließt und die Temperatur in einem 
2x8 LED Array anzeigt. Das Anzeigen funktioniert so, dass 4 LED für die 
Zahlen 1,2,4,8 stehen und je nachdem welche LED leuchten werden die 
Werte addiert.
Mit dem 10er Bereich ist es genau so.
1 [ ] [ ] 10
2 [x] [x] 20
4 [x] [ ] 40
8 [ ] [ ] 80

^^in dem Bsp leuchten die LED mit den Werten2, 4, 20  d.h. es sind 26°C

Jetzt muss ich mit einem weiteren Atmega diese LED's wieder auslesen und 
die ganze Sache wieder in einen Zahlenwert umwandeln so das der Atmega 2 
Werte miteinander vergleichen kann. Das Auslesen ist einfach, nur wie 
mache ich aus den Signalen von PIC und PIND etwas das ich mit < oder > 
vergleichen kann?

Das ist der Code der aus den Daten des DS18S20 die LED Hausnummer macht:
1
do
2
        {
3

4
                // Kommando an den Sensor (Messung starten)
5
                // >>Notiz>> Wir gehen einfach von einem Erfolg aus <<
6
                start_meas();
7
        
8
                // Temperatur vom Sensor holen
9
                t = read_meas_fast();
10
        t = t/8;
11
        u = t;
12

13
                // Temperatur in Grad Celsius:
14
                tC = (t >> 1) | (t & 0xFF00);
15
                if(tC < 0) tC = -tC; //Vorzeichen entfernen
16
                        
17

18
                //reset (alle LEDs aus)
19
                p = 0x00;
20

21
           //Konfiguration der Pins für LEDs setzen
22
                // (0 = LED an, 1 = LED aus)
23
                if(tC >= 80) { p |=(1<<7); tC -= 80; } //Pin7 für 80°C an
24
                if(tC >= 40) { p |=(1<<6); tC -= 40; } //Pin6 für 40°C an
25
                if(tC >= 20) { p |=(1<<5); tC -= 20; } //Pin5 für 20°C an
26
                if(tC >= 10) { p |=(1<<4); tC -= 10; } //Pin4 für 10°C an
27
                if(tC >= 8)  { p |=(1<<3); tC -= 8;  } //Pin3 für 8°C  an
28
                if(tC >= 4)  { p |=(1<<2); tC -= 4;  } //Pin2 für 4°C  an
29
                if(tC >= 2)  { p |=(1<<1); tC -= 2;  } //Pin1 für 2°C  an
30
                if(tC >= 1)  { p |=(1<<0); tC -= 1;  } //Pin0 für 1°C  an
31

32
           
33
        p = ~p;
34
        
35
        //Eichung des Thermometers
36
        LED_OUT = p;
37
        
38
                        
39
                // ein wenig warten verhindert,
40
                // dass der Sensor durch Selbsterw?rmung
41
                // falsche Ergebnisse liefert
42
                _delay_ms(1000);



Für das Auslesen und das Vergleichen habe ich bisher follgendes 
Auszugsweise:
1
#define WTEMP_IN   PINC        //Wärmebad abfragen
2
#define KTEMP_IN   PIND        //Kältebad abfragen  
3

4
//und die main:#########################
5

6

7
uint8_t w_temp = 0;          //Variable zum speichern der Zustände vom Wärmebad
8
uint8_t k_temp = 0;          //Variable zum speichern der Zustände vom Kältebad
9

10
KTEMP_DDR = 0x00;    //Eing?nge
11
WTEMP_DDR = 0x00;    //Eing?nge
12

13
        do
14
        {
15
      k_temp = KTEMP_IN;          //Temp vom Kältebad abholen
16
      w_temp = WTEMP_IN;          //Temp vom Wärmebad abholen
17

18
        if((p_temp <= k_temp + 1))   //fals Probentemp gleich Kältebadtemp ist
19
        {  Mache etwas }

Danke für die Hilfe

Gruß Rocco
#2361336
Lesenswert?

Rocco schrieb:

> Jetzt muss ich mit einem weiteren Atmega diese LED's wieder auslesen und
> die ganze Sache wieder in einen Zahlenwert umwandeln so das der Atmega 2
> Werte miteinander vergleichen kann. Das Auslesen ist einfach, nur wie
> mache ich aus den Signalen von PIC und PIND etwas das ich mit < oder >
> vergleichen kann?

Indem du in deinem Programm genau das gleiche machst, was du beim 
Ablesen der Temperatur als Mensch auch machst. Sprich: Du baust dir erst 
mal die durch die LED angezeigte Zahl zusammen.

 Zahl = 0
 wenn die Led mit der Wertigkeit 1 leuchtet, dann Zahl = Zahl + 1
 wenn die Led mit der Wertigkeit 2 leuchtet, dann Zahl = Zahl + 2
 wenn die Led mit der Wertigkeit 4 leuchtet, dann Zahl = Zahl + 4
 ...

jetzt hast du eine Zahl, die der LED-Anzeige entspricht und mit der 
kannst du in weiterer Folge machen was immer du willst.
#2361639
Lesenswert?

Rocco L. schrieb:
> das das so einfach ist...

Nicht wahr :-)

Und dabei hast du es sogar die ganze Zeit gewusst! Ich zitiere
> anzeigt. Das Anzeigen funktioniert so, dass 4 LED für die
> Zahlen 1,2,4,8 stehen und je nachdem welche LED leuchten
> werden die Werte addiert.


> Ich brauche einen zweiten weil alle anderen Füße bereits belegt sind.

Ich glaub, ich wills gar nicht wissen. Genausowenig wie ich wissen will, 
warum jemand eine binäre Anzeige ein paar 7-Segment vorzieht.
#2362309
Lesenswert?

Hallo,

ich habe das mal versucht umzusetzen. Könnten sie bitte nochmal drüber 
sehen?

Die Idee ist das ein Motor eine Probe in ein Kältebad fahren soll und 
später in ein Wärmebad. Dabei wird die Temperatur in den beiden Bädern 
und in der Probe gemessen. Wenn die Probentemperatur gleich der 
Temperatur des jeweiligen Bades ist, soll ins andere Bad gewächselt 
werden.
1
//B2 Taster K?ltebad
2
//B3 Taster W?rmebad
3

4

5

6
#include <avr/io.h>
7
#include <avr/interrupt.h>
8
#define F_CPU 2000000
9
#include <util/delay.h>
10
#include <inttypes.h>
11
#include <stdint.h>
12

13
#define TRUE 1
14
#define FALSE 0
15

16
// Anchlussbelegung:
17

18
#define KTEMP_DDR DDRD        //Temperatur Input vom Kältebad
19
#define WTEMP_DDR DDRC        //Temperatur Input vom Wärmebad
20
#define PTEMP_DDR DDRA        //Temperatur Input von Probe
21

22
#define MOTOR_DDR DDRB        //Datenrichtung zum Motor-Steuer-Atmega festlegen
23
#define MOTOR_OUT PORTB        //Ausgänge zum Motor-Steuer-Atmega
24
#define MOTOR_IN  PINB
25

26
//#define WTEMP_IN   PINC        //Wärmebad abfragen
27
//#define KTEMP_IN   PIND        //Kältebad abfragen      
28
//#define PTEMP_IN   PINA        //Probentemperatur abfragen
29

30
#define CW   PB0          //Motor cw richtung Kältebad
31
#define CCW  PB1          //Motor ccw richtung Wärmebad
32
#define KB   PB2          //Taster Kältebad abfragen 
33
#define WB   PB3          //Taster Wärmebad abfragen
34

35

36

37

38

39

40

41

42
int main(void)
43
{
44
    uint8_t w_temp = 0;          //Variable zum speichern der Zustände vom Wärmebad
45
    uint8_t k_temp = 0;          //Variable zum speichern der Zustände vom Kältebad
46
    uint8_t p_temp = 0;          //Variable zum speichern der Zustände von der Probe
47
         
48
        const uint16_t pause = 200;
49
    const uint16_t pause_2 =80;
50
    
51
    
52
    KTEMP_DDR = 0x00;    //Eing?nge D
53
        WTEMP_DDR = 0x00;    //Eing?nge C
54
    PTEMP_DDR = 0x00;    //Eing?nge A
55
    //B0 un B1 als Ausgänge, B2 und B3 als Eingänge:
56
    MOTOR_DDR = DDRB = (1 << DDB0) | (1 << DDB1) | (0 << DDB2) | (0 << DDB3);
57
        
58

59

60
    //Pause für 20 Sekunden damit alles andere initialisieren kann
61
    //for(int a=0; a<10; a++){_delay_ms( 1000 )};
62

63
    
64

65
        do
66
        {
67
      k_temp = 0;          
68
      p_temp = 0;          
69
      w_temp = 0;          
70
      //k_temp = KTEMP_IN;          //Temp vom Kältebad abholen
71
      //p_temp = PTEMP_IN;          //Temp der Probe abholen
72
      //w_temp = WTEMP_IN;          //Temp vom Wärmebad abholen
73

74
      if ( PINA & (1<<PINA0) ) {p_temp = p_temp + 1}
75
      if ( PINA & (1<<PINA1) ) {p_temp = p_temp + 2}
76
      if ( PINA & (1<<PINA2) ) {p_temp = p_temp + 4}
77
      if ( PINA & (1<<PINA3) ) {p_temp = p_temp + 8}
78
      if ( PINA & (1<<PINA4) ) {p_temp = p_temp + 10}
79
      if ( PINA & (1<<PINA5) ) {p_temp = p_temp + 20}
80
      if ( PINA & (1<<PINA6) ) {p_temp = p_temp + 40}
81
      if ( PINA & (1<<PINA6) ) {p_temp = p_temp + 80}
82

83
      if ( PINC & (1<<PINC0) ) {w_temp = w_temp + 1}
84
      if ( PINC & (1<<PINC1) ) {w_temp = w_temp + 2}
85
      if ( PINC & (1<<PINC2) ) {w_temp = w_temp + 4}
86
      if ( PINC & (1<<PINC3) ) {w_temp = w_temp + 8}
87
      if ( PINC & (1<<PINC4) ) {w_temp = w_temp + 10}
88
      if ( PINC & (1<<PINC5) ) {w_temp = w_temp + 20}
89
      if ( PINC & (1<<PINC6) ) {w_temp = w_temp + 40}
90
      if ( PINC & (1<<PINC6) ) {w_temp = w_temp + 80}
91

92
      if ( PIND & (1<<PIND0) ) {k_temp = k_temp + 1}
93
      if ( PIND & (1<<PIND1) ) {k_temp = k_temp + 2}
94
      if ( PIND & (1<<PIND2) ) {k_temp = k_temp + 4}
95
      if ( PIND & (1<<PIND3) ) {k_temp = k_temp + 8}
96
      if ( PIND & (1<<PIND4) ) {k_temp = k_temp + 10}
97
      if ( PIND & (1<<PIND5) ) {k_temp = k_temp + 20}
98
      if ( PIND & (1<<PIND6) ) {k_temp = k_temp + 40}
99
      if ( PIND & (1<<PIND6) ) {k_temp = k_temp + 80}
100

101
      //Wenn Taster vom K?ltebad an (d.h. Probe ist im Kältebad)
102
      if((PINB & (1<<KB)))
103
      {
104
        //Motor erst mal grundlegend ausschalten, um einen definierten Startwert zu haben
105
      PORTB &= ~ (1<<CCW);  //Motor aus
106
      PORTB &= ~ (1<<CW);    //Motor aus
107

108

109
        if((p_temp <= k_temp + 1))   //fals Probentemp gleich Kältebadtemp ist
110
        {
111
         //Pause um damit Probe die Temp vom Kältebad vollständig annehmen kann
112
             //     for(int a=0; a<20; a++){_delay_ms( 1000 );}
113

114
         //ins Wärmebad fahren)
115
         PORTB &= ~ (1<<CCW);
116
         PORTB |= (1<<CW);
117

118
         //Pause für 20 Sekunden
119
               //for(int a=0; a<20; a++){_delay_ms( 1000 );} 
120
        }
121
      }
122
         
123
      //Wenn Taster vom Wärmebad an (d.h. Probe ist im Wärmebad)
124
      if((PINB & (1<<WB)))
125
      {
126
        //Motor erst mal grundlegend ausschalten, um einen definierten Startwert zu haben
127
      PORTB &= ~ (1<<CCW);  //Motor aus
128
      PORTB &= ~ (1<<CW);    //Motor aus
129
        
130
      
131
        if((p_temp >= w_temp - 1))// fals Probentemp gleich Wärmebadtemp ist
132
        {
133
         //Pause um damit Probe die Temp vom Wärmebad vollständig annehmen kann
134
         //for(int a=0; a<20; a++){_delay_ms( 1000 );}
135

136
         //ins Kältebad fahren
137
         PORTB &= ~ (1<<CW);
138
         PORTB |= (1<<CCW);
139
         
140
        }
141
      }
142

143

144
         
145

146

147

148
        } //ENDE do
149
    while(1);
150

151
} //ENDE main

Habe gerade nochmal genau gelesen, 7 Segment haben Sie geschrieben, ich 
weis nicht warum ich dabei an LCD gedacht habe. So eine 7 Segmentanzeige 
wäre natürlich gescheiter...
Beim nächsten mal ;)
#2362445
Lesenswert?

Wenn ich mir hier mal den Fehler PINA7 / PINA6
wegdenke
1
      if ( PINA & (1<<PINA0) ) {p_temp = p_temp + 1}
2
      if ( PINA & (1<<PINA1) ) {p_temp = p_temp + 2}
3
      if ( PINA & (1<<PINA2) ) {p_temp = p_temp + 4}
4
      if ( PINA & (1<<PINA3) ) {p_temp = p_temp + 8}
5
      if ( PINA & (1<<PINA4) ) {p_temp = p_temp + 10}
6
      if ( PINA & (1<<PINA5) ) {p_temp = p_temp + 20}
7
      if ( PINA & (1<<PINA6) ) {p_temp = p_temp + 40}
8
      if ( PINA & (1<<PINA6) ) {p_temp = p_temp + 80}

dann ist die Pinbelegung genau so, dass ein einfaches
1
      p_temp =  ((PINA & 0xF0) >> 4 ) * 10;
2
      p_temp +=  (PINA & 0x0F );

genau dasselbe macht.




> Beim nächsten mal ;)

Aber nur weil die Hardware schon steht und wahrscheinlich irgendwo 
eingebaut ist.
Aber mal im Ernst: Wäre es nicht vernünftig die original untauglich 
Hardware durch eine neue zu ersetzen und jemand an den Editor zu lassen, 
der auch ein wenig programmieren kann?

Sorry. Aber ich kann da einfach nicht mehr widerstehen. Da werden von 
Leuten, die grade mal sinngemäss "krabbeln" gelernt haben, Lösungen 
gebaut und programmiert, wo du dir als interessierter Bastler (und noch 
nicht einmal Hardware-Profi) nur noch auf den Kopf greifst. Ein 
interessierter Bastler hat in längstens 3 Tagen eine Lösung (inkl. 
Hardwareaufbau) fertig, die um Welten besser ist. Für einen Profi ist 
die Programmierung eine Sache auf 2 Stunden, inkl. ausgiebigem Testen.
Ich will dir ja nicht dein Hobby vermiesen, aber ein gewisser Realismus 
sollte schon sein, dass das hinten und vorne nichts gescheites ist. Und 
ich rede von der Originalplatine!
Du sagst du brauchst einen 2.ten µC weil du keine Pins mehr frei hast. 
Junger Mann: Du hast 24 Pins nur mit LED verbraten!
D.h. den 2.ten µC brauchst du nur, weil du Altlasten mitschleppst. 
Denkst du nicht, das es besser wäre, diese Altlasten erst mal 
loszuwerden. Und schwupps, ist die Notwendigkeit für einen 2-ten 
Prozessor überhaupt nicht mehr vorhanden.

> Habe gerade nochmal genau gelesen, 7 Segment haben Sie geschrieben,
> ich weis nicht warum ich dabei an LCD gedacht habe. So eine 7
> Segmentanzeige wäre natürlich gescheiter...

Eigentlich nicht. Eigentlich wäre ein LCD gscheiter gewesen, wenn man 3 
Temperaturen anzeigen lassen will. Aber 3 Stück 2 stellige 7-Segment 
kann man auch so noch relativ problemlos mit nur 14 Stück µC Pins 
ansteuern. Bleiben immer noch 10 Anschlüsse gegenüber der Originallösung 
frei, die zum Schalten verwendet werden können.


Manchmal kann ich nicht anders als nur noch den Kopf zu schütteln.
Wenn ich keine Ahnung von Dieselmotoren hab, dann red ich doch nicht 
meinem Nachbar ein, ich könnte ihm einen neuen Motor in sein Auto 
einbauen und baue ihm dann einen Federmotor zum Aufziehen ein!
#2362524
Lesenswert?

da ich mich gern weiter entwickeln möchte würde mich Ihr Code Schnipsel 
schon interessieren. Können Sie das kurz komentieren, vieleicht verstehe 
ich so wie man an Sachen ran gehen kann besser:
1
      p_temp =  ((PINA & 0xF0) >> 4 ) * 10;
2
      p_temp +=  (PINA & 0x0F );

ich kapier was F0 und 0F Binär ergibt. Aber was macht der 
Schiebeoperator und die 4?
#2362547
Lesenswert?

Einfach mal auf dem Papier durchspielen.

Der angezeigte Wert sei 46
d.h. von den LED kommt das Bitmuster

    0100 0110

und jetzt den Code durchgehen und nachvollziehen was passiert.

(dabei ist es hilfreich, die Bitmuster der Zahlen von 0 bis 9 zu kennen

   0  00000000           5 00000101
   1  00000001           6 00000110
   2  00000010           7 00000111
   3  00000011           8 00001000
   4  00000100           9 00001001

entscheidend ist, das das Bitmuster von jeweils 4 Bit (sowohl den oberen 
als auch den unteren 4 Bit) direkt den Zahlen 0 bis 9 entspricht.


PS: Ich entschuldige mich für das Pamphlet weiter oben. Ich lasse es 
trotzdem stehen, denn in der Sache an sich bin ich nach wie vor 
derselben Meinung würde es aber diplomatischer ausdrücken. Aber ich 
musste mir einfach mal Luft machen.
#2362647
Lesenswert?

PINA & 0xF0 belendet also kein Bit aus, im Gegenteil zu
PINA & 0x01 wo nur das erste Beinchen abgefragt wird.

Dann wird der abgeholte Wert, z.B. 46 (00101110) vier stellen nach 
rechts geschoben und mit 10 multipliziert
00101110 jetzt wir geschoben:
00010111
00001011
00000101
00000010

mit 10 multiplizieren ergibt nun 20



der zweite Codeschnipsel macht das gleiche, nur mit den hinteren 4 Bit 
und addiert das zu der ersten Zahl, also

00000010 +        2+
----1110          14
----------       -----
   10000          16

da komm ich auf 16 :-( nicht auf 46
Gast #2362664
Lesenswert?

1. Du hättest +20 rechnen (nicht+2) müssen. Aber das ist trotzdem noch 
verkehrt, denn

2. Rocco schrieb:
> 1 [ ] [ ] 10
> 2 [x] [x] 20
> 4 [x] [ ] 40
> 8 [ ] [ ] 80
>
> ^^in dem Bsp leuchten die LED mit den Werten2, 4, 20  d.h. es sind 26°C


46 ist bei deiner Darstellung demnach 01000110

01000110 & 0xf0 = 01000000
                  01000000 >> 4 = 0100 = 4
                                         4 * 10 = 40
01000110 & 0x0f = 00000110 =                       6
                                                 ----
                                                  46
#2362671
Lesenswert?

Wobei man sich die Und-Verknüpfung mit 0xF0 sparen kann denn durch das 
Rechts-Verschieben fallen die unteren 4 Bit sowieso weg.

Was das Einlesen der Bitmuster an PINA (und PINC sowie PIND) angeht: 
Hier sollte man die Ports zunächst in eine Variable mit einem einzigen 
Zugriff einlesen und die anschließende Auswertung anhand dieser 
Variablen durchführen. Andernfalls kann es passieren das sich der 
Eingangswert an den Ports während des sequentiellen Einlesens ändert und 
somit ein fehlerhafter Wert ermittelt wird.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren