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

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

Código:
%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...
 
Última edición por un moderador:
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:
Código:
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.
 
Última edición:
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...
 
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.
 
Última edición:
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:
Código:
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


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""

Código:
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);
 
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 .
 

Adjuntos

  • MICROCON CONTROL REMOTO.rar
    286.7 KB · Visitas: 93
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.
 
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);
}
}
 
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
Código:
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
Código:
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""
 
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.



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

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
Código:
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
Código:
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""

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
 
Última edición:
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...
Código:
fprintf(Ser,'%s','5');%%manda lel numero '5' en  Ascii
y en Arduino lo identificas así...
Código:
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"
 
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.
 
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)
 
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
 
Atrás
Arriba