Hallo, ich hab da ein kleines Problem.
Für das auslesen mehrerer Motor-Sensoren habe ich mir folgende Struktur
an Variablen angelegt:
1
typedefstruct{
2
uint16_tui16_sensor_val;
3
chardescription_string[20];
4
}SENSOR;
5
6
structsensors{
7
SENSORoil_pressure;
8
SENSORoil_temp;
9
SENSORcoolant_pressure;
10
SENSORcoolant_temp;
11
SENSORambient_temp;
12
}datafields;
13
14
uint8_tui8_active_screen=0;
Jetzt möchte ich diese Sensorwerte auf einem Display ausgeben, abhängig
vom Wert der in ui8_active_screen der gewählten Bildschirmseite soll
der entsprechende Sensor angezeigt werden.
also statt so für einen einzelnen Wert:
@mr.mo
danke, werde ich mal ansehen...
@Daniel
hätte ich dann aber nicht 3 mal das komplette struct ? Also 3 mal den
Ölsensor, 3 mal den Kühlmittelsensor, usw ?
1
charBuffer[6]
stimmt, an die maximale 65535 muss ja als String noch ne '\0' ran...
ganz vergessen, danke ^^
Marcel P. schrieb:> typedef struct{> uint16_t ui16_sensor_val;> char description_string[20];> } SENSOR;>> struct sensors {> SENSOR oil_pressure;> SENSOR oil_temp;> SENSOR coolant_pressure;> SENSOR coolant_temp;> SENSOR ambient_temp;> } datafields;
Servus,
du willst ja mit Pointer arbeiten. Ein großes Thema ist es immer wieder,
wenn es um dynamische Speicherverwaltung geht...
Hier ein hardcoded bsp.:
@aSma
irgendwie stehe ich gerade auf dem Schlauch was du mir genau sagen
möchtest.
Liegt vielleicht aber auch daran, das ich gerade versuche den ->
Operator zu verstehen o.O
Im Grunde möchte ich folgende Funktion erreichen, nur eben sehr viel
einfacher, da die Sensoren mehr werden sollen und ich nicht für jeden
Sensor ein extra case-Block schreiben möchte.
Marcel P. schrieb:> typedef struct{> uint16_t ui16_sensor_val;> char description_string[20];> } SENSOR;>> struct sensors {> SENSOR oil_pressure;> SENSOR oil_temp;> SENSOR coolant_pressure;> SENSOR coolant_temp;> SENSOR ambient_temp;> } datafields;
Servus,
du willst ja mit Pointer arbeiten. Ein großes Thema ist es immer wieder,
wenn es um dynamische Speicherverwaltung geht...
Hier ein hardcoded bsp.:
1
//in header
2
#define MAX_SENSOR 3
3
4
typedefstruct{
5
uint16_tui16_sensor_val;
6
chardescription_string[20];
7
}SENSOR_t;
8
9
typedefstruct{
10
SENSOR_toil_pressure;
11
SENSOR_toil_temp;
12
SENSOR_tcoolant_pressure;
13
SENSOR_tcoolant_temp;
14
SENSOR_tambient_temp;
15
}DATAFIELD_t;
16
17
DATAFIELD_t*read_data();//fkt in header
18
19
20
//gloabal var
21
DATAFIELD_tDATA[MAX_SENSOR];
22
23
//fkt mit einen pointer als rückgabetyp
24
DATAFIELD_t*read_data(){
25
26
staticuint8_tsensor_counter=0;// No malloc use. Hard coded.
27
28
if(sensor_counter==MAX_SENSOR)// Max sensor arrived.
29
returnNULL;
30
31
//hier ist dein pointer
32
DATAFIELD_t*p=(DATAFIELD_t*)&DATA[sensor_counter++];//pointer zeigt auf sensor i!
33
34
p->oil_pressure.ui16_sensor_val=xxx;
35
36
...
37
returnp;
38
}
39
40
//main
41
externDATAFIELD_t*read_data();
42
DATAFIELD_t*sensor1_p,*sensor2_p,*sensor3_p;
43
44
intmain(){
45
46
sensor1_p=read_data();
47
sensor2_p=read_data();
48
sensor3_p=read_data();
49
}
Wenn du
> uint16_t ui16_sensor_val;> char description_string[20];
nicht gleichzeitig brauchst, dann kannst du daraus auch eine union
machen.
mfg
Marcel P. schrieb:> @aSma>> irgendwie stehe ich gerade auf dem Schlauch was du mir genau sagen> möchtest.
sry, habe noch nicht fertig gehabt. Bin auf den enter botton drauf
gekommen.
Marcel P. schrieb:> char Buffer[5];>> switch(ui8_active_screen) {>> case 0:> itoa(datafields.oil_temp.sensor_val, Buffer, 10);> break;> ...
Dein case ist nicht ausgagekräftig. Du brauchst hier keinen Pointer,
wenn du alles global hälst. Aber du kannst natürlich einen nutzen. Wie
zuvor von mir gezeigt.
Marcel P. schrieb:> @Daniel>> hätte ich dann aber nicht 3 mal das komplette struct ? Also 3 mal den> Ölsensor, 3 mal den Kühlmittelsensor, usw ?
Ups, ich hatte nicht nachgesehen, was im Struct drin steht. Neuer
vorschlag: (c11)
1
typedefstruct{
2
uint16_tui16_sensor_val;
3
chardescription_string[20];
4
}SENSOR;
5
6
structsensors{
7
union{
8
SENSORsensor_list[1];
9
struct{
10
SENSORoil_pressure;// Müssen alle vom typ SENSOR sein
@aSma
ok, ich versuche mal zu verstehen, wie ich das dann anwende. Momentan
stehe ich gerade immernoch auf den Schlauch, was aber eher an mir liegt
^^ .
Ich hab mal kommentiert, wie ich das verstanden habe... und ab wo ich
auf dem schlauch stehe...
1
//in header
2
#define MAX_SENSOR 3 // meine Anzahl an sensoren (eigentlich 5)...
3
4
typedefstruct{
5
uint16_tui16_sensor_val;
6
chardescription_string[20];
7
}SENSOR_t;
8
9
typedefstruct{
10
SENSOR_toil_pressure;
11
SENSOR_toil_temp;
12
SENSOR_tcoolant_pressure;
13
SENSOR_tcoolant_temp;
14
SENSOR_tambient_temp;
15
}DATAFIELD_t;
16
17
DATAFIELD_t*read_data();//fkt in header
18
19
20
//gloabal var
21
DATAFIELD_tDATA[MAX_SENSOR];// indiesem Array stehen meine jeweiligen Sensorwerte aus ui16_sensor_val
22
23
//fkt mit einen pointer als rückgabetyp
24
DATAFIELD_t*read_data(){
25
26
staticuint8_tsensor_counter=0;// No malloc use. Hard coded. //fängt bei 0 an, klar
27
28
if(sensor_counter==MAX_SENSOR)// Max sensor arrived. //wenn alle Sensoren durch, fertig
29
returnNULL;
30
31
//hier ist dein pointer
32
DATAFIELD_t*p=(DATAFIELD_t*)&DATA[sensor_counter++];//pointer zeigt auf sensor i! // Hier fängt es an für mich unverständlich zu werden
33
34
p->oil_pressure.ui16_sensor_val=xxx;// Hier steig ich ganz aus ? das ist ja nur der Öldruck-Sensor.. was ist mit den anderen ? Entsprechend so ?:
35
36
p->oil_temp.ui16_sensor_val=xxx;// =xxx wäre dann etwa mein = ADC_Read_avg(channel, samples); für jeden sensor ?
37
38
...
39
returnp;
40
}
41
42
//main
43
externDATAFIELD_t*read_data();
44
DATAFIELD_t*sensor1_p,*sensor2_p,*sensor3_p;// verstehe ich nicht ganz genau, aber das sind dann 3 pointer für das struct DATAFIELD_t ?
45
46
intmain(){
47
48
sensor1_p=read_data();
49
sensor2_p=read_data();
50
sensor3_p=read_data();
51
}
Sorry, das ich mich doof anstelle, aber pointer sind für mich irgendwie
ein rotes Tuch....
@Daniel
mache ich mir durch deinen Vorschlag nicht den Vorteil des struct
zunichte wenn alle vom Typ SENSOR sein müssen ? Weil dann könnte ich
doch auch ein Array draus machen ? Also statt dem hier:
1
typedefstruct{
2
uint16_tsensor_val;
3
chardescription_string[20];
4
}SENSOR;
5
6
structsensors{
7
union{
8
SENSORsensor_list[1];
9
struct{
10
SENSORoil_pressure;// Müssen alle vom typ SENSOR sein
11
SENSORoil_temp;
12
SENSORcoolant_pressure;
13
SENSORcoolant_temp;
14
SENSORambient_temp;
15
};
16
};
17
}datafields;
dann so:
1
enumsensors{
2
OIL_PRES_e=0,
3
OIL_TEMP_e,
4
COL_TEMP_e,
5
EOL_PRES_e,
6
AMB_PRES_e
7
};
8
9
SENSORsensors[5];
10
11
itoa(sensors[OIL_PRES].sensor_val,Buffer,10);
oder ?
Ich habe das "Datafields" als struct angelegt, weil da in Zukunft noch
andere sachen ausser SENSOR-typen dazu kommen sollen. Diese anderen
enthalten zwar auch immer die Felder "sensor_val" und
"sensor_descriptor" aber eben auch noch zusätzliche Felder.
Marcel P. schrieb:> mache ich mir durch deinen Vorschlag nicht den Vorteil des struct> zunichte wenn alle vom Typ SENSOR sein müssen ? Weil dann könnte ich> doch auch ein Array draus machen ? Also statt dem hier:
Ja. In solchen fällen nutze ich Basisklassen.
Marcel P. schrieb:> Sorry, das ich mich doof anstelle, aber pointer sind für mich irgendwie> ein rotes Tuch....
Siehe Überschrift: "Zeiger" auf struct-Element
Dann lasse einfach die Zeiger und Unions weg.
Wichtig ist, dass man aussagekräftig programmiert, denn dann brauchst du
auch kaum zu kommentieren (Stichwort: real programmer).
Schreibe jetzt ein header und .c Datei und poste hier.
mfg
Ich werde versuchen das sinnig in mein Code zu setzen und dann poste ich
das ganze Ding mal hier sobald es passt.
Vielen vielen Dank aber schon mal. Die Codebeispiele haben mir aber auch
noch viele andere Kleinigkeiten gezeigt, die den Programmierstil viel
besser machen.
Grüße, Marcel