Arduino engine indicator too slow

Hello,

I've been building an engine indicator. It works for low rpm steam engines, but I noticed 2 things, that slows down the indicator to the point of inoperability in higher rpms. The point is, that I also wan to use this indicator for ic-engines, which is just not possible at the moment.
There are 2 issues: Firstly, the 2.4" LCD screen burns 1-2 seconds for displaying the pV-graph (100 points have to be calculated). The display seems to consume considerable time as well as the loop calculations.
Secondly, the pressure transducer I use are the ones you can find on ebay (1/8 NPT 500 psi pressure transducer). The issue is they work in slow rpms (they have a lag of ~1-2miliseconds). 1ms for one signal times 100 signals per rotation means 100-200ms per rotation is the fastest it can do. It translates to 300-600rpm, which is already very optimistic, as the time lag of the sensor needs to be significantly smaller than the time between 2 neighboring of the 100 signals per rotation.

This is not a software question. My questions are:

  • Is another microcontroller with a higher frequency better suited for this project?
  • Where do I get a pressure transducer, with which I can create a pV-diagram up into the thousands of rpm (7000 max)

@Riccardo001

Your topic was Moved to it's current location / section as it is more suitable.

Could you also take a few moments to Learn How To Use The Forum.

Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.

Riccardo001:
There are 2 issues: Firstly, the 2.4" LCD screen burns 1-2 seconds for displaying the pV-graph (100 points have to be calculated). The display seems to consume considerable time as well as the loop calculations.
Secondly, the pressure transducer I use are the ones you can find on ebay (1/8 NPT 500 psi pressure transducer). The issue is they work in slow rpms (they have a lag of ~1-2miliseconds). 1ms for one signal times 100 signals per rotation means 100-200ms per rotation is the fastest it can do. It translates to 300-600rpm, which is already very optimistic, as the time lag of the sensor needs to be significantly smaller than the time between 2 neighboring of the 100 signals per rotation.

This is not a software question. My questions are:

  • Is another microcontroller with a higher frequency better suited for this project?
  • Where do I get a pressure transducer, with which I can create a pV-diagram up into the thousands of rpm (7000 max)

What do you mean by "the 2.4" LCD screen burns 1-2 seconds for displaying the pV-graph (100 points have to be calculated). The display seems to consume considerable time as well as the loop calculations."
This would be a software problem.
How often do you need to take data readings?

Can you post a block diagram of your system and your code please?

Thanks.. Tom... :slight_smile:

Riccardo001:
This is not a software question.

If the display is taking 1 or 2 seconds to update then it does sound like a software problem.

...R

.

Hi,
I presume you are aiming to produce a diagram like this;


This takes me back too many years to remember in Thermodynamics Class.

Tom... :slight_smile:

Tom George:
The pressure sensor is read every time the incremental encoder sends a pulse. The encoder gives 100 pulses per rotation.

Robin2:
It isn't a software problem in the sense, that it does, what it can. The code can't be made significantly faster, because there are calculations, that can not be moved out of the loop. And I also noticed the less the display needs to be updated, the faster it gets. Even if it's things, that don't need (hand-written) calculations, like many tft.print commands.

Tom George:
I'm not just aiming, as it fortunately already works. But it doesn't work in the high rpm range as well as the display updates take way too much time. I am now using a very, very basic display setup - only the numbers and the graph. Nothing fancy. BUT I want to implement a much more sophisticated display and many more functions to the indicator (dynamic display elements, multi-page display use,..). Which is why I suspect I might be better off with a raspberry or something faster.

The code and the manual for the already working indicator (with the limitations I mention and try to fix) is in this thread:

https://thesteamboatingforum.net/forum/viewtopic.php?f=8&t=1688

Search for the posts by "Steam Captain", which is me, and you can download the code and the manual to set it up and use commercially or non-commercially. I have the links in my signature there.

The point is maybe I COULD live with the lag between display updates (I disabled the encoder interrupts and it only reenables when the display is finished displaying, which eliminates any errors), but while the encoder is already tested up to 1750 rpm without the slightest skips, the story is a whole different one with the pressure transducer. The speeds just end up being too fast for it.

That is why I was asking if anybody knows faster pressure transducers maybe in the 50-100KHz sensor-reading region.

That is why I was asking if anybody knows faster pressure transducers maybe in the 50-100KHz sensor-reading region.

On the 16 MHz Arduinos, analogRead() normally takes about 110 microsceconds, but can be speeded up with selection of the adc prescaler.
https://www.gammon.com.au/adc

It appears that you are taking two analog reading in the 100 ppr interrupt

//Encoder Subroutine 1st level - ppr
/////////////////////////////////////////////
void blink1()
{
  a++;
  yaxis1[a]=analogRead(sensorPin1);
  yaxis2[a]=analogRead(sensorPin2);
}

I doubt that you can achieve the analog reading speed with the Mega your program is based on. You will need a different processor or an external adc converter.

Reading the sensor is independent from the sensor response, and how fast its internal electronics actually process the signal from the physical transducer which is responding to the pressure changes.

This pressure sensor looks interesting with a 10KHz internal sampling

High speed dynamic pressure sensing is not a simple matter, independent of your display issues.

The encoder gives 100 pulses per rotation.

How long does a rotation take?
Define "low RPM".
Define "high RPM.

You'd get better performance from, say, a Due but you do an awful lot of time-intensive TFT operations -- block fills for example -- that will pretty much always be a problem unless you can double-buffer the display and have access to DMA so that the actual updating of the display doesn't take away from CPU cycles reading and processing interrupts and reading ADC channels.

Have you characterized the math vs the TFT operations to see how much time is actually being spent doing one over the other?

A fast external ADC and perhaps a Raspberry PI would be a better option.

Riccardo001:
Robin2:
It isn't a software problem in the sense, that it does, what it can. The code can't be made significantly faster, because there are calculations, that can not be moved out of the loop. And I also noticed the less the display needs to be updated, the faster it gets. Even if it's things, that don't need (hand-written) calculations, like many tft.print commands.

I'm not convinced.

For example if you are sampling every revolution of the engine then there is no need to update the display every revolution - the human eye/brain could not keep up with that.

On the other hand if you want to display the data for a single revolution then you can suspend the data collection for the next several revolutions while the human is studying the data.

...R

cattledog: Thank you for the information. It sounds like the Arduino analogRead is slightly too slow for rpms in the thousands. Your remark about the difference between reading and the response of the sensor is something crucial I wasn't aware of.

JCA34F: As described further up, the indicator works well in the low hundreds rpms (order of magnitude for steam launch engines), but the thousands ("high" rpm - order of magnitude for IC-engines VERY generally speaking). So don't expect extremely specific numbers. It's more about the position of the period.

Blackfin: Yeah, I do a lot of TFT stuff and I actually wanted to expand it MUCH, much more (e.g. dynamic display graphics, fast display response (50-60Hz range) and more complex graphing, which doesn't happen with the Arduino. Yes, I actually have placed some code lines here and there to se how much time is spent on different parts of the code just to see who is the culprit. Surprisingly, the interrupts and the analogRead is not the problem. But I begin more and more to suspect the display as the main source of the lag. Yeah, I guess I need to migrate to raspberry or comparable, "real" computers. I was also thinking of combining the Arduino with a Raspberry, but I have to read into the matter more to see if the Raspberry can work well with interrupts and such.

Robin2: I understand your considerations, but the code is already programmed to update the display at every 10th rotation. The Z-channel pulse (once per rotation) gets counted and when it reaches 10, it's set to 0 and the display displays the data collected on the last complete rotation. That way I also remove errors, because the interrupts are enabled after the display is finished (and after a 2-second-delay for reading), regardless of the crank angle. That means when they are reenabled, the crankshaft angle is not known, because the new Z-channel pulse for top dead center didn't happen yet. That means the first rotation after the display-writing and waiting is useless. Effectively, only every 10th rotation gets displayed. Otherwise, you would be right of course. It doesn't make sense to display the data of every rotation. It happens just too fast.

For what I gather, I think I might look into the feasibility of the project with a Raspberry for later versions. Until now, it works, but just for steam engine rpms.

Run two processors. One watches the psi and does calculations. The other reads the results and updates the display.

Processors are cheap, its a quick solution. (I've used it myself)

-jim lee

Riccardo001:
Robin2: I understand your considerations, but the code is already programmed to update the display at every 10th rotation. The Z-channel pulse (once per rotation) gets counted and when it reaches 10, it's set to 0 and the display displays the data collected on the last complete rotation. That way I also remove errors, because the interrupts are enabled after the display is finished (and after a 2-second-delay for reading), regardless of the crank angle. That means when they are reenabled, the crankshaft angle is not known, because the new Z-channel pulse for top dead center didn't happen yet. That means the first rotation after the display-writing and waiting is useless. Effectively, only every 10th rotation gets displayed. Otherwise, you would be right of course. It doesn't make sense to display the data of every rotation. It happens just too fast.

Modern internal combustion engines operate very much faster than steam engines so I don't think it makes sense to update the display every 10 revs - the human eye could never keep up.

And if you are only viewing the data for occasional cycles I can't see any problem in missing the data for a cycle while the system catches up.

Plus what @jimlee said in Reply #11

...R

Use a faster processor. The Wemos D1 Mini and NodeMCU boards run at 80MHz.