Forum: PC-Programmierung verschiedene Kommandoslänge per Rs232 senden


von Kaiser K. (kingkong_18)


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;
}

von Joachim B. (jar)


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!

von Peter D. (peda)


Lesenswert?

Kaiser K. schrieb:
> was mich gerade
> irritiert ist die Variable "total".

Mich auch, wozu hast Du sie definiert?
Strings enden immer mit '\0', d.h. die Länge ist bekannt.
Stringfunktionen beenden sich daher mit Erkennen von '\0', andere 
Funktionen können mit strlen() die Länge ermitteln.

: Bearbeitet durch User
von Purzel H. (hacky)


Lesenswert?

>if(kbhit()) { c =_getch(); ..

Uiiii... Die letzten 20 Jahre was anderes gemacht ? Ne kommandozeilen 
Applikation, wo man das command sogar noch ausschreibt.

Heute geht das eher per buttonclick.

von Bert3 (Gast)


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

von georg (Gast)


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

von Marco H. (damarco)


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.

: Bearbeitet durch User
von Anka B. (Gast)


Lesenswert?

Da 'total' nicht definiert ist, kann dieses Programm nicht laufen. Warum 
dann noch Begriffe wie Header eingeworfen werden, erschließt sich dem 
Betrachter nicht.

von Marco H. (damarco)


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.

: Bearbeitet durch User
von Anka B. (Gast)


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?

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.