517 lines for a single function? And you wonder why its slow?
I think the first plan of attack is to restructure loop() so that it is a just a few calls to functions than
manage a single input or output, then try to figure out where all the time is going - you use several
libraries and some of them appear to be I2C, so will take a little time anyway, but some of them
may be blocking libraries, which could be an issue.
You want loop to only call other functions when those functions have actual work to do, so its important
that you have a quick way to check for work for each of the things you are managing.
But most of them are just logic and simple math, reading the adc and output it using dac (this one need to be fast), do some calculation, do some encoder things, call lcd menus function every 100ms.
What do you mean by blocking libraries?, sorry english is not my native language.
Round-robin, you mean by sequencing it per loop?, adc0 first loop, adc1 second loop, etc...,
Yep, float calculation is slow, but what is the other way to do this then?
Ehm, one thing, i've been trying to comment the float computation and lcd, just counting up and down (outputting triangle waveform probably) using the dac, and it seems to be faster, but it's still pretty slow i think, i can still see the fluctuation with my multimeter, i don't have a scope there, so can't really conclude confidently
A blocking library waits for the hardware to finish, rather than returning immediately after sending the
request. Your key and encoder libraries might be doing debouncing by waiting, for instance.
Characterise the time each library call takes to see which is worst and work on that first.
Remember you can call micros() twice and take the difference to get a time accurate to 4µs
Have'nt checked the encoder and keypad, my guess is the ADS1115 and LCD that is blocking library, gonna try to characterise the time tomorrow,it's night there, thank you in advance
Always consider if you can use long ints by ‘multiplying’ the input values, do your processing, then ‘dividing’ back down to get the result.
There are several ways to approach this.
Manually keeping track of the decimal precision. It’s always an order of magnitude faster than ‘floats on the fly’ !
Remember numbers are just numbers.
Well, my guess is right it's the ADC and the LCD, the float was pretty slow too, here is the time characterization of the function in my sketch's loop
LCD : 146828 microseconds
4x ADS1115 Reading : 10640 microseconds
Float Computation : 1192 microseconds
Keypad : 340 microseconds
DAC : 176 microseconds
Encoder : 12 microseconds (without any event, probably still same even when there is an event though)
1 Loop total : 159212 microseconds
I think i'll optimize the float computation using method that 'lastchancename' suggest and i'll try to change the LCD Library, there are pretty lots of lcd library on google, but it's pretty hard to find ADS1115 library other than Adafruit, any suggestions?
EDIT : I've try pert suggestion, and the LCD takes 87740 microseconds, and using lcd.clear() instead of deleting each row using space improve the timing to 43716 microseconds.
A majority of the used time is spent on the LCD. Reconsider what information and how frequently You display it.
I once, 30 years ago, built a speed indicator to my car while the original was out of order and repairs were told to be costly. Updating the display every 500 mS felt like very good to me. Too less, jumping info, to often, an unneccessary flying and unreadable numbers.
Writing to the LCD probably puts the message into a buffer and interrupts handles the output of the message. But! If the buffer gets full the sketch will be hanging, waiting for free space in the buffer.
What do You think?
I have not anlyzed Your program deaply, only read Your report telling that LCD consumes a majority of the execution time. Read sensors, calculate, but display the results less frequently. You can probably inhibit some sensor work that happends more often than twice per second. Why read and calculate data more often then they can be read?
figoarzaki:
But still, if i write the LCD for every 500ms (or any interval else), there will always a time that the DAC slowed down by 43ms because of LCD.
That's where the advice comes in to only write what's changed to the LCD.
You can also split up your writes: Write some data, do other stuff, write some data, do other stuff, etc.
You know tings I don't know. Your first issue was to cut down 200 mS of loop time. I don't understand how "43 mS" can be an issue. I hope You don't call LCD during a loop for several ADC.
Perform the maintaining work, calculating outputs, read inputs when it's needed, and display data when they can be observed. Divide the display update in two parts if that would help.
pert:
That's where the advice comes in to only write what's changed to the LCD.
You can also split up your writes: Write some data, do other stuff, write some data, do other stuff, etc.
Probably this will increase the performance, gonna try it,
Did increasing the I2C frequency will make it faster?
Or do you have a faster I2C library?
Railroader:
You know tings I don't know. Your first issue was to cut down 200 mS of loop time. I don't understand how "43 mS" can be an issue. I hope You don't call LCD during a loop for several ADC.
Perform the maintaining work, calculating outputs, read inputs when it's needed, and display data when they can be observed. Divide the display update in two parts if that would help.
43ms will still be an issue, because the power supply needs to react fast on short circuited load,
The best way is using interrupt, but when i call DAC on interrupt the arduino freezes, Timer1 interrupt and 1000 microseconds. Any idea why?
wolframore:
Go to a cortex M0 :D. Especially for all the ADC reads and calculations.
Definitely will go faster, but it's not a good solution, because the pcb already use atmega328 footprint....
My knowledge is small regarding interrupts, timers, internal registers. Sometimes various libs use systemfunctions like this. Double use of the same resource leads to trouble. Maybe a more experienced member can comment the use of interrupt,
Do Yoi need to do all AD readings in every turn of loop? Can they be iffed regarding to what You are displaying for the moment? My guess….