Servo Filter Jitter - Attiny85

Hello,
I am currently trying to make a servo filtering system that takes the PWM output of a receiver channel (throttle) and check if it is below the neutral point aka braking and then output that to the servo and anything above neutral isn't sent to the servo. The servo jitters around, however it does the overall function but not very precisely.

I have tried using interrupts for reading the PWM from the receiver to try to get a more accurate reading of the timing and that didn't work either (I originally used pulseIn). I think it is down to the 4us accuracy of the micros() function and that is then amplified when being sent out from the attiny as that also uses the micros() function for the PWM timing.

Here's the code I am currently using, this is currently the most jitter-free code I have. Using the difference filter of 8us.

#include <EEPROM.h>

/************ Pin assignments ************************************************/

/* DIP  PRT  PCINT   EXT   SYS    TIME  ANLG   PWM1  PWM0  USI   TWI  PROG  APP
 * ----------------------------------------------------------------------------
 *   1  PB5  PCINT5        RESET        ADC0                          dW    
 *   2  PB3  PCINT3        XTAL1  CLKI  ADC3  _OC1B                         
 *   3  PB4  PCINT4        XTAL2  CLKO  ADC2   OC1B                         
 *   4                     GND                                              
 *   5  PB0  PCINT0        AREF         AIN0  _OC1A  OC0A  DI    SDA  MOSI  
 *   6  PB1  PCINT1                     AIN1   OC1A  OC0B  DO         MISO  IR LED
 *   7  PB2  PCINT2  INT0         T0    ADC1               USCK  SCL  SCK   Rx in
 *   8                     VCC                                              
 *
 */

#define RecieverIn 0 // physical pin 7
#define ServoOut 1 // physical pin 6
#define Switch A1 // physical pin 5
#define NEUTRAL_ADDRESS 0

unsigned long NeutralPosition = 0;
unsigned long RecieverDuration = 0;
unsigned long LastRecieverDuration = 0;

void setup() {
  // put your setup code here, to run once:
  pinMode(RecieverIn, INPUT);
  pinMode(ServoOut, OUTPUT);
  pinMode(Switch, INPUT_PULLUP);
  
  if (ReadLong(0) != (0 || 0xFFFFFFFF)) { // Check if it isn't an unset value.
    NeutralPosition = ReadLong(NEUTRAL_ADDRESS); // Read from EEPROM.
  } else {
    NeutralPosition = 1500; // Rough guess.
  }
}

void loop() {
  RecieverDuration = pulseIn(RecieverIn, HIGH);
  
  if (RecieverDuration < NeutralPosition && abs(RecieverDuration - LastRecieverDuration) > 8) { // Filter with 8us difference. Will reduce reaction speed of the thing. 4us diff in, 4us diff out
    writeServoPulse(ServoOut, RecieverDuration);
  }
  
  if (digitalRead(Switch) == LOW) { // Might change this to direct register to speed it up a bit.
    NeutralPosition = RecieverDuration;
    WriteLong(NEUTRAL_ADDRESS, NeutralPosition);
  }

  LastRecieverDuration = RecieverDuration;
}

// PINB to read
// PORTB to write

void writeServoPulse(int pin, unsigned long delay) {
  PORTB |= (1 << pin);
  unsigned long start = micros();
  while (micros() - start < delay) {}
  PORTB &= !(1 << pin);
}

// Taken from http://playground.arduino.cc/Code/EEPROMReadWriteLong

void WriteLong(int address, unsigned long value) {
      //Decomposition from a long to 4 bytes by using bitshift.
      //One = Most significant -> Four = Least significant byte
  byte four = (value & 0xFF);
  byte three = ((value >> 8) & 0xFF);
  byte two = ((value >> 16) & 0xFF);
  byte one = ((value >> 24) & 0xFF);
  
  //Write the 4 bytes into the eeprom memory.
  EEPROM.write(address, four);
  EEPROM.write(address + 1, three);
  EEPROM.write(address + 2, two);
  EEPROM.write(address + 3, one);
}

unsigned long ReadLong(long address) {
  //Read the 4 bytes from the eeprom memory.
  long four = EEPROM.read(address);
  long three = EEPROM.read(address + 1);
  long two = EEPROM.read(address + 2);
  long one = EEPROM.read(address + 3);
  
  //Return the recomposed long by using bitshift.
  return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);
}

Processor is running at 1 MHz?

PORTB &= !(1 << pin);

Oops.

I am fairly certain it's running at 8Mhz after setting the fuses, and I upload the code using the 8Mhz setting too.

Oh, and thats logical not, not bitwise not, needs to be ~ right?

Yup.

Have you tried Cunning Turtle's servo library?

http://www.cunningturtle.com/attiny4585-servo-library/

I'll give it a go now, thanks for the help.

I am using the library and it worked! The servo no longer jitters and does the required function. Thank you very much for the help, it is greatly appreciated. I assume the timers are more accurate than the micros() function?

Not really. The biggest difference is that timers are not affected by interrupts.