Autor Tema: Comportamiento erratico en comunicacion serie  (Leído 3151 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado esperanzachat

  • PIC10
  • *
  • Mensajes: 39
Comportamiento erratico en comunicacion serie
« en: 30 de Mayo de 2019, 17:23:35 »
Hola, como dije queria mudar un codigo del ds1307 al ds3231 y al parecer estoy mas cerca de ello. el problema es que cuando mando los comandos a la usart del pic a veces me responde y a a veces tengo que repetir los comando varias veces para lograr la respuesta, esto no me pasaba antes con el ds1307. Por ejemplo si mando el comando "hora" por la usart, me tiene que decir la hora del reloj. Aqui el codigo un poco precario. Este es el codigo editado.Ojala me ayuden a resolver este problema.

Código: [Seleccionar]
/* Real time clock using PIC16F887 & DS3231 (DS3232) CCS C code
   Read DS3231 RTC datasheet to understand the code!
   Internal oscillator used @ 8MHz
   http://ccspicc.blogspot.com/
   electronnote@gmail.com
*/
////COMANDOS:
///set:22:21 ///pone hour en 22:21
///hour ///muestra la hour
///tiempo  muestra el tiempo de activacion grabado en dir 0x00
///ta:10;//ajusta tiempo activacion en eeprom 0x00
////ver ///muestra los programas
///de:1///borra programa 1
//pr1:23:45  ///setea programa en 23:45
///los programas estan en las posiciones:
///t1=0x20, m1=0x21
//t2=0x30, m2=0x31
//t3=0x41, m3=0x041
///t4=0x50, m4=0x51
//t5=0x60; m5=0x61
#include <16F887.h>
#include <stdlib.h>////para poder hacer las conversiones a entero
#include <string.h>
#fuses MCLR NOBROWNOUT NOLVP INTRC_IO PROTECT
#use delay(clock = 4MHz)
#use I2C(master, I2C1, SLOW)
#use rs232(uart1, baud=9600)//usart1 -->ajuste de XMIT y RCV para la USART 1
unsigned int8  i, second, minute, hour, date=1, month=5, year=19,DHora,DMinutos,UHora,UMinutos,TActivacion=10;
int8 t1,t2,t3,t4,t5;
int8 m1,m2,m3,m4,m5;
// CONSTANTES /////////////////////////////////////////////////////////////////
int const lenbuff=32;                  // Longitud de buffer, Ajustar
                                       // a lo que desees (o te sea posible)
                                       
                                       // VARIABLES EN RAM ///////////////////////////////////////////////////////////
int  xbuff=0x00;                       // Índice: siguiente char en cbuff
char cbuff[lenbuff];                   // Buffer
char rcvchar=0x00;                     // último caracter recibido
char strHoras[3];
char strMinutos[3];
char strTa[3];
int1 flagcommand=0;                    // Flag para indicar comando disponible
int1 EsNumero=0;
int1 EsHora=0;
int8 CantidadNumeros=0;
int1 Activar=0;//me dice si tengo que activar la salida

// Declaración de Funciones ///////////////////////////////////////////////////
void inicbuff(void);                   // Borra buffer
int  addcbuff(char c);                 // añade caracter recibido al buffer
void echos(char c);                    // Eco

// Desarrollo de Funciones ////////////////////////////////////////////////////

void inicbuff(void){                   // Inicia a  cbuff -------------------
   int i;

   for(i=0;i<lenbuff;i++){             // Bucle que pone a 0 todos los
      cbuff[ i ]=0x00;                   // caracteres en el buffer
   }
   xbuff=0x00;                         // Inicializo el indice de siguiente
                                       // caracter
}

int addcbuff(char c)
{                  // Añade a cbuff -----------------------   
   cbuff[xbuff++]=c;          // Añade caracter recibido al Buffer
}

// INTERRUPCIONES /////////////////////////////////////////////////////////////

#int_rda
void serial_isr() {                    // Interrupción recepción serie USART

   ///restart_wdt();
   rcvchar=0x00;                       // Inicializo caracter recibido
   if(kbhit()){                        // Si hay algo pendiente de recibir ...
      rcvchar=getc();                  // lo descargo y ...
      addcbuff(rcvchar);               // lo añado al buffer y ...
      ///echos(rcvchar);                  // hago eco (si procede).
   }
}

ImprimirPlantillaReloj(void)
{
   printf("%u",DHora);
   printf("%u",UHora);
   printf(":");
   printf("%u",DMinutos);
   printf("%u\r\n",UMinutos);//salto de linea
}

ObtenerHoraActual(void)
{
    // read current time and date from the RTC chip}
    i2c_start();                                  // Start I2C protocol
    i2c_write(0xD0);                              // DS3231 address
    i2c_write(0);                                 // Send register address
    i2c_start();                                  // Restart I2C
    i2c_write(0xD1);                              // Initialize data read
    second = i2c_read(1);                         // Read seconds from register 0
    minute = i2c_read(1);                         // Read minuts from register 1
    hour   = i2c_read(1);                         // Read hour from register 2
    i2c_read(1);                                  // Read day from register 3 (not used)
    date   = i2c_read(1);                         // Read date from register 4
    month  = i2c_read(1);                         // Read month from register 5
    year   = i2c_read(0);                         // Read year from register 6
    i2c_stop();                             
}

ModificarPrograma(int8 DirHora,DirMin)
{
write_eeprom(DirHora,hour);
delay_ms(5);
write_eeprom(DirMin,minute);
delay_ms(5);
}

int8 LeerTActivacion(void)
{
   TActivacion=read_eeprom(0x00);///lee la memoria
   if(TActivacion==0xFF)TActivacion=10;///valor por defecto
   delay_ms(5);
   return(TActivacion);
}

GuardarTActivacion(void)
{
   write_eeprom(0x00,TActivacion);///guardo el tiempo de activacion
   delay_ms(5);
}

int1 comprobarSiNumero()
{
   EsNumero=0;
   CantidadNumeros=0;
   for (i=4;i<=8;++i)
      if((cbuff[i]=='0')||(cbuff[i]=='1')||(cbuff[i]=='2')||(cbuff[i]=='3')||(cbuff[i]=='4')||(cbuff[i]=='5')||(cbuff[i]=='6')||(cbuff[i]=='7')||(cbuff[i]=='8')||(cbuff[i]=='9'))CantidadNumeros=CantidadNumeros+1;
      if(CantidadNumeros==4)EsNumero=1;
      else EsNumero=0;
   return(EsNumero);
}

int1 comprobarTActivacion()
{
   CantidadNumeros=0;//inicalizo la cuenta
   if((cbuff[4]=='0')||(cbuff[4]=='1')||(cbuff[4]=='2')||(cbuff[4]=='3')||(cbuff[4]=='4')||(cbuff[4]=='5')||(cbuff[4]=='6')||(cbuff[4]=='7')||(cbuff[4]=='8')||(cbuff[4]=='9'))CantidadNumeros=CantidadNumeros+1;      if(CantidadNumeros==4)EsNumero=1;
   if((cbuff[3]=='0')||(cbuff[3]=='1')||(cbuff[3]=='2')||(cbuff[3]=='3')||(cbuff[3]=='4')||(cbuff[3]=='5')||(cbuff[3]=='6')||(cbuff[3]=='7')||(cbuff[3]=='8')||(cbuff[3]=='9'))CantidadNumeros=CantidadNumeros+1;      if(CantidadNumeros==4)EsNumero=1;
   if(CantidadNumeros==2) return(1);
   else return(0);
}
CargarProgramas(void)//cargo los tiempos de programacion
{
///los programas estan en las posiciones:
///t1=0x20, m1=0x21
//t2=0x30, m2=0x31
//t3=0x41, m3=0x041
///t4=0x50, m4=0x51
//t5=0x60; m5=0x61
   t1=read_eeprom(0x20);///lee la memoria
   delay_ms(5);
   t2=read_eeprom(0x30);///lee la memoria
   delay_ms(5);
   t3=read_eeprom(0x40);///lee la memoria
   delay_ms(5);
   t4=read_eeprom(0x50);///lee la memoria
   delay_ms(5);
   t5=read_eeprom(0x60);///lee la memoria
   delay_ms(5);
   
   m1=read_eeprom(0x21);///lee la memoria
   delay_ms(5);
   m2=read_eeprom(0x31);///lee la memoria
   delay_ms(5);
   m3=read_eeprom(0x41);///lee la memoria
   delay_ms(5);
   m4=read_eeprom(0x51);///lee la memoria
   delay_ms(5);
   m5=read_eeprom(0x61);///lee la memoria
   delay_ms(5);
}

MostrarProgramas(void)
{
  printf("Los Horarios programados son:\r\n");
  if(t1==0xFF) printf("vacio:\r\n");     
      else
         {
         DHora=t1/10;///descompongo hora actual
         UHora=t1%10;
         DMinutos=m1/10;
         UMinutos=m1%10;
         ImprimirPlantillaReloj();
         }
  if(t2==0xFF) printf("vacio:\r\n");     
      else
         {
         DHora=t2/10;///descompongo hora actual
         UHora=t2%10;
         DMinutos=m2/10;
         UMinutos=m2%10;
         ImprimirPlantillaReloj();
         }
  if(t3==0xFF) printf("vacio:\r\n");     
      else
         {
         DHora=t3/10;///descompongo hora actual
         UHora=t3%10;
         DMinutos=m3/10;
         UMinutos=m3%10;
         ImprimirPlantillaReloj();
         }
         
  if(t4==0xFF) printf("vacio:\r\n");     
      else
         {
         DHora=t4/10;///descompongo hora actual
         UHora=t4%10;
         DMinutos=m4/10;
         UMinutos=m4%10;
         ImprimirPlantillaReloj();
         }
  if(t5==0xFF) printf("vacio:\r\n");     
      else
         {
         DHora=t5/10;///descompongo hora actual
         UHora=t5%10;
         DMinutos=m5/10;
         UMinutos=m5%10;
         ImprimirPlantillaReloj();
         }
}

int1 ComprobarSiHora()
{
   EsHora=0;
   if((comprobarSiNumero()==1)&&(cbuff[6]==':'))
      {
      strHoras[0]=cbuff[4];
      strHoras[1]=cbuff[5];
      hour=atol(strHoras);
      strMinutos[0]=cbuff[7];
      strMinutos[1]=cbuff[8];
      minute=atol(strMinutos);
      if((hour<24)&&(minute<60))EsHora=1;
      else EsHora=0;
      }
   return(EsHora);
}

ModificarSalida(void)
{
   ObtenerHoraActual();//obtiene la hora
   if(((t1==hour)&&(m1==minute))||((t2==hour)&&(m2==minute))||((t3==hour)&&(m3==minute))||((t4==hour)&&(m4==minute))|((t5==hour)&&(m5==minute)))Activar=1;
   else Activar=0;
   while((second<TActivacion)&&(Activar==1))
      {
      //restart_wdt();
      ObtenerHoraActual();//obtiene la hora
      output_high(PIN_B3);
      delay_ms(1000);///espera que pase el tiempo
      }
   output_Low(PIN_B3);///salida rele
   Activar=0;
}


void SetDateTime(){
      // Convert decimal to BCD
      minute = ((minute / 10) << 4) + (minute % 10);
      hour = ((hour / 10) << 4) + (hour % 10);
      date = ((date / 10) << 4) + (date % 10);
      month = ((month / 10) << 4) + (month % 10);
      year = ((year / 10) << 4) + (year % 10);
      // End conversion
      // Write data to DS3231 RTC
      i2c_start();                               // Start I2C protocol
      i2c_write(0xD0);                           // DS3231 address
      i2c_write(0);
      i2c_write(0);                              // Reset sesonds and start oscillator
      i2c_write(minute);                         // Write minute value to DS3231
      i2c_write(hour);                           // Write hour value to DS3231
      i2c_write(1);                              // Write day value (not used)
      i2c_write(date);                           // Write date value to DS3231
      i2c_write(month);                          // Write month value to DS3231
      i2c_write(year);                           // Write year value to DS3231
      delay_ms(200);                             // Wait 200ms
    }
   
void DS3231_display(){
  // Convert BCD to decimal
  second = (second >> 4) * 10 + (second & 0x0F);
  minute = (minute >> 4) * 10 + (minute & 0x0F);
  hour = (hour >> 4) * 10 + (hour & 0x0F);
  date = (date >> 4) * 10 + (date & 0x0F);
  month = (month >> 4) * 10 + (month & 0x0F);
  year = (year >> 4) * 10 + (year & 0x0F);
  // End conversion
  DHora=hour/10;///descompongo hora actual
  UHora=hour%10;
  DMinutos=minute/10;
  UMinutos=minute%10;
   
  printf("%u",DHora);
  printf("%u",UHora);
  printf(":");
  printf("%u",DMinutos);
  printf("%u\r\n",UMinutos);//salto de linea
}

void main(){
  setup_oscillator(OSC_4MHZ);                    // Set internal oscillator to 8MHz
  enable_interrupts(int_rda);
  enable_interrupts(global);
  set_tris_b (0x00);///todos Salidas
  inicbuff();    // Borra buffer al inicio
  output_Low(PIN_B3);///salida rele en bajo
  CargarProgramas();///Cargo los programas
  while(TRUE){
      flagcommand=0;///todavia no recibi un comando
      inicbuff(); ///borra buffer
      ModificarSalida();///modifica la salida segun los programas
      delay_ms(1000);///espera que pase el tiempo
      if((cbuff[0]=='h')&&(cbuff[1]=='o')&&(cbuff[2]=='r')&&(cbuff[3]=='a'))///comando para ver la hour
        {
        flagcommand=1; ///me dice que recibio un comando
        printf("%s\r\n",cbuff);//salto de linea
        printf("La hora Actual es: ");
        ObtenerHoraActual();////me da la hora actual
        DS3231_display();///muestra la hour
        inicbuff(); ///borra buffer
        }
         if((cbuff[0]=='t')&&(cbuff[1]=='i')&&(cbuff[2]=='e')&&(cbuff[3]=='m')&&(cbuff[4]=='p')&&(cbuff[5]=='o'))///comando para ver tiempo activacion
         {
         flagcommand=1; ///me dice que recibio un comando
         TActivacion=LeerTActivacion();
         printf("El tiempo de activacion es: ");
         printf("%d\r\n",TActivacion);//salto de lineaTactivacion
         inicbuff(); ///borra buffer
         }
      if(flagcommand==0) inicbuff(); ///borra buffer 
      delay_ms(1000);
      }
}

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Comportamiento erratico en comunicacion serie
« Respuesta #1 en: 31 de Mayo de 2019, 09:00:31 »
Algunas cosas que encuentro

Código: C
  1. int addcbuff(char c)
  2. {                  // Añade a cbuff -----------------------    
  3.    cbuff[xbuff++]=c;          // Añade caracter recibido al Buffer
  4. }

No hay proteccion contra un buffer-overflow, unicamente lo pones a 0 cuando llega lo que vos queres. Y si no llega lo que vos queres en el orden que vos quereS?
No hay necesidad de usar

Código: C
  1. rcvchar=0x00;                       // Inicializo caracter recibido
  2.    if(kbhit()){                        // Si hay algo pendiente de recibir ...

Primero, el getc() lo va reemplazar, y el kbhit es algo redundante, ya que si entro ahi, es porque llego algo.

Código: C
  1. if((cbuff[i]=='0')||(cbuff[i]=='1')||(cbuff[i]=='2')||(cbuff[i]=='3')||(cbuff[i]=='4')||(cbuff[i]=='5')||(cbuff[i]=='6')||(cbuff[i]=='7')||(cbuff[i]=='8')||(cbuff[i]=='9'))

Mas simple si:

Código: C
  1. if((cbuff[i]=>'0')&&(cbuff[i]<='9'))

Y hace una funcion sola para comparar los numeros, asi no repetis lo mismo para cada indice.

Código: C
  1. strHoras[0]=cbuff[4];
  2.       strHoras[1]=cbuff[5];
  3.  
  4. //Otra linea
  5.       if((cbuff[0]=='h')&&(cbuff[1]=='o')&&(cbuff[2]=='r')&&(cbuff[3]=='a'))///comando para ver la hour

Estas suponiendo que lo enviado por el puerto serial SI o SI va a llegar en orden y con todo lo que vos pretendes. Pero que pasaria si hay algun caracter que no es el indicado?

Desconectado esperanzachat

  • PIC10
  • *
  • Mensajes: 39
Re:Comportamiento erratico en comunicacion serie
« Respuesta #2 en: 01 de Junio de 2019, 22:44:01 »
Gracias por reponder, en vez de usar:
Código: [Seleccionar]
    int addcbuff(char c)
    {                  // Añade a cbuff -----------------------   
       cbuff[xbuff++]=c;          // Añade caracter recibido al Buffer
    }
cual seria el codigo?
Lo segundo, segun interpreto el buffer contiene caracteres, y con los caracteres no hay uno que sea mayor al otro, por lo que no entiendo la linea: 
Código: [Seleccionar]
    if((cbuff[i]=>'0')&&(cbuff[i]<='9'))Lo del desborde del buffer no me afecta, ya que si el comando tiene mas de la longuitud maxima, no es un comando valido y por lo tanto no se debe hacer nada, pero es cierto que si yo mando ""hora1234", el comando se ejecuta igual, pero eso no tiene nada que ver con el desbordamiento. Me seria util poder obtener la longuitud de la cadena de caracteres que me envian, pero no se como hacer eso.
Si algun caracter no coincide no se debe hacer nada.
Como puedo solucionar el problema que se da si mando "hora1234"?ya que lo tomaria como un comando correcto?
Yo vengo de la epoca del asembler y aprendi algo de C por mi cuenta, es por eso que mi programacion es un poco rustica.
Lo que le expreso arriba no significa que usted no tenga razon, solo son algunas aclaraciones al respecto. De nuevo gracias por su tiempo.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Comportamiento erratico en comunicacion serie
« Respuesta #3 en: 01 de Junio de 2019, 23:32:12 »
Citar
Yo vengo de la epoca del asembler y aprendi algo de C por mi cuenta, es por eso que mi programacion es un poco rustica.

Ese no es el problema, tendrias el mismo problema si lo pensas en ASM.
Vos tenes un lugar para 32 caracteres. Pero... si nunca proteges que superen los 32 caracteres, entonces quiere decir que en algun momento vas a estar escribiendo sobre otra posicion de memoria que NO deberias. Esto es independiente del lenguaje, es como si usara los FSR y aumentara para siempre...

Debido a que unicamente te preocupas a poner en 0 el indice cuando se detecta la palabra justa que es "hola" y en la posicion correcta. En caso de que llegue "1hola" ya no funcionaria para nada. Porque cbuff[0] seria '1'. Y estarias en peligro de que eso ocurra.

Citar
Lo segundo, segun interpreto el buffer contiene caracteres, y con los caracteres no hay uno que sea mayor al otro, por lo que no entiendo la linea: 
Lo que vos comparas son numeros, los caracteres estan representados por numeros hexadecimales, el '0' es el 0x30, el 9 es 0x39. Por lo tanto al comparar en realidad estamos diciendo que si es mayor o igual a 0x30 y menor o igual a 0x39, en ves de preguntar por 0x30, x031,etc ..

Citar
cual seria el codigo?
Agregar una proteccion al indice... para que nunca exceda el largo dado por "lenbuff"

Citar
Como puedo solucionar el problema que se da si mando "hora1234"?ya que lo tomaria como un comando correcto?
Mas que ese problema y el del buffer overflow me preocuparía por cambiar tu sistema de detección de palabras.... en alguno que sea independiente de la posición en el array.
Y no tendrias buffer con el que lidiar. Una pequeña maquina de estado..
Estado 0: No recibio nada y pregunto por la 't' y la 'h', Se recibe la 't' asigno estado 1 y salgo, se recibe la 'h' asigno estado 2 y salgo, no se recibe ninguno de los 2, descarto el valor y salgo.
Estado 1: Espero una 'i', ocurre? SI-> espero las otras letras, NO-> vuelvo a estado 0
Estado 2: Espero una 'o', ocurre? SI-> espero las otras letras, NO-> vuelvo a estado 0

Util tener los string con un caracter de final escritos en el programa. Asi de esa forma poder incrementar solo un indice y verificar las letras una por una hasta encontrar el caracter final, que seguramente sea el 0x00, con eso activar una flag segun el modo que se pida.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Comportamiento erratico en comunicacion serie
« Respuesta #4 en: 02 de Junio de 2019, 15:58:54 »
Este codigo deberia servir. La funcion test es la funcion a la cual deberias pasarle lo que te llega..

En la estructura vas a tener una variable que se llama flags... Si es 0 no recibiste nada, si es distintos de 0 si.... Si es 1 significa que recibiste el primer texto, si es 2 significa que recibiste el segundo texto, si es 3 significa que recibiste los 2. Por lo tanto con esto sabes si llego algo o no.
Una ves que enviaste la respuesta necesitas poner a 0 el bit del flag.

Algunos pros y contras:
No se necesita un buffer.
No tenes permitido usar string que comienzen iguales.
Sea lo que sea que envies "123hola321" va a tomar unicamente el hola, este en la posicion que este.

Código: C
  1. struct myRxStruct
  2. {
  3.         uint8_t indexStr;
  4.         const char  *ptrCheck;
  5.         uint8_t flags;
  6. };
  7.  
  8. struct myRxStruct myRxStruct = {0,0,0};
  9.  
  10. const char *txtComp[]={
  11.     "hola",
  12.     "tiempo"
  13. };
  14.  
  15.  
  16. void test(char a)
  17. {
  18.         char recv;
  19.         recv = a;
  20.         if(!myRxStruct.indexStr)
  21.         {
  22.           // Recien comienzo? Veo si alguno de los string comienza con la letra que quiero
  23.           uint8_t i = 0;
  24.       for(i=0 ;i < (sizeof txtComp / sizeof (txtComp[0]));i++){
  25.         if(*txtComp[i] == recv) {
  26.           // Solo tengo en cuenta cuando tengo alguna coincidencia
  27.           myRxStruct.indexStr = i;
  28.           myRxStruct.indexStr++;
  29.           myRxStruct.ptrCheck = txtComp[i];
  30.           myRxStruct.ptrCheck++;
  31.           break;
  32.         }
  33.       }
  34.         } else {
  35.           // Continuo con las demas letras
  36.           if(recv == *myRxStruct.ptrCheck){
  37.                 // Aca coinciden
  38.                 myRxStruct.ptrCheck++;
  39.                 // Termino el string?
  40.                 if(!*myRxStruct.ptrCheck)
  41.                 {
  42.                         myRxStruct.flags |= myRxStruct.indexStr;
  43.                         myRxStruct.indexStr = 0;
  44.                 }
  45.           } else {
  46.                 // Aca no coincide
  47.                 myRxStruct.indexStr = 0;
  48.           }
  49.         }
  50. }


Funcion de prueba:

Código: C
  1. void main(void){
  2.  
  3.     char text[]= "456tiempo123";
  4.     while(1)
  5.     {
  6.        
  7.         uint8_t j;
  8.         for(j=0;j<sizeof text;j++)
  9.             test(text[j]);
  10.     }
  11. }
« Última modificación: 02 de Junio de 2019, 16:36:41 por KILLERJC »

Desconectado esperanzachat

  • PIC10
  • *
  • Mensajes: 39
Re:Comportamiento erratico en comunicacion serie
« Respuesta #5 en: 04 de Junio de 2019, 17:35:56 »
Gracias por responder. En realidad si los comandos no son los correctos, por ejemplo "hola", no tiene que pasar nada, lo que si, si mando "hola1234", no tendria que ejecutar ningun comando. Para ello debo saber la longuitud de la palabra recibida. que supongo que puede ser aumentando un indice con cada recepcion. Voy a tratar de implementar. Yo necesito poder recibir string que empiecen igual y solo aceptar el comando si éste está en la posicion correcta y no tiene caracteres adicionales. Voy a implementar eso que me dijiste de los flag, gracias por tu tiempo.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Comportamiento erratico en comunicacion serie
« Respuesta #6 en: 04 de Junio de 2019, 17:58:25 »
Gracias por responder. En realidad si los comandos no son los correctos, por ejemplo "hola", no tiene que pasar nada, lo que si, si mando "hola1234", no tendria que ejecutar ningun comando. Para ello debo saber la longuitud de la palabra recibida. que supongo que puede ser aumentando un indice con cada recepcion. Voy a tratar de implementar. Yo necesito poder recibir string que empiecen igual y solo aceptar el comando si éste está en la posicion correcta y no tiene caracteres adicionales. Voy a implementar eso que me dijiste de los flag, gracias por tu tiempo.

Pero para eso SI o SI necesitas algo que te indique donde comienza el string.... Es decir debe enviar un dato y luego "hola"... Sino vas a tener problemas.