//////////////////////////////////////////////////////
//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)
{
}
}
}