In this example (moving the procedure outside the void() loop) perhaps this would reflect how the code actually executes? bDataReady is set about every 250uS (4,000Hz sample rate).
//----------------------------------------------------------------------------
void GetData()
{
bDataReady = false;
ADXL355Data d;
accel.readData(d);
if (period_us < 1) {return;}
if (abs(d.x) > 128000) {return;}
if (abs(d.y) > 128000) {return;}
if (rpm < (TargetRPM - TargetRPMTolerance)) {return;}
if (rpm > (TargetRPM + TargetRPMTolerance)) {return;}
int32_t delta = sample_time_us - last_tach_time_us;
if (delta < 0) {return;}
if (delta >= period_us) {return;}
int index = (MAX_SAMPLES * delta) / period_us;
// add values to one of MAX_SAMPLES slots or bins in rotation period
sample_buffer[index].NumberOfSamples += 1;
sample_buffer[index].x += d.x;
sample_buffer[index].y += d.y;
// location in buffer with highest value should be angle location
}
//----------------------------------------------------------------------------
void loop()
{
if (bDataReady) GetData();
}
if the TargetRPMTolerance and targetRPM do not change (often)
and they are of the float data type,
you might pre-calculate them.
(float sub/add might be relative expensive)
if (rpm < minimumRPM) {return;}
if (rpm > maximumRPM) {return;}
void loop() {
if (!bDataReady) return;
bDataReady = false;
ADXL355Data d;
accel.readData(d);
// --- Gate checks --------------------------------------------------------
if (period == 0) return; // no tach yet
if (sample_time < last_tach) return; // sample before tach edge
if (rpm < (TargetRPM - TargetRPMTolerance)) return;
if (rpm > (TargetRPM + TargetRPMTolerance)) return;
...
I still don't understand why return; is allowed in loop().
Really illogic. What does it return to? loop() was not called and we certainly do not want to exit it. A google search says that loop() just starts a new iteration. Odd.
The only « issue » with return is that you don’t get a chance to do something else in the loop - so you kinda have a semi blocking conditional statement.
This is OK if there is really nothing else to do while you wait for the conditions to become OK but as a rule of thumb I tend to not return early and keep the loop going and reaching the natural end of the function.
For example say you get the idea to show a blinking led while waiting for the conditions or handle something else then you do want to give the loop a chance to do other stuff.
I would gather the conditions into a bool returning function to keep the loop code simple to read
inline bool systemIsReady() {
if (sample_time < last_tach) return false; // sample before tach edge
if (rpm < (TargetRPM - TargetRPMTolerance)) return false;
if (rpm > (TargetRPM + TargetRPMTolerance)) return false;
…
return true;
}
void action() {
…
}
void loop() {
if (systemIsReady()) action();
// here you can do other stuff
…
}
Not perse slowness, more that no matter which path the code takes, it is equal in duration and if possible even in power usage and heat dissipation (use equally complex math in the "false path"). Clearly a case where high security has a priority over performance.
/*
main.cpp - Main loop for Arduino sketches
Copyright (c) 2005-2013 Arduino Team. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <Arduino.h>
// Declared weak in Arduino.h to allow user redefinitions.
int atexit(void (* /*func*/ )()) { return 0; }
// Weak empty variant initialization function.
// May be redefined by variant files.
void initVariant() __attribute__((weak));
void initVariant() { }
void setupUSB() __attribute__((weak));
void setupUSB() { }
int main(void)
{
init();
initVariant();
#if defined(USBCON)
USBDevice.attach();
#endif
setup();
for (;;) {
loop();
if (serialEventRun) serialEventRun();
}
return 0;
}