Forum: Mikrocontroller und Digitale Elektronik 2 Sketche vereinen


von Markus (Gast)


Lesenswert?

Hi Leute,


ich brauche dringend eure Hilfe.

Ich habe 2 Sketche, die unabhängig von einander relativ gut 
funktionieren, aber ich würde es gerne vereinen.

Das eine Programm ist der Empfänger von einem Sender/Empfänger Programm. 
Dieser empfängt int-Werte und schaltet LEDs an bzw. aus.

Das andere Programm erkennt XML Tag und Inhalt wie z.B. <LED1>An, 
Tag=<LED1> und Inhalt=An.

Diese 2 Programme habe ich schon versucht zu vereinen, aber durch 
mangels der Kenntnisse der Programmiersprache, wende ich mich nach mehr 
als einer mühen vollen Woche ohne Erfolg an euch.

Bitte hilft mir.

Hier die Programme

1. XML
1
#include <string.h>
2
3
char Tag[20] = "";
4
char Inhalt[20] = "";
5
char tmpStr[20] = "";
6
char endTag[3] = {'<', '/', '\0'};
7
8
// Flags fuer Daten und XML-Code
9
boolean TagFlag = false;
10
boolean InhaltFlag = false;
11
12
void setup()
13
{
14
  Serial.begin(9600);
15
}
16
17
void loop() {
18
  while (Serial.available()) {
19
    XML(); 
20
  }
21
}
22
 
23
void XML() {
24
25
      char Zeichen = Serial.read();
26
  
27
   if (Zeichen == '<') {
28
      ZuLang(Zeichen, tmpStr);
29
      TagFlag = true;
30
      InhaltFlag = false;
31
32
   } else if (Zeichen == '>') {
33
      ZuLang(Zeichen, tmpStr);
34
35
      if (TagFlag) {      
36
         strncpy(Tag, tmpStr, strlen(tmpStr)+1);
37
      }
38
      // Tmp buffer wird geloescht
39
      Loschen(tmpStr);
40
41
      TagFlag = false;
42
      InhaltFlag = true;      
43
      
44
   } else if (Zeichen != 10) {
45
      if (TagFlag) {
46
         // fuegt den tag in den string bsp. <tempraum1>
47
         ZuLang(Zeichen, tmpStr);
48
49
         // Checkt </XML> end tag und ignoriert es
50
         if ( TagFlag && strcmp(tmpStr, endTag) == 0 ) {
51
            Loschen(tmpStr);
52
            TagFlag = false;
53
            InhaltFlag = false;
54
         }
55
      }
56
      if (InhaltFlag) {
57
         
58
         ZuLang(Zeichen, Inhalt);
59
      }
60
   }  
61
      Serial.print("Tag: ");
62
      Serial.println(Tag);
63
      Serial.print("Inahlt: ");
64
      Serial.println(Inhalt);
65
}
66
67
// Function im String zu loeschen
68
void Loschen (char* str) {
69
  
70
   int len = strlen(str);
71
   for (int c = 0; c < len; c++) {
72
      str[c] = 0;
73
   }
74
}
75
76
void ZuLang (char ch, char* str) {
77
  
78
   char *TagNachr  = "<TAG ZU LANG>";
79
   char *InhaltNachr = "-INHALT ZU LANG-";
80
81
//Wenn string zu lang wird, ignoriert er ihn
82
   if (strlen(str) > 20 - 2) {
83
      if (TagFlag) {
84
         Loschen(Tag);
85
         strcpy(Tag,TagNachr);
86
      }
87
      if (InhaltFlag) {
88
         Loschen(Inhalt);
89
         strcpy(Inhalt,InhaltNachr);
90
      }
91
      //loescht den tem buffer
92
      Loschen(tmpStr);
93
      TagFlag = false;
94
      InhaltFlag = false;
95
96
   } else {
97
        //fuegt ein eingelesenen Wert dem String hinzu
98
     str[strlen(str)] = ch;
99
   }
100
}

2. Empfänger
1
/**
2
 * MISO -> 12
3
 * MOSI -> 11
4
 * SCK -> 13
5
 * CE -> 8
6
 * CSN -> 7
7
 */
8
9
#include <SPI.h>
10
#include <Mirf.h>
11
#include <nRF24L01.h>
12
#include <MirfHardwareSpiDriver.h>
13
14
int fall=0;
15
16
void setup(){
17
  
18
  pinMode(4,OUTPUT);
19
  pinMode(3,OUTPUT);
20
  pinMode(2,OUTPUT);
21
  Serial.begin(9600);
22
23
  Mirf.spi = &MirfHardwareSpi;
24
  Mirf.init();
25
  Mirf.setRADDR((byte *)"serv1");// Name des Servers
26
  Mirf.payload = sizeof(unsigned long);
27
  Mirf.config();
28
  
29
  Serial.println("Empfangen..."); 
30
}
31
32
void loop(){
33
34
  byte data[Mirf.payload]; // Hier wird der empfangene byte gespeichert
35
  
36
  if(!Mirf.isSending() && Mirf.dataReady()){
37
    Serial.println("Got packet");
38
39
    Mirf.getData(data); // Packet (daten) empfangen
40
     
41
    Mirf.setTADDR((byte *)"clie1");//Bestimmen des Client Namens 
42
    
43
     Serial.println(data[0]);
44
    fall = data[0];
45
     switch (fall){
46
      
47
      case '1':
48
      digitalWrite(4,HIGH);break;
49
      case '2':
50
      digitalWrite(3,HIGH);break;
51
      case '3':
52
       digitalWrite(2,HIGH);break;    
53
      case '4':
54
      digitalWrite(4,LOW);break;
55
      case '5':
56
      digitalWrite(3,LOW);break;
57
      case '6':
58
       digitalWrite(2,LOW);break; 
59
     } 
60
    Mirf.send(data); // Sendet wert zurueck zum Clienten,
61
      
62
    Serial.println("Reply sent.");
63
  }
64
}

Wer die Module(Arduino Uno, nRF24l01 Funkmodul) zur Hand hat, kann das 
testen, dafür sende ich noch den Sender dazu

3. Sender
1
#include <SPI.h>
2
#include <Mirf.h>
3
#include <nRF24L01.h>
4
#include <MirfHardwareSpiDriver.h>
5
6
int hall; //Variable wird deklariert diese wird dann dem System Uebergeben
7
8
void setup(){
9
  Serial.begin(9600); 
10
  
11
  Mirf.spi = &MirfHardwareSpi; 
12
  Mirf.init(); 
13
  
14
  Mirf.setRADDR((byte *)"clie1"); //Der Name bzw. Adresse des Clienten wird erstellt
15
16
  Mirf.payload = sizeof(unsigned long); // Hier wird die Laenge des Buffers 
17
18
  Mirf.config(); //Laden der Konfigurationsdatein
19
  
20
  Serial.println("Beginn ... "); 
21
}
22
23
void loop(){
24
   unsigned long time = millis(); 
25
26
  int hall=0;
27
  
28
  if (Serial.available() > 0) {
29
                hall = Serial.read();} 
30
  Mirf.setTADDR((byte *)"serv1"); // Sucht den Server mit dem Namen "serv1"
31
  
32
  Mirf.send((byte *)&hall); 
33
  
34
  while(Mirf.isSending()){
35
  }
36
  Serial.println("Empfang beendet");
37
  delay(10);
38
  while(!Mirf.dataReady()){
39
    
40
    if ( ( millis() - time ) > 1000 ) {
41
      Serial.println("Server antwortet nicht!");
42
      return;
43
    }
44
  }
45
  Mirf.getData((byte *) &time);
46
  
47
  Serial.print("Zeit in mills: ");
48
  Serial.println((millis() - time));
49
  
50
  delay(1000);
51
}

Vielen Dank schon mal im Vorraus

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Lies bitte, was über jedem Eingabefeld steht:
1
Wichtige Regeln - erst lesen, dann posten!
2
  Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
Deine Arduino Programme sind übrigens C-Verschnitt, deshalb wäre es 
sinnvoll, wenn du die Datei(en) nach *.c umbenennst. Dann gibt hier 
kostenlos nettes Syntaxhighlighting dazu...

Oder machs wenigstens so:
1
Formatierung 
2
    [c]C-Code[/c]

von Markus (Gast)


Lesenswert?

Verzeih mir, habe das übersehen.

kann ich es noch ändern?

von Max H. (hartl192)


Lesenswert?

Markus schrieb:
> kann ich es noch ändern?
Nur als Registrierter User. Ein Mod hat es für dich gemacht...

von Christian B. (chbalnuweit)


Lesenswert?

Was funktioniert denn nicht? Gibt es Fehler beim kompilieren (oder wie 
das bei dem Arduino-Quatsch heissen mag)?

von Nachhilfe (Gast)


Lesenswert?

Christian B. schrieb:
> Gibt es Fehler beim kompilieren (oder wie das bei dem Arduino-Quatsch
> heissen mag)?

"Übersetzen" heißt das da - komisches Wort ;-)

von Markus (Gast)


Lesenswert?

HI Christian,


nein, Fehler gibt es nicht, die Programme  funktionieren unabhängig von 
einander relativ gut. Ich habe es nicht geschafft das XML Programm in 
den Empfänger zu integrieren.

Beispiel

<LED1>1</LED1> soll geschickt werden

und der Empfänger soll dann die LED1 einschalten

von Karl H. (kbuchegg)


Lesenswert?

Ich denke, du wirst wieder mal den Fehler Nummero Uno in so einem Fall 
gemacht haben.

Du hast Programm A und Programm B und versuchst die beiden irgendwie 
miteinander zu vermischen.

So was geht praktisch immer schief.

Was du statt dessen machen musst, ist Programm C zu schreiben.

D.h. deine Strategie ist es nicht, die beiden Programm zu mischen, 
sondern zu allererst schreibst du erst mal ein komplett neues Programm.
Punkt.
In dieses neue Programm kannst du Ideen und Techniken aus den beiden 
anderen Programmen übernehmen. Übernehmen bedeutet in dem Fall: die Idee 
übernehmen, die Grundtechnik übernehmen. Ab und an kann man eventuell 
auch schon mal Codeteile übernehmen. Aber sich darauf zu versteifen, 
dass man den Code 1:1 übertragen kann, funktioniert nur sehr selten und 
auch nur dann, wenn die zu übernehmenden Codeteile ordentlich in ein 
Modul ausgelagert wurden.

Also:
Wenn du jedes der beiden Programme einzeln geschrieben hast, dann kennst 
du ja die Ideen die da drinn stecken und es sollte eigentlich nicht so 
schwer sein, ein komplett neues Programm zu schreiben, welches die 
Fähigkeiten der beiden Einzelprogramm vereint.


> aber durch mangels der Kenntnisse der Programmiersprache
und das ist der erste Punkt, den du abstellen musst.
Wer programmieren will, muss seine Programmiersprache können.
Punkt.

von Markus (Gast)


Lesenswert?

Danke Karl Heinz für deine Antwort.


Ich nehme mir dein Vorschlag zur Herzen und werde versuchen ein neues 
Programm zuschreiben mit den Ideen von den anderen beiden.


Leider bleibt mir nicht viel Zeit, um die Programmiersprache komplett 
vorher zu erlernen. Kenntnisse in C sind vorhanden, aber keine 
überragende.

Nichtsdestotrotz wäre es cool, wenn mir jemand direkte Hinweise dafür 
geben würden.

Vielen Dank

von Düsendieb (Gast)


Lesenswert?

welche Fehler kommen denn wenn Du mal gnadenlos mit control c und 
control v den Text aus dem einen Sketch in den anderen kopierst und dann 
das ganze unter einem neuen Namen abspeicherst und wieder übersetzt?

von Markus (Gast)


Lesenswert?

Also wenn ich das ein so rein kopiere ohne variable namen zu ändern, 
dafür den rest an die richtige stelle setzte, was in Loop kommt habe ich 
in Loop kopiert usw. dann führt der nicht die XML Datei durch. dafür 
muss ich bestimmte variable unbennen und einiges mehr.

von Mark B. (markbrandis)


Lesenswert?

Max H. schrieb:
> Markus schrieb:
>> kann ich es noch ändern?
> Nur als Registrierter User. Ein Mod hat es für dich gemacht...

Auch als registrierter Nutzer hätte er es an dieser Stelle nicht mehr 
ändern können ;-)

von Max H. (hartl192)


Lesenswert?

Mark Brandis schrieb:
> Auch als registrierter Nutzer hätte er es an dieser Stelle nicht mehr
> ändern können ;-)
Den Eröffnungspost, kann ich auch später, nach einer Antwort, noch 
bearbeiten.

Als Demonstration: Schau dir an, wann dieser Post bearbeitet wurde: 
Beitrag "PIC24 ASM Tutorial"

von Karl H. (kbuchegg)


Lesenswert?

Düsendieb schrieb:
> welche Fehler kommen denn wenn Du mal gnadenlos mit control c und
> control v den Text aus dem einen Sketch in den anderen kopierst und dann
> das ganze unter einem neuen Namen abspeicherst und wieder übersetzt?

Es bringt ihn nicht weiter.

Der erste Sketch parst offenbar einen Input, der von der seriellen 
Schnittstelle kommt. Der zweite Sketch ist offenbar die Übertragung von 
Kommandos über eine MIRF Schnittstelle (was immer das auch ist).
Die Zusamenführung der beiden: Übertragung von XML über MIRF und parsen 
dessen, was als XML aus dem MIRF dann rauskommt, gelingt nicht, indem 
man einfach naiv alles zusammenkopiert. Dazu muss man die beiden 
Einzelteile schon verstehen und zb auch verstehen, wie diese MIRF 
Übertragung funktioniert, solche Dinge, wie das hier
1
  Mirf.payload = sizeof(unsigned long); // Hier wird die Laenge des Buffers
müssen zb angepasst werden.
Hat man das erst mal, hat man die MIRF Übertragung auf Text umgestellt, 
dann kann man den XML Teil da hinten drann hängen. Denn der erste Sketch 
besteht ja auch aus 2 Teilen: dem Teil der das nächste Zeichen von der 
Schnittstelle holt
1
      char Zeichen = Serial.read();
und dem Rest, der dann mit dem Zeichen etwas macht.

Den Teil, der 1 Zeichen von der Schnittstelle holt, wenn eines da ist, 
den muss man eben durch dieses MIRF ersetzen.

In Summe nicht so schwer. Aber mit naiver Herangehensweise und schwachen 
Programmierfähigkeiten nicht zu machen.

von Markus (Gast)


Lesenswert?

Ja, einfach rein kopieren geht leider nicht. Man muss bestimmte Dinge 
anpassen, wie Karl Heinz schon erwähnt hat.

Senden und empfangen funktioniert über ein Funkmodul(nRF24l01). Dieses 
Funkmodul hat 2 Bibs, eine davon ist die Mirf. Diese Mirf hat bestimmte 
Befehle, wie beispielsweise es Daten sendet und empfängt. Zu denen 
gehört auch diese von Karl Hein erwähnten Befehl.

Karl Heinz schrieb:
> In Summe nicht so schwer

Ich bin seit knapp 2 Wochen dabei.

von Mark B. (markbrandis)


Lesenswert?

Max H. schrieb:
> Den Eröffnungspost, kann ich auch später, nach einer Antwort, noch
> bearbeiten.

Na sowas. Ich hatte den Satz "Eigene Beiträge können bis maximal 60 
Minuten nach dem Absenden bearbeitet werden, und nur wenn noch keine 
Antworten eingetroffen sind" wohl zu wörtlich genommen. ;-)

von Peter D. (peda)


Lesenswert?

Am besten ist es, erstmal ausfürlich zu beschreiben, was die beiden 
Sketsche überhaupt machen sollen.
Einfach so drauf los zu programmieren ist der falsche Weg.

von Markus (Gast)


Lesenswert?

HI Peter,
wie gewünscht, beschreibe ich die Programme genauer was die machen 
sollen.

Sender

Der Sender soll eine Zeichenkette senden, die man in die Konsole 
eingegeben hat, wie z.B. <LED1>1</LED1>


Empfänger

Der Empfänger soll diese Zeichenkette empfangen und durch das 
XML-Programm laufen lassen.
Dadurch bekommt man 2 Informationen, anhand des obigen Beispiel 
<LED1>1</LED1>

Tag: <LED1>
Inhalt: 1

Mit diesen Informationen läuft das Programm durch mehrere if-Schleifen, 
eine davon wäre
1
if(Tag==<LED1>){ 
2
   
3
   if(Inhalt==1){
4
   digitalWrite(4,HIGH);
5
6
   }else if(Inhalt==2){
7
   digitalWrite(4,LOW);
8
9
   }else {
10
   serialprint(Eingabe falsch)
11
   }
12
}

Natürlich vergleicht das Programm dann Zeichen für Zeichen,
also Tag[0]==<...

Das war denke ich alles.
Ich hoffe, das man jetzt ein besseres Verständnis dafür hat, was ich 
will und dringend brauche

von Peter D. (peda)


Lesenswert?

Markus schrieb:
> Mit diesen Informationen läuft das Programm durch mehrere if-Schleifen,

Also das eine ist eine Unterfunktion des anderen.
Dann ruf doch das 2. am Ende des 1. auf.

Ich sehe allerdings nirgends, wo die 1. irgendwas ablegt, was dann die 
2. auswerten kann.

von Markus (Gast)


Lesenswert?

Mit mehrere if-Schleifen, habe ich gemeint, das es mehrere Schleifen für 
den Tag gibt, und jede diese Schleife enthält weitere Schleifen

So ungefähr
1
if(Tag==<LED1>){ 
2
   
3
   if(Inhalt==1){
4
   digitalWrite(4,HIGH);
5
6
   }else if(Inhalt==2){
7
   digitalWrite(4,LOW);
8
9
   }else {
10
   serialprint(Eingabe falsch);
11
   }
12
}
13
14
if(Tag==<LED2>){ 
15
   
16
   if(Inhalt==1){
17
   digitalWrite(3,HIGH);
18
19
   }else if(Inhalt==2){
20
   digitalWrite(3,LOW);
21
22
   }else {
23
   serialprint(Eingabe falsch);
24
   }
25
}
26
27
if(Tag==<SERVO1>){ 
28
   
29
   if(Inhalt==1){
30
   digitalWrite(2,HIGH);
31
32
   }else if(Inhalt==2){
33
   digitalWrite(2,LOW);
34
35
   }else {
36
   serialprint(Eingabe falsch);
37
   }
38
}
so in etwa.

von Karl H. (kbuchegg)


Lesenswert?

Markus schrieb:
> Mit mehrere if-Schleifen,

Es geht nicht mehr.
ES GIBT KEINE IF_SCHLEIFEN!

Das Wesen einer Schleife ist es, dass etwas wiederholt werden kann. 
Zumindest prinzipiell. Drum heißt es Schleife. Wie bei einem Tonband, 
das zu einer Schleife zusammen geklebt wird und das daher beim Abspielen 
immer wieder von vorne anfängt.

In einem if wird nichts wiederholt. Ein if trifft eine Auswahl aus 2 
Möglichkeiten. Das hat mit einer Schleife genau gar nichts zu tun.

von Karl H. (kbuchegg)


Lesenswert?

Markus schrieb:

> so in etwa.

Ja.
Aber nur wenn man die Regeln der Programmiersprache sehr sehr frei 
interpretiert. Ausserdem fehlt da 80%. Die interessanten 80%: nämlich, 
wie kommt der Text erst mal in die String Variable "Tag" hinein.

von Mark B. (markbrandis)


Lesenswert?

Karl Heinz schrieb:
> Markus schrieb:
>> Mit mehrere if-Schleifen,
>
> Es geht nicht mehr.
> ES GIBT KEINE IF_SCHLEIFEN!

In der Tat:

http://www.if-schleife.de/

Diese Fehlbezeichnung hält sich leider sehr hartnäckig... :-(

von Markus (Gast)


Lesenswert?

Ja gut, dann keine Schleife, sondern eine if-Funktion.

das XML-Programm alleine Funktioniert relativ gut.

Aktuell ist es so, dass das XML-Programm eine Zeichenkette einließt und 
den Tag und Inhalt herausgibt.

dadurch könnte man diese dann durch die if-Funktion durch gehen lassen.

von A. W. (uracolix)


Lesenswert?

Komplettes neu schreiben, das macht den Code immer besser!

Also, du hast zwei funktionierende Implementierungen, das ist gut um 
dagegen zu testen. Du hast das Problem vollstaendig verstanden, sonst 
gaebe es die
beiden Programme nicht.

Jetzt setz dich hin und schreib ein drittes Programm was a und b 
vereint.
Du wirst staunen wieviel Optimierungspotenzial deine aktuellen 
Implementierungen haben.

Der Wert deiner Arbeit steckt nicht in den Tastenanschlaegen mit denen 
du
den Code eingegeben hast, sondern im Durchdenken des Problems. Also 
schreibs
einfach neu und mach es besser (und bleib bei der Sprache die kannst, 
wozu was neues Lernen, das waere wirklich ein unnuetzes Nebenprojekt im 
Moment).

Ein Programm ist wie eine Packung Pralinen, die Idee ist die Schokolade 
und der Quelltext die Verpackung.

von Karl H. (kbuchegg)


Lesenswert?

A. W. schrieb:

> Ein Programm ist wie eine Packung Pralinen, die Idee ist die Schokolade
> und der Quelltext die Verpackung.

Das hast du schön gesagt. Der Spruch ist es wert, gemerkt zu werden.

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.