Aquarium light timer problems

Good afternoon. The goal is to make an LED lamp control for an aquarium based on Arduino nano.
We have:
Arduino nano - 1 pc
LSD display L2S - 1 pc.
Keypad of 5 buttons - 1 pc
real time clock - 1 piece
4 digital PWM outputs to control the light drivers of the Wite+RGB.

Sample program: 7 time segments, with adjustment for each channel of the PWM signal strength + 8 time segment - night. Ability to turn on the light manually.

The ideal option is the ability to configure the program to turn on and off, as well as the power of the lamps with a keypad slop, without flashing the arduino.

Everything was implemented in the program, except for the external settings of the device, however, with full control of the PWM signal of each line, the weight of the program exceeds 38 kb.
I ask for help - how can I facilitate this algorithm?
In the attached file ā€œ1-aqua-lightā€ -cropped sketch
1-aqua-light-copy- complete sketch (too big)


Blank progekt.xodball (278.3 KB)

Arduino memory is very limited, especially if you use one of the smaller options. Select patch and anything with strings is going to use quite a bit of that memory.

One option to reduce memory is to have fewer time segments. If part of the reason you have so many is so you can slowly make lights brighter/dimmer, maybe you could use fade instead of having so many time segments. The fade node would go between the select and pwm nodes. It might not work for your use-case, but it is something to consider.

If you are trying to simulate a day, you might be able to calculate the desired brightness based on time-of-day instead of using select. Based on just hour-of-day, turn lights off if it is before dawn or after dusk, else fade to full-bright over X hours if it is before noon, else fade to full dark over X hours if it is after noon. The down-side of this is it wonā€™t work well the first day if you start the cycle during daylight hours. You might be able to work out a formula to calculate brightness based on time-of-day (maybe one formula for use before noon, and a different formula for use after noon).

Any time you have this:
image
You are wasting memory. You are just converting true/false to true/false, so it is not needed.

You are also feeding analog-read to discretize to debounce. This forces discretize to re-calculate every time there is a slight variation from analog-read, even if debounce ends up ignoring it. It wonā€™t save you any memory, but it will likely free up CPU cycles if you feed analog-read to debounce, then to discretize.

It wonā€™t free up much memory, but you are using true-to-pulse conversion node. This is the same thing as the built-in pulse-on-true node, and in fact is the default action if you connect a boolean output to a pulse input, so usually it is not needed.

Since ACT pin on your pwm-load nodes is always true, you might be able to free up a few bytes using this instead:
image

Using the final concat to add percent symbol instead of having additional concat nodes in to-percent nodes might save you some memory since the strings will not need to be copied as often. The final concat might look like this:
image

Using a combination of techniques, you might be able to get your program to fit into the available memory. If you want all seven time-segments and to display strings, you might have to switch to an Arduino model with more memory.

1 Like

Thanks for the info!
what do you mean by ā€œSelect patch and anything with strings is going to use quite a bit of that memoryā€? I didnā€™t quite understand you.

about the idea of ā€‹ā€‹smooth regulation to full power and back - this option will not work - it will be extremely difficult to match the power to the clock - this lamp is not decorative in nature - it is precisely for regulating the life of aquatic organisms. Therefore, 8 time periods seem to be the minimum allowable (as it happened in practice).

ā€œif-elseā€ used the function to forcibly activate the ā€œmanualā€ mode - Iā€™ll try to bypass it with another hitch.

on the button - Iā€™ll try to simplify.

ā€œPVM-Vriteā€ and ā€œconkatā€ - I understand - Iā€™ll try it.

In general, there is a strong feeling that it is possible to remove all the constructions ā€œmoreā€ ā€œlessā€ except for one and change the parameters of time conditions and powers on it from the condition ā€œfalseā€ or ā€œtrueā€, but I just canā€™t figure out how to get around this.
Thanks for the info!
what do you mean by ā€œSelect patch and anything with strings is going to use quite a bit of that memoryā€? I didnā€™t quite understand you.

about the idea of ā€‹ā€‹smooth regulation to full power and back - this option will not work - it will be extremely difficult to match the power to the clock - this lamp is not decorative in nature - it is precisely for regulating the life of aquatic organisms. Therefore, 8 time periods seem to be the minimum allowable (as it happened in practice).

ā€œif-elseā€ used the function to forcibly activate the ā€œmanualā€ mode - Iā€™ll try to bypass it with another hitch.

on the button - Iā€™ll try to simplify.

ā€œPVM-Vriteā€ and ā€œkonkatā€ - I understand - Iā€™ll try it.

In general, there is a strong feeling that it is possible to remove all the constructions ā€œmoreā€ ā€œlessā€ except for one and change the parameters of time conditions and powers on it from the condition ā€œfalseā€ or ā€œtrueā€, but I just canā€™t figure out how to get around this.

So letā€™s get started. current program size 38230 bytes

You are using ā€˜selectā€™ nodes to chose brightness of each color at each timer. These nodes use quite a bit of RAM. Strings (what is used to store values for ā€˜concatā€™ node and display on LCD) also use quite a bit of RAM.

It does seem like there should be an easier/better way to determine which timer should be active, but Iā€™m not sure there is if they are ā€œrandomā€ times. If they are fairly evenly spread throughout the day, you might be able to take hour-of-day, subtract sunrise time, then divide by <hours at each brightness (which could be a fraction like 1.75 for an hour & 45 minutes)> to get equally-divided times throughout the day to make changes. Then instead of ā€˜selectā€™, you could use nth-input to choose the brightness. If nth-input canā€™t handle fractional numbers, you can use ā€˜floorā€™ to convert to an integer.

Oh, I got it! Select really eats up a lot of memory.
So far, I have changed PWM load to PWM record, split the conversion into percentages and combined everything into 1 concat.
The size of the program has been reduced to 35520 bytes.

As for the light - Iā€™m afraid that the intensity will become less predictable - usually edits are made in this or that situation like ā€œMove 100% peak by half an hour in the evening, reduce the intensity by 50% by half an hour in the afternoon and an hour in the afternoon.ā€ Approximate work schedule of another lamp (it is clear that the ranges were already ruled once"

Something you can try to see if it reduces memory:
Use a single select statement to determine time-range. Have it output index 0 if you are before your 1st timer, 1 for your 1st timer, 2 for 2nd timer, etc. and 8 for past last timer (using your above example with 7 on-times).

Now use the output of that to provide index input for 4 ā€˜nth-inputā€™ nodes to provide the intensity values for your 4 colors.

Logically, it doesnā€™t make much sense that this would save memory, but it might if select uses a lot more memory than nth-input.

You could also get rid of the select completely (and some of the ā€˜andā€™ nodes) by using cascading if-else:
image
Kind of ugly by the time you get all 8/9 conditions, but might use less memory, and might even use less CPU since you are not comparing most timer values twice. The last if-else-F would just be your last index (which could be a repeat of the 1st index when all lights are off).

1 Like

Looks interesting! Iā€™ll try tomorrow already - for today my head is already boiling ā€¦ reduced to 32908 bytes ā€¦
Thanks for the help!
Blank progekt.xodball (484.3 KB)

Good evening! The cascade idea worked! The only thing is that I weighed it down a bit.

Of the minuses - returned the old button. For some reason, when using ā€œdigital readā€ ā€œtrueā€ ā€œfalseā€ change continuously, constantly switching the mode ā€œmanualā€ ā€œAutomaticā€, which is unacceptable.

Also from the tangible disadvantages - compiling the program code before writing it to the arduino takes 4-5 minutes! (The problem disappears if you remove the real time clock from the program).
However, after 4 minutes the program is still recorded and takes up 23540 bytes.

Iā€™ll try to separate the cascade from the conversions and PWM modules - maybe this will somehow help.

Since there is still space left, Iā€™ll try to figure out how to write parameters from the device using the touchpad - maybe something will come of this.

Š¤Š°Š¹Š» ŠæрŠøŠ»Š°Š³Š°ŃŽ "1-aqua-light-copy2
Blank progekt.xodball (499.9 KB)
"

ā€œFor some reason, when using ā€œdigital readā€ ā€œtrueā€ ā€œfalseā€ change continuouslyā€

How do you have the button wired? Does it have a pull-down resistor so the value doesnā€™t float when the button is not pressed?

this is a keypad shield of 5 buttons - resistors should be built in by default.

I doubt that is supposed to use digital-read. Since there is only one output for 5 buttons, you are probably supposed to use analog-read and the level of output tells you which button is pushed (if any). Pushing multiple buttons can cause issuesā€¦

so it was - I planned to use the shield to manually set the timestamps and the power of the PWM signals, but when there was an extreme lack of space, I changed the function to ā€œbuttonā€, removing the definition of the pressed button and leaving the only purpose - to turn on the light in manual mode. Now, thanks to you, about 6kbytes of space have appeared - I will again try to implement the manual configuration functionality

I got into a dead end ā€¦ I seem to understand that I need to use the ā€œaccumulatorā€ function to accumulate and record the time and power values that I need, but at the same time I donā€™t understand at all how to set up switching the desired position from 8 time options to the required one when the button is pressed

  1. Not sure this is the way you want to go if ā€œADDā€ will be based on a trigger from timers. Rather than adding to increment through timers, it should be hard-set to correct time-frame based on time.

  2. If you do want to increment through, your code should work if you add 1 instead of 0.

  3. If you do want to increment through, using a ā€˜countā€™ node instead of add/select/buffer would probably be a better option
    image

Most likely I did not express myself correctly.
The general functionality of the buttons is to add the ability to manually correct time markers during the operation of the Aquarium - shift by an hour, and so on, as well as correct the power of the PWM signal - also without turning off and flashing the arduino.

On purchased analogues, this is carried out by switching through all these parameters in the order of priority and editing the numbers ā€œplusā€ and ā€œminusā€, after sorting through all the data, the program is updated and works taking into account the edits.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.