sending multiple bytes of data from pc serial port to custom hardware using matlab - matlab

I am using the following matlab program to send multiple serial port data through the PC using a USB-serial port
close all; clear all; clc;
array_1st = ones(64, 1, 'uint8');
array_1st = array_1st';
for i=1:64
array_1st(i) = array_1st(i) * i ;
end
dummy_var = zeros(1,1);
if ~isempty(instrfind)
fclose(instrfind);
delete(instrfind);
end
s=serial('COM9');
set(s,'Terminator','CR','DataBits',8,'Parity','none','StopBits',1,'baudrate', 38400);
fopen(s);
disp('fopen(s)');
fwrite(s, array_1st);
pause(0.5);
dummy_var = fread(s, 1);
dummy_var
fclose(s);
clear s
A custom hardware is connected to the serial port. I have already been able to read multiple bytes of data sent by the custom hardware in the PC using a similar matlab program (that is, multiple byte transfer from hardware -> PC through serial port using matlab is working)
I am expecting the code above to write an array of 8-bit unsigned ints when the fwrite(s, array_1st); function is executed. The custom hardware at this point displays the bytes received in the serial port in it's IDE's terminal and waits in a breakpoint before dummy_var = fread(s, 1); in the matlab program is called
The problem is matlab is always sending only the first byte of the array_1st array to the serial port hardware. I have tried all kinds of variations in the above program, such as removing the array_1st = array_1st'; line, using char instead of uint8, usinf LF for terminator property in the serial port object, but the problem is always same: only the first bte of the array being sent actually goes through the serial port hardware to the custom device.
After calling fwrite(s, array_1st);, matlab also the following warning:
Warning: The specified amount of data was not returned within the
Timeout period.
The properties of the serial object after the fopen():
Serial Port Object : Serial-COM9
Communication Settings
Port: COM9
BaudRate: 38400
Terminator: 'CR'
Communication State
Status: open
RecordStatus: off
Read/Write State
TransferStatus: idle
BytesAvailable: 0
ValuesReceived: 0
ValuesSent: 0
It's properties after executing the dummy_var = fread(s, 1); line are:
Serial Port Object : Serial-COM9
Communication Settings
Port: COM9
BaudRate: 38400
Terminator: 'CR'
Communication State
Status: open
RecordStatus: off
Read/Write State
TransferStatus: idle
BytesAvailable: 0
ValuesReceived: 0
ValuesSent: 64
The ValuesSent property has been updated to 64 from 0, which I guess is indicating that, at least as far as the matlab serial port object is concerned, 64 data are being sent, but for some reason only the 1st one is actually going through the serial port hardware
What could be the reason for this? Is it that matlab just doesn't support what I want to do? If only 1 data is getting sent through the serial port hardware, why does ValuesSent show 64?
Matlab version is R2009b
EDIT 1: -----
I recorded the serial object data using the serial/record function, and here is what it recorded:
Legend:
* - An event occurred.
> - A write operation occurred.
< - A read operation occurred.
1 Recording on 29-Jul-2018 at 23:27:19.241. Binary data in little endian format.
2 > 64 uchar values.
01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10
11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20
21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30
31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40
3 < 0 uchar values.
4 Recording off.

Related

Saving the oucomes of a model run to use as starting point for future runs

OBJECTIVE: My plan is to run my model for ~60 ticks, and use the outcome of that run (i.e. the changes to the patches) as the starting point for all future runs. The idea behind this is that the first 60 ticks simulate a landscape from the past up until today (without any policy interventions). Then, from today on, I want to explore a range of policy scenarios, all starting with the same base conditions.
QUESTION: Do you know if there is a smart way to take stock of / save the outcomes of a run so that I can use them as a starting point for future runs, or do I need to assess the conditions after 60 ticks manually and then build an alternative setup-button that replicates those conditions?
I agree with Charles that export-world and import-world should work.
An alternative (see code below ) would be to use a fixed random seed for your alternative setup for the first 60 ticks, then change to a run-specific random seed, which would also work on a web-based run. ( I suspect export-world doesn't work over the web. )
Here's an example of changing the random seed mid-flight. Be sure to save the random seed before you define the new random seed or everything will always be the same!
Load this code and hit setup and go buttons multiple times and you can confirm it's working.
globals [ variable-random-seed fixed-ticks]
to setup
clear-all
set variable-random-seed random 999999999 ;; nine nines works
random-seed 123456789 ;; any fixed number to use for low ticks
set fixed-ticks 10 ;; or 60 in your case
print " ----------- fixed ------------- ===== -------- varies by run ----------- "
reset-ticks
end
to go
if ticks > 20 [ print "\n" stop ]
write random 100
if ticks = fixed-ticks [ write "=====" random-seed variable-random-seed ]
tick
end
Sample output of three runs
----------- fixed ------------- ===== -------- varies by run
66 68 42 59 14 1 34 20 3 15 86 "=====" 1 80 87 54 85 51 37 53 94 69
----------- fixed ------------- ===== -------- varies by run
66 68 42 59 14 1 34 20 3 15 86 "=====" 94 72 60 26 18 90 65 50 65 18
----------- fixed ------------- ===== -------- varies by run
66 68 42 59 14 1 34 20 3 15 86 "=====" 23 93 75 68 17 44 17 30 99 94

CPU and Memory Friendly Solution to Merge Large Matrix

For the following typical case:
n = 1000000;
r = randi(n,n,2);
(assume there are 0.05% common numbers between all rows; n could be even tens of millions)
I am looking for a CPU and Memory efficient solution to merge rows based on any common items (here integer numbers). A list of sample codes in Python is available here and a quick try to translate one into Matlab can be found here.
In my attempt they take ages (minutes to hours), so I am in favor of finding faster solution.
For the above example, the typical output should look like (cell):
{
[1 90 34 67 ... 9]
[35 89]
[45000 23 828 130 8999 45326 ... 11]
...
}
Note also that, I have tried to compile as mex but failed due to no-support for cell in Matlab-Coder.
Edit: A tiny demonstration example
%---------------------------------------
clc
n = 100;
r = randi(n,n,2); % random integers in [1,n], size(n,2)
%---------------------------------------
>> r
r =
82 17 % (1) 82 17
91 13 % (2) 91 13
13 32 % (3) 91 13 32 merged with (2), common 13
82 53 % (4) 82 17 53 merged with (1), common 82
64 17 % (5) 82 17 53 64 merged with (4), common 17
...
94 45
13 31 % (77) 91 13 32 31 merged with (3), common 13
57 51
47 52
2 13 % (80) 91 13 32 31 2 merged with (77), common 13
34 80
%---------------------------------------
c = merge(r); % cpu and memory friendly solution is searched for.
%---------------------------------------
c =
[82 17 53 64]
[91 13 32 31 2]
...
You need an index.
In Python, use a dict. In MATLAB - I'd not use MATLAB, because open-source is the future, and MATLAB is dying out.
But Python is quite slow. You can likely get a 10x speedup by using e.g. Cython to translate and optimize the code in C. Avoid using Python data types such as a list of int, because they are very memory intensive. numpy has memory-efficient arrays of integer.
If you get a new pair (a,b) you can use this dictionary to find existing items to merge. Then update the dict after the merge.
Actually for integers, you should use an array instead of a dict.
The trickiest part is handling the case when both a and b exist, but are large different groups. There are some neat optimizations possible here, if that isn't fast enough yet.
It's not clustering, but connected components.

Getting started with LibSVM for a particular case

I have read quite a lot about LibSVM library, but I would like to ask you for some advices in my particular case. The problem is that I have some 3D medical images (DCE-MRI) of a stomach. My goal is to perform a segmentation of a kidney, and find its three parts. Therefore, I need to train a classifier - I'm going to use SVM and neural network
Feature vectors:
What is available is the pixel (voxel) brightness value (I guess the value range is [0; 511]). In total, there are 71 frames, each taken every second. So the crucial feature of every voxel is how the voxel brightness/intensity is changing during the examination time. In my case, every part of a kidney has a different chart (see an example below), so the way how the voxels brightness is changing over the time will be used by the classifier.
Training sets:
Every training set is a vector of intensity value of one voxel (74 numbers). An example is presented below:
[22 29 21 7 19 12 23 25 33 28 25 5 21 18 27 21 11 11 26 12 12 31 15 15 12 29 17 34 30 11 12 24 35 28 27 26 29 22 15 23 24 14 14 37 241 313 350 349 382 402 333 344 332 366 339 383 383 379 394 398 402 357 346 379 365 376 366 365 360 363 376 383 389 385]
Summary and question to you:
I have many training sets consisting of 74 values from the range [0; 511]. I have 3 groups of voxels, which have a characteristic feature - the brightness is changing in the similar way. What I want to obtain is a classificator, which after getting one voxel vector with 74 numbers, will assess if the voxel belongs to one of these 3 groups, or to none of them.
Question: how to start with LibSVM, any advices? From what I know now is that I should transform input values to be from the range [0; 1] or [-1; 1]. I have many training sets prepared belonging to one of these 3 groups. I will be grateful for any advice, as I'm a newbie and I just need some tips just to start.
You can train and use you model like this:
model=svmtrain(train_label,train_feature,'-c 1 -g 0.07 -h 0');
% the parameters can be modified
[label, accuracy, probablity]=svmpredict(test_label,test_feaure,model);
train_label must be a vector,if there are more than two kinds of input(0/1),it will be an nSVM automatically. If you have 3 classes, you can label them using {1,2,3}.Its length is equal to the number of samples.
The feature is not restricted. It can be what ever you want.
However, you'd better preprocess them to make the results better. For example, you can change range[0:511] to range[0:1] or minus the mean of the feature.
Notice that the testset data should be preprocessed in the same way.
Hope this will help you!

Manual Wilcoxon Rank-Sum Test

My statistics professor wants us to perform a manual Wilcoxon Rank-Sum Test using Matlab. Unfortunately, I have no experience with Matlab whatsoever, and I have been discovering as I go along. In short, we are given a list of 24 paired observations:
33 53 54 84 69 34 60 34 50 56 64 50 76 47 58 63 55 66 58 43 28 80 45
55
66 62 54 58 60 74 54 68 64 60 53 59 61 49 63 55 61 64 54 59 64 46 70
82
I've gotten to the point where I have a matrix with the absolute differences in the first column, the sign of the difference (indicated by a 1 for positive and -1 for negative) in the second column and the rank of the difference (1 through 24) in the third column.
I am struggling with finding a quick and efficient way to "break the ties" between the differences of equal size and allocating the average rank to each of these differences. I expect that some loops and logical statements may be required, but I am having a hard time with them as I have no prior experience.
Any suggestions on how to do this would be much appreciated.
One way to average over the ranks for entries with matching differences is as follows:
irankavg=zeros(length(dp),1);
[dpu,ix,iclass]=unique(dp);
for ii=1:length(dpu)
irankavg(iclass(ii)==iclass) = mean(irank(iclass(ii)==iclass));
end
where dp is a column array that contains the differences

information about tiff image

iminfo of my image gives
FormatSignature: [73 73 42 0]
Offset: 264322
what is an offset?how this value comes?
It is the signature of a TIFF file. Matlab's way of saying "I endorse this file as TIFF".
Matlab detects the file type by itself, not from the extension. Change the extension to JPG or XYZ, you'll still open it as a TIFF file.
Edit:
This is for PNG for example :
137 80 78 71 13 10 26 10
GIF:
71 73 70 56 57 97 16 0
You can also use an hex editor, open the file, grab the first 8 bytes and convert it from hex to decimal.