[SOLVED] Stepper motor with Arduino and Matlab - Page 1
Forum section: electronics / general

author: GuilTy
author_rank: Contributor
timestamp: March 18, 2017, 11:19:09 am
content: Hello,I have a 28byj-48 stepper motor and the shiel uln2003. I want to program the arduino to control the stepper using Matlab.Code:clear all; close all; clc;a=arduino()configurePin(a,'D2','DigitalOutput');configurePin(a,'D3','DigitalOutput');configurePin(a,'D4','DigitalOutput');configurePin(a,'D5','DigitalOutput');pins={'D2', 'D3', 'D4', 'D5'};steps={'1100', '0110', '0011','1001'};steps_size=size(steps,2); %steps = 4for i = 1:100step = steps{mod(i,steps_size)+1}; % step=1,2,3,4for j=1:4writeDigitalPin(a, pins{j}, str2double(step(j)));end%pause(0.01);endIt works, but the speed at which the motor is turning around is very very slow. Does anyone knows how to increase the speed between Matlab and Arduino. I think that is something that has to do with the BaudRate.Thank you,GuilTy

author: donotdespisethesnake
author_rank: Super Contributor
timestamp: March 18, 2017, 12:29:04 pm
content: I doubt that increasing the baud rate will make much difference, you will never get this to run at an adequate speed with this method.You are using the wrong tool for the job, you should be programming the Arduino directly.

author: Lovely_Santa
author_rank: Contributor
timestamp: March 18, 2017, 09:52:44 pm
content: Quote from: GuilTy on March 18, 2017, 11:19:09 amLet me explain BaudRate first: BaudRate is the speed you send data over, this is equal to your clock rate that you have on your bus. This is not equal to the amout of data you send over! (=bitrate)When you send serial data, you send normaly 1 bit (0V or 5V => low or high => '0' or '1') every clock pulse, in this case your baudrate equals your bitrate (bitrate is number of bits you send from your PC to the arduino)Now, we increase our detection voltages to 0, 1.5, 3, 5V => we have 4 logic levels '00', '01', '10', '11' , so in this case your baudrate isn't changing, but your bitrate has doubled.If you can implement this in your design, this might be a sollution, but it will probably still be slow.Your serial communication will always be your bottleneck. A way to solve this problem is to send the configuration data over to your arduino (with interrupt maybe) and then re-confugure the arduino with the received data. So even when it's not communicating, the arduino will drive the motor on it's own depending on your configuration.So Mathlab -> Arduino sends speed & direction, or maybe number of degrees to turn (?)Arduino driving the motor on it's own depending on configured variable speed and direction etc...

author: GuilTy
author_rank: Contributor
timestamp: March 19, 2017, 05:42:13 pm
content: Thank you, you are right.Now, I am using Matlab to send commands to Arduino. Arduiono has a program implemented in it and when the data is send from Matlab the motor is moved. But I can only send data from the command line in matlab, I want to build a function which sends the same data when I call it without typing the data in the command line.Here is the code:function []=send_comm()delete(instrfindall);s=serial('COM8','BAUD', 9600); % Make sure the baud rate and COM port is% % same as in Arduino IDEfopen(s);%%%servalue= input('Enter the value 100 to turn ON LED & 101 to turn OFF LED :');fprintf(s,servalue); %This command will send entered value to Arduinoendthe "servalue" is taken with input but I have to write it in the command line. Do you know how to write a function that sends automatically the data without typing it in the command line?If I take out "input" it doesn't work.Best,GuilTy

author: mbless
author_rank: Regular Contributor
timestamp: March 20, 2017, 03:51:35 am
content: Change the function call toCode:function send_comm(servalue)and remove the input line. This programmatically inputs the value instead of requiring user intervention.You can then call the function likeCode:send_comm(100);pause(1);send_comm(101);

author: GuilTy
author_rank: Contributor
timestamp: March 20, 2017, 08:14:07 pm
content: Thank you for your replyQuote from: mbless on March 20, 2017, 03:51:35 amIt still doesn't work.This is my arduino code:Code:#include <Stepper.h>const int stepsPerRevolution = 300; // change this to fit the number of steps per revolution// for your motor// initialize the stepper library on pins 8 through 11:Stepper myStepper(stepsPerRevolution, 2, 3, 4, 5);int recValue;void setup(){Serial.begin(9600);myStepper.setSpeed(60);}void loop(){if(Serial.available()>0){recValue=Serial.read();if (recValue == 100) // If use will send value 100 from MATLAB then LED will turn ON{ Serial.begin(38400);myStepper.step(stepsPerRevolution);}}}This is the Matlab code with input from the command line:Code:function send_comm()delete(instrfindall);s=serial('COM8','BAUD', 9600); % Make sure the baud rate and COM port is% % same as in Arduino IDEfopen(s);%%%servalue= input('Send 100 for the motor to rotate:');fprintf(s,servalue); %This command will send entered value to ArduinoendThis works perfectly. When I type from command line "100" the motor works perfect.But when I write this function and only call it from the command line it doesn't do anything.Code:function send_comm(servalue)delete(instrfindall);s=serial('COM8','BAUD', 9600); % Make sure the baud rate and COM port is% % same as in Arduino IDEfopen(s);%%%fprintf(s,servalue); %This command will send entered value to ArduinoendI used HyperTerminal to monitor the transmission. Both functions send the same thing, but the motor is turnning only when I use the first function.Regards,GuilTy

author: mbless
author_rank: Regular Contributor
timestamp: March 20, 2017, 09:38:30 pm
content: Can you see if the Arduino gets the serial command? If so, what is recValue?How are you calling the Matlab function? The only thing I can think of is if it's sending a string vs. integer. You can tryCode:send_comm(100);orCode:send_comm('100');

author: GuilTy
author_rank: Contributor
timestamp: March 20, 2017, 10:00:27 pm
content: I think that arduino gets the serial command, because when I use the first function, the one in which I have to type in the command line the value "100", it works.And when I watched the serial connection with HperTerminal both functions have sent the same thing.I tried using in the second function :Code:fprintf(s,'%d',servalue); %This command will send entered value to Arduinobut still nothing.And also, I tried to call the function the way you said, still doesn't work.I don't know what else to do.Thank you,GuilTy

author: mbless
author_rank: Regular Contributor
timestamp: March 20, 2017, 11:07:49 pm
content: Quote from: GuilTy on March 20, 2017, 10:00:27 pmIt'd really help if you can see what the recValue is then. It should give insight as to whether there is a translation error somewhere.

author: GuilTy
author_rank: Contributor
timestamp: March 21, 2017, 07:54:38 am
content: Quote from: mbless on March 20, 2017, 11:07:49 pmI think you are right, but how do I see what the recValue is? Do I have to search for it in the memory of Arduino?

author: FrankBuss
author_rank: Unknown
timestamp: March 21, 2017, 09:03:31 am
content: Serial.begin(38400) in your loop function doesn't look good, because in Matlab you are using 9600 baud, and you need it only once in your setup function anyway. BTW, you can use 115200, too.But Windows/Mac/Linux is not a realtime operating system. If you do a wait for 10 milliseconds, you can get anything from 10 milliseconds to 100 milliseconds if you are unlucky and e.g. Windows decides it wants to download an update in the background. Also note the USB latency, if you don't use a real built-in serial port, which can be several milliseconds as well for each communication call from Matlab. Better idea to send the whole stepper motor instructions as one block, e.g. withG code, and do all the delays and timing critical things on the Arduino side.

author: GuilTy
author_rank: Contributor
timestamp: March 21, 2017, 02:36:17 pm
content: I solved it!It looks like Arduino and Matlab need a short time to establish communication. Using the function in Matlab that sends the data automatically, the data didn't wait for the establishment. I had to use the command "pause" in Matlab, so the program won't send the data until the connection have been established.This is how the code looks now.Code:function commanda(servalue)delete(instrfindall);s=serial('COM8','BAUD', 9600); % Make sure the baud rate and COM port is% same as in Arduino IDEfopen(s);pause(3);fprintf(s,servalue); %This command will send entered value to ArduinoendThank you all for your responses and for your interest in helping me.GuilTy