MATLAB - Arduino Uno Serial Communication Issue

Hi All,

I tried a few other troubleshooting steps. Out of all of them, writing two that give any new insight. Let me know if this gives any ideas:

  • In case of something weird happening (spurious characters in serial input, etc), I rewrote the MATLAB code such that after sending the data to the Arduino, wait a bit, and read the two lines I was having the Arduino print: 1) It received the data, and 2) How many bytes are sitting in the serial port, just to see if anything gets leftover and it crosses 64. Nothing unexpected, and as usual when the program stops working, the Arduino does not enter the loop under:

if Serial.available() > 0

  • Only interesting thing was, that if I waited a few minutes between executing the MATLAB script, then the error disappeared. So maybe it's something about the way MATLAB is setting up the serial connection to the Arduino ("desperation explanations"). So I wrapped the MATLAB function in a for loop that iterates 10 times without setting up a new serial connnection or clearing it. It worked six times before cutting off. What was interesting was what the Arduino printed when it entered its loop against the sixth iteration from MATLAB, following which it stopped working. I have attached screenshot of our MATLAB "Serial monitor" on the sixth iteration. Note, the outputs follow this format, first it prints "Serial received", next it prints the number of bytes sitting there.

  • Thought exercise: The Arduino is not powering the Songle brand Relays, only the inputs. I read logic input current is 2-4 mA. Having multiple relays on, and before when I used to have the conveyor one on (20 mA current to a VFD), I don't think I have enough current demand to cause issues on the hardware. Let me know if this sounds right.

Arduino & MATLAB codes below - barely any changes except what is described

Arduino:

const byte pins [] = {2, 5, 6, 7};
const byte conveyorpin = 3;
char conveyorstring[10];
char speedchar[2];
const int  Npin = sizeof(pins);
int speed;
int bytecount = 0;

struct Instr {
    int           state;
    int           pin;
    unsigned long msecStart;
    unsigned long msecStop;
};

const int Ninstr = 30;
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) {
	Serial.println("Serial received");
        delay(64);
        bytecount = Serial.available();
	Serial.println(bytecount);
        char buf [80];
        const char delim[] = {' '};
        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);
        //  analogWrite(conveyorpin,speed);
        //}else{
        char *portion1 = strtok(buf,delim);
        pin = atoi(portion1);
        char *portion2 = strtok(NULL,delim);
        msecStart = atol(portion2);
        char *portion3 = strtok(NULL,delim);
        msecDuration = atol(portion3);
        //sscanf (buf, "%d %ld %ld", & pin, & msecStart, & msecDuration);
        addInstr (pin, msec + msecStart, msec + msecStart + msecDuration);
        //}
   
        
    }

    // 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);
    }
    pinMode(conveyorpin,OUTPUT);
   
}


MATLAB Code:

% Define the COM port and communication settings
comPort = 'COM4'; % Replace 'COMX' with your Arduino's COM port
baudRate = 9600;

% Create a serial port object
s = serialport(comPort, baudRate);
pause(5);
for i = 1:10
% % Define the instruction set (relay, activation time, and duration)
relayPin = 2; % Example: Control relay on pin 
relayPin = num2str(relayPin);
activationTime = 500; % Activation time in milliseconds 
activationTime = num2str(activationTime);
%activationTime = activationTime*1000;
duration = 10; % Duration in milliseconds 
duration = num2str(duration);
%duration = duration*1000;

% 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);
pause(0.5);
readline(s)
readline(s)

% % Define the instruction set (relay, activation time, and duration)
relayPin = 5; % Example: Control relay on pin 
relayPin = num2str(relayPin);
activationTime = 2000; % Activation time in milliseconds 
activationTime = num2str(activationTime);
%activationTime = activationTime*1000;
duration = 10; % Duration in milliseconds 
duration = num2str(duration);
%duration = duration*1000;

% 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);
pause(0.5);
readline(s)
readline(s)

% % Define the instruction set (relay, activation time, and duration)
relayPin = 7; % Example: Control relay on pin 
relayPin = num2str(relayPin);
activationTime = 4000; % Activation time in milliseconds 
activationTime = num2str(activationTime);
%activationTime = activationTime*1000;
duration = 10; % Duration in milliseconds 
duration = num2str(duration);
%duration = duration*1000;

% 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);
pause(0.5);
readline(s)
readline(s)

% % Define the instruction set (relay, activation time, and duration)
relayPin = 5; % Example: Control relay on pin 
relayPin = num2str(relayPin);
activationTime = 4000; % Activation time in milliseconds 
activationTime = num2str(activationTime);
%activationTime = activationTime*1000;
duration = 10; % Duration in milliseconds 
duration = num2str(duration);
%duration = duration*1000;

% 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);
pause(0.5);
readline(s)
readline(s)
end


% Close the serial port when done
pause(5)
clear s;
clear all;