Brauche Hilfe

Hallo Leute,
ich bin neu hier! Wenig Ahnung von der Arduinoprogrammierug. Ich habe nun ein Problem, welches vermutlich sehr einfach zu lösen wäre, aber ich suche die Lösung schon seit Stunden und Tagen, ja seit Wochen und finde sie nicht. Also folgendes Problem. Ich habe eine Wetterstation gebaut, welche mir auf einen Telefonanruf hin automatisch eine SMS schickt mit den Daten: Windgeschwindigkeit, Temperatur aussen, Temperatur im Tiefkühlschrank, Luftfeuchtigkeit, Knoten und Beaufort. Es funktioniert eigenlich alles. Diese Daten erscheinen auch auf einem 20x4 LCD. Ebenfalls wird mir die Windrichtung "NORD", "WEST" etc. auf dem Display angezeigt. Die Windrichtung wird in der Variablen (windRicht) gespeichert. Das Problem besteht nun, dass ich die Variable der Windrichtung nicht mit der sms ausgeben kann. Der Sketch für die SMS-Ausgabe sieht so aus:

void checkForCall(){
//Checks status of call
Serial.println("Check for call");
stat=call.CallStatusWithAuth(number,1,2);
//If the incoming call is from an authorized number
//saved on SIM in the positions range from 1 to 3.
if(stat==CALL_INCOM_VOICE_NOT_AUTH){
//Hang up the call.
call.HangUp();
Serial.println("SMS Senden");
//printToSerial();
char message[80];
char tempOut[9];
char luftfOut[9];
char windGeschwOut[9];
char beaufortOut[9];
char knotenOut[9];
char tempTiefkOut[9];
char windRichtOut[5]; // ?????????????
dtostrf(temp,7, 1, tempOut); // Temp. aussen
dtostrf(luftf,7, 1, luftfOut); // Luftfeuchtigkeit
dtostrf(windGeschw,7, 1, windGeschwOut); // Windgeschwindigkeit
dtostrf(beaufort,7, 1, beaufortOut); // Beaufort
dtostrf(knoten,7, 1, knotenOut); // Knoten
dtostrf(tempTiefk,7, 1, tempTiefkOut); // Temp. Tiefkühler
**// dtostrf(windRicht[5], windRichtOut); // Windrichtung > funktioniert nicht!!!! **
sprintf(message, "Ort: \nWind:%s km/h \nKnot:%s \nTiefk:%s C \nTemp:%s C \nLuftf: %s %% \nWindR:", windGeschwOut, knotenOut, tempTiefkOut, tempOut, luftfOut, windRichtOut);
sms.SendSMS(number, message);
Serial.println("\nSMS gesendet OK");
}
}

Ich hoffe ers kann mir jemand auf die Sprünge helfen. Vielen Dank zum voraus.

Das kann ja nicht gehen, da kommt immer 0 raus.
Warum willst du
dtostrf(windRicht[5], windRichtOut);
machen ?

Wenn, dann kopiere wenigstens den C string.
oder schicke das Original:

sprintf(message, "Ort: \nWind:%s km/h \nKnot:%s \nTiefk:%s C \nTemp:%s C \nLuftf: %s %% \nWindR:", windGeschwOut, knotenOut, tempTiefkOut, tempOut, luftfOut, windRicht);

Ich nehme an, daß das unten erklährte Problem das ist das richtige ist, da Du aber nur einen Teil des Sketches zeigst kann ich nicht sicher sein.

Das ist kein Problem von Arduino sondern von C.
Da gibt es gloable variablen un lokale Variablen.
Eine Variable innerhalb einer Funktion definiert (lokal) gibt es nur dort. in einer anderen Funktion gibt es die Veriable nicht oder es kann eine Variable mit gleichen Namen geben die aber verschieden von der Variable in der Funktion ist.
siehe: scope - Arduino Reference

Grüeß Uwe

Warum verwendest du solch einen nichtssagenden Namen für deinen Thread.
Besser wäre doch das Problem zu benennen.

Enschuldigung: Ihr müsst eigentlich nicht das "dtostrf(windRicht[5], windRichtOut);" oder das "char windRichtOut[5]; " anschauen. Das waren nur hilflose Versuche meinerseits >:( .
Vielleicht hilft das:
Die Windrichtung habe ich definiert mit: char windRicht[5]; mit einer if...else lese ich den Graycode von der Windfahne und mit sprintf(windRicht, "NORD"); erhalte ich die Windrichtung. Auf dem LCD kann ich dann mit
lcd.print("windR:";
lcd.print(windRicht);
die Windrichtung z.B "NORD" ausgeben.
Meine Frage ist:
Wie muss ich in der SMS-Ausgabe die Variable windRicht (welche ja "NORD", OST" etc. enthält) eintragen damit auch "NORD", "WEST" etc. in der sms ausgegeben wird? Mit Zahlen funktioniert es, aber mit dem Text nicht!

messen.JPG

da ja Windricht eine globale Variable zu sein scheint:

sprintf(message, "Ort: \nWind:%s km/h \nKnot:%s \nTiefk:%s C \nTemp:%s C \nLuftf: %s %% \nWindR:", windGeschwOut, knotenOut, tempTiefkOut, tempOut, luftfOut, windRicht);

auch auf die Gefahr hin, mich zu wiederholen. Aber, hast du das schon probiert?
Aber poste den ganzen Sketch, damit man sieht, was wo wie deklariert wird. Weil grundsätzlich lan man das was man auf das LCD schreiben kann, auch per SMS schicken.

Vielleicht ist auch nur message mit 80 nur zu klein deklariert? Mach mal grösser, eine SMS kann bis zu 160 Zeichen.

Ja, ich habe beides ausprobiert, jedoch ohne Erfolg. Die SMS kommt eigentlich mit den Daten an, ausser der WindRichtung! Wenn es weiter hilft, könnte ich den ganzen Sketch senden. Er ist aber ziemich gross, muss nur noch schauen wie senden.
Gruss Erni

sms.JPG

Der Aufruf ist falsch:

dtostrf(windRicht[5], windRichtOut);

Sollte eigentlich gar nicht kompilieren. dtostrf hat 4 Parameter:
1.) Der Wert
2.) Die Breite des gesamten Strings, inklusive Punkt und Vorzeichen. Aber ohne Terminator
3.) Die Anzahl der Nachkommastellen
4.) Das Puffer Array

Überlege dir auch ob du für wirklich Float für jeden Wert brauchst. Integer kannst du auch direkt mit sprintf() formatieren. Mit %d

Wie muss ich in der SMS-Ausgabe die Variable windRicht (welche ja "NORD", OST" etc. enthält) eintragen damit auch "NORD", "WEST" etc. in der sms ausgegeben wird?

%s ist für C Strings im RAM. Um einen konstanten Text in ein Array zu schreiben kannst du strcpy(), bzw. strncpy() verwenden.

z.B. sowas:

char windRichtOut[5];
strcpy(windRichtOut, "WEST");

Bei dir wird gar nicht klar wo mal irgendwo Text in das Array geschrieben wird.

Den Sketch als zip packen (oder direkt als .ino wenn es geht) und als Datei anhängen.
Dazu musst du auf Reply klicken, nicht in diesem Quick Reply Fenster.

Ja, vielen Dank für eure Antworten. Aber offenbar ist es für mich zu kompliziert, lesen kann ich, aber verstehen....

Wenn ich
strcpy(windRichtOut, "WEST");

eintrage, ist es ja klar dass die Windrichtung "WEST" mit dem sms gesendet wird.
Die Windrichtung ist aber kein konstanter Text. Dieser ändert sich je nach Windrichtung. Ich mache es so: (Schalterzustand1 bis 4 = A2,A3,A4,A5.) Auf diese 4 Eingänge beim Arduino wird ein Greycode gesendet. Daraus ergeben sich 16 Windrichtungen und werden mit Hilfe einer if....else Abfrage ausgelesen, so:

if (SchalterZustand2 == 0 && SchalterZustand3 == 0 && SchalterZustand4 == 0 && SchalterZustand5 == 0) // 0000
** {**
** sprintf(windRicht, "NORD");**
** } **
** else if (SchalterZustand2 == 0 && SchalterZustand3 == 0 && SchalterZustand4 == 0 && SchalterZustand5 == 1) //0001**
** {**
** sprintf(windRicht, "N-NW");**
** }**

etc. bis alle 16 Möglichkeiten abgefragt sind.

Auf dem LCD funktioniert dann die Ausgabe mit:

lcd.print("WindR:");
lcd.print(windRicht);

Ausgabe: z.B. WindR: NORD

aber wie ich das NORD, SUED etc. je nach Windrichtung in die SMS-Ausgabe bekomme, schnalle ich nicht!

Ja ich weiss es, zuerst richtig lernen zu progammieren. Vielleicht hilft mir doch noch jemand diese Hürde zu überwinden. Sonst funktioniert alles einwandfrei
Gruss Erni

Abkürzen kann man das ganz einfach wenn du deine 4 Variablen erst mal in einen Integer packst und dann damit auf ein Array aus Strings zugreifst. Dann spart du dir viel Code und das Zwischen-Array fällt auch weg:

char windStrings[16][5] = { "NORD", "N-NO", "N-O ", "O-NO",
                            "OST ", "O-SO", "S-O ", "S-SO",
                            "SUED", "S-SW", "S-W ", "W-SW",
                            "WEST", "W-NW", "N-W ", "N-NW"
                          };

void setup()
{
  Serial.begin(9600);

  for (int s1 = 0; s1 < 2; s1++)
    for (int s2 = 0; s2 < 2; s2++)
      for (int s3 = 0; s3 < 2; s3++)
        for (int s4 = 0; s4 < 2; s4++)
        {
          int index = 0;
          bitWrite(index, 0, s1);
          bitWrite(index, 1, s2);
          bitWrite(index, 2, s3);
          bitWrite(index, 3, s4);

          print(index);
        }
}

void loop()
{
}

void print(int index)
{
  Serial.print(F("index ")); Serial.print(index); Serial.print(F(": "));

  char message[80];
  snprintf(message, sizeof(message), "Windrichtung: %s", windStrings[index]);
  Serial.println(message);
}

Die Reihenfolge ist etwas durcheinander. Das liegt aber nur an dem Test-Code mit den 4 for-Schleifen. Bei dir fallen die weg

Oder mit PROGMEM damit die Strings kein RAM belegen (dann %S statt %s):

const char windStrings[16][5] PROGMEM = { "NORD", "N-NO", "N-O ", "O-NO",
                                          "OST ", "O-SO", "S-O ", "S-SO",
                                          "SUED", "S-SW", "S-W ", "W-SW",
                                          "WEST", "W-NW", "N-W ", "N-NW"
                                        };

void setup()
{
  Serial.begin(9600);

  for (int s1 = 0; s1 < 2; s1++)
    for (int s2 = 0; s2 < 2; s2++)
      for (int s3 = 0; s3 < 2; s3++)
        for (int s4 = 0; s4 < 2; s4++)
        {
          int index = 0;
          bitWrite(index, 0, s1);
          bitWrite(index, 1, s2);
          bitWrite(index, 2, s3);
          bitWrite(index, 3, s4);

          print(index);
        }
}

void loop()
{
}

void print(int index)
{
  Serial.print(F("index ")); Serial.print(index); Serial.print(F(": "));

  char message[80];
  snprintf_P(message, sizeof(message), PSTR("Windrichtung: %S"), windStrings[index]);
  Serial.println(message);
}

Es ändert sich nur das Array und der printf() Aufruf. snprintf_P() sorgt zusätzlich dafür dass der Format-String kein RAM belegt.

F() wird bei print(), println() genauso verwendet

Wenn ich mich nicht verzählt habe gibt doch das sprintf Statement gar keine Windrichtung aus (mangels %s) ?

sprintf(message, "Ort: \nWind:%s km/h \nKnot:%s \nTiefk:%s C \nTemp:%s C \nLuftf: %s %% \nWindR:",
                         windGeschwOut, knotenOut, tempTiefkOut, tempOut, luftfOut, windRichtOut);

Whandall:
Wenn ich mich nicht verzählt habe gibt doch das sprintf Statement gar keine Windrichtung aus (mangels %s) ?

Gutes Argument.

Vielen Dank, aber das fehlende %s bei windR: ist beim Kopieren rausgefallen. Daran liegt es nicht. Ich befasse mich nun mit der Anwort von Serenifly. Ist sehr interessant und sieht auch professionel aus. Ich hoffe ich komme damit zurecht.

Wo bleibt eigentlich der Sketch? Ist der geheim?

Nein der Sketch ist natürlich nicht geheim. Aber ich kann es selber fast nicht glauben, die Sache funktioniert jetzt plötzlich. Nachdem ich nur char windRichtOut[5]; und dtostrf(windRicht[5] gelöscht und die SMS-Ausgabe so formatierte:

sprintf(message, "Ort: \nWind:%s km/h \nKnot:%s \nTiefk:%s C \nTemp:%s C \nLuftf: %s %% \nWindR: %s", windGeschwOut, knotenOut, tempTiefkOut, tempOut, luftfOut, windRicht);

Einige Anregungen von Serenifly werde ich noch versuchen in de Sketch einzubringen.
Vielen Dank an alle die mir mit ihren Anregungen geholfen haben.

Gruss Erni

nach Deinem

Nein der Sketch ist natürlich nicht geheim.

erwarte/n ich mir /sich andere Deinen gesamten Sketch sehen zu dürfen.
Grüße Uwe

ok. kommt morgen !!

Danke

Dann schau dir mal meinen Post 5 genauer an.

Da hatte ich dich bereits in die richtige Richtung geschubst und deinen Fehler mit windRicht korrigiert. Aber Mangels Sketch den Rest nicht analysiert.