# profile3.cpp

This sketch shows how to assign time to a custom category in the profiling system. There are three categories reserved for sketch use: TICKER_SKETCH0, TICKER_SKETCH1, and TICKER_SKETCH2; here we use just the first.

Calls on SFBTicker::pushTime(u32) and SFBTicker::popTime() must be properly matched, as in this sketch. (Be careful if you have `return` statements buried in the middle of functions!)

Typical output from this sketch in response to 'p' packets:

        p
        Ln 29.598 BG=89.28 SI=0.01 OI=1.60 PH=0.04 AH=0.34 S0=8.71
        p
        Ln 46.299 BG=89.30 SI=0.01 OI=1.60 PH=0.03 AH=0.34 S0=8.70

showing that over 8% of the time is now assigned to our 'sketch 0' category, while background still gets nearly 90%.

    // Demonstrate using a custom category with the 'Profile' profiling object
    //
    // This sketch is just a small extension to profile2.cpp

    void reportProfile(u8 *) {
      logNormal("BG=%f SI=%f OI=%f PH=%f AH=%f S0=%f\n",
                Profile.getPPM(TICKER_BACKGROUND)/10000.0,
                Profile.getPPM(TICKER_SERIAL_ISR)/10000.0,
                Profile.getPPM(TICKER_OTHER_ISR)/10000.0,
                Profile.getPPM(TICKER_PACKET_HANDLER)/10000.0,
                Profile.getPPM(TICKER_ALARM_HANDLER)/10000.0,
                Profile.getPPM(TICKER_SKETCH0)/10000.0);
    }

    void doWork(u32 when) {
      // Normally, time spent in this alarm handler would be assigned to
      // TICKER_ALARM_HANDLER.  But we'll assign it to SKETCH0 instead:

      Ticker.pushTime(TICKER_SKETCH0); // Start billing to a custom category

      // Here we just waste time with a busy loop.  (Note the 'volatile'
      // keeps the compiler from throwing away the whole loop!)
      for (volatile u32 i = 0; i < 100000; ++i) { }

      Alarms.set(Alarms.currentAlarmNumber(), when+250); // Run four times a second

      Ticker.popTime();                // Finished with our custom work
    }

    void setup() {
      Profile.begin();              // Start longer-term profiling system
      QLED.begin();                 // Let's use QLEDs to drive some alarm usage
      Body.reflex('p',reportProfile);
      Alarms.set(Alarms.create(doWork),millis()); // Create and schedule a worker
    }

    void loop() {
      // Spin the LEDs
      for (u32 i = 0, f = NORTH; i <= 3; ++i, f = CLOCKWISE_FACE(f)) {
        QLED.off(pinInFace(FACE_LED_PIN,f),i*80);      // First, increasing off time
        QLED.on(pinInFace(FACE_LED_PIN,f),100);        // then same amount of blink time
        QLED.off(pinInFace(FACE_LED_PIN,f),(3-i)*80);  // then decreasing off time to even up
      }

      // once per second
      delay(1000);
    }