**You are now following this question**

- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.

# Reading ADC data from MSP430 to Matlab via serial port

20 views (last 30 days)

Show older comments

My situation is

1. external ADC samples from one channel and transmit to Serial port Via Uart and then switches over to second channel to do same and then third.

2. I manage to view data in Hterm and it looked quite fine.

3. I want to plot it live in matlab- I know there are ways to do it but can someone here explain me a basic step by step to achieve my objective?

I have basic idea of what i should be doing

- setup serial communication.
- create array to store uart values
- calculate voltage values
- plot live values

It would be nice if someone points out me for where to look for point 2 and 4 specifically.

##### 19 Comments

Walter Roberson
on 15 Jun 2022

Hiril Patel
on 16 Jun 2022

Actually I dont have answer to that for following reason

- I haven't yet experimented this circuit on the workbench where i will apply known strain to test my circuit so I don't think I have limit to specific number of samples needed. Lets assume I will be watching matlab data and plot while experimenting so I have not clear answer for this.

Walter Roberson
on 16 Jun 2022

Walter Roberson
on 16 Jun 2022

Hiril Patel
on 16 Jun 2022

ok I understand the memory limitations here. So if I resort to recording the data first and later analyzing it on matlab, still I could not find any example of grouping data coming from serial port in following way( i am not looking for direct answer):

- the data from adc is sampled channel by channel so I am taking data from ads as 1 sample per channel and then proceding to next channel.
- this means that i am trasnferring data to serial port in above mentioned way.
- If i want to record it i first have to seperate data which UART is pushing out as 8 bit(adc samples 24 bit of data for single sample) hence I would have to record 4 byte and sort it into 1 row and then switch to another row to record one more sample ..........

Can you advice me for this question?

Walter Roberson
on 16 Jun 2022

Read from each channel. Then

counter = counter + 1;

all_data(:, counter) = samples;

I used columns instead of rows because that is more efficient.

Hiril Patel
on 17 Jun 2022

Thank you for the suggestion but I didn't quite understood it well so I have proceeded with following code:

clear all;

clc;

%USB port config

delete(instrfind);

s = serial('COM11','BaudRate',115200,'databits',8,'stopbit',1);

fopen(s);

data = fscanf(s);

adc_data = split(data,"/"); %I have inserted "/" in my microcontroller code to send that at beginning of channel 1 so I can have data seperation in matlab.

%Closing port

fclose(s);

I haven't yet designed loops yet but the problem is how should i convert them into hex values since the split command make a cell to store the data.

Walter Roberson
on 17 Jun 2022

Could you show an example of what is being sent? And is it binary or character?

Hiril Patel
on 17 Jun 2022

Walter Roberson
on 18 Jun 2022

You have binary, and it looks like you have a different number of bytes at times. You just might be sending a space after each / but that is not clear. If that is / space then it is generally followed by 8 bytes. But sometimes it is only 7 and sometimes it is 9.

You should switch to one of the following schemes:

1. Write numbers in character form, either decimal or hexadecimal, with non-number between the entries. Either put newline after each individual number or put newline at the end of a group of samples; or 2. Write numbers in binary using a fixed number of bytes per entry, so that you can ask to read a fixed number of bytes with no delimiter; or 3. At the beginning of each burst of numbers, write a byte (or two) which is the number of bytes that follow in that packet, with no end of line. The input side reads the size (fixed size) and uses the size to read that many bytes; or * use a variable length binary stream with a fixed termination byte, with the binary stream having been carefully adjusted so that it never accidentally includes the termination character. For example you might use newline, and everywhere that newline would have been sent as data send 255 0 and everything 255 would have been sent, send 255 255.

Hiril Patel
on 19 Jun 2022

ok so I semi followed your advice in a way and put unique delimiters before transaction of each channel;:

channel 1 has delimiter = /A/

channel 2 has delimiter = /B/

channel 3 has delimiter = /C/

and then i used function

data = fscanf(s);

adc_data = split(data,["/A/","/B/","/C/"]);

but now the result comes in 74x1 cell with sequential results. is there any commant to split data in three seperate arrays/files/cell for seperate delimiter?

Hiril Patel
on 21 Jun 2022

Ok till now I successfull splitted till each measurements,

clear all;

clc;

%USB port config

delete(instrfind);

s = serial('COM11','BaudRate',115200,'databits',8,'stopbit',1);

%timeonut infinite

s.Timeout = 300;

s.InputBufferSize = 5000;

fopen(s);

% w = s.bytesavailable

data2 = fscanf(s);

adc_data = split(data2,'/A/');

l= strlength(adc_data);

rowsToDelete = strlength(adc_data) ~= 12;

adc_data(rowsToDelete) = [];

CH0 = extractBefore(adc_data,5);

CH1 = extractBetween(adc_data,5,8);

CH2 = extractAfter(adc_data,8);

fclose(s);

But how do I convert these AsCI to numerical values?

Walter Roberson
on 23 Jun 2022

Look at https://www.mathworks.com/matlabcentral/answers/uploaded_files/1036145/Capture.JPG in your display of the input data. That's the one that starts

ÿ ù/

Those are binary not character.

You have two choices:

- you can continue to send in binary, and do binary reads using fread() (for serial) or read() (for serialport). If you are not always sending the same number of bytes or if not everything is the same binary data type, then you may need to add some extra bytes to indicate how the following data is to be treated. If you use this fread() binary approach, you do not put any delimiters between values and you do not send newline; OR
- you can switch to sending the numbers as text. If you send as text, put a space between the values and put newline at the end of the line. On the MATLAB end, fscanf() will read the entire line of values, returning a numeric vector.

You only need things like your /A/ or similar if you are sending the channels in inconsistent order. For example if you had a series of devices that generated interrupts when it was ready, and you wanted to send the data in the order received, then there might be reason to tag each value according to the channel it is associated with.

Hiril Patel
on 28 Jun 2022

Kk I figured out solution for the whole problem but this include both python and matlab since I am a bit more proficient in it so now i am recording data in csv file in python and later importing it in matlab for furthur calculations.

Thank you million for all these advices they helped me in many ways.

regards

Hiril Patel

Hiril Patel
on 30 Jun 2022

Hello again Walter,

can you suggest me what to do with following case, as it is associated with the previous system:

i managed to get those values in matlab and working with calculation but here I am solving Mohr's circle formulas and thus I have three equation and three variables( i studied about syms and solve functions and feature but still have some error which I am not able to figure out). Perhaps I am not converting those variables to appropriate data type( I have little to no idea whats going on behind them, here is the script and a sample of data type :

ch0, ch1, ch2 are csv file i imported generated from python

clc;

clear;

% ADC and strain gauge settings

vref = 3300; % ADC reference millivolts

ADC_resolution = 8388607; % 2^23 24bit of resolution

A = 4; % if fsr = +/-2

pga = 1; % ADS1220 amplifier gain setting

E = 3.3; % Bridge excitation voltage

K = 2.04; % Gauge factor

% Importing adc values

ch0 = readmatrix('ch0.csv');

ch1 = readmatrix('ch1.csv');

ch2 = readmatrix('ch2.csv');

% Conversion to proportional millivoltage

n = vref/ADC_resolution;

Channel0 = n*ch0;

Channel1 = n*ch1;

Channel2 = n*ch2;

% Strain calculation

gauge0 = (4/2.04)*(Channel0/E);

gauge1 = (4/2.04)*(Channel1/E);

gauge2 = (4/2.04)*(Channel2/E);

% Calculation of unblanced bridge in nonstrained state:

% Vr = (bridge strained output - bridge unstrained output)/excitation voltage

% Measured strain to principle strain conversion

% Maximum principal strain

syms e_x e_y lamda_xy

eq0 = (gauge0 - (e_x*((cos(0)).^2)) +(e_y*((sin(0)).^2)) + (lamda_xy*(sin(0))*(cos(0))));

eq1 = (gauge1 - (e_x*((cos(60)).^2)) +(e_y*((sin(60)).^2)) + (lamda_xy*(sin(60))*(cos(60))));

eq2 = (gauge2 - (e_x*((cos(120)).^2)) +(e_y*((sin(120)).^2)) + (lamda_xy*(sin(120))*(cos(120))));

solve(eq0,eq1,eq2,e_x,e_y,lamda_xy);

Walter Roberson
on 30 Jun 2022

ch0 = readmatrix('ch0.csv');

Those ch0, ch1, ch2 are probably not scalars.

Channel0 = n*ch0;

so the Channel* variables are probably not scalars.

gauge0 = (4/2.04)*(Channel0/E);

and that makes the gauge* variables not scalars.

eq0 = (gauge0 - (e_x*((cos(0)).^2)) +(e_y*((sin(0)).^2)) + (lamda_xy*(sin(0))*(cos(0))));

So the eq* variables are individually probably not scalars, since they are in terms of the gauge variables that are (probably) not scalars.

solve(eq0,eq1,eq2,e_x,e_y,lamda_xy);

You are asking to solve those arrays of equations that are in terms of 3 scalar variables e_x ,e_y, lamda_xy and you are asking for a single e_x and e_y and lamda_xy that solves those arrays simultaneously.

For example if ch0 is 10 x 1 then eq0 would be 10 x 1, and your call to solve would be solve(10x1, 10x1, 10x1, scalar, scalar, scalar).

solve() is the simultaneous equation solver. When you pass it more than one equation, it has to find the values of the free variables that make all of the equations true at the same time.

What you can do is arrayfun():

sols = arrayfun(@(E0,E1,E2)) solve(E0,E1,E2,e_x,e_y,lamda_xy), eq0, eq1, eq2, 'uniform', 0);

I used uniform, 0 because there might be no solutions in some cases, or there might be multiple solutions perhaps.

Hiril Patel
on 3 Jul 2022

Hiril Patel
on 18 Sep 2022

Hello again,

I had to change the formula since this one didn't yielded true results. But right now I don't know how to ask this query on internet so I had to ask it here.

the new formula contains serveral condition in order to get correct resutls. I want to know how to apply those condtion on each cell. Here is the query:

I have three equal size csv file. I have to take one value from each file from same row of those three file and compute it to get a value. I was able to do that, it is simple. But now what I need its that those computed value needs to be passed from certain condtion in order to apply next formula in order to get true value. Can you tell me how should i take those computed value(all the computed values satishfy a certain condition on which their formula changes).

I hope I have explained it in understandable way.

for more information, I am using these base CSV value to get principle strain value and principle strain direction.( I am able to find principle strain value but the direction has some condition in order to get it calculated).

this is hte reference document:( on page 197 and 198)

thank you

### Answers (0)

### See Also

### Categories

### Community Treasure Hunt

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

Start Hunting!**An Error Occurred**

Unable to complete the action because of changes made to the page. Reload the page to see its updated state.

Select a Web Site

Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .

You can also select a web site from the following list:

## How to Get Best Site Performance

Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.

### Americas

- América Latina (Español)
- Canada (English)
- United States (English)

### Europe

- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)

- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)

### Asia Pacific

- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)