1
\$\begingroup\$

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

\$\endgroup\$
19
  • \$\begingroup\$ 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"? \$\endgroup\$ Commented Jul 3, 2017 at 13:32
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ Commented Jul 3, 2017 at 13:35
  • 1
    \$\begingroup\$ @ChrisStratton I think you have an answer - 540 byte shift register! \$\endgroup\$ Commented Jul 3, 2017 at 13:40
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ Commented Jul 3, 2017 at 13:43
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ Commented Jul 3, 2017 at 18:04

3 Answers 3

1
\$\begingroup\$

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.

\$\endgroup\$
0
\$\begingroup\$

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 !

\$\endgroup\$
2
  • \$\begingroup\$ you should still accept one of these answer, even if it's your own! \$\endgroup\$ Commented Dec 1, 2018 at 20:29
  • \$\begingroup\$ Yup I should have done it sooner. Done \$\endgroup\$ Commented Dec 1, 2018 at 20:36
0
\$\begingroup\$

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. .....

\$\endgroup\$
1
  • \$\begingroup\$ 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' \$\endgroup\$ Commented Jul 4, 2017 at 12:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.