Writing serial data to MATLAB using the write function

13 次查看(过去 30 天)
Hello,
I am trying to write data to an Arduino via serial port. Looking on MATLAB answers, I see several examples of methods using the serial function, and fprintf to print to the serial port. However, I also get the note that the serial function is going to be discontinued; so I am trying to implement using the serialport. I am posting my code below - I am not sure what's wrong with the formatting I am specifying that MATLAB is sending out to the Arduino in this implementation. I am posting below my MATLAB code, and you may not need it but will post the Arduino IDE code I have to receive (just to give credit where it's due: this is not my code, a very nice poster on Arduino forums helped me). When I send the string commands through the Serial Monitor, it works as expected, so I am missing something on the MATLAB side
% Define the COM port and communication settings
comPort = 'COMX'; % Replace 'COMX' with your Arduino's COM port
baudRate = 9600;
% Create a serial port object
s = serialport(comPort, baudRate);
% Define the instruction set (relay, activation time, and duration)
relayPin = 4; % Example: Control relay on pin 4
activationTime = 500; %Activation in milliseconds
duration = 2500; % Duration in milliseconds
% Create the instruction string with the relay, activation time, and duration
instruction = sprintf('%d %ld %ld\n', relayPin, activationTime, duration);
% Send the instruction to the Arduino
write(s, instruction, "char");
% Close the serial port when done
clear s;
Arduino Code (please ignore the interpretation of MATLAB reserved words, if you have visual studio or another editor you could paste it there):
const byte pins [] = { 2, 5, 6, 7};
const byte conveyorpin = 3;
char conveyorstring[8];
char speedchar[2];
const int Npin = sizeof(pins);
int speed;
struct Instr {
int state;
int pin;
unsigned long msecStart;
unsigned long msecStop;
};
const int Ninstr = 10;
Instr instr [Ninstr] = {}; // initialize all fields to zero
enum { Available = 0, InUse, Set }; // Available (0) will be default value
enum { Off = HIGH, On = LOW };
char s [80]; // for use with sprintf()
// -----------------------------------------------------------------------------
void
addInstr (
int pin,
unsigned long msecStart,
unsigned long msecStop )
{
sprintf (s, "addIntr: pin %d, %lu start, %lu stop",
pin, msecStart, msecStop);
Serial.println (s);
for (int i = 0; i < Ninstr; i++) {
if (Available == instr [i].state) {
instr [i].state = InUse;
instr [i].pin = pin;
instr [i].msecStart = msecStart;
instr [i].msecStop = msecStop;
return;
}
}
Serial.println ("addIntr: none available");
}
// -----------------------------------------------------------------------------
void loop ()
{
unsigned long msec = millis ();
if (Serial.available () > 0) {
char buf [80];
int n = Serial.readBytesUntil ('\n', buf, sizeof(buf)-1);
buf [n] = '\0';
int pin;
unsigned long msecStart;
unsigned long msecDuration;
for (int j = 0;j<8;j++){
conveyorstring[j]=buf[j];
}
conveyorstring[8] = '\0';
if (strcmp(conveyorstring,"Conveyor") == 0){
sscanf(buf, "Conveyor %d", & speed);
Serial.println (speed);
analogWrite(conveyorpin,speed);
}else{
sscanf (buf, "%d %ld %ld", & pin, & msecStart, & msecDuration);
addInstr (pin, msec + msecStart, msec + msecStart + msecDuration);
}
//memset(conveyorstring,0,sizeof(conveyorstring));
}
// Check and execute relay instructions
for (int i = 0; i < Ninstr; i++) {
switch (instr [i].state) {
case InUse:
if (msec >= instr [i].msecStart) {
instr [i].state = Set;
digitalWrite (instr [i].pin, On);
sprintf (s, "loop: set pin %d", instr [i].pin);
Serial.println (s);
}
break;
case Set:
if (msec >= instr [i].msecStop) {
instr [i].state = Available;
digitalWrite (instr [i].pin, Off);
sprintf (s, "loop: clear pin %d", instr [i].pin);
Serial.println (s);
}
break;
}
}
}
// -----------------------------------------------------------------------------
void setup () {
Serial.begin (9600);
for (int i = 0; i < Npin; i++) {
pinMode (pins[i], OUTPUT);
digitalWrite (pins[i], Off);
}
}
Thanks in advance!!!

回答(1 个)

UDAYA PEDDIRAJU
UDAYA PEDDIRAJU 2023-11-3
Hi pb,
I understand that you are trying to write data to an Arduino via a serial port using MATLAB. it seems that the formatting issue lies in the instruction string that you are sending to the Arduino. The Arduino code expects the instruction string to be in a specific format, with the relay pin, activation time, and duration.
To fix this issue, you can modify the instruction string formatting in MATLAB as follows:
write(s, relayPin, "uint8");
write(s, activationTime, "uint16");
write(s, duration, "uint16");
By transferring the commands, you should be able to rectify the error that you’re facing. Once you make this change, try running your MATLAB code again to send the formatted instruction string to the Arduino via the serial port.
You can refer to the MathWorks documentation to know more about the supported format for write function in MATLAB: https://www.mathworks.com/help/matlab/ref/serialport.write.html#mw_0f814938-a574-441f-a0e1-d9cdf848c35e.
I hope this helps!
  1 个评论
pb
pb 2023-11-11
Hi Udaya,
Thanks very much for the response. So the arduino code expects it to be a character array, as opposed to integers. The sscanf function on the Arduino side is doing the conversions from character to integer/unsigned long.
I was able to solve the issue using the writeline, function (below a sample code posted). However, I am still curious to know why write did not work when sending it as a string.
% % Define the instruction set (relay, activation time, and duration)
relayPin = 6; % Example: Control relay on pin 2
relayPin = num2str(relayPin);
activationTime = 7000; % Activation time in milliseconds
activationTime = num2str(activationTime);
duration = 250; % Duration in milliseconds
duration = num2str(duration);
% Create the instruction string with the relay, activation time, and duration
instruction = horzcat(relayPin,' ',activationTime,' ',duration);
% Send the instruction to the Arduino
writeline(s,instruction);

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 MATLAB Support Package for Arduino Hardware 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by