ATTiny85 time drifting

Hi! i'm making a clock multiplier for musical purpose. Im using a ATTiny85 to take in a 5v pulse at a regular interval and detecting the time between each pulse. Then i use the time to set an output pulse to trigger things externally.
It works as expected but the output clock (or the time detection?) is slowly drifting so the output is not longer in sync with the input.

here is my code:

long timeSpend = 0;
int pulseState = LOW;
int clockSpeed = 2000;
int pulsePin;
long lastPulse;
bool pulseHigh = false;
const int in = 3;
const int out = 2;
const int mult = 1;

unsigned long time;

void setup() {
  pinMode(out, OUTPUT);
  pinMode(in, INPUT);
}

void loop() {
  time = millis();

  // clock input 1
  pulsePin = digitalRead(in);
  if (digitalRead(in) == HIGH && pulseHigh == false) {
    clockSpeed = (time - lastPulse) * mult;
    lastPulse = time;
    pulseHigh = true;
  }
  if (digitalRead(in) == LOW) {
    pulseHigh = false;
  }

  // clock output
  if (time - timeSpend > clockSpeed) {

    timeSpend = time;
    if (pulseState == LOW)
    {
      pulseState = HIGH;
    }
    else {
      pulseState = LOW;
    }

    digitalWrite(out, pulseState);
  }

}

Thanks! :slight_smile:

You measure the interval between the start of one input pulse and the start of the next input pulse. You use this interval to generate a long output pulse Between 1 and 3 times the length of that interval. Is that right ?

When should that output pulse start ? as soon as you have received the first input pulse ?

6v6gt:
You measure the interval between the start of one input pulse and the start of the next input pulse. You use this interval to generate a long output pulse Between 1 and 3 times the length of that interval. Is that right ?

When should that output pulse start ? as soon as you have received the first input pulse ?

Ah! i kind of see my problem. yeah i want both input and output to be aligned:

input pulses:
!...!...!...!...
output pulses: (mult=2)
!.!.!.!.!.!.!.!.

I guess then something like this for the frequency doubling (ignoring the middle 2 intermediate waveforms)

Of course it will be phase shifted because you will not know the period of the incoming signal until you have received 2 pulses,

6v6gt:
I guess then something like this for the frequency doubling (ignoring the middle 2 intermediate waveforms)

Of course it will be phase shifted because you will not know the period of the incoming signal until you have received 2 pulses,

In input not be a 50% pulse width. but thanks for making be realise that it is the start phase of the output i need to look at. :slight_smile:

changed the code, so that the output is dependent on the input, but it still seems to slowly phase out of sync.

  long timeSpend = 0;
  int pulseState = LOW;
  int clockSpeed = 0;
  int pulsePin;
  long lastPulse;
  long lastOutPulse;
  bool pulseHigh = false;
  const int in = 3;
  const int out = 2;
  const int mult = 2;
  unsigned long time;
  
void setup() {
  pinMode(out, OUTPUT); 
  pinMode(in, INPUT); 
}

void loop() {
  time = millis();
  
  // clock input
  pulsePin = digitalRead(in);
  if(digitalRead(in) == HIGH && pulseHigh == false){
    PulseOut();
 
    clockSpeed = (time - lastPulse) / mult;
    lastPulse = time;
    pulseHigh = true;
    }
if (digitalRead(in) == LOW){
      pulseHigh = false;
      }

  // clock output
  if(time >= lastOutPulse + clockSpeed){
    PulseOut();
  } 

}

void PulseOut()
  {
   if (pulseState == LOW)
  {
    lastOutPulse = time;
    pulseState = HIGH;
  }
  else{
    pulseState = LOW;
    }
    digitalWrite(out, pulseState);
  }

Nevermind. seems like i was using the wrong bootloader/internal-clock-speed :stuck_out_tongue:
using 16Mhz now and it seems so be synced up perfectly now :smiley: