• I think you just want:

        JsSysTime period = jshGetTimeFromMilliseconds(10);
        jstExecuteFn(notifTimerCB, NULL, jshGetSystemTime()+period, 0);

    Setting a period will make the timer keep calling the function (like setInterval). Also the first call would have been scheduled right away.

    You could then avoid jstStopExecuteFn unless you're calling sendNotifBuffer direct from addCharToNotif when startNotifTimer has already been called.

    I'd also forget about notifBuffer - the characters should already have been pushed onto the FIFO so you could just pull them off of there when you're ready to send. For now it might be worth commenting out the notifBufferPnt >= notifBufferSize as it should work without it and it avoids complexity :)

    Realistically the polling interval for BLE connections will be something like 20ms, so having a 10ms delay really isn't going to slow anything down too much - in fact in 50% of cases it'll have no effect at all :)

    So I'd say something like:

    bool inNotif = false;
    void notifTimerCB(){
      char buf[BLE_NUS_MAX_DATA_LEN];
      int idx = 0;
      int ch = jshGetCharToTransmit(EV_BLUETOOTH);
      while (ch>=0) {
        buf[idx++] = ch;
        if (idx>=BLE_NUS_MAX_DATA_LEN) break;
        ch = jshGetCharToTransmit(EV_BLUETOOTH);
      if (idx>0) {
        if(uart_gatts_if != ESP_GATT_IF_NONE){
      } else { // no data to transmit
        inNotif = false;
    void startNotifTimer(){
        inNotif = true;
        JsSysTime period = jshGetTimeFromMilliseconds(10);
        JsSysTime time = jshGetSystemTime();
        jstExecuteFn(notifTimerCB, NULL, time+period, period);
    void jshUSARTKick(IOEventFlags device) {
      if (device == EV_BLUETOOTH) {
        if(!inNotif) startNotifTimer();

Avatar for Gordon @Gordon started