News:

SMF for DIYStompboxes.com!

Main Menu

ATtiny85 code issues

Started by patrick398, September 09, 2020, 06:24:12 AM

Previous topic - Next topic

potul

Here you have a piece of code that works on my end using millis(). It does only the tap tempo thing, not the rest. It does not use any interrupt but code never stops (it runs as fast as possible)
I think you could add your trigger code easily following the same scheme. Take a look and ask whatever questions you may have.

You just need to change the pin numbers to your circuit.


int tempoInput = 0;
int tempoOutput = 1;
int inputState;
bool lastInputState=LOW;
unsigned long lastEdgeTime=millis();
unsigned long pulsePeriod=0;

void setup() {
  pinMode (tempoInput, INPUT);
  pinMode (tempoOutput, OUTPUT);
}

void loop() {
 
  // check input
 
  bool inputState = digitalRead(tempoInput);
 
  if (inputState){  //input is HIGH
    if (!lastInputState) {  //last state was LOW, so we have a rising edge
      pulsePeriod = millis() - lastEdgeTime;
      lastEdgeTime = millis();
    }
  } 
  lastInputState = inputState;

  //set output

if (millis()-lastEdgeTime > pulsePeriod/2){
    digitalWrite(tempoOutput, HIGH);
  } else {
    digitalWrite(tempoOutput, LOW);
  }

}

patrick398

Wow thank you so much for that man, i really appreciate you taking time to do that for me. I'll go through it with a fine tooth comb and try to understand as much of it as i can, though i may have questions.

The other part of the code is using a delay so this won't interfere with that, but is this short enough to run during an interrupt of the other code?

Thanks again!

potul

This code needs to be "free running". If the rest of the code uses delay instructions, then you will need to put the tap tempo code inside an interrupt to ensure it is not stopped.  It should be fast to execute each loop, so just drop it into the interrupt and adjust interrupt time if needed.


pruttelherrie

Quote from: patrick398 on September 25, 2020, 04:21:50 AM
Wow thank you so much for that man, i really appreciate you taking time to do that for me. I'll go through it with a fine tooth comb and try to understand as much of it as i can, though i may have questions.

The other part of the code is using a delay so this won't interfere with that, but is this short enough to run during an interrupt of the other code?

Thanks again!

You can implement the delayed-trigger without using the delay() function, using the same technique as used here:

Quote
if (millis()-lastEdgeTime > pulsePeriod/2){
    digitalWrite(tempoOutput, HIGH);
  } else {
    digitalWrite(tempoOutput, LOW);
  }

Then everything can stay free-running.

potul

That's right. what my code does is simply a delayed trigger by half of the period. You can use whatever delay you want here.

patrick398

That worked beautifully, thanks so much!

Here's the full code on the off chance any of this is useful to anybody:

#include <TimerOne.h>

//don't forget 10k pulldown on TRIGGER_IN



int TRIGGER_IN = 0; // ATtiny pin (5) connected to flip flop output
int TRIGGER_OUT = 1; // ATtiny pin (6) connected to bass drum trigger
int PULSE = 50; // Set trigger out pulse length as 50 ms
int triggerState; // set variale for trigger state
int lastTriggerState = 0; //set variable for last trigger state
int tempoInput = 2; // ATtiny pin (7) connected to tap tempo output
int tempoOutput = 3; // ATtiny pin (2) connected to high hat trigger
int inputState;
bool lastInputState = LOW;
unsigned long lastEdgeTime = millis();
unsigned long pulsePeriod = 0;



void setup() {
  Timer1.initialize (1000);   // starting interrupt which will go off every ' 1000 ' microseconds (1 millisecond)
  Timer1.attachInterrupt (offBeat);
  pinMode (TRIGGER_IN, INPUT); // define TRIGGER_IN as an input (could try using just input_pullup)
  pinMode (TRIGGER_OUT, OUTPUT); // define TRIGGER_OUT as an output
  pinMode (tempoInput, INPUT);
  pinMode (tempoOutput, OUTPUT);
}



void loop() {


  int readValue = analogRead(2) * 3; // ATtiny pin (3) read pots value between 0 and 1023 and multiplies it by 3
  triggerState = digitalRead(TRIGGER_IN); // read the trigger in pin


  if (triggerState != lastTriggerState) { // is trigger state not equal to last trigger state
    if (triggerState == HIGH) { // if trigger state has changed...

      delay (readValue); // delay for period set by POT_PIN
      digitalWrite (TRIGGER_OUT, HIGH); // if it's high write TRIGGER_OUT high
      delay (PULSE);
    }

    lastTriggerState = triggerState;

    digitalWrite (TRIGGER_OUT, LOW); // if it's low write TRIGGER_OUT low
  }
}

void offBeat(){
 
// check input

  bool inputState = digitalRead(tempoInput);

  if (inputState){  //input is HIGH
    if (!lastInputState) {  //last state was LOW, so we have a rising edge
      pulsePeriod = millis() - lastEdgeTime;
      lastEdgeTime = millis();
    }
  }
  lastInputState = inputState;

  //set output

if (millis()-lastEdgeTime > pulsePeriod/2){
    digitalWrite(tempoOutput, HIGH);
  } else {
    digitalWrite(tempoOutput, LOW);
  }
  return;
}

potul

glad to see it works. Don't hesitate to ask if you need more help