1

Edit3: As requested I'm going to be more specific about my issue, previous description is still below

A motor must not be activate more than MAX_TIME hours (20hours - consecutive or not) during a sliding time window of WINDOW_TIME hours (72hours). Every SAMPLE_TIME minutes (1minute), the software check if the motor must be ON or OFF. My idea was to create timestamp on rising/falling event of the motor state and store them in a buffer. This buffer will be evaluated every SAMPLE_TIME to check if the sum of the timestamp is not greater than MAX_TIME. Because of the sliding window, the buffer must also be updated to remove timestamp that are too old and add new ones.

I have limited memory (around 60bytes). I'm looking for somekind of algorithm that could be use to handle this problem (with an embedded approach if possible, at least for the memory footprint)

According to comments I should:

  • reduce the SAMPLE_TIME period to reduce the memory footprint of my buffers. If I evaluate the state of the motor every 10 minutes which is the maximum time for my application, I still have (72*60)/10 = 432 data to store if it's the worst case scenario and the motor is toggled ON and OFF every 10 minutes. It can be stored as bits (ON or OFF), so that's 54 bytes. Problem with this solution is that when the software check if the motor is ON, it might be the case, even if the last 9minutes it was OFF, and this will still count as 10minutes of motor activation

Previous description:

I have an embedded software project where I need to check if a motor was not activated too often during a time window. Every minute the program acquire data that tells if the motor must or must not be activated. During a 72hours time window, the motor should not be activated more than 20hours in total (it doesn't need to be 20hours consecutive), that's why I need to get a warning when this happens.

I'm using a microcontroler from Renesas (RL78) and I don't have any OS.

Since I have limited ressources and the time window is huge, I though of using somekind of timestamp. When the system activate the motor a timestamp is saved, and it's deactivated another timestamp is saved and it goes on. Once i reached the first 72 hours i can compute how long the motor was activated thanks to the multiple timestamps. The timestamps are erased when there are out of the window (since it's 'moving').

I guess there is something easier but I don't know where to start.

Edit1: I need to check if the 20hours period is reached within the 72hours, and if it's the case, set a flag.

Edit2: I have a really limited RAM size, around 60bytes available

Asmature
  • 11
  • 3
  • Start by defining your requirements more accurately, for instance is it "prevent it from being active for more than 20 hours" or "warn if it's been active for more than 20 hours"? – Finbarr Jul 03 '17 at 13:32
  • You fundamentally cannot store more state possibilities than you are willing to use memory to represent, so you may need to look at simplifying the requirement. Can you change to track things in terms of minutes run per hour? Worrying about precisely which minutes of the time unit spanning 19 to 20 hours ago seems unlikely to have significance. If you need to track more recent usage more precisely, you can dedicate memory to storing that and later compact to less detail. Or can you enforce some usage pattern, such as counting a minimum run time no matter how short a given run actually is? – Chris Stratton Jul 03 '17 at 13:33
  • Do note that storing 20 hours of records by minute would require 150 bytes of bitmap. Storing it by 2 minute intervals would require 75, and so on. – Chris Stratton Jul 03 '17 at 13:35
  • @ChrisStratton Surely you'd need to store 72 hours? That's 540 bytes of bitmap by minute. – Finbarr Jul 03 '17 at 13:37
  • And controller is having 5.5 KB of SRAM, seems to be really affordable. – Anonymous Jul 03 '17 at 13:38
  • @Finbarr - sorry, yes, misread. Some combination of a bitmap for recent hours and an hourly total for old ones and some smoothing may work. – Chris Stratton Jul 03 '17 at 13:38
  • This is more of a programming question than an electronics question. You would run a time loop in seconds or minutes. You would use two counter values to count seconds or minutes. One counter will always count up to 72 hours. The other counter will only count if the motor is running and see if it exceeds 20 hours in a fixed 72 hour period. If you need to evaluate if the run time exceeds 20 hours during any 72 hour period ( outside a fixed period) then than becomes more difficult and may require your time stamp idea. – Tinkerer Jul 03 '17 at 13:38
  • @Tinkerer that won't work - the time interval is constantly sliding. So first you need to evaluate the one starting at 9am 3 days ago, and then the one starting at 9:01 am, and so on - though hopefully this can be done is coarser time steps. – Chris Stratton Jul 03 '17 at 13:40
  • @ChrisStratton I think you have an answer - 540 byte shift register! – Anonymous Jul 03 '17 at 13:40
  • A large shift register would work if the storage can be dedicated, but there are likely optimizations - both compressing the older history to less minute-by-minute detail, and implementing at least the byte level as a circular buffer rather than constantly shifting all those bits. Though if mains power is available, and the CPU has little else to do, actually shifting the bits might save code space. – Chris Stratton Jul 03 '17 at 13:43
  • 540 bytes is too much, I'll need to get something around 50 bytes. To decrease the number of bytes needed, I will check every 10minutes i think then – Asmature Jul 03 '17 at 13:57
  • Then it really depends how often the motor is likely to be switched on and off and how accurate your 20 hours needs to be. Back to problem definition. – Finbarr Jul 03 '17 at 13:59
  • I edited the post and tried to be more specific. – Asmature Jul 03 '17 at 14:33
  • If you check every 10 minutes, you need to store 432 on/off values. You only need one bit for each, hence 54 bytes. That assumes you have enough code space to manipulate individual bits. – Finbarr Jul 03 '17 at 14:38
  • @Finbarr I need to store something like a timestamp in order to know when the motor was set, when it was stopped, so that i can compute the ON time. – Asmature Jul 03 '17 at 14:40
  • @Asmature, no, in the sampled schemes proposed you do not need to store a time stamp. That is implicit in the sample number stretching back from "now" - the 0th sample is current, the 1st is one sample interval ago, the next two intervals ago, etc. You should probably mark an interval as "on" if the motor was active at *any* point during it. On the other hand, if you make your sample periods very large (such as an hour) then you probably want to store the number of minutes run during that hour (potentially you can use 6 bit fields) for a hybrid scheme. – Chris Stratton Jul 03 '17 at 14:47
  • Oh ok I got it ! If I implement a circular buffer for that, I will just need to compute the sum of 'ON' states which will gave me the total time the motor was ON. When the first 72hours periods is reached, the data will be rewritten in the 0th sample and it goes on right ? Edit: If you have any idea of how i can still limit the memory footprint I'd like to hear about that ! – Asmature Jul 03 '17 at 14:53
  • Yes, you've got it. The challenge is going to be how you decide whether to flag a 10 minute period as on or off. If you flag it as on if it's actually only on for one minute out of those ten, you could flag a warning when you don't need to. – Finbarr Jul 03 '17 at 14:58
  • A neat optimisation is to ALSO keep a count of how many on bits you have in the buffer (initialise a count to zero, then every time you clock a new bit into the shifter subtract the value of the old bit you are replacing and add the value of the new bit. This way you are not constantly scanning the buffer, but instead just know how long the thing has been on during the length of the buffer. – Dan Mills Jul 03 '17 at 18:04

3 Answers3

1

You can probably get an equivalent functionality using a exponential moving average.

y[n]=αx[n]+(1−α)y[n−1]

Where α is your window.

X is >1 when the motor is on, and 0 when it's off. If X is >1 enough samples in the window time, Y will become true (>=1).

This can be calculated in fixed point maths by using factors of 2 for α. More details from the neighbours.

Note that a fixed point implementation might not yield a perfect 72000 seconds limit. But since you've given hours there is some flexibility.

Jeroen3
  • 21,976
  • 36
  • 73
0

Thanks to @Finbarr, @Chris Stratton and @Dan Mills, this is the solution i'm going to implement:

  • Every 10 minutes the system will check the status of the motor (ON or OFF), and write a bit in a circular buffer that stores the state of the motor over the 72h window.
  • A variable will keep track of the number of ON bit in this circular buffer so that instead of evaluation the content of the circular buffer every time, a single variable will store the number of 10 minutes activation of the Motor
  • The size of the circular buffer should be: (72*60)/10 = 432 bits (ON or OFF), that's 54 bytes + 2 bytes for storing the number of ON bits.

Drawbacks:

  • I won't sample the state of the motor every minutes, to save memory (54bytes instead of 540bytes). This means that every 10minutes, the state of the motor that is read assume the state of the motor for the last 10minutes. So if the motor was OFF for 9 minutes, but when the system check one minute later and the motor is ON, the system will think that the motor was ON for 10minutes.

Thanks for your help !

Asmature
  • 11
  • 3
0

There is no point in keeping the time in bits. Instead each hour has its own byte and you can sample every minute (so each our has a Max on value of 60) or each 15 seconds (a Max on value of 240) or anywhere in-between.

That way you need a Max of 72 bytes. Or you can pack more hours into one byte. Like one sample every 4 minutes so every byte for two hours. .....

dannyf
  • 4,272
  • 1
  • 7
  • 9
  • With your method, when the we need to rewrite the data on the first hour byte (after 72hours), the system must erase it before rewriting to it. If it checks every minutes then this means that there is a lost of 59 minutes of data and if there were evaluated might have raised the flag 'Motor is ON for too long now' – Asmature Jul 04 '17 at 12:09