2

I working on a project where I want to collect sensor data (from a sensor) and I want to analyze the first 20 data sample (e.g., find the range, trendline e.t.c.). I know how to compile a timer interrupt in Arduino IDE (using an ISR timer), but how would I be able to do this something similar (ISR timer) in MATLAB. The reason being, I want to collect my sensor data at exactly 20 Hz and using a delay function can prove to be inaccurate. Also, when I run a sample program that collects data in MATLAB, my sample frequencies change from 15Hz to even 24Hz (as shown below) . Does anyone have any suggestion on how I can do this? If the question is not clear enough I can elaborate more in the comments.

This is my MATLAB code:

clear all;
a = arduino('com4', 'uno');
i = 0;
v1 = zeros(1e4,1);
v2 = zeros(1e4,1);
x = zeros(1e4,1);
t = timer('TimerFcn', 'stat=false; disp(''Timer!'')',... 
                 'StartDelay',5,'Period', 1);
start(t)

stat=true; tic while(stat==true) %while i<60 i = i + 1; v1(i) = readVoltage(a, 'A0'); v2(i) = readVoltage(a, 'A1'); x(i) = i; disp(x(i)); pause(.00001);

% end end toc

% %Plot voltage versus time v1 = v1(1:i); v2 = v2(1:i); x = x(1:i);

p = v1; n = v2; %Plot voltage versus time figure(1); plot(x,p,'-',x,n,'-') xlabel('Elapsed time (sec)') ylabel('v') title('Ten Seconds of voltage Data') %set(gca,'xlim',[t(1) t(i)]) legend('v1', 'v2');

% delete(t) % Always delete timer objects after using them.

Output is

>> Timer
     1
 2

 3

 4

 5

 6

 7

 8

 9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

Timer! 76

Elapsed time is 5.032553 seconds. >>

I apologize for the long output. But as you can see, I specified a pause time of .00001, which should give me well over a 20Hz sampling frequency. But I only get 76 samples/5 seconds = 15.2Hz. Also, sometime when I run this the program may collect 79sample/5secons, or even 121sample/5seconds. It just is not consistent. I was hoping to solve this with a timer interrupt that will be hard coded in MATLAB to collect data at exactly 20Hz. Please let me know what y'all think. Thank you.

2 Answers2

1

I've configured the timer differently making use of its UserData property. The timer will update the data every fixed period for a specified number of samples.

close all;
clear all;

% Some useful constants. NUM_SAMPLES = 20; PERIOD = 0.05;

global a; a = arduino('com4', 'uno');

% Initialise data. It will be updated by the timer. data.i = 0; data.v1 = zeros(NUM_SAMPLES, 1); data.v2 = zeros(NUM_SAMPLES, 1); data.x = (1:NUM_SAMPLES) * PERIOD;

% Initialise timer for a fixed period for a specific number of samples. t = timer; t.ExecutionMode = 'fixedRate'; t.Period = PERIOD; t.TasksToExecute = NUM_SAMPLES; t.TimerFcn = @TimerCallback; t.UserData = data;

% Run the timer and wait for it to complete. start(t); wait(t); stop(t); data = t.UserData; % Retrieve the updated data. delete(t);

% Plot voltage versus time. figure(1); plot(data.x, data.v1, '-', data.x, data.v2, '-'); xlabel('Elapsed time (s)'); ylabel('Voltage (V)'); title('Voltage Data'); st = sprintf("%0.3f seconds", NUM_SAMPLES * PERIOD); subtitle(st); legend('v1', 'v2');

function TimerCallback(obj, event) global a; obj.UserData.i = obj.UserData.i + 1; obj.UserData.v1(obj.UserData.i) = readVoltage(a, 'A0'); obj.UserData.v2(obj.UserData.i) = readVoltage(a, 'A1'); end

tim
  • 699
  • 6
  • 15
0

Each communication with Arduino takes 20ms, you have two in the loop so in the ideal conditions you could get 25 readings/second. See here the source

This also depends on the size of the data you request.

I think this is what you are looking for but I cant give you any advice since I don't have Matlab and Octave is not having this feature.

Dorian
  • 369
  • 2
  • 10