Hallo Kollegen,
habe ein Problem .... hmmm HERAUSforderung:
habe einen array/string angelegt (80x3),
String iomodus[80][3] = {
//"presentation", "set/req", "description"
{„0“, “0“, “free“},
{„0“,“0“,“free“},
{"S_BINARY","V_STATUS","test switch"}, //D3
{„0“,“0“,“free“}, //D4
...
{„0“,“0“,“free“}, //D80
};
es beinhaltet Daten, als "text" also sowas
S_BINARY
V_STATUS
test switch
alle dreispalten in jeder Zeile werden zum aufrufen anderer Funktionen
gebraucht (Siehe unten) z.B. funktion
present(uint8_t childSensorId, uint8_t sensorType, const char
*description, bool enableAck)
i= CHILD_ID
iomodus[i][1st COLUMN] = presentation ID
iomodus[i][3rd COLUMN] = description as Text
ACK= true
soooo und jetzt kommt das Problem!!!!
Ich kriege die Daten aus dem Array /String nicht raus...
bei dieser Funktion:
void presentation()
{
// Send the sketch version information to the gateway and Controller
sendSketchInfo("Relay+Max31855", "1.0");
for (int i = 0; i<70; i++) //all Ports D0 bis D69
//present(uint8_t childSensorId, uint8_t sensorType, const char
*description, bool enableAck)
present(i, iomodus[i][1], iomodus[i][3], true);
}
Bekomme ich Fehler:
**cannot convert 'String' to 'uint8_t {aka unsigned char}' for argument
'2' to 'void present(uint8_t, uint8_t, const char*, bool)'**
Sass jetzt mehr als 10 Stunden dran und kein Erfolg!
Bitte um Hilfe!!!!
Max M. schrieb:> present(i, iomodus[i][1], iomodus[i][3], true);> ...> '2' to 'void present(uint8_t, uint8_t, const char*, bool)'**
Noch viel eindeutiger kann die Fehlermeldung doch eigentlich garnicht
mehr werden:
Was übergibst du denn als Parameter Nummer 2 der gemäß der Deklaration
von present(...) ein uint8_t sein soll?
Ein "iomodus[i][1]" und von welchem Typ ist dies?
PS: Codetags wurden bereits erfunden, und Arrays beginnen bei index 0
und für sensorType könnte ein enum sinnvoll sein.
Edit:
Du könntest auch die Funktion present nach "void present( iomodus_t* io,
bool enableAck )" ändern und mit "present( iomodus+i, true )" aufrufen.
Dadurch spart man Argumente, und in present könnte man dann z.B. mit
"io->description" auf description zugreifen.
Daniel A. schrieb:> Entweder du änderst die Parameter von present, damit diese strings> nimmt, oder du speicherst die Daten im richtigen Format ab.
kann leider nicht, da in einer library enthalten....
Vielen Dank für dein Vorschlag...
leider bekomme ich diesen Fehler:
in der ZEile {S_BINARY, V_STATUS, "test switch"},
1
170:error:'S_BINARY'wasnotdeclaredinthisscope
habe überall die "" entfrnt
z,B.:
{0,0,"free"},
{0,0,"free"},
Bei "present(uint8_t childSensorId, uint8_t sensorType" ist sensorType
nunmal ein Integer, und S_BINARY ist eine Konstante. Diese muss irgendwo
definiert werden. Muss S_BINARY einen bestimmten Wert haben, oder woher
kommt dass, wozu wird es gebraucht?
Daniel A. schrieb:> Muss S_BINARY einen bestimmten Wert haben, oder woher> kommt dass, wozu wird es gebraucht?
Jede Wette, das sollte eigentlich aus einem #include File aus einer
benutzten Library kommen und die Reihenfolge der Deklaration versus
#include ist falsch.
Max M. schrieb:> Sass jetzt mehr als 10 Stunden dran und kein Erfolg!
Du könntest die Zeit viel besser nutzen, wenn du zumindest C-Buch
durcharbeiten würdest. Schon nach 20 Minuten lesen und überdenken des
Gelesenen hättest du dir dann die Frage selbst beantworten können.
Woher kommt eigentlich immer die Idee, man könne programmieren ohne
wenigstens minimale Grundkentnisse der verwendeten Programmiersprache zu
haben?
Max M. schrieb:> also es gibt ein enum in der library für sensor:
und der steht in einem Header File drinnen.
Also muss das Header File inkludiert werden, ehe du dann in deinen
Definitionen den Begriff S_BINARY benutzen kannst.
Es ist wirklich ganz einfach: Der COmpiler liest das Programm von oben
nach unten. DU kannst nur Dinge verwenden NACHDEM sie definiert wurden.
Willst du eine Konstante S_BINARY benutzen, dann muss die auch vor der
Verwendung definiert worden sein.
Ganz simpel.
Es ist wie in einem Krimi. Erst muss jemand umgebracht werden und erst
dann gibt es einen Mörder.
Karl H. schrieb:> Also muss das Header File inkludiert werden, ehe du dann in deinen> Definitionen den Begriff S_BINARY benutzen kannst.
In deinem Fall:
Erst
1
#include"MySensor.h"
und erst dann kannst du den Begriff S_BINARY (der über diesen Header
hereingezogen wird) verwenden.
Grundlagen!
> Willst du eine Konstante S_BINARY benutzen, dann muss die auch vor der> Verwendung definiert worden sein.> Ganz simpel.
Ja... verstanden...
diese Varable soll aber in dem array keine Variable sin (so verstehe ich
es).
Dieser
"text/string" S_BINARY soll in die
present(uint8_t childSensorId, uint8_t sensorType, const char
*description, bool enableAck)
als uint8_t sensorType
eingetragen werden....
danach ist es eine Variable siehe ENUM
Max M. schrieb:> diese Varable soll aber in dem array keine Variable sin (so verstehe ich> es).
D A S I S T V O E L L I G W U R S C H T
Du willst den Begriff S_BINARY in irgendeiner FOrm verwenden. Zum
Beispiel hier
Also muss der entsprechende Include, der dem COmpiler letzten Endes
verrät, was das sein soll, VOR dieser Verwendung kommen und nicht
hinterher.
Der Compiler hüpft im Text nicht kreuz und quer und sucht sich die Dinge
zusammen. Er liest den Text von oben nach unten. Und zwar genau nur ein
einziges mal.
Falsch rum:
Max M. schrieb:> 295: error: request for member 'sensorType' in 'iomodus', which is of> non-class type 'iomodus_t [80] {aka s_iomodus [80]}'
iomodus ist ein Array!
Ein Array hat keine Komponente 'sensorType'. Ein einzelnes ELement aus
diesem Array hat es.
Oder anders ausgedrückt: DU willst ja (kannst ja) hier nicht das ganze
Array als ganzes da reinstopfen. Du willst 1 Element aus diesem Array
haben und von diesem einem Element (eine Zeile in deiner
Initialisierung) dann den Member 'sensorType'.
Jetzt wo klar ist, um welche enums es sich handelt, kann man das Strukt
anpassen.
1
typedefstructs_iomodus{
2
sensorsensorType;
3
variableTypevariableType;
4
Stringdescription;
5
}iomodus_t;
Ich find diesen Thread ausserst amüsant. So viele freie Tür Temperatur
IOs ;)
Max M. schrieb:> present(i, iomodus.sensorType, iomodus.description, true);
Ups, da habe ich wohl etwas zu schnell getippt. muss natürlich
iomodus[i].sensorType und iomodus[i].description sein...
Daniel A. schrieb:> Max M. schrieb:>> present(i, iomodus.sensorType, iomodus.description, true);>> Ups, da habe ich wohl etwas zu schnell getippt. muss natürlich> iomodus[i].sensorType und iomodus[i].description sein...
Ist eigentlich egal. Denn eigentlich sollte er das selber rausfinden
bzw. beheben können.
Amüsant sind solche Dinge schon lang nicht mehr.
> Dann würde ich doch eher int nehmen, falls sich die API nochmal ändert.
so?
typedef struct s_iomodus {
int sensorType;
int variableType;
String description;
} iomodus_t;
iomodus_t iomodus[] = {
Daniel A. schrieb:> Diese Doku scheint nicht besonders brauchbar zu sein:
Es ist wie meistens:
Doku ist veraltet und stimmt nicht mit dem Code überein. Im Zweifelsfall
gilt daher immer der Code und aus der Doku leitet man sich die
Prinzipien der Benutzung her.
> Dann würde ich doch eher int nehmen, falls sich die API nochmal ändert.
Die enum Namen zu nehmen ist schon ok. Der Lib-Benutzer muss sich ja
nicht darum kümmern, was da genau dahinter steckt. Dafür passt der C++
Compiler auf ihn auf, dass er nicht die falsche Konstante bei einem
Parameter übergibt. In C würde das nichts bringen. Aber in C++ ist das
ein echter Mehrwert, dass enums richtige eigene Datentypen sind.
(d.h. wenn die FUnktion auch die enum als Argumente nehmen würde, was
ich nicht kontrolliert habe)
So allerdings
Max M. schrieb:>>>> Ich find diesen Thread ausserst amüsant. So viele freie Tür Temperatur>> IOs ;)>> wird von mir schon gefüllt :-)
Warten wirs ab.
Bis jetzt schwimmst du bei den einfachsten Dingen und bis jetzt hast du
praktisch noch keine einzige Zeile Code selbst geschrieben. Und das was
du geschrieben hast, ist voller Fehler bzw. unverstandenen Dingen.
Das kann ja noch heiter werden.
;-)
danke LÄUFT!!!!
ich bin halt kein pürogrammierer... habe in der FH c++ "gelern"
/geschnuppert
einfache dinge funktionieren, aber bei solchen sachem mit arrays
schwimme ich halt "noch"
Danke an EUCH BEIDE!!!!!
Karl Heinz (kbuchegg) (Moderator) +++ Daniel Abrecht (daniel-a)
Max M. schrieb:> und diesen fehler>> error: invalid conversion from 'int' to 'mysensor_sensor' [-fpermissive]
Arduino ist nunmal C++, in C hätte es keine Fehlermeldung gegeben.
Max M. schrieb:>> Ich find diesen Thread ausserst amüsant. So viele freie Tür Temperatur>> IOs ;)>> wird von mir schon gefüllt :-)
Aber es ist gut, dass der Compiler warnt, weil S_DOOR und V_TEMP haben
den Wert 0. Die Bemerkung war ein Hinweis darauf, das du dort womöglich
etwas noch nicht bemerkt hast: Du hast noch keine Information abgesehen
von der Beschreibung, die Besagt, ob der IO frei ist.
Du hast noch keine Information abgesehen
> von der Beschreibung, die Besagt, ob der IO frei ist.
du meinst also ich soll so lassen
1
typedefstructs_iomodus{
2
mysensor_sensorsensorType;
3
mysensor_datavariableType;
4
Stringdescription;
5
}iomodus_t;
6
7
iomodus_tiomodus[]={
und dafür alle sensoren mit einem aus der enum füllen?
>Du hast noch keine Information abgesehen>von der Beschreibung, die Besagt, ob der IO frei ist.
free bedeutet dass der PIN frei ist und kein anderer sensor angeschlosen
ist.
in MQTT sehe ich dann in dem PAYLOAD das es frei ist... also kann ich
"aussortieren"
ich will es so aufbauen:
1. es soll alle Pins presentieren, damit MQTT gefüllt ist und weiss was
mit den mins los ist
dann läuft einne schleife mit mills, die nach den "UNfreien" pins schaut
und diese ggf. updated ODER wenn eine meldung kommt wird SOFORT auf den
PIN zugegriffen und ggf. geändert...
klingt doch gut :-) ?
Jein, ob int oder mysensor_sensor ist nicht besonders wichtig, ich
meinte du solltest eine Information zum Struct hinzufügen und einen
Default Entry erstellen und eine Abfrage einbauen, ob iomodus[i]
überhaupt benutzt wird:
Edit: (Habe erst jetzt den Zusatz bemerkt)
Max M. schrieb:> MQTT sehe ich dann in dem PAYLOAD das es frei ist... also kann ich> "aussortieren"
...
> klingt doch gut :-) ?
Ja, das macht sinn.
------------------------
Max M. schrieb:> mann sieht schon WER hier ne Ahnung hat und wer n... schwimmt ;-)
Bitte versuche die Mods nicht zu verärgern, diese geben sich mühe,
invertieren viel Zeit und ohne Sie würde dieses Forum untergehen.
Daniel A. schrieb:> Bitte versuche die Mods nicht zu verärgern, diese geben sich mühe,> invertieren viel Zeit und ohne Sie würde dieses Forum untergehen.
Nö. Ich bin sowieso raus. Denn das ist sogar mir zuwenig Grundlagen auf
denen man aufbauen kann. Das ist von seiner Seite nur noch ein
Ratespielchen mit Fehlermeldungen.
> Nö. Ich bin sowieso raus. Denn das ist sogar mir zuwenig Grundlagen auf> denen man aufbauen kann. Das ist von seiner Seite nur noch ein> Ratespielchen mit Fehlermeldungen.
Sorry... bin halt als anfänger auf EUCH angewiesen!!!!
dafür werde ich mein Wissen/Sketches mit den anderen forum-mitglieder
teilen, damit sie EUCH nicht ärgern :-)
War auf keinen fall meine Absicht mit meinem Unwissen euch zu ärgern :-(
Daniel A. schrieb:> Ups, Ist eine alte Angewohnheit von mir in C, die es ja in C++ nicht> gibt. Dann eben so:>>
1
>constiomodus_tEMPTY_ENTRY={
2
>false,(mysensor_sensor)0,(mysensor_data)0,"free"
3
>};
4
>
Das ändert aber nichts.(*)
Die verwendenden Funktionen sehen nach wie vor einen S_DOOR bzw. V_TEMP.
Ich würde hergehen und ganz einfach im enum entsprechende S_UNUSED bzw.
V_UNKNOWN an erster Stelle hinzufügen. Wenn alle brav die Bezeichnungen
aus dem enum verwenden und nicht auf den numerischen Wert zugreifen, ist
das kein Problem.
(*) ausser natürlich, dass es in C++ compilierbar wird.
VIIIIEEEEEELEN Dank!!!
werd einen Pull request bei dem library inhaber stellen dass er
S_UNUSED bzw.
V_UNKNOWN
an ertser stelle implementiert!
bis dahin verwende ich dann DEINE Version!!!
Vieeeln Dank noch mal!!!!
Habe meiner Frau gerade "gebeichtet", dass ich gestern/heute nacht 10
Stunden dran gesessen bin und IHR das in 2 min hattet!
Sie meinte : "es kann nur besser werden " :-/
STIMMT !
DaNKE!
Karl H. schrieb:> Das ändert aber nichts.> Die verwendenden Funktionen sehen nach wie vor einen S_DOOR bzw. V_TEMP.
Ja, die Überlegung war, dass es der Wert "bool used" erlaubt zu prüfen,
ob der Eintrag gesetzt ist, und wenn dies nicht der Fall ist muss man
die entsprechenden Funktionen ja garnicht Aufrufen.
Daniel A. schrieb:> und wenn dies nicht der Fall ist muss man> die entsprechenden Funktionen ja garnicht Aufrufen.
das wollte ich "klassisch" machen mit abfrage jeder Zeile [i] ob der
erste Wert= sensorType = 0 ist...
So ist es aber eleganter!
und ich kann es in weiteren funktionen verwenden...
oder ?
Max M. schrieb:> So ist es aber eleganter!>> und ich kann es in weiteren funktionen verwenden...>> oder ?
natürlich.
S_UNUSED oder S_UNKNOWN ist dann ein ganz normaler zulässiger Wert für
sensorType, so wie das auch ein S_DOOR oder ein S_BINARY weäre. Seine
Bedeutung ist dann eben, dass man nichts genaueres über den Sensor Typ
weiss. Damit fällt zb in der Datenhaltung ein extra boolscher Wert, der
über die Gültigkeit des Eintrags entscheidet weg bzw. den braucht man
nicht mehr. Auf Kosten eines nicht benutzbaren Sensor Typs hat man dann
dort dieselbe Information drinnen.
So ein 'Unknown' Wert ist eigentlich in den meisten
Aufzählungsdatentypen immer wieder sinnvoll um anzuzeigen, dass es sich
um keinen der restlichen vereinbarten Werte handelt. Das liest sich dann
auch im Code besser. Denn ein
1
if(data.type!=S_UNKNOWN){
2
...
oder ein
1
if(data.type!=S_INVALID){
2
...
erzählt mir dann eben schon die ganze Geschichte in kompakter Form und
ohne das ich noch zusätzlich 93 'gültig' oder 'unbenutzt' Flags
benötige.
Ich würds für mich auf jeden Fall machen.
Wenn ich davor zurückschrecke, den Zahlenbereich des enum zu
verschieben, kann ich das ja immer noch so lösen
1
typedefenum{
2
S_DOOR,// Door sensor, V_TRIPPED, V_ARMED
3
S_MOTION,// Motion sensor, V_TRIPPED, V_ARMED
4
S_SMOKE,// Smoke sensor, V_TRIPPED, V_ARMED
5
S_LIGHT,// Binary light or relay, V_STATUS (or V_LIGHT), V_WATT
6
S_BINARY=3,// Binary light or relay, V_STATUS (or V_LIGHT), V_WATT (same as S_LIGHT)
7
S_DIMMER,// Dimmable light or fan device, V_STATUS (on/off), V_DIMMER (dimmer level 0-100), V_WATT
8
....
9
S_VIBRATION,// Vibration sensor, V_TRIPPED, V_ARMED, V_LEVEL (vibration in Hz)
10
S_MOISTURE,// Moisture sensor, V_TRIPPED, V_ARMED, V_LEVEL (water content or moisture in percentage?)
11
12
S_INVALID=255,// ******* <- we don't know or invalid
13
}mysensor_sensor;
14
15
// Type of sensor data (for set/req/ack messages)
16
typedefenum{
17
V_TEMP,// S_TEMP. Temperature S_TEMP, S_HEATER, S_HVAC
18
....
19
...
20
V_HVAC_SETPOINT_HEAT,// S_HEATER, S_HVAC. HVAC/Heater setpoint (Integer between 0-100)
21
V_HVAC_FLOW_MODE,// S_HVAC. Flow mode for HVAC ("Auto", "ContinuousOn", "PeriodicOn")
22
23
V_UNKNOWN=255,// ******** <--- We don't know
24
}mysensor_data;
Das liest sich dann auch in der Verwendung um einiges besser
Karl H. schrieb:> immer wieder sinnvoll um anzuzeigen, dass es sich> um keinen der restlichen vereinbarten Werte handelt.
habe jetzt library angepasst mit
1
typedefenum{
2
3
...
4
5
S_UNUSED=255,// UNUSED PIN or INVALID
6
}mysensor_sensor;
7
und
8
9
typedefenum{
10
11
....
12
V_UNKNOWN=255,// <--- We don't know
13
}mysensor_data;
dazu dann das zurück geändert als Version2 für die Zukunft:
1
typedefstructs_iomodus{
2
intsensorType;
3
intvariableType;
4
constchar*description;
5
}iomodus_t;
6
7
iomodus_tiomodus[]={
8
/*
9
{presentation, set/req, description}
10
*/
11
{S_UNUSED,V_UNKNOWN,"free pin"},
12
{S_UNUSED,V_UNKNOWN,"free pin"},
compiler meckert NICHT!!!!!
und damit frage ich es ab
MAN MERKE
ich habe deine
data.type in iomodus[i].sensorType SELBSTÄNDIG (nach compiler
fehler)geändert ohne hier nachzufragen!!!!
Also trägt es schon früchte!