verschiedene Kommandoslänge per Rs232 senden

OP #5522059
Lesenswert?

Hallo ihr wissenden,
ich schreibe hier ein programm bei dem ich ein parr Kommando per RS232 
zu einem Messgerät schicken soll. das beigefügte bespielprogramm zeigt 
an wie die Nachrichten geschickt werden sollen. was mich gerade 
irritiert ist die Variable "total". sie ändert sich jenach welche 
Kommando man schickt. das alle kommando unterschiedliche Länge haben. 
Hat einer Vielleicht eine Idee wie man dieses Problem lösen könnte ohne 
die Sendeschleife(die For-schleife) für jede kommando zu schreiben? ich 
habe ungefähr 30 kommando, die gesendet werden können und wenn ich für 
jede Kommando diese Schleife wiederholen würde,  wird das program 
bestimmt unübersichtlich

Danke im Voraus


#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <time.h>


#define SerialNumber            10
#define Status                  11

#define MAXBUFFER 200
int main()
{
    char Sendstring[20];
    int a, total;
    int chr_cnt=0, Command = 0;
    char in_command[MAXBUFFER];
    char in_buff[MAXBUFFER];
    while(1)
    {
        if(kbhit())
        { c =_getch();
          if(c == '\r')  // Wenn das Enter ankommt
          { in_buff[chr_cnt]=0;
            strcpy(in_command, in_buff);
            // strcpy(in_buff,"");
            memset(&in_buff[0], 0, sizeof(in_buff));
            chr_cnt = 0;

            if(0 == strcmp((const char*)in_command, "SerialNumber")
            {
                Command = SerialNumber;
            }
            if(0 == strcmp((const char*)in_command, "Status")
            {
                Command = Status;
            }
            else
            {
                printf("%s invalid name", in_command);
            }


            if (SerialNumber == Command)
            {
                Sendstring[0] = 'S';
                Sendstring[1] = 'e';
                Sendstring[2] = 'r';
                Sendstring[3] = 'i';
                Sendstring[4] = 'a';
                Sendstring[5] = 'l';
                Sendstring[6] = 'N';
                Sendstring[7] = 'u';
                Sendstring[8] = 'm';
                Sendstring[9] = 'b';
                Sendstring[10] = 'e';
                Sendstring[11] = 'r';
            }
            if (Status == Command)
            {
                Sendstring[0] = 'S'
                Sendstring[1] = 't'
                Sendstring[2] = 'a'
                Sendstring[3] = 't'
                Sendstring[4] = 'u'
                Sendstring[5] = 's'
            }

            for (n = 0; n <= total; n++)
            {
                rs232Sendbyte(Cport, Sendstring[n]);
            }
          }
          else
          {
             if(isprint(c))
             {  if(chr_cnt<(MAXBUFFER-2))
                  in_buff[chr_cnt++] = c;
                else
                { //Serial.println(F("serBUF ov-> DEL"));
                  *in_buff=0;
                  *in_command=0;
                  chr_cnt=0;
                } // if(!(chr_cnt<(MAXBUFFER-2)))
             } // if(isprint(c))
          } // if(!(c == '\r'))
       } // if(kbhit())
    } // while(1)
    printf("You Pressed enter, End Of Program");
    return 0;
}
#5522077
Lesenswert?

du solltest programmieren lernen, wo steckt der Sinn dein Sendstring in 
Einzelbuchstaben zuzuweisen?

was hast du gegen strcpy?

Kaiser K. schrieb:
> int a, total;

total wird keinen Startwert zugewiesen ist bei Programmstart also 
vielleicht zufällig?

Kaiser K. schrieb:
> for (n = 0; n <= total; n++)

woher soll die Schleife wissen wieviel n werden darf? wenn total keinen 
definierten Wert hat?

ich denke nun auch du bist ein Troll wie andere schon vermuteten!
Gast #5525713
Lesenswert?

void rs232SendStr(int Cport, char* str, int size)
{
            for (n = 0; n < total; size++)
            {
                rs232Sendbyte(Cport, str[n]);
            }
}

und ersetz die direkte for-Schleife durch den Funktions-Aufruf

            rs232SendStr(Cport, &Sendstring[0], total);

und so einfach ein paar Hilfs-Funktionen einbauen (die alle Daten per 
Parameter bekommen) und schon sieht du wie das ganze aufgeräumt werden 
kann
Gast #5525779
Lesenswert?

Peter D. schrieb:
> Strings enden immer mit '\0', d.h. die Länge ist bekannt.

Das ist in MANCHEN Sprachen so (auch da nicht immer). Aber wenn man 
nichts anderes kennt...

Aber letzlich ist es egal, woher man die Länge kennt. Zum Senden über 
eine serielle Schnittstelle muss man sie halt wissen.

Ansonsten ja, der TO sollte wenigsten ein kleines bisschen Programmieren 
lernen, z.B. dass man die Anzahl von Zeichen einer Sendefunktion auch 
als Parameter übergeben kann. Ganz tolle Erfindung, das mit den 
Parametern.

Georg
#5526180
Lesenswert?

erst mal baut man sich eine Struktur für den Header, die eigentlichen 
variablen Daten hängt man als payload an. Die send Funktion sendet nur 
den Frame.

Ich kann mir auch kaum vorstellen das das Interface des Messgerätes mit 
Strings funktioniert ?  cmd -> "strings", "status" ...
1
 enum {cmd_error,cmd_string,cmd_status}
 -> 0,1,2 usw.

Das packt man in einen header...
1
struct header{
2

3
uint8_t cmd;
4
uint8_t status;
5
uint16_t length;
6
uint8_t payload[];
7
}

Die send Funktion schreibt den header und die Daten in einen Buffer und 
sorgt für die Ausgabe.

Ja nach dem wie komplex deine payload Daten sind müssen die mit extra 
Funktionen erzeugt werden...

Als Antwort verwendet das Messgerät den gleichen Header und hängt den 
Status mit an ->
1
enum {success,error,not_found}

kurz gesagt entwerfe erst mal ein ordentliches Protokoll für das 
Messgerät. Ich kann mir kaum vorstellen das das Gerät die Strings wieder 
auseinander bastelt.
#5526836
Lesenswert?

Eben und es soll aufgezeigt werden das man es anders lösen kann! Die 
Länge des Headers ist bekannt, die Länge der payload steckt im header.

Als String Kommandos oder auch Werte zu übertragen macht in so weit nur 
Sinn wenn sie als String auch wieder ausgegeben/verarbeitet werden. 
Sonst hast du er eine Datenschleuder..

Gerade durch enums und Strukturen wird er Code übersichtlich und 
funktionell.

Lange switch oder if else Konstrukte lassen sich auch vermeiden wenn man 
mit Pointern, enum und Strukturen umgehen kann.
Gast #5527066
Lesenswert?

Marco H. schrieb:
> Lange switch oder if else Konstrukte lassen sich auch vermeiden wenn man
> mit Pointern, enum und Strukturen umgehen kann.
...wobei man dann schon fast bei der Assembler-Denke ist. 
Pointer-Arrays, Pointer auf *Pointer auf **Pointer.... Schon mal dran 
gedacht, dass das nicht jedermanns Sache sein könnte?

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