int led1 = 13, led2 = 12;
int buton1 = 9;
//int buton1 = 11;
int buton2 = A0;
int interruptPin = 2;
volatile int ctr = 0;
volatile uint8_t ctrFallFalse = 0;
volatile uint8_t ctrFallTrue = 0;
const uint8_t OUTPUT_PIN = 3; // = OC2B
//const uint8_t OUTPUT_PIN = 11; // = OC2A
const int PWM_FREQ = 380; //KHz
const uint8_t PERIOD = uint8_t(16*1024/PWM_FREQ-1); // CPU cycles ~ 16 MHz / PWM Freq
//const uint8_t PERIOD = 16;
volatile bool ch = true;
volatile bool tmpCh = false;
void setupTimer2()
{
pinMode(OUTPUT_PIN, OUTPUT);
TCCR2B = 0; // stop timer
TCNT2 = 0; // reset timer
TCCR2A =
_BV(COM2B1) // non-inverting PWM on OC2B
//_BV(COM2A1) // non-inverting PWM on OC2A
| _BV(WGM20) // fast PWM mode, TOP = OCR2A
| _BV(WGM21); // ...ditto
TCCR2B = _BV(WGM22); // ...ditto
OCR2A = PERIOD/2 - 1;
OCR2B = PERIOD/2 - 1;
//TIMSK2 &= ~_BV(TOIE2);
}
void setupTimer1()
{
//pinMode(10, OUTPUT); //OC1B
pinMode(9, OUTPUT); //OC1A
TCCR1B = 0; // stop timer
TCCR1A = 0;
//TCCR1B = (_BV(WGM13) | _BV(WGM12));
TCCR1B |= _BV(WGM13);
TCCR1B |= _BV(WGM12);
//TCCR1A = (_BV(WGM11) | _BV(WGM10)); // select Fast PWM with OCR1A BOTTOM TOP
TCCR1A |= _BV(WGM11);
TCCR1A |= _BV(WGM10);
//TCCR1A |= _BV(COM1B1);
//TCCR1A &= ~_BV(COM1B0); // Set OC1B OUTUT pin 10
TCCR1A |= _BV(COM1A1);
TCCR1A &= ~_BV(COM1A0); // Set OC1B OUTUT pin 10
OCR1AH = 0;
OCR1AL = PERIOD/2 - 1;
//OCR1BH = 0;
//OCR1BL = PERIOD/2 - 1;
TCNT1H = 0;
TCNT1L = 0;
/*
TIMSK1 = 0;
TIMSK1 |= (_BV(OCIE1B) | _BV(TOIE1));
*/
}
void setupTimer0()
{
pinMode(6, OUTPUT); //OC1A
TCCR0B = 0; // stop timer
TCCR0A = 0;
TCCR0B |= _BV(WGM02);
TCCR0A |= _BV(WGM01);
TCCR0A |= _BV(WGM00);
TCCR0A |= _BV(COM0A1);
TCCR0A &= ~_BV(COM0A0);
OCR0A = PERIOD/2 - 1;
TCNT0 = 0;
}
void irBuff(){
//TCCR2B |= _BV(CS20); // F_CPU / 1
//TCCR1B |= _BV(CS10); // F_CPU / 1
TCCR0B |= _BV(CS00); // F_CPU / 1
digitalWrite(led1, HIGH);
}
void silenceIr(){
//TCCR2B &= ~_BV(CS20);
//TCNT2 = 0;
//TCCR1B &= ~_BV(CS10); // F_CPU / 1
TCCR0B &= ~_BV(CS00); // F_CPU / 1
//Serial.println(TCNT1L);
//TCNT1L = 0;
//TCNT1H = 0;
digitalWrite(led1, LOW);
}
void irHandler(){
if (ch){
irBuff();
}
else{
silenceIr();
}
ch = !ch;
}
//pin change interrupt ayar fonksiyonu
void pciSetup(byte pin)
{
*digitalPinToPCMSK(pin) |= bit (digitalPinToPCMSKbit(pin)); // enable pin
PCIFR |= bit (digitalPinToPCICRbit(pin)); // clear any outstanding interrupt
PCICR |= bit (digitalPinToPCICRbit(pin)); // enable interrupt for the group
}
void setup() {
// put your setup code here, to run once:
//led ve buton tanımları
Serial.begin(115200);
pinMode(led1, OUTPUT);
//pinMode(led2, OUTPUT);
//pinMode(buton1, INPUT);
//pinMode(buton2, INPUT);
pinMode(interruptPin, INPUT);
//pciSetup(buton1); //9 nolu pin için pci ayarlandı
//pciSetup(buton2); //A0 pini için pci ayarlandı
attachInterrupt(digitalPinToInterrupt(interruptPin), irHandler, CHANGE);
//attachInterrupt(digitalPinToInterrupt(2), silenceIr, RISING);
//setupTimer2();
//setupTimer1();
setupTimer0();
irBuff();
//irBuff();
}
ISR (PCINT0_vect) // handle pin change interrupt for D8 to D13 here
{
//D9 butonu basıldı ise ledi söndür
//PCIFR = 0x00;
/*
if (!digitalRead(buton1))
{
//digitalWrite(led2, LOW);
irBuff();
//digitalWrite(led1, !digitalRead(led1));
//digitalWrite(led1, HIGH);
}
else
{
silenceIr();
//digitalWrite(led1, LOW);
//digitalWrite(OUTPUT_PIN, LOW);
}
*/
if(ch){
irBuff();
//digitalWrite(led1, HIGH);
}
else{
silenceIr();
//digitalWrite(led1, LOW);
}
ch = !ch;
/*
if(ctr > 1000){
if (!digitalRead(buton1)){
if (!ch) ctrFallFalse++; else ctrFallTrue++;
digitalWrite(led2, HIGH);
}
if (ctr > 1030){
digitalWrite(led2, LOW);
if (ctrFallFalse > ctrFallTrue) tmpCh = false; else tmpCh = true;
ctrFallFalse = 0;
ctrFallTrue = 0;
ctr = 0;
}
}
ctr++;
ch = !ch;
*/
}
ISR (PCINT1_vect) // handle pin change interrupt for A0 to A5 here
{
//A0 butonu basıldı ise ledi yak
if (!digitalRead(buton2))
{
silenceIr();
digitalWrite(led2, HIGH);
OCR2B = (OCR2B + int(PERIOD/10))%(PERIOD-1);
delay(1000);
}
else
{
//
digitalWrite(led2, LOW);
}
}
void loop() {
/*
if(ch == tmpCh){//if FALLING
irBuff();
}
else{ //IF RISING
silenceIr();
}
*/
//bool tmpCh = ch;
//ctr++;
delay(2000);
}
Here is the full code, as you can see I do not use any library (Servo Etc.)
I need to use both interrupt pin of arduino uno, (1&2), for same signal, one for rising, one for falling. Because, the interrupt signal is 38KHz and reading the interrupt pin change cause to miss some events (Arduino sucks at this). By interrupt, I will generate 380KHz PWM so I need to use fast PWM. Timer2 fast PWM blocks me to utilize it because its output is pin3. So I wanted to use Timer0 or 1. But I could not get any thing either on Pin9 (OC1A) nor Pin6(OC0A). Why is that?
On my research, I ve seen many answers to that claiming the problem is servo library which blocks those pins however, that is not the case.