Hi all, i was trying to send some float values from matlab representing voltages from 0 to 10V. They way of transmitting them is to multiply them by 10000 to get them integers. Then send it to the serial port as strings and conver it into integers in arduino. Hence the conversion is made to double and then the original valu sent from matlab is set to the analog ports. This is to send a DC control voltage values generated from matlab and set the analog output ports with these DC control voltages.
The ports used are 8. From 6 to 13. If there are more incoming voltages values, the programs starts again setting the port 6 and goes ahead.
This is the code in MATLAB:
%Creates a serial connection
serialPort=serial('COM4','BaudRate',9600);
%Change the Terminator property of the serial port to make it faster
%set(serialPort,'Terminator','CR');
%Informs about errors
warning('off','MATLAB:serial:fscanf:unsuccessfulRead');
%Opens the serial port
fopen(serialPort);
volt=[10,5,0,3,0,8,0,1];
%Voltages are mapped from 0-10 to 0-100000
for i=1:length(volt)
voltmapped(i)=map2(volt(i),0,10,0,100000);
end
display('Press any button to continue.');
pause
for i=1:length(voltmapped)
fprintf(serialPort,'%d',voltmapped(i));
end
fclose(serialPort);
% This function converts one value within the range [fromLow,fromHigh]
% to the corresponding value within the range [toLow,toHigh].
%
% INPUT PARAMETERS:
% val: Value which it is going to be converted.
% fromLow: Minimum value of the origin range.
% fromHigh: Maximum value of the origin range.
% toLow: Minimum value of the destination range.
% toHigh: Maximum value of the destination range.
%
% OUTPUT PARAMETERS:
% num: Converted value of val within the range [toLow,toHigh]
%
function [num]=map2(val,fromLow,fromHigh,toLow,toHigh)
aux1=val/(fromHigh-fromLow);
aux2=aux1*(toHigh-toLow);
num=floor(aux2);
end
Arduino:
float data_rec;
float data_conv1,data_conv2;
float volt;
int portNum;
void setup(){
portNum=6;
Serial.begin(9600);//A serial communication is defined
for(int i=6;i<14;i++){
analogWrite(i,0);
}
}
void loop(){
//If there is data to read at the serial port
if(Serial.available() > 0){
if(portNum>13){
portNum=6; //All ports have a voltage, then start again to set
//values from port 2
}
data_rec=Serial.parseInt(); //Converts the string received into an integer
//it is also converted into a double by implicit conversion
data_conv1=(data_rec)/10000; //Voltage value sent from Matlab through the serial port
volt=convert(data_conv1,0,10,0,255); //Voltage value converted, to set the voltage value
//into the analog port
analogWrite(portNum,volt); //Sets the output port with the desired voltage value
portNum++;
}
delay(100);
}
/* Function responsible for expressing the voltage values within the interval [0,255] */
float convert(double val,double fromLow,double fromHigh, double toLow, double toHigh){
double aux1,aux2;
aux1=val/(fromHigh-fromLow);
aux2=aux1*(toHigh-toLow);
return aux2;
}
But it does not work. Only works if I write line by line in matlab. It does not work with scripts or loops like:
for i=1:length(voltmapped)
fprintf(serialPort,'%d',voltmapped(i));
end
I get a solution but is very slow and inefficient. It consist of doing the same but the arduino sends the values received from matlab. but i cant use it in scripts and i have problems using the code in guide.
The solutions are:
Matlab:The serial port is has been already declared. It is better obviate the parameter scan angle. From this value the matlab obtain the voltage values required to be sent.
function main(ScanAngle,serialPort)
clc
f=2.4*10^9;
c=3*10^8;
lambda=c/f;
N=8;
d=0.055;
phase_sf=calculate_phasesf(lambda,d,ScanAngle);
disp(['phase shift = ' num2str(phase_sf)]);
phases=calculate_phases2(N,phase_sf);
if(ScanAngle<0)
phases=toggle(phases);
end
disp(['phases = ' num2str(phases)]);
for i=1:length(phases)
voltages(i)=get_voltage(phases(i));
end
disp(['voltages = ' num2str(voltages)]);
for i=1:length(voltages)
voltages_mapped(i)=map2(voltages(i),0,10,0,100000);
end
for i=1:length(voltages_mapped)
fprintf(serialPort,'%d',voltages_mapped(i));
a(i)=fscanf(serialPort,'%d');
end
disp(['a = ' num2str(a)]);
Aduino:
float data_rec;
float data_conv1,data_conv2;
float volt;
int portNum;
void setup(){
portNum=6;
Serial.begin(9600);//A serial communication is defined
for(int i=6;i<14;i++){
analogWrite(i,0);
}
/* Definition of analog output ports*/
// pinMode(2,OUTPUT);
// pinMode(3,OUTPUT);
// pinMode(4,OUTPUT);
// pinMode(5,OUTPUT);
// pinMode(6,OUTPUT);
// pinMode(7,OUTPUT);
// pinMode(8,OUTPUT);
// pinMode(9,OUTPUT);
}
void loop(){
//If there is data to read at the serial port
if(Serial.available() > 0){
if(portNum>13){
portNum=6; //All ports have a voltage, then start again to set
//values from port 2
}
data_rec=Serial.parseInt(); //Converts the string received into an integer
//it is also converted into a double by implicit conversion
data_conv1=(data_rec)/10000; //Voltage value sent from Matlab through the serial port
volt=convert(data_conv1,0,10,0,255); //Voltage value converted, to set the voltage value
//into the analog port
analogWrite(portNum,volt); //Sets the output port with the desired voltage value
Serial.println(volt);
portNum++;
}
delay(100);
}
/* Function responsible for expressing the voltage values within the interval [0,255] */
float convert(double val,double fromLow,double fromHigh, double toLow, double toHigh){
double aux1,aux2;
aux1=val/(fromHigh-fromLow);
aux2=aux1*(toHigh-toLow);
return aux2;
}
This salution works, but at some cases, like in gui, or loops does not work. The error in matlab is
subscription assignment mismatch with a(i).
This is for a research , please if anyone knows the answer please i would be glad if i could get some help.
Thank you