Serial Comunnication between matlab and arduino - matlab

I am trying to send data from MATLAB to ARDUINO using the following code for arduino and the second one for the matlab. Both code work fine and when i press 1 led lights up and when press 2 led become off. But actually what i am trying to do is when matlab run code it automatically send 1 to arduino and the led become on. i have tried may changes but cant able to do. when iam trying to run the third code (given below) the arduino status led blink that show it receive some thing but my actual led which is connected to pin 13 still off.
int ledPin=13;
int matlabData;
void setup()
{
pinMode(ledPin,OUTPUT);
Serial.begin(9600);
}
void loop()
{
if(Serial.available()>0) // if there is data to read
{
matlabData=Serial.read(); // read data
if(matlabData==1)
digitalWrite(ledPin,HIGH); // turn light on
else if(matlabData==2)
digitalWrite(ledPin,LOW); // turn light off
}
}
(MATLAB)
1.
clear all
2.clc
3.
4.answer=1; % this is where we'll store the user's answer
5.arduino=serial('COM4','BaudRate',9600); % create serial communication object on port COM4
6.
7.fopen(arduino); % initiate arduino communication
8.
9.while answer
10. fprintf(arduino,'%s',char(answer)); % send answer variable content to arduino
11. answer=input('Enter led value 1 or 2 (1=ON, 2=OFF, 0=EXIT PROGRAM): '); % ask user to enter value for variable answer
12.end
13.
14.fclose(arduino); % end communication with arduino
(MY edit code)
1.
clear all
2.clc
3.
4.answer=1; % this is where we'll store the user's answer
5.arduino=serial('COM4','BaudRate',9600); % create serial communication object on port COM4
6.
7.fopen(arduino); % initiate arduino communication
8.
9.%while answer
10. fprintf(arduino,'%s',char(answer)); % send answer variable content to arduino
11. answer='1'%('Enter led value 1 or 2 (1=ON, 2=OFF, 0=EXIT PROGRAM): '); % ask user to enter value for variable answer
12.%end
13.
14.fclose(arduino); % end communication with arduino

The difference is the following:
answer = input('bla')
yields an answer that is a number, i.e. answer is of type double. In your third case, you wrote answer='1' which is a char, so in fact, the variable answer is different in both cases. Try and change the code in the third part to this here:
answer = 1;
or change the fprintf command to
fprintf(arduino, '%s', str2num(answer));

Related

Matlab Serial buffer issue

I am attempting to communicate from my Simblee Rfduino to Matlab, with the following Arduino code:
char testing[] = {1,2,3,4,5,6,7,8,'\0'};
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(6,OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
digitalWrite(6,LOW);
Serial.flush();
testing(EMG);
Serial.flush();
digitalWrite(6,HIGH);
}
In Python I am able to correctly read in the 1-8 in the correct order consistently.
However in Matlab it continuously changes order with no consistency, with the following code:
function serial()
global ser
ser = serial('COM5', 'BaudRate', 9600, 'FlowControl', 'hardware');
fopen(ser);
end
function serial_callback(~, ~)
global ser
time = tic;
fread(ser,1) % pull in data from serial port
toc(time);
end
I think there could be some issue in the Serial buffer.
Could you please provide some guidance as to how to consistently get Matlab to read in the data in order? Have others been able to get Matlab to reliably read from a serial port?
Thank you!
You could set the FlowControl to software (xOn and xOff flags). Hardware is only possible if you have the "hardware ressources".
The input buffer of matlab usually works with fifo principle.
After fopen() you have to wait for one second. Because some microcontrollers (like arduino uno ...) restarts after initialization of the uart interface.
--> pause(1);

Incorrect analog input reading in legacy interface matlab

I tried to use analog input signal for triggering purpose, however I have a problem with analog input reading. For example, when I send 6 V, I can read only 0.5 V, and signal form shown in the link is supposed to be square pulse but obviously, it is not.
My Daq card is NI PCI 6120. I used MAX software to check if it is a hardware issue, but it gives correct value and signal form, and as I try a session based matlab code to read only one analog input channel, I can get correct signal.
There should be a mistake in my matlab triggering code. Any suggestion ?
dig= digitalio('nidaq','Dev1');
line = addline(dio,0:1,'Out');
ai = analoginput('nidaq','Dev1');
channel = addchannel(ai,0:1);
set(ai,'SampleRate',fs);
set(ai,'SamplesPerTrigger',N);
set(ai,'Timeout',10000)
set(ai,'TriggerChannel',channel(1));
set(ai,'TriggerType','Software');
set(ai,'TriggerCondition','Rising');
set(ai,'TriggerConditionValue',0.5);
set(ai,'TriggerDelayUnits','Samples');
set(ai,'TriggerDelay',-3000);
set(ai,'LogFileName','file00.daq')
set(ai,'LoggingMode','Disk&Memory')
putvalue(dig,1)
start (ai)
[data t] = getdata(ai);
putvalue(dio,0)
delete(ai);
delete(dig);
enter image description here

Unable to send data (1) from MATLAB to Arduino

I am sending 1 from MATLAB to Arduino. My Arduino code works perfectly when I send 1 from teraterm terminal software. But when I send 1 from MATLAB by using this code arduino TX lite blinks but cannot get the 1 output.
s = serial('COM7','BaudRate',9600);
fopen(s)
fprintf(s,'1');
fclose(s)
Problem with this code is that you are not giving Delay to process the code.
According to my calculation : fopen(string) command needs 0.8754 Seconds of Processing time.
So add 1 second delay, it will work.
..
Your Modified Code :
clear all
clc
s=serial('COM7','BaudRate',9600);
fopen(s);
pause(1);
fprintf(s,1);
fclose(s);

analogRead function not working in MATLAB

I am new to Arduino and I am trying to control it through MATLAB. I have downloaded the arduino IO package and installed it.I am using MATLAB 2014a.I have a LED and I change its brightness by changing the PWM voltage as follows :
a=arduino('COM3');
brightness_step = (5-0)/20;
for i = 1:20
writePWMVoltage(a, 11, i*brightness_step);
val=a.analogRead(0);
display(val)
pause(0.1);
end
for i = 1:20
writePWMVoltage(a, 11, 5-i*brightness_step);
val=a.analogRead(0);
display(val)
pause(0.1);
end
clear a
Everything works great except for the analogRead part which throws the following error :
No appropriate method, property, or field analogRead for class arduino.
What am I doing wrong?
Maybe you can try to use fscanf() like in the following example from AllAboutEE.
I had the same problem with the analogRead when I connected my ArduinoUno R3.
After an hour's struggle, I changed to readVoltage, as Controller replied in 2014, and it works perfectly.

Can you synchronize the data acquisition toolbox and the image acquisition toolbox of Matlab?

I'd like to simultaneously get data from a camera (i.e. an image) and an analog voltage using matlab. For the camera I use the imaq toolbox, for reading the voltage I use the daq toolbox (reading NI-USB device), with a following code:
clear all
% Prepare camera
vid = videoinput('gentl', 1, 'Mono8');
src = getselectedsource(vid);
vid.FramesPerTrigger = 1;
vid.TriggerRepeat = Inf;
triggerconfig(vid, 'hardware', 'DeviceSpecific', 'DeviceSpecific');
src.FrameStartTriggerMode = 'On';
src.FrameStartTriggerActivation = 'RisingEdge';
% prepare DAQ
s=daq.createSession('ni');
s.addAnalogInputChannel('Dev1','ai1','Voltage');
fid = fopen('log.txt','w');
lh = s.addlistener('DataAvailable',#(src,event)SaveData(fid,event));
s.IsContinuous = true;
% Take data
s.startBackground();
start(vid)
N=10;
for ii=1:N
im(:,:,ii)=getsnapshot(vid);
end
% end code
delete(lh );
fclose('all');
stop(vid)
delete(vid)
where the function SaveData is:
function SaveData(fid,event)
time = event.TimeStamps;
data = event.Data;
fprintf(fid, '%f,%f\n ', [time data]);
end
I do get images and a log.txt file with the daq trace (time and data), but how can I use the external triggering (that trigger the camera) or some other clock to synchronize the two?
For this example, the daq reads the camera triggering TTL signal (# 50 Hz), so I want to assign each TTL pulse to an image.
Addendum:
I've been searching and have found a few discussions (like this one) on the subject, and read the examples that are found in the Mathworks website, but haven't found an answer. The documentation shows how to Start a Multi-Trigger Acquisition on an External Event, but the acquisition discussed is only relevant for the DAQ based input, not a camera based input (it is also working in the foreground).
This will not entirely solve your problem, but it might be good enough. Since the synchronization signal you are after in at 50 Hz, you can use clock in order to create time stamps for both types of your data (camera image and analog voltage). Since the function clock takes practically no time (i.e. below 1e-7 sec), you can try edit to your SaveData function accordingly:
fprintf(fid, '%f,%f\n ', [clock time data]);
And in the for loop add:
timestamp(i,:)=clock;
Can you use the sync to trigger the AD board? From the USB-6009 manual...
Using PFI 0 as a Digital Trigger--
When an analog input task is defined, you can configure PFI 0 as a digital trigger input. When the digital trigger is enabled, the AI task waits for a rising or falling edge on PFI 0 before starting the acquisition. To use AI Start Trigger (ai/StartTrigger) with a digital source, specify PFI 0 as the source and select a rising or falling edge.
My experience suggests that delay between trigger and AQ is very short
I'm sorry I use Python or C for this, so I can't give you MatLab code, but you want to look at functions like.
/* Select trigger source */
Select_Signal(deviceNumber, ND_IN_START_TRIGGER, ND_PFI_0, ND_HIGH_TO_LOW);
/* specify that a start trigger is to be used */
DAQ_Config(deviceNumber, startTrig, extConv); // set startTrig = 1
/* start the acquisition */
DAQ_Start(deviceNumber, …)
If you want to take this route you could get more ideas from:
http://www.ni.com/white-paper/4326/en
Hope this helps,
Carl
This is yet no complete solution, but some thoughts that might be useful.
I do get images and a log.txt file with the daq trace (time and data), but how can I use the external triggering (that trigger the camera) or some other clock to synchronize the two?
Can you think of a way to calibrate your setup? I.e. modify your experiment and create a distinct event in both your image stream and voltage measurements, which can be used for synchronization? Just like this ...