ATtiny85 running code incorrectly

Hi All,

Weird thing going on the last three 85's I've tried programming are not executing the code properly.

I've tried them on every different internal clock setting. I'd try external but don't have a Chrystal laying around.

I know that this code executes properly as I have programmed a few other 85's that run it with miner errors.

The past few chips are not responded well at all varying in their erratic behavior between the different clock settings. Other things I have tried is burning the bootloader which each attempt and placing a 0.1uf cap between Vcc and GND.

Any thoughts?

No changed where made to the code since the first programmed chips so I'm assuming its something with the chips themselves but what?!

Here's the code anyway, it always helps:

#include<avr/interrupt.h>   // These are sets of 'library' functions needed
#include<avr/sleep.h>

const int switchPin = 2;
const int statusLED = 1;

uint8_t onOff;

volatile uint8_t buttonPushCounter = 0;
volatile uint32_t pressStart = 0;
volatile uint32_t pressEnd = 0;

void init_interrupt() {     // A function to set up the button press 
  GIMSK|=_BV(PCIE);         // interrupt. It fires on any change on the pin 
  PCMSK|=_BV(PCINT2);       // so on press or release of the button. 
  sei();
} // end of init_interrupt

ISR(PCINT0_vect) {                      // This is the function the interrupt triggers
  if(digitalRead(switchPin) == LOW) {   // low will indicate the button press
    //buttonPushCounter += 1;           // increment the button press counter
    pressStart = millis();              // start/enable a 'soft' timer
  }
  else {                                // high indicates release
    buttonPushCounter += 1;             // or increment on release (better I think)
    pressEnd = millis();                //   
  }                                     // Plus it wakes the trinket up from sleep of course
} //end of ISR


void setup() {
  pinMode(switchPin, INPUT_PULLUP);
  pinMode(statusLED, OUTPUT);
  onOff = HIGH;
  init_interrupt();             // set up the button interrupt
  
  //Flash quick sequence so we know setup has started i.e. power applied
  for(int k=0;k<10;k=k+1){
    if(k%2==0){
      digitalWrite(statusLED,HIGH);
    }
    else{
      digitalWrite(statusLED,LOW);
    }
    delay(250);
  } // end of flashing routine
} //  end of setup

void loop() {
  if(pressEnd) {                          // Button press released and can be measured
    if((pressEnd - pressStart) > 1000) {  // if it was pressed longer than a second
      onOff = !onOff;                     // toggle device on or off
    }
    pressStart = 0;               // disable the 'soft' timer (see line 82)
    pressEnd = 0;
  }
  if(onOff) {                             // if switched on, run the switch statement
    switch(buttonPushCounter)
    {
      case 1:
        digitalWrite(statusLED,HIGH);       // full LED on 1st press
        break;
      case 2:
        analogWrite(statusLED,127);         // next press set the led to half
        break;
      case 3:
        analogWrite(statusLED,85);          // quarter
        break;
      case 4:
        analogWrite(statusLED,45);          // and dimmer
        break;
      case 5:                             
        analogWrite(statusLED,15);          // dimmest
        break;
      case 6:
      digitalWrite(statusLED,HIGH);
      delay(50);
      digitalWrite(statusLED,LOW);
      delay(50);
      break;
      default:
        buttonPushCounter = 1;              // another press or any other unforeseen roll over counter
        break;
    } // end of switch
  } // end of on functionality
  else {                                     // if switched off
    if(!pressStart) {                        // ...and not currently timing a button
      digitalWrite(statusLED,LOW);           // lights out
      buttonPushCounter = 0;                 // counter back to 0
      set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // go to sleep
      sleep_enable();
      sleep_cpu();
  
      sleep_disable();
    }
  } // end of off functionality
}

It has worked pretty well on the 85's that accepted it properly apart from sometimes terminating without a prolonged button press or skipping on of the case. If there are any thoughts on that as well it'd be appreciated.

You don't seem to have ever considered the idea that your code could be buggy.

It would help if you explained what the code is supposed to do when it is working and then explain what it does when it isn't working.

sometimes terminating without a prolonged button press or skipping on of the case

Seems to me that you haven't debounced the button (there's no debouncing in your code) so "skipping" would be one of the symptoms.

Pete

Hey Pete,

I guess your right but the reason I didn't think it was the code is because it ran moderately well on other chips and I had some good help in writing it.

It is a tact button light switch. A prolonged press will awake the attiny for sleep and turn on the LED. Secondary presses will run through different functions of the LED. Prolonged press turns it off.

The chips that act funny can be pretty erratic generally when set to the internal 8mhz the light will just blink contentiously sometime it'll turn off from a button press.

1 mhz the chip seems unresponsive from most presses but ever now and again will spit out something. 16 mhz it seems to do anywhere between the two.

  sei();

This should be removed. Interrupts will be enabled when the setup function finishes.

You can add a capacitor across the switch to debounce it - it'll be easier than adding code to do it. Along with the INPUT_PULLUP you have already set, it should work. I've used .1uF which seems to work (but given my electronics knowledge it might have been more luck than good judgement).

Pete

I'll try it with removing the sei();

Oh yeah forgot to mention there's a 1uf cap across the GND side of the button for debouncing.

1uf cap across the GND side of the button

That doesn't make it clear how the cap is wired. The cap should be connected in parallel with (i.e. across) the button. If the cap is polarized, the negative end should be connected to the ground side of the button.

Pete

It's a ceramic capacitor, and correct one side of the button is parrallel with the capacitor.