//////////////////////////////////////////////////////
//ATtiny85 Activity_Counter &Frequency_meter programs;
// Time counting more than 255. Tiny 4kOled not compatible with ISR timer0OVF_vect
// Mokhtar Zerdali 2022.
#include<avr/io.h>
#include<util/delay.h>
#include <TinyWireM.h> //  Implementation of I2C
#include <Tiny4kOLED.h>
//#include<avr/interrupt.h>

#define F_CPU 8000000UL
#define PIN2 PB2 // INT0 -> PB2 external interrupt pin
#define PIN0 PB0
#define PIN1 PB1 // input PCINT1 signal activity and pulse beat
#define PIN3 PB3 // input PCINT3 program selector
#define PIN4 PB4 // output 

volatile unsigned long Overflowprb ; // value >256, and volatile between void programs
volatile unsigned long Countprb;
volatile unsigned long Countex;
volatile unsigned long Time;

volatile unsigned long Start_Time;
volatile unsigned long Finish_Time;
volatile unsigned long Elapsed_Time;
volatile  float Frequency;
volatile  float PRB;// pulse rate beat

//////Oled code////////
void SSD1306_setup()
{

  oled.begin(128, 64, sizeof(tiny4koled_init_128x64br), tiny4koled_init_128x64br);
  // Two fonts are supplied with this library, FONT8X16 and FONT6X8
  oled.setFont(FONT6X8);
  // To clear all the memory
  oled.clear();
  oled.on();
  oled.setCursor(1, 1);
  oled.print(F("Pulse Beat Rate"));
  //prepareDisplay();
}
//////Oled code////////

void setup()
{
  TinyWireM.begin();
  //Debug.println(F("Hello, clock is running"));
  pinMode(PIN3, INPUT); // selector high low
  pinMode(PIN1, INPUT); //
  pinMode(PIN4, OUTPUT);
  TCCR0A = 0X00; //TCCR0A to low for normal port operation and mode 0.
  TCCR0B = 0X00; //WGM02=0
  TCNT0 = 0; //initializing the counter to 0
  Countex = 0;
  //TIMSK = bit (TOIE0); //|= (1 << TOIE0); //enabling overflow >255 interrupts of  timer0 ISR timer0_OVF_vect
  TIMSK = bit (OCIE0B); //|= (1 << TOIE0); //enabling overflow >255 interrupts from compB
  OCR0B = 0xFF; //valeur  max 255 to compare with TCNT0
  cli();
  GIMSK |= (1 << PCIE); // enable pin change
  PCMSK |= bit(PCINT1); // PCInter external at pin PB1
  PCMSK |= bit(PCINT3); // | bit(PCINT1); // pin PB3 as pin change important to toggle between PRB and activity programs
  sei(); //global interruption
}
////////////////////////////////////////////
void Pulse_RB()
{
  Overflowprb = 0;
  TCCR0B |= (1 << CS00); //No prescaling clk
  // Mode sense of MCUCR Register to choose the adequate sense
  MCUCR = (1 << ISC01); //3/ FALLING mode sense
  //MCUCR = bit(ISC01) | bit(ISC00); //4// RISING mode sense
}
////////////////////////////////////////////
void External_counter()
{

  //TCCR0B |= (1 << CS00); //No prescaling clk, counting clk tick
  TCCR0B |= (1 << CS01) | (1 << CS02); //external counting, Clk on Falling edge sense
  /////////////////////////////////////Mode sense
  MCUCR = bit(ISC01) | bit(ISC00); //4// RISING mode sense
  //MCUCR = (1 << ISC01); //3/ FALLING mode sense
  //MCUCR &= ~(bit(ISC01) | bit(ISC00));    //1/ INT0 on low level, while ISR senses by mode low level
  // The low level of INT0 generates an interrupt request
}
///////////////////////////////
ISR (TIMER0_COMPB_vect) //Interrupt vector for Timer0 by

{
  if (digitalRead(PIN3) == HIGH)
  {
    Overflowprb++; // count number of overflow
  }
  else if (digitalRead(PIN3) == LOW)
  {

  }
} // End of TIMER0_OVF_vect

///////////////////Interruption Routine///////////////////////
ISR(PCINT0_vect) // pin change Interrupter vector for external inerruption
{
  //SSD1306_setup();
  if (digitalRead(PIN3) == HIGH)
  {
    Countprb = TCNT0 + (Overflowprb * 256); //n° overflow*256
    Time = 0.000125 * Countprb; // 8MHz ; clk : 125 ns.
    Start_Time = Time;
    oled.begin();
    oled.setCursor(0, 10);
    oled.println(PRB, 1);
    oled.setCursor(35, 10);
    oled.print("/min");
  }
  else if (digitalRead(PIN3) == LOW)
  {
    Countex++;
    oled.begin();
    oled.setCursor(0, 20);
    oled.println(Countex, 1);
  }

}
///////////////end of interruption////////////////////////////////////////////////////

int main()
{
  SSD1306_setup();
  setup();

  if (digitalRead(PIN3) == HIGH)
  {
    Pulse_RB(); // pulse rate beat program
    while (1)
    {
      Countprb = TCNT0 + (Overflowprb * 256); //n° overflow*256
      Time = 0.000125 * Countprb; // 8MHz ; clk : 125 ns.
      Finish_Time = Time;
      Elapsed_Time = Finish_Time - Start_Time;
      Frequency = 1000 / float(Elapsed_Time); // on Hz
      PRB = 60 * Frequency; //pulse rate beat
      //if (Start_Time > 1500)
    }
  }
  else if (digitalRead(PIN3) == LOW)
  {
    //External_counter();
    // counting Activity program
    while (1)
    {

    }
  }
}

ATTINY8520PU