Go Down

Topic: problemas serial mathlab/arduino [Solucionado] (Read 1 time) previous topic - next topic

angel67

Apr 22, 2012, 12:52 pm Last Edit: Apr 22, 2012, 07:39 pm by angel67 Reason: 1
Hola chicos, estoy intentado desde mathlab -esto es igual-creo, mandar información a arduino.
La idea es que es enviar un comando y un valor, el comando en de 8 bits y el valor es de 16 bits.
he hecho el codigo que veis más abajo y para probarlo abro el monitor que trae el ide por defecto de arduino y pongo 99 -que es digamos el comando de prueba- si es reconocido, pasa a leer el valor...
el problema es que parece que no lee nada...alguna ayudita?. Gracias.

Code: [Select]

// definir variables
unsigned int t_motor;
byte comando;

void setup() {
            }  
       
       



void loop() {

Serial.flush();
delay(50);
if (Serial.available()>0){
  delay(500);
  comando=Serial.read();
  if (comando==99){
                   digitalWrite(13,HIGH);
                   delay(5000);
                   t_motor=Serial.read();
                   Serial.println(t_motor,DEC);
                  }
     
  }  
 
  digitalWrite(13,LOW);
 
}


Sergegsx


angel67

#2
Apr 22, 2012, 02:18 pm Last Edit: Apr 22, 2012, 02:20 pm by angel67 Reason: 1

En el setup() te falta el serial.begin

juas!, pues es verdad, pero sigo teniendo un problema

parece que el comando en 8 bits lo lee correcto porque entra en el if y activa el led.

Pero el segundo numero que es en 16bits no lo interpreta correctamente, porque
el tiempo que envio (en milisegundos-por eso lo de 16bits)...no es correcto...
ahora queda así el código en arduino
Code: [Select]



// definir variables
unsigned int t_motor;
byte comando;

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



void loop() {

//Serial.flush();
delay(50);
if (Serial.available()>0){
   delay(500);
   comando=Serial.read();
   if (comando==99){
                    digitalWrite(13,HIGH);
                    t_motor=Serial.read();
                    Serial.println(t_motor,DEC);
                    delay(t_motor);
                   
                   }
     
   } 
 
   digitalWrite(13,LOW);
   
}





por ejemplo envio desde mathlab esto:

Code: [Select]
%borrar previos
delete(instrfind({'Port'},{'COM3'}));
%crear objeto serie
s = serial('COM3','BaudRate',9600,'Terminator','CR/LF');
warning('off','MATLAB:serial:fscanf:unsuccessfulRead');
%abrir puerto
fopen(s);

pause(3);

comando=99;
t_motor=2200;
fwrite(s,comando,'uint8');
pause(2);
fwrite(s,t_motor,'uint16');

a = fscanf(s,'%d')';
a

fclose(s);
delete(s);
clear s;


y lo que obtengo en a
es: a =

      65535

alguna idea


chiva

Lee con detenimiento que devuelve Serial.read
http://arduino.cc/es/Serial/read

Si no leemos la documentación y las cosas no funcionan, no estaría mal leerla.
Mercadillo electrónico. Kit iniciación a Arduino, shield LCD a color y más cosas!

angel67


Lee con detenimiento que devuelve Serial.read
http://arduino.cc/es/Serial/read

Si no leemos la documentación y las cosas no funcionan, no estaría mal leerla.

ok, entonces veo que no hay manera de leer directamente un numero de 16bits,
luego tengo que leer 2 bytes consecutivos y transformalos en un integer, no?

chiva

#5
Apr 22, 2012, 05:29 pm Last Edit: Apr 22, 2012, 05:31 pm by chiva Reason: 1
Exacto!

Puedes hacer por ejemplo:

Code: [Select]
int leer16bits(){
  int num;
  num = Serial.read();
  num += Serial.read() << 8;
  return num;
}
Mercadillo electrónico. Kit iniciación a Arduino, shield LCD a color y más cosas!

angel67

pues sigo sin resolverlo...una vez modificado el código según tus gentiles consejos queda así el de arduino
Code: [Select]

// definir variables
unsigned int t_motor;
byte comando, bytelow, bytehigh;

void setup() {
              pinMode(13,OUTPUT);
              Serial.begin(9600);
             
             }   
       
void loop() {

delay(50);
if (Serial.available()>0){
   delay(500);
   comando=Serial.read();
   if (comando==99){
                    digitalWrite(13,HIGH);
                    t_motor=leer16bits();
                    Serial.print(t_motor);
                    delay(t_motor);
                    Serial.flush();
                   }
     
   } 
 
   digitalWrite(13,LOW);
   
}

int leer16bits(){
  int num;
  num = Serial.read();
  num += Serial.read() << 8;
  return num;
}



y ahora lo que he puesto en mathlab

Code: [Select]
%borrar previos
delete(instrfind({'Port'},{'COM3'}));
%crear objeto serie
s = serial('COM3','BaudRate',9600,'Terminator','CR/LF');
warning('off','MATLAB:serial:fscanf:unsuccessfulRead');
%abrir puerto
fopen(s);

pause(3);

comando=99;
t_motor=2200;
fwrite(s,comando,'uint8');
pause(2);
fwrite(s,t_motor,'uint16');


a=fscanf(s,'%d');
a

fclose(s);
delete(s);
clear s;


y el resultado es:
a =

       65279

cuando me debería devolver el valor de la variable t_motor=2200

ademas cuando aplica el delay para dejar el led encedido no lo hace por 2200milisegundos....luego
algo no está recibiendo (o enviando bien)?

chiva

No se exactamente como manda Matlab los datos, pero puede que tengas que cambiar el 'terminator' a nada, mira si hay una opción que haga eso, no mande ni CR ni LF.
Mercadillo electrónico. Kit iniciación a Arduino, shield LCD a color y más cosas!

angel67

si ya busque la opción
he anadido en mathlab s.Terminator='';
pero  no parece hacer nada....
de todas formas eso sería a la hora de usar el Serial.print recogido en mathlab por el scanf

lo que no explica por que el led no luce el tiempo que le envio desde mathlab mediante fwrite
y recogido en Serial.read por tu subrutina....
ya que según la documentacion de mathlab sólo se envian byte secos segun pone en su documentación:

http://www.mathworks.es/help/techdoc/ref/serial.fwrite.html


ufff....esto es medio pesadilla!


chiva

Mercadillo electrónico. Kit iniciación a Arduino, shield LCD a color y más cosas!

angel67


Quita el delay(2) del codigo de matlab

acabo de hacer eso, antes de leer lo que me has puesto...y funciona!
posteo el código completo, porque tampoco se lleva bien con el envio desde mathlab de código de 16bits...
así que he tenido que hacer esto....pero ahora va bien, gracias por la ayuda:

arduino:
Code: [Select]

// definir variables
int t_motor;
byte comando, bytelow, bytehigh;

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

void loop() {

//Serial.flush();
delay(50);
if (Serial.available()>0){
   delay(500);
   comando=Serial.read();
   if (comando==99){
                    digitalWrite(13,HIGH);
                    bytelow=Serial.read();
                    bytehigh=Serial.read();
                    t_motor=bytehigh+bytelow*256;
                    Serial.println(comando);
                    Serial.println(bytelow);
                    Serial.println(bytehigh);
                    Serial.println(t_motor);
                    delay(t_motor);
                    Serial.flush();
                   }
     
   } 
 
   digitalWrite(13,LOW);
   
}



mathlab:
Code: [Select]

%borrar previos
delete(instrfind({'Port'},{'COM3'}));
%crear objeto serie
s = serial('COM3','BaudRate',9600,'Terminator','CR/LF');
warning('off','MATLAB:serial:fscanf:unsuccessfulRead');

%abrir puerto
fopen(s);

pause(3);

comando=99;
t_motor=2200;
fwrite(s,comando,'uint8');
highbyte=floor(t_motor/256);
lowbyte=t_motor-highbyte*256;
data=[highbyte lowbyte];
fwrite(s,data,'uint8');

pause(2);

for i=1:4
a=fscanf(s,'%d');
b(i)=a;
end
b
fclose(s);
delete(s);
clear s;

chiva

Mercadillo electrónico. Kit iniciación a Arduino, shield LCD a color y más cosas!

Go Up