Servo.write stops working for no reason, please help

I have the following code to read data from a serial bus and write to some servos, and for no reason i can find, the servo write just stops working after a few mins.

/*
 * Fly Sky IBus RC system to ESC and servo.
 */

#include <Arduino.h>
#include <inttypes.h>
#include <Servo.h> 

Servo aiServoM, elServo, thServo, ruServo, aiServoS;  // create servo object to control a servo 

#define DEBUG

enum State
{
  GET_LENGTH,
  GET_DATA,
  GET_CHKSUML,
  GET_CHKSUMH,
  DISCARD,
};

static const uint8_t PROTOCOL_LENGTH = 0x20;
static const uint8_t PROTOCOL_OVERHEAD = 3; // <len><cmd><data....><chkl><chkh>
static const uint8_t PROTOCOL_TIMEGAP = 3; // Packets are received very ~7ms so use ~half that for the gap
static const uint8_t PROTOCOL_CHANNELS = 10;
static const uint8_t PROTOCOL_COMMAND40 = 0x40; // Command is always 0x40

uint8_t state;
uint32_t last;
uint8_t buffer[PROTOCOL_LENGTH];
uint8_t ptr;
uint8_t len;
int16_t channel[PROTOCOL_CHANNELS];
uint16_t chksum;
uint8_t lchksum;

bool ledState=false; int ledDivider=0;

void FlySkyIBusloop(void)
{
  while (Serial.available() > 0)
  {
    uint32_t now = millis();
    if (now - last >= PROTOCOL_TIMEGAP)
    {
      state = GET_LENGTH;
    }
    last = now;
    
    uint8_t v = Serial.read();
    switch (state)
    {
      case GET_LENGTH:
        if (v <= PROTOCOL_LENGTH)
        {
          ptr = 0;
          len = v - PROTOCOL_OVERHEAD;
          chksum = 0xFFFF - v;
          state = GET_DATA;
        }
        else
        {
          state = DISCARD;
        }
        break;

      case GET_DATA:
        buffer[ptr++] = v;
        chksum -= v;
        if (ptr == len)
        {
          state = GET_CHKSUML;
        }
        break;
        
      case GET_CHKSUML:
        lchksum = v;
        state = GET_CHKSUMH;
        break;

      case GET_CHKSUMH:
        // Validate checksum
        if (chksum == (v << 8) + lchksum)
        {
          // Execute command - we only know command 0x40
          switch (buffer[0])
          {
            case PROTOCOL_COMMAND40:
              // Valid - extract channel data
              for (uint8_t i = 1; i < PROTOCOL_CHANNELS * 2 + 1; i += 2)
              {
                channel[i / 2] = buffer[i] | (buffer[i + 1] << 8);
              }
              break;

            default:
              break;
          }
        }
        state = DISCARD;
        break;

      case DISCARD:
      default:
        break;
    }
  }
}

void setup() 
{
  Serial.begin(115200);

  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
  
  // servo setup
  aiServoM.attach(7); aiServoM.writeMicroseconds(1500);
  elServo.attach(8); elServo.writeMicroseconds(1500);
  thServo.attach(9); thServo.writeMicroseconds(1000);
  ruServo.attach(10); ruServo.writeMicroseconds(1500);
  //aiServoS.attach(11); aiServoS.writeMicroseconds(1500);
#ifdef DEBUG
  Serial.println("Setup done");
#endif
}

void loop() 
{
  FlySkyIBusloop();

#ifdef DEBUG
  Serial.print(" 0:"); Serial.print(channel[0]);
  Serial.print(" 1:"); Serial.print(channel[1]);
  Serial.print(" 2:"); Serial.print(channel[2]);
  Serial.print(" 3:"); Serial.print(channel[3]);
/*  Serial.print(" 4:"); Serial.print(channel[4]);
  Serial.print(" 5:"); Serial.print(channel[5]);
  Serial.print(" 6:"); Serial.print(channel[6]);
  Serial.print(" 7:"); Serial.print(channel[7]);
  Serial.print(" 8:"); Serial.print(channel[8]);
  Serial.print(" 9:"); Serial.println(channel[9]);
  */
  Serial.println();
  
#endif

  aiServoM.writeMicroseconds(channel[0]==0 ? 1500 : channel[0]);
  elServo.writeMicroseconds(channel[1]==0 ? 1500 : channel[1]);
  thServo.writeMicroseconds(channel[2]==0 ? 1500 : channel[2]);
  //ruServo.writeMicroseconds(channel[3]);
  //aiServoS.writeMicroseconds(channel[4]);

  if(++ledDivider>10) {
    // blink at 500mS
    digitalWrite(LED_BUILTIN, ledState = !ledState);   // turn the LED on/off
    ledDivider=0;
  }
  delay(20);
}

i know the loop continues to run, the serial monitor is showing valid data and the LED is blinking at 1Hz

but all the servos and ESC just stop randomly after a few seconds, and don’t restart without a reset

if doesn’t see to be related to input for anything, if i leave the input alone in the neutral position it still happens

any thoughts about how i might debug the servo code?

thanks

I just tried patching out all but one servo write per loop and same problem

I also tried a longer loop time but that didn’t help

UPDATE, i just tried the sweep program and that seem to re running OK for about 5 mins so far, so seems like a software thing

ok, i worked it out, i was getting a memory corruption problem because if this line
buffer[ptr++] = v;

i guess something on serial data was incrementing ptr out of bounds, so i added a test

if(ptr<0 || ptr>=PROTOCOL_LENGTH) {
          Serial.println("BAD PTR");
          state = DISCARD;
          break;
       }

and it seems ok now

the moral of the story is, don’t assume code you download (ibus read code) works perfectly, check it out first