# ¿Cómo enviar un dato ASCII a MATLAB a través del puerto serial?



## danieldanielko (May 9, 2012)

Hola!

Resulta que quiero mandar numero ascii a matlab, a travez del puerto serial,lo que hago es que en un protoboar pongo un numero binario con un dip switch, y es precisamente este el que quiero que aparezca en matlab, todo lo relacionado con el hardware ya lo tengo ( no utilice pic por cuestiones de que asi lo pidieron, si a alguien le interesa me lo hace saber  )
de hecho, estos datos los he visto ya en hyperterminal, pero no logro hacerlo con matlab,  y de hecho lo que quiero conseguir es que el dato mandado, inmediatamente lo regrese , ya que mando datos a traves de un control y recibo datos en el carrito que estoy moviendo, o si alguien supiera de algun programa que ya tengo esto definido

Estoy utilizando comunicacion asincronica, 9600 baudios,  he buscado en google y nada. 


 lo curioso es que de matlab si logre enviar datos, pero no logro recibir,

para enviar datos utilice el siguiente codigo, el cual si funciona


```
%Programa de ensayo de movimiento de los motores servos HS-311
%ABRIR el puerto COM1
clc; disp('BEGIN')
SerPIC = serial('COM1');
set(SerPIC,'BaudRate',9600);
set(SerPIC,'DataBits',8);
set(SerPIC,'Parity','none');
set(SerPIC,'StopBits',1);
set(SerPIC,'FlowControl','none');
fopen(SerPIC);
%*-*-*-*-*-*-
fprintf(SerPIC,'%s','A');pause(0.2)
%*-*-*-FIN Posición final

%CERRAR el puerto COM1 al finalizar
fclose(SerPIC);
delete(SerPIC)
clear SerPIC
disp('STOP')
```

Espero alguien me ayude...


----------



## Scooter (May 11, 2012)

Yo si que lo conseguí, con lo que fue imposible fue con el bloque de simulink. 
Buscaré a ver si encuentro el .m que establecía la comunicación.


Lo he encontrado, tenía dos .m uno para leer y otro para escribir, esta es la función de matlab:

```
function valor=leead(entrada)
S=serial('COM1','BaudRate',115200,'Terminator',13);
fopen(S);
fprintf(S,'mute'); % Envía un comando al microcontrolador
fprintf(S,strcat(['ea ' num2str(entrada)])); %Envía otro comando de "entrada analógica y el número de entrada
String=fscanf(S,'%s'); %Lee la respuesta del micro
fclose(S)
Valor=str2double(String(4:length(entrada)])); %Convierte el valor ASCII a un valor numérico double
```
Lo que hace es mandar dos comandos al micro "mute" para que se ponga en modo silencioso, y "ea xx" para que lea la entrada analógica xx, el valor de esa lectura lo devuelve como parámetro.

Para poder aclararme con el micro hice dos modos de funcionamiento "mute" y "dialog", en "dialog" el equipo respondía cosas legibles por un usuario humano en un terminal ASCII de forma que se podía controlar el sistema sin mas. En "mute" es mucho mas críptico en sus respuestas para manejar desde un programa y ahorrar así bytes en las transmisiones.


----------



## danieldanielko (May 11, 2012)

Gracias!! lo he probado y me funciono , lo unico es que a veces si lo lee y a veces no... yo pienso que quiza sea la funcion terminator "13" segun entiendo, matlab recibe datos hasta que llegue este comando,,  o sea que en tu caso el pic mandaba este comando?? o era hasta que se preciona enter en la pc (supongo eso en base a esta info que vi: www.elcodigoascii.com.ar  )...   porque si voy a mandar 8 bits de informacion, por ejemplo 10001100, es ascii es 132,, y a en matlab veo "ä". lo que no entiendo, es que papel juega " terminator " es todo esto y como lo incorporo a lo que estoy haciendo?  

Gracias de antemano...


----------



## Scooter (May 11, 2012)

No era un pic, era un 8052 pero para el caso es lo mismo.
El código ascii 13 es el retorno de carro. Ojo porque windows manda un 10 que es salto de linea y luego un 13 o al revés, no recuerdo.
Yo mandaba la información en ascii así que para enviar un 132 se manda un uno en ascii que creo que es el 31, luego el 2 y luego el tres que es el 33, al terminar se envía un retorno de carro.
Depende de si vas a comunicar en ascii o en binario puro.


----------



## danieldanielko (May 13, 2012)

Hola!

Finalmente entregue mi proyecto, no funciono tan bien como yo queria pero si que me sirvio el codigo que posteaste... Gracias!!


----------



## chin0o (Mar 28, 2013)

Scooter dijo:


> Yo si que lo conseguí, con lo que fue imposible fue con el bloque de simulink.
> Buscaré a ver si encuentro el .m que establecía la comunicación.
> 
> 
> ...




Que tal scooter perdón por abrir el tema nuevamente lo que pasa es que tengo un problema similar a la hora de leer el puerto serial en matlab anexo parte de mi código. 

Lo que pasa es que he notado que a la hora de conectar en matlab es mucho mas lento que si lo hiciera con VB.net, a la hora de mandar el dato lo hace bien y con buena velocidad, a la hora de recibir es el problema puesto que tarda en recibirlo (entre 1 y 2 seg) y me aparece la siguiente advertencia: Warning: Unsuccessful read: A timeout occurred before the Terminator was reached. 

De ante mano Gracias !!! Saludos""


```
SerPIC=serial('COM4','BaudRate',9600,'Terminator','CR/LF');
set(SerPIC,'DataBits',8);
set(SerPIC,'Parity','none');
set(SerPIC,'StopBits',1);
set(SerPIC,'FlowControl','none');
set(SerPIC,'Timeout',1);
get(SerPIC)
fopen(SerPIC);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Cuando se presiona un boton en el Gui, manda dato por el serial  que enciende un led
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function LED1_Callback(hObject, eventdata, handles)
global SerPIC
 fprintf(SerPIC,'%s','1');
read=fscanf(SerPIC);
set(handles.texto1, 'string',read);
```


----------



## chin0o (Mar 28, 2013)

Ya lo solucione, me faltaba lo de mandar el "carriage return" 

De todas formas Gracias!!!!!


----------



## Scooter (Mar 29, 2013)

De nada; llegué tarde.
Suele pasar que al postear en un foro la pregunta uno mismo la encuentra


----------



## Alcocer Garcia Felix Davi (Ago 19, 2013)

Yo tengo el siguiente circuito de un control remoto universal para  sony nec etc con comunicacion serial con matlab el problema es que cuando lo simulo funciona y en la vida real no me manda los datos el matlab .  Este circuito lo probé con hyperterminal y funciona .


----------



## Scooter (Ago 20, 2013)

Ve por partes, conectando el matlab a un terminal y cosas así a ver si lo encuentras.
Ya te digo que con simulink no lo conseguí, en teoría estaba todo bien pero no iba y a lo mejor era una tontería.


----------



## CristianAcosta (Abr 20, 2014)

Buenas noches a todos

Siento reactivar el foro, pero es una urgencia, lo que sucede es que necesito enviar valores desde MatLab a Arduino UNO y estoy utilizando un código parecido a los de ustedes, pero Arduino no me reconoce bien el dato que recibe, necesito ayuda, por favor

CODIGO MATLAB:

clc; disp('Inicia')
ps = serial('COM8');
set(ps, 'BaudRate',9600);
set(ps,'DataBits',8);
set(ps,'Parity','none');
set(ps,'StopBits',1);
set(ps,'FlowControl','none');
fopen(ps);

fprintf(ps,'%s','51');
pause(3)

fclose(ps);
delete(ps)
clear ps
disp('Finaliza')

CODIGO ARDUINO:

byte dato;

void setup()
{
  Serial.begin(9600);
  pinMode(8, OUTPUT);
  pinMode(10, OUTPUT);
}

void loop ()
{
  if(Serial.available()> 0)  // 
  {
    dato = Serial.read();
    Serial.println(dato);
  }

  if(dato==51)
  {
    digitalWrite(10,HIGH);
    delay(1000);
    digitalWrite(10, LOW);
    delay (1000);
  }
  else if(dato==50)
  {
    digitalWrite(8, HIGH);
    delay(2000);
    digitalWrite(8, LOW);
    delay(2000);
  }
  else
  {
    digitalWrite(10, LOW);
    digitalWrite(8, LOW);
    delay(400);
  }  
}


----------



## Scooter (Abr 20, 2014)

Estás enviando en ASCII y recibiendo en binario


----------



## chin0o (Abr 20, 2014)

Que onda brother espero poderte ayudar....

Me gustaría saber que es lo que hace y no hace tu Arduino como por ejemplo: si manda un paquete a matlab y matlab no recibe.


mientras tanto te paso una lineas de código que creo te podrían servir.  
MAtlab

```
Ser=serial('COM8','BaudRate',9600,'Terminator','CR');%%importante que pongas CR porque la funcion println()
                                                                     %%de Arduino agrega un '/r' 
set(Ser,'DataBits',8);
set(Ser,'Parity','none');
set(Ser,'StopBits',1);
set(Ser,'FlowControl','none');
set(Ser,'Timeout',4);
set(Ser,'RequestToSend','off')
fopen(Ser);
pause(1)%Delay 1 second
fprintf(Ser,'%s','A');%%manda la letra 'A' en Ascii
read = fscanf(Ser,'%s')
pause(1)
fclose(Ser);
delete (Ser);
clear Ser
```


Arduino

```
void setup() { 
 Serial.begin(9600);
}
void loop(){//loop principal
        if (Serial.available()){//primer condicional de dato entrante
                              wrt = Serial.read();//guarda el valor recibido
                    if (wrt==0x41){//llega el codigo 'A'
                                       Serial.println("Conectado");
                    }
         }
}
```


Porfa comenta tus resultados Saludos""


----------



## CristianAcosta (Abr 20, 2014)

Bueno, respondo chin0o

quiero enviar constantes numéricas desde Matlab a mi Arduino UNO eso quiero hacer, para comprobar que Arduino recibió las constantes, hice el programa de arduino que adjunte al inicio. Que lo probe desde el monitor serial de arduino donde le escribia 3, lo enviaba y el lo recibe en código ASCII como un 51, entonces por eso puse los if's con 50 y 51, es decir, para que cuando envie un 2 o 3 desde el monitor serial, Arduino encienda dos led's, pero eso lo hice para probar como Arduino me recibe los datos

Entonces, deje uno de los LED'S encendido con el monitor serial y cerre el IDE de Arduino e intente enviar desde Matlab un número 2 o 3 para que me encendiese el otro LED , pero no lo hace, lo unico es que me cambia el valor de dato y apaga el led que estaba encendido y cuando abro de nuevo el monitor serial me resetea el valor de dato sin permitirme ver que valor fue el que envio desde Matlab.

Si miro el estado del objeto ps, me muestra que envio 2 datos, y busque que queria decir y lo que entendi es que me envia un valor X de formato Double, y ahi ya me perdi, por que no puedo verlo con monitor serial.





Scooter dijo:


> Estás enviando en ASCII y recibiendo en binario



No entiendo por que me dice usted que estoy recibiendo en binario si configure Arduino a 9600 Baudios/s y así creo que me recibe es en ASCII, por eso los comparadores en Arduino estan con 50 y 51 que son lo números 2 y 3 en código ASCII



chin0o dijo:


> Que onda brother espero poderte ayudar....
> 
> Me gustaría saber que es lo que hace y no hace tu Arduino como por ejemplo: si manda un paquete a matlab y matlab no recibe.
> 
> ...



Quisiera que me colaboraran con este mismo código pero para enviar en vez de una letra A un número cualquiera, si puede ayudarme con el código en matlab y arduino se lo agradeceria mucho


----------



## Scooter (Abr 20, 2014)

Si envías sin mas envías la representación ASCII del valor numérico.
Para recibir tienes que hacer parsefloat o parseint o algo semejante.
http://arduino.cc/en/Reference/Serial


----------



## chin0o (Abr 20, 2014)

A ok mira es que tu estas poniendo '51' ese numero se parte en dos valores '5' y '1' es decir que tienes 2 bytes porque estas manejando caracteres ASCII por eso no los reconoce,

si lo que quieres es mandar un dato solo para identificar que el arduino esta haciendo una buena comunicación te recomiendo que solo uses un caracter algo asi...

```
fprintf(Ser,'%s','5');%%manda lel numero '5' en  Ascii
```
y en Arduino lo identificas así...

```
if(dato==0x35)
```


Ahora si lo que quieres es mandar el valor numérico 51 se hace de otra manera pero si solo quieres mandar numeros para identificar con esto es suficiente.


*Nota: el valor hexadecimal 0x35 representa en ASCII el carácter 5...
Saludos"


----------



## Scooter (Abr 21, 2014)

No me acuerdo mucho de matlab pero yo diría que o pones '5'&'1' o pones "51" no me suena '51'
Si vas a enviar los números como cadenas usa el parseint o parsefloat en el arduino. Si vas a enviar en binario tendrás que complicar te la vida a a ver como controlas el flujo de datos; ya no vale el retorno de carro etc porque es otro de los números posibles.


----------



## CristianAcosta (Abr 21, 2014)

Scooter dijo:


> No me acuerdo mucho de matlab pero yo diría que o pones '5'&'1' o pones "51" no me suena '51'
> Si vas a enviar los números como cadenas usa el parseint o parsefloat en el arduino. Si vas a enviar en binario tendrás que complicar te la vida a a ver como controlas el flujo de datos; ya no vale el retorno de carro etc porque es otro de los números posibles.



Buenas Scooter

Ya entendí que me queria decir con los comando Serial.parseInt con el IDE de Arduino por el monitor serial le envio 50 y el toma todo el número. Con el siguiente programa me enciende el LED rojo enviando (50) y el LED verde enviando (51):

ARDUINO:

void loop ()
{
  if(Serial.available()> 0)  // 
  {
    r=Serial.parseInt();
    dato =r -'0';
    data = dato;
    delay(500);
    Serial.println(dato);
  }

  if(dato==3)
  {
    digitalWrite(13,HIGH);
    delay(500);
    digitalWrite(13, LOW);
    delay (500);
  }
  else if(dato==2)
  {
    digitalWrite(12, HIGH);
    delay(500);
    digitalWrite(12, LOW);
    delay(500);
  }
  else
  {
    digitalWrite(13, LOW);
    digitalWrite(12, LOW);
    delay(500);
  }  

Ahora el problema es con MatLab no se si usted me pueda colaborar, en Matlab utilizo el siguiente codigo y arduino me recibe lo que Matlab me envia pero creo que Matlab no lo envia en código ASCII por que en arduino no me lo reconoce, he intendado abriendo de nuevo el monitor serial pero este me resetea los valores de las variables. El código que utilizo en matlab es el siguiente (ya intente enviando el numero como: ''3'', "3" y no funciona en arduino.

clc; disp('Inicia')
ps = serial('COM8');
set(ps, 'BaudRate',9600);
set(ps, 'Terminator','CR');
set(ps,'DataBits',8);
set(ps,'Parity','none');
set(ps,'StopBits',1);
set(ps,'FlowControl','none');
fopen(ps);

fprintf(ps,'%s','3');
pause(3)

fclose(ps);
%delete(ps)
%clear ps
disp('Finaliza')

Agradezco la Ayuda y paciencia de todos ustedes (Y)


----------



## Scooter (Abr 21, 2014)

No entiendo por que restas '0' al número. Parseint ya lo hace


----------



## MPepe (Abr 27, 2014)

Buenas

Yo tengo el problema pero al reves, es decir yo envío código desde arduino a matlab, y lo represento en gráficas, pongo el código que se explica mejor.

Arduino:

 if(horaactual-horaprevia> intervalo){
    horaprevia=horaactual;
    Serial.print(ECG,2);
    Serial.print('\r');
  }

Matlab:

clear all;clc;
delete(instrfind({'Port'},{'COM8'}));
pserie=serial('COM8','BaudRate',115200);
set(pserie,'terminator', 'CR'); 
pserie.inputbuffersize=2000; %taamaño del buffer de lectura enbytes
fopen(pserie);

while lectura(1)~='E'
 disp('entrada bucle inicio')
 lectura=fscanf(pserie) %leemos un dato 
 if lectura=='E'
     disp('salida bucle E')
     start=1
     break     
 end

end


El problema es que el carácter 'E' no me lo lee bien por lo que nunca me entra en el bucle.

¿Alguien me podría ayudar?

Gracias


----------



## Scooter (Abr 27, 2014)

Seguramente pillaras una cadena dentro de la cual esté la E.
Trocea la cadena y buscarlo dentro o bien comprueba la cadena en cada carácter que recibes.
Otra opción es buscar cadenas enteras de ordenes con retorno de carro y todo lo que sea.


----------



## MPepe (Abr 27, 2014)

Esto es lo que envía el arduino, una secuencia de datos

0.4839
-1.00
-1.00
0.4839
P
0
0
E
1.00
0.92
0.84
0.78
0.71
0.65
0.60
0.58


los números me los representa bien, pero los caracteres no les hace caso.

Si aparecen por pantalla, pero parecce que el While no lo hace bien, he visto en la ayuda de matlab como hacer un while y parece que está bien, asi que ya no sé donde está el falo.


----------



## Scooter (Abr 27, 2014)

Porque nunca llega E
Llega E y algo mas, es típico


----------



## MPepe (Abr 28, 2014)

Scooter dijo:


> Porque nunca llega E
> Llega E y algo mas, es típico



y que le puede estar llegando, 

en el arduino envío el dato con la siguiente instrucción:
Serial.println('E);

y en Matlab he provado a poner 'terminador', 'CR y LF' y no me hace nada
lectura=fscanf(pserie)

asi que he optado por cambiar los caracteres por numeros que sé que nunca le llegan, pero ahora tengo el problema de que no me representan los datos en tiempo real (cosa que necesito hacer en matlab), me representa datos pero no los datos actuales, asi que siguiere investigando

saludos

y gracias por la ayuda


----------



## Scooter (Abr 28, 2014)

El retorno de carro, el line feed...
Hay que mirar bien que hay dentro del buffer
A veces es al revés, el PC no mira el buffer hasta que no llegan n caracteres o hasta que no llega el retorno de carro.
Hay que poner que el PC lea el buffer a cada carácter o enviar un saco de E para llenarlo


----------



## ArturoJ17 (Nov 12, 2022)

Quiero realizar el flujo de control de datos por hardware *RS-*232 en *MATLAB*. Mi duda es:

S.FlowControl(Hardware);


*¿*Solo poner así la instrucción o hay que declarar cada señal del *RS-*232*?*


----------



## Scooter (Nov 12, 2022)

Nunca he usado control de flujo en ningún sistema.


----------

