Silver

Hello,

I have a thingSpeak project that requires some analysis. However, Matlab is totally foreign to me. I have been able to accomplish much of what I need but I'm stuck and would like some guidance.

I have a channel that has 8 fields and the values within those fields are zeroes or ones. I want to calculate for one specific day, and one specific field how much time the zeroes have been on. I cannot create a variable that contains the data points for just those zeroes such that I can then calculate the difference between the timestamps and then sum them. Here's what I thought would work but doesn't:

[data2,timestamps,chInfo] = thingSpeakRead(YYYYYY,'ReadKey','XXXXXX','Fields',[1],'DateRange',[datetime('Jan 21, 2017'),datetime('Jan 22, 2017')],'OutputFormat','timetable');

t=table2array(data2);

for i =1:1:60

if(t(i,1) == 0)

zerodata=[t(i,1),1;];

end

end

t1=diff(t.Timestamps);

t1a=cumsum(t1);

t2=max(t1a);

t2

I believe the statement defining zerodata is wrong, but I cannot fix it. Also, I am just trying 60 data points rather than all the data for that day.

Please excuse any stupid errors since I am trying to use Matlab without getting deeply into it.

Thank for any guidance you can give me.

I think you're looking for a feature in MATLAB called logical indexing.

All you need is the timetable that is in the variable data2 in your example. Assuming it looks something like this:

`data2 =
time field1 field2 field3
____________________ ______ ______ ______
23-Jan-2017 06:57:28 1 0 1
23-Jan-2017 07:57:28 0 0 1
23-Jan-2017 08:57:28 0 1 1
23-Jan-2017 09:57:28 0 1 1
23-Jan-2017 10:57:28 1 1 0
23-Jan-2017 11:57:28 0 0 0
23-Jan-2017 12:57:28 0 0 1
`

You can take the diff of the timestamps to get the duration between the timestamps, like you did

timeon = diff(data2.time);

Since diff returns one fewer rows than it's given, you'll need to decide what to do with the last row. If you just ignore it (which is simple), you'll need to "tack on" a duration of 0:

`timeon = [timeon;hours(0)]`

A more sophisticated solution would be to tack on the elapsed time since the last row was written.

OK, now you can use the logical indexing. With it, you only select the rows that meet your condition (in this case, where field1 == 0)

`timeon(data2.field1 == 0)`

ans = 5×1 duration array 01:00:00 01:00:00 01:00:00 01:00:00 00:00:00 Really, you want the sum though: sum(timeon(data2.field1 == 0))

ans = duration 04:00:00Repeat for the other fields:sum(timeon(data2.field2 == 0)) sum(timeon(data2.field3 == 0))

Hope this helps, -Rob

Senior Development Manager for IoT and Hardware Interfacing for MATLAB at MathWorks. Visit ThingSpeak.com to explore the IoT Analytic platform that speaks MATLAB made for engineers and scientists. You can collect, analyze, and act in 5 minutes or less!

Silver

Rob Purser saidtimeon = diff(data2.time);

OK, now you can use the logical indexing. With it, you only select the rows that meet your condition (in this case, where field1 == 0)

timeon(data2.field1 == 0)Rob,Thanks a lot for your help. One thing I don't understand: Doesn't the second equation listed above from your post go back to the original

data (ie data2) rather than use the difference data of equation one? Will I not get from timeon(data2.field1 ==0)the original data from data2 that has 0 in field 1 but not the difference in the timestamps? So shouldn't I do it this way then:

timeon(data2.field1 == 0)

then

timeondiff = diff(timeon.time)

BTW, when I run your code, I get message: Unrecognized variable name 'time'.

Of course my code doesn't run either!

What now?

Thanks again for your help.

Hi,

The timeon array contains the duration of time elapsed between each reading -- both the times that the condition was met, and the times when it wasn't.

This line does two things:

timeon(data2.field1 == 0)

1. It compare the contents of field1 in the data2 timetable with the value of 0. This produces a logical array of trues and falses identifying all the rows that met the condition (in this case, has a value of zero).

2. It then uses that logical array to select from the timeon array the only the periods of time when the condition was met. Now, you have an array of all the durations when the field1 value was 0. You can just sum them.

-Rob

Senior Development Manager for IoT and Hardware Interfacing for MATLAB at MathWorks. Visit ThingSpeak.com to explore the IoT Analytic platform that speaks MATLAB made for engineers and scientists. You can collect, analyze, and act in 5 minutes or less!

Silver

Well, I guess it is not quite perfect. At times, I get the following message:

Count =

966

Index exceeds matrix dimensions.

I then run it again later and all is well:

Count=

1023

etc

Here's my code. I have removed comment lines but left in lines that are never used in the code that could be removed but haven't been. Field1 is Boiler (with values of 0 or 1) and Field8 is dataNo (an index that counts the number of data points created by the Arduino but not necessarily transmitted for whatever reason).

readChannelID = xxxx;

BoilerFieldID = 1;

readAPIKey = 'xxxxxxx';

writeChannelID = xxx;

writeAPIKey = 'xxxxx';

[data2,timestamps,chInfo] = thingSpeakRead(xxx,'ReadKey','xxxxxx','Fields',[1,8],'NumMinutes',1440,'OutputFormat','timetable');

t=table2array(data2);

Count=max(data2.dataNo)

timeon = diff(data2.Timestamps)

Sum = sum(timeon(data2.Boiler == 0))

formatOut = 13; % sets output to HH:MM:SS see datestr description

TotalBoilerOn = datestr(Sum,formatOut) %convert to string

thingSpeakWrite(writeChannelID, {TotalBoilerOn, Count}, 'writekey', writeAPIKey); %{} needed to write nonnumeric data

I test it by running it every hour -everything is fine, then set it to every day and it sometimes gives that error.....Index exceeds matrix dimensions.

Can anyone explain?? Thanks for your help.

I can't see anything obvious by inspection. Can you add a few calls to disp() to try and figure out what line is failing?

Senior Development Manager for IoT and Hardware Interfacing for MATLAB at MathWorks. Visit ThingSpeak.com to explore the IoT Analytic platform that speaks MATLAB made for engineers and scientists. You can collect, analyze, and act in 5 minutes or less!

Silver

Rob Purser said

I can't see anything obvious by inspection. Can you add a few calls to disp() to try and figure out what line is failing?

I don't have a lot of experience with it, but I was thinking that since it printed "count' and a number and then said 'Index exceeds matrix dimensions' that the problem would be with the next statement that should have printed a result - that being the statement 'timeon = diff(data2.Timestamps)'. Would disp() tell me anything different? I suspect index means in this context the position within the matrix that is being referred to and then that position is larger than the matrix dimension. But I don't see anywhere that I'm doing that!

Thanks for your help.

Hi Doug,

You're absolutely right. I tried a few experiments to figure out what would cause the diff function to give that error, and didn't see anything obvious. Can you send me an email at rob.purser at mathworks.com, and we can try to figure it out another way?

Thanks,

-Rob

Most Users Ever Online: 114

Currently Online:

12 Guest(s)

Currently Browsing this Page:

1 Guest(s)

Top Posters:

rw950431: 224

Vinod: 134

vespapierre: 63

piajola: 62

chrisjmears: 54

turgo: 54

Newest Members:

eli

sally

Metabolicz

RodrigoSos

tjheikki

manimb54

Forum Stats:

Groups: 4

Forums: 17

Topics: 1124

Posts: 3994

Member Stats:

Guest Posters: 1

Members: 5293

Moderators: 0

Admins: 2

Administrators: Hans, lee