Clear Filters
Clear Filters

Serial communication Matlab to Arduino issue

6 views (last 30 days)
Hello everyone, first off all, thanks for reading this and thanks also for wasting a little bit of your time to answer.
Basically, i want to send different numbers from Matlab to Arduino, that represent different states to a stepper motor, while i do some other staff.
So the secuence i want to follow is:
1.- Send the number 1 from Matlab to Arduino.
2.- Run a simulink model from Matlab and read some data from it.
3.- Send the number max_edge_time from Matlba to Arduino.
4.- Send the number 2 from Matlab to Arduino.
My problem is that i can´t manage to send any data from Matlab to the Arduino in order to activate the stepper motor.
Here i give you my Matlab and Arduino code so that you can read it:
MATLAB CODE:
%% Etapa 1 - Avance del motor:
fprintf ("ETAPA 1 ONGOING\n")
arduino_UNO = serialport ("COM4", 9600); % Abrir puerto serie.
stage = 1; % Valor que hará que el motor haga un paso u otro.
write (arduino_UNO, stage, "int8"); % Enviar data de Matlab al Arduino.
fprintf ("ETAPA 1 FINISHED\n")
%% Ejecutar el programa de Simulink desde Matlab:
simOut = sim ('vipliveedgedetection_win_mod.slx','StartTime','0','StopTime','3'); % Abrir y ejecutar el programa de Simulink, durante 1 segundo.
close_system ('vipliveedgedetection_win_mod.slx') % Cerrar el programa de Simulink.
%% Leer el osciloscopio de Simulink:
fprintf ("DATOS RECIVIDOS\n")
edge_measure_aux = simOut.ScopeData.signals.values; % Valores del eje X (Cantidad de ejes detectados).
edge_measure = squeeze(edge_measure_aux); % Eliminar una dimension de la matriz para convertirla en un vector.
time_measure = simOut.ScopeData.time; % Valores del eje Y (Segundos).
[max_edge, max_edge_index] = max (edge_measure); % Guardar valor máximo de X y posición en el array (Segundos).
max_edge_time = time_measure (max_edge_index); % Obtener valor de tiempo coincidente con el valor máximo de borde detectado.
%% Mostrar gráfica de detección:
figure
hold on
plot (time_measure, edge_measure) % Representación de la gráfica de borde detectado.
plot (max_edge_time, max_edge, 'rx', 'LineWidth', 5, 'MarkerSize', 4) % Representación del máximo obtenido.
xlabel ('t (seconds)') % Etiqueta del eje X.
ylabel ('Quantity of edges detected') % Etiqueta del eje Y.
grid on % Muestra las lineas de fondo con la gráfica.
title ('Data generated by Simulink and plotted in Matlab') % Titulo de la gráfica.
legend ('Quantity of edges detected', 'Maximum edge detected') % Etiquetas de la grafica representada.
%% Etapa 2 - Retroceso hasta punto máximo de bordes detectados:
fprintf ("ETAPA 2 ONGOING\n")
stage = max_edge_time;
write (arduino_UNO, stage, "int8"); % Enviar data de Matlab al Arduino.
fprintf ("ETAPA 2 FINISHED\n")
%% Etapa 3 - Retroceso hasta punto de reset:
fprintf ("ETAPA 3 ONGOING\n")
txt = '(Pulse ENTER para volver a la posición de reset)'; % Indicamos con un mensaje como comenzar.
title (txt, 'FontWeight', 'normal'); % Se especifica el formato del texto.
pause % Espera hasta que se pulsa una tecla para pasar a la siguiente parte del código.
stage = 2;
write (arduino_UNO, stage, "int8"); % Enviar data de Matlab al Arduino.
clear arduino_UNO % Resetear valores de comunicación en serie.
fprintf ("ETAPA 3 FINISHED\n")
ARDUINO INO CODE:
#include <Stepper.h> // Incluimos la librería del motor paso a paso.
#define STEPS 32 // Definimos el número de steps.
Stepper stepper (STEPS, 8, 10, 9, 11); // Definimos los pines que se van a utilizar en el arduino.
long motor_steps = 0; // Pasos que da el motor en cada momento.
long seconds_to_checkpoint = 0; // Segundos hasta el punto máximo de bordes detectado.
long motor_steps_to_checkpoint = 0; // Pasos que debe dar el motor para llegar al máximo de bordes detectados.
long motor_steps_to_resetpoint = 0; // Pasos que debe dar el motor para llegar al punto de reset.
int stage = 0; // Etapa en la que se encuentra del proceso.
// DIFFERENT STAGES OF THE ENGINE:
// STAGE : 0 --> ENGINE STOP
// STAGE : 1 --> ENGINE CONSTANT ADVANCE
// STAGE : 2 --> ENGINE RETURN TO RESETPOINT
// STAGE : X --> SECONDS THE ENGINE HAS TO REVERSE TO RETURN TO CHECKPOINT
void setup(){ // Bucle de definición de parametros.
Serial.begin (9600); // Definimos el boud rate al que se envía la comunicacnión en serie.
stepper.setSpeed (200); // Definimos la velocidad de movimiento del motor.
}
void loop(){ // Bucle de ejecución.
if (Serial.available()>0){ // Si recibe comunicación en serie entra en el if.
stage = Serial.read ();
if (stage > 2){ // Si el valor recibido es mayor que 2 entra en el if.
seconds_to_checkpoint = stage; // Guardar el valor recibido de los segundos donde se ha encontrado el máximo de bordes.
motor_steps_to_checkpoint = ((4096 * (40 - seconds_to_checkpoint)) / 40) * (- 1); // Hallar el número de pasos hasta el máximo de bordes detectados.
motor_steps_to_resetpoint = ((motor_steps_to_checkpoint * (- 1)) - 4096); // Hallar el número de pasos hasta el punto de reset.
}
switch (stage){ // Dependiendo de la etapa en la que se encuentre entra en un switch o en otro.
case 0: // Paro del motor.
motor_steps = 0;
break;
case 1: // Avance del motor a velocidad constante.
motor_steps = 4096;
Serial.println (stage);
Serial.println (motor_steps);
stepper.step (motor_steps);
break;
case 2: // Rotroceso del motor a la posición de reset.
motor_steps = motor_steps_to_resetpoint;
Serial.println (stage);
Serial.println (motor_steps);
stepper.step (motor_steps);
break;
default: // Retroceso del motor a la posición donde se ha encontrado el máximo de bordes.
motor_steps = motor_steps_to_checkpoint;
Serial.println (stage);
Serial.println (motor_steps);
stepper.step (motor_steps);
break;
}
}
}

Answers (1)

Asim
Asim on 29 Jan 2024
Hello Alvar,
Based on the MATLAB code you provided, it seems you are attempting to write an integer value to the Arduino using the write function. However, the write function expects data in uint8 format, and you are trying to send an "int8" and later a "long" value, which could be causing the problem. Additionally, the write function does not automatically convert numeric values to their string representation, which is what the Arduino Serial.read() function is likely expecting.
Here's what you can do to fix the issue:
MATLAB Code
write(arduino_UNO, uint8(stage), "uint8"); % Send number 1 to the Arduino
max_edge_time_str = num2str(max_edge_time); %Convert max_edge_time to string
for i = 1:length(max_edge_time_str)
write(arduino_UNO, uint8(max_edge_time_str(i)), "uint8");
end
write(arduino_UNO, uint8('\n'), "uint8");
Arduino Code
void loop() {
if (Serial.available() > 0) {
String readString = Serial.readStringUntil('\n'); // Read the string until newline character
int receivedNumber = readString.toInt(); // Convert the string to an integer
// Now you can use receivedNumber as the stage variable or for other purposes
stage = receivedNumber;
// ... rest of your code
}
}
Ensure the baud rate is the same in both MATLAB and Arduino code, and consider adding a delay after opening the serial port in MATLAB to allow the Arduino to reset.
I hope this helps.
Best Regards,
Asim Asrar

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!