Go Down

Topic: Experiencias con puerto serie (Read 2969 times) previous topic - next topic

victorin

Hola a todos!!

Despues de hacer mis pruebas para familiarizarme con las Entradas/Salidas digitales con arduino, me he lanzado a conectarlo con el pc a través de un puerto serie i monitorizar la comunicación.

Para este paso he creado un cable serie con 3 cables: Rx,Tx,Gnd

Lo he conectado al pc, y los cables el Gnd a Gnd del arduino y el Tx con el Rx del arduino.

Me he encontrado con 2 problemas:

1) He hecho una prueba para concatenar chars (rollo buffer.. para crear un string). He creado un array de bytes con los caracteres 'B','U','F' y al imprimirlo por el Serial monitor la F siempre me sale mal. Luego he probado con un caracter nulo al final ('\0') y continua haciendo lo mismo...

Es posible que el charset de arduino este cambiado? O es algun problema externo a esto??

2) La comunicación mediante el puerto serie de PC (con el hyperterminal abro el puerto serie y escribo caracteres) va bien, o sea que arduino luego me monitoriza los datos entrantes a su Rx.
El problema esta en que las letras pocas veces coinciden, incluso si apreto 2 veces la misma letra me pueden salir dos caracteres distintos (y mayormente caracteres raros).

Es posible que me falte algun otro pin para el puerto serie? Mala conexion de pins al arduino? Mala codificación de caracteres??



Perdon por mis preguntas de novatillo ;)

Os paso el código que he probado donde se reproducen los errores.


Un saludo!


char c;
char buffer[];
int bytesDisponibles=0;
int bytesBuffer=0;

void setup()
{
  beginSerial(9600);
  printString("Esperando datos del puerto serie...\n");
  
  buffer[0]='B';
  buffer[1]='U';
  buffer[2]='F';
  buffer[3]='\n';
  buffer[4]='\0';
  
  printString("Provando buffer: ");
  printString(buffer);

  printString("OK??\n");
}

void loop()
{
  bytesDisponibles = serialAvailable();
  if (bytesDisponibles > 0) {
    bytesBuffer=0;
    
    while (bytesBuffer < bytesDisponibles){
      buffer[bytesBuffer] = serialRead();
      bytesBuffer++;
    }
    
    buffer[bytesBuffer]='\0';

    printString("Recibidos ");
    printInteger(bytesBuffer);
    printString(" bytes del puerto serie: ");
    printString(buffer);
    printString("\n");

  }
  
  //delay(1000);                  // waits for a second
}

victorin

Nadie puede comentar nada sobre mis experiencias?

Cual es la manera de crear una simple string??

Alguien ha hecho alguna prueba con dispositivos puerto serie y ha conseguido comunicarse correctamente??

Gracias

David Cuartielles

#2
Jan 25, 2006, 06:48 pm Last Edit: Jan 25, 2006, 06:54 pm by DojoDave Reason: 1
Hola,

perdona el retraso en responder, pero lei tu mensaje mientras estaba de viaje la semana pasada y, al quitar la marca de "mensaje no leido", se me perdio entre los foros.

Para simplificar tu pregunta:

1) al meter la señal directamente de la placa al PC, estas mezclando tecnologia TTL (que funciona a 5 voltios) con el estandar de puerto serie (que puede llegar a 12 voltios). El problema es pues que las señales que tu mandas no se reflejan apropiadamente en el PC. Para que este experimento funcione, vas a necesitar un conversor de niveles como el MAX232 o el ST232. O bien, un par de transistores como hemos puesto nosotros en la placa serie (puedes consultar los esquematicos en la seccion de Hardware)

2) para crear un string, tienes que declarar un array de caracteres:

char str[] = "hola";

o

char serInString[100];

son ejemplos de como declarar strings.

3) por lo demas, el setup de tu experimento parece correcto, los cables estan bien conectados, el programa tiene sentido, etc.

4) si instalas Arduino-0003, te recomiendo que eches un vistazo al ejemplo por Beltran Berrocal "serialComm_strings" que explica como mandar cadenas de caracteres por el puerto serie

Ahora bien, de cara a echarte una mano mas a fondo: que placa tienes serie o USB?

/David

beltran


victorin

Gracias, David

Tengo una placa usb. Me he hecho con un conversor de niveles de estos, hoy intentare provar a ver la lectura desde puerto serie (con los ejemplos de beltran) y comentare mis resultados

Gracias!


David Cuartielles

Hola,

entonces lo dicho, si tienes placa USB hazte con el conversor de niveles. Lo decia porque las placas serie ya llevan sus transistores para hacer la comunicacion.

/David

victorin

Hola David,

he probado los ejemplos de beltran berrocal con el conversor de niveles y funciona perfecto, pero he intentado modificarlos para almacenar la cadena hasta encontrar un ENTER y no me funciona bien:

  if( isStringEmpty(serInString) == false) {
    if (serInString[buffLength - 1] == '\n' || serInString[buffLength - 1] == '\r') {
      printString("Has escrito: ");
      printSerialString(serInString);
      printNewLine();
      clearBuffer(serInString);
    }
  }


He probado tambien con el numero ascii de estos caracteres (13 y 10) y tampoco funciona... no es correcto este condicional?
Puedes orientarme un poco sobre como puedo detectar enters? graciass

David Cuartielles

#7
Jan 26, 2006, 02:14 pm Last Edit: Jan 26, 2006, 02:14 pm by DojoDave Reason: 1
Hola,

la cuestion es que, si estas enviando desde flash a traves de serproxy, el fin de linea se convertira en el numero 0, pero no ascii ( 48 ) -lease el caracter "0"- sino el numero entero 0.

Si miras la configuracion de serproxy veras que hay una propiedad al principio que activa este cambio. La razon es que serproxy emplea fin de linea como indicador de fin de cadena, pero flash emplea un 0, por lo que si no mandasemos ese 0 a traves del socket que comunica con flash, este ultimo no entenderia que es final de cadena.

Del mismo modo, al mandar desde Arduino, necesitaras mandar fin de linea (lo de poner ese caracter funciona en las dos direcciones).

/David

victorin

La comunicación no la hago desde serproxy ni flash, de momento he empezado abriendo un hyperterminal y escribiendo caracteres directamente al puerto serie.

De toda manera sustituire mi "final de linea (\n\r) por un byte 0 y provare esto.

El problema es que si uso un modem GSM que manda comandos terminados en \n\r el arduino interpreta el final como 0? O como podria determinar cuando se me ha mandado un comando completo?

Gracias

David Cuartielles

Aha,

si no usas serproxy, entonces el problema esta en otro sitio. Arduino detecta los caracteres 10 y 13 sin problemas, asi que lo que esta pasando es un problema a otro nivel ...

espera, ahora que me fijo:

Quote
if (serInString[buffLength - 1] == '\n' || serInString[buffLength - 1] == '\r') {
porque no revisas eso y lo cambias por:

Code: [Select]
   if ((serInString[buffLength - 1] == '\n') || (serInString[buffLength - 1] == '\r')) {


veras que he añadido dos parentesis. No creo que sea eso, pero a ver si el compilador de C esta partiendo la expresion?

/David

beltran

hola,

nadie te impide de modificar la funcion printSerialString segun tus necesidades...puedes crear tu protocolo.

podrias simplemente añadirle al final, despues de haber leido todo lo contenido del serial buffer, tu byte the interrupcion personalizado
Code: [Select]

//read a string from the serial and store it in an array
//you must supply the array variable
void readSerialString (char *strArray) {
    int i = 0;
    if(serialAvailable()) {    
       while (serialAvailable()){            
          strArray[i] = serialRead();
          i++;
       }
     //añade aqui tu byte te interrupcion personalizado como este
          strArray[i] = '\n'
    }      
}

y lo mismo para la funcion que la lee...puedes seguir leyendo hasta que no encuentre un byte '\r'

hack it baby!

ciao
b.

victorin

Muchas gracias a los dos, esta claro que es una question práctica. Cuando saque un poco de tiempo para pelearme lo sacaré sin ningun problema y os comentare los acontecimientos.


Me sabe muy mal no podre estar en el workshop de barcelona por motivos laborales... a ver si podeis hacer uno mas adelante y estoy mas libre de faena.

Gracias!

Go Up