Spark Core Execution Speed

@zach There’s no doubt you have made it easy for the user, that work is clearly visible :wink:

Perhaps make some background goals to achieve at least the performance of the Arduino Uno as far as speed goes. I’m pretty sure the digitalWrite() execution time is already faster. I remember the Arduino taking 3 to 5 microseconds to set a pin high or low. It might not be possible to whittle that loop() delay down to nothing, but certainly there is room optimize it like you said. Giving the user a way to bit bang pins would be sweet with the speed of the STM32.

I will agree with @ScruffR as well that a way to know when the long background tasks were about to occur would be goo to know. A way to temporarily disable them would be nice as well, like disabling interrupts for time critical routines.

Can you tell me what the longest blocking delay might be for the background tasks?

I haven’t used FreeRTOS in any of my embedded designs, so I can’t speak too much for it… but my gut tells me it will suck up a lot of RAM and real-time in trade for convenience. In the Arduino it’s already pretty easy to roll your own state machine or timed processes without much effort. You just need to provide some decent examples like this one for timed processes.

//----------------------------------------------------
// Temperature filtering with a 1/16th Dilution Filter
// BDub 12-21-2013 tested and working on Spark Core
//
// 1/16th of the new reading gets added to the ongoing 
// running total of 16 virtual readings, with a little 
// correction for the truncation process.  Very fast 
// filter for slow 8-bit uC's that don't have multiply 
// or divide instructions.
//
// avg = (new + (avg * 16) - avg +/- offset) / 16;
// avg = (new + (avg * 15) +/- offset) / 16;
//----------------------------------------------------

uint8_t TEMP_PIN = A0;
uint8_t LEDPIN = D7;
uint8_t DEBUG = false;
uint16_t rawTemp = 0;
uint16_t avgTemp = 0;
int16_t offset = 0;
uint32_t lastTime = 0;
uint8_t msCounter = 0;
uint16_t threshTEMP = 2048; // approx. 3.3V/2

// The larger the update interval, the heavier the filter will be.
uint32_t UPDATE_INTERVAL = 10; // in milliseconds

void setup()
{
  // for debug
  if(DEBUG) Serial.begin(115200);                   
  pinMode(TEMP_PIN, INPUT);
  pinMode(LEDPIN, OUTPUT);
  // seed the average reading
  avgTemp = analogRead(TEMP_PIN);
}

void loop() {
  // Update the filter every 10ms (default)
  if(millis() - lastTime > UPDATE_INTERVAL) {
    // Set a new last time
    lastTime = millis();
    
    // Read the temperature input
    rawTemp = analogRead(TEMP_PIN);
    // Add or subtract the offset based on new reading
    if(rawTemp >= avgTemp)
      offset = 15;
    else
      offset = -15;
    // Filter the ADC every 10 ms (will resolve in approx. 740ms worst case 0-5V)
    avgTemp = (uint16_t)((rawTemp + (avgTemp << 4) - avgTemp + offset ) >> 4);
    // You can see this is a fast way to multiply by 15.
    
    // Debug
    if(DEBUG) {
      Serial.print("RAW: ");
      Serial.print(rawTemp);
      if((rawTemp > 99) && (rawTemp < 1000))
        Serial.print(" ");
      else if((rawTemp > 9) && (rawTemp < 100))
        Serial.print("  ");
      else if(rawTemp < 10)
        Serial.print("   ");
      Serial.print(" AVG: ");
      Serial.println(avgTemp);
    }
    
    // Process Temperature Reading every 100ms
    // Every time through is 10ms, 10 x 10ms = 100ms.
    if(++msCounter > 10) {
      msCounter = 0;

      // If temperature is above thresh, light the LED
      if(avgTemp > threshTEMP) {
        digitalWrite(LEDPIN,HIGH);
      }
      // else keep the LED off
      else {
        digitalWrite(LEDPIN,LOW);
      } 
    } // End inner timing loop (100 ms) 
  } // End outer timing loop (10 ms)
} // End main loop (currently runs every 5-6 ms