Closed Rimbaldo closed 10 months ago
I agree that that should work, especially if it works for other pins. I can't think of anything on PB2 that could cause a problem
I'm not sure what's up with the digispark core - I don't recommend touching that one, and don't particularly care how busted it is. But that they have a more widespread problem is strange. If it was PB3 or PB6 - I'd be like "You using a digispark pro? What do you expect those are the USB pins!" but you're not using PB2. And the result would be tons of unexpected triggers.
You're doing that in a way that leaves very little room for the core to have impacted it. I'd be interested to know how many pins you see this on.
You can verify 100% that the core is not at fault, by overriding main to skip the init code (there will be no millis, PWM, or ADC, of course - nothing will work) all you can really do to confirm the ISR fired is toggle an LED or something (writing 1 to the PINx register bit acts as a strobe bit to toggle the pin if you didn't know) - you could put what you have in setup now into main(), thus overriding the stock main. When you do this, the sei() which right now does nothing because interrupts are already enabled by init(), will be essential.
(note: for context, stock main is essentially
This code below expects a LED to be on some pin on PORTA.
It should give a 1 second flash at startup (assuming it's set to default speed).
#include <util/delay.h>
int main() {
if (MCUSR == 0 && GPIOR0 == 0) {
/* If this triggers and you get this fast blink until reset when you trigger the interrupt, the wrong interrupt
* is being triggered- namely one you haven't defined */
/* Some versions of the bootloader stash MCUSR in GPIOR0 so checking both*/
DDRA |= 1 << (bit on PORTA connected to an LED);
while(1) {
PINA |= 1<< LEDBIT;
_delay_ms(100);
PINA |= 1<< LEDBIT;
_delay_ms(100);
}
} else {
MCUSR = 0;
}
PORTB |= 1 << PB1; // enable pull up resistor at PB1
PORTB |= 1 << PB2; // enable pull up resistor at PB2
initInterrupt();
// Note that pins have a default state: DDRx = 0, PORTx = 0. So if you're running first thing, you just need to set
// the pins high to get input pullup on classic AVR. They're already set as inputs.
// set the LED pin output, and do 1 sec on 1 sec off on startup.
DDRA |= 1 << (bit on PORTA connected to an LED);
PINA |= 1<< LEDBIT;
_delay_ms(1000);
PINA |= 1<< LEDBIT;
_delay_ms(1000);
while(1); // no equivalent to loop
return 0; //needed to keep the compiler happy - Blame the C standard group not me.
}
void initInterrupt() {
PCICR |= 1 << PCIE1; // enable PCINT[8:15] pin change interrupt
PCMSK1 |= 1 << PCINT10; // configure interrupt at PCINT10 PIN 10
sei(); // now this actually does something
}
ISR(PCINT1_vect) {
PINA |= 1 << (bit on PORTA with an LED used above);
}
I'd be interested to hear two things: 1: Is it a digispark pro board or a vanilla board? 2. What is the symptom? Does it fail to do anything? Reboot unexpectedly? The results of this test:
The code above has a "dirty reset detector" which will put it into a state where it continually flashes the LED much faster if a dirty reset is seen so that you can catch that case too. <util/delay.h> uses cyclecounting loops and hence works without init() (as long as your running at the default speed of the selected clock source, without prescaling not set by fuses, that is, the 2MHz and 4 MHz internal options that may be offered on the old release and are now offered on the new on and it also blinks the light 1 sec on 1 sec off on startup so you can see that the LED works and see any reboots that are somehow not dirty.
(A dirty reset is when program execution arrives at the reset vector without a hardware reset having occurred. This can happen from three things not involving overclocking or undervoltaging. It is the THIRD case that is relevant to you, and is BOLDED so you don't need to read all this shit
All this happens without a reset occurring but all initialization code in the core assumes that the chip is in it's poweron reset state when the sketch starts. This is the mechanism by which array overruns lead to both erratic behavior and bootloops/hangs, and I'm convinced that it accounts for the vast majority (on the modern AVR cores, where the consequences are even worse in the interrupt case (the interrupt system is a little different, in mostly good ways, but it has a sideffect that that BADISR jump from interrupt context to reset makes it impossible to execute any other interrupts until hardware reset because the CPU thinks it's still in one), I implement dirty reset trap that forces reset if it sees one in the core and have it on and non-obvious how to disable (intentionally, because most people shouldn't be disabling it)).)
Hi! Thanks for all info!
I tested last night your sketch in a bare attiny167 and it worked perfectly in all ports. With a negative wire I triggered each PCINT pin and all of them (in each setting) could turn the led on and off.
I was puzzled but then when checking my sketch, I had removed a library that deals with blink patterns (and this library declare the led's pins internally as outputs) and I forgot to declare myself the led pins as outputs..
But even then, I had managed to make the PCINT10 flash a led, but it was strange... Like the trigger, the interrupt, kept being constantly fired, non-stop
I was using analogWrite(12, 50) - red led, and analogWrite(13,50) - green led, to give me the output if the cable was connected or disconnected. That's the reason for my PCINT interrupt. To check a cable status.
But the led, instead of a faint glow, was turning on and off really quickly. And in my previous versions of my sketch, when I used analogWrite, even to a value of 1, the leds didn't blink (to the human eye perception). They had a faint glow.
Now they were "blinking". So I thought the interrupt had a problem..
The thing is I had been running the Attiny at 1Mhz before... For these tests you asked me to run I let the Attiny run at 4Mhz...
I saw written somewhere here in the ISSUES someone asking about the PWM frequency... and you wrote something about that PWM frequencies would be different at each speed.
Then, testing the different speeds, I came to realize that, in 1Mhz, 2Mhz and 8Mhz, pwm on the led works normally, with no flicker to the human eye. But only in 4Mhz speed the pwm frequency must be so low that we can actually see the led blink between on and off.
So I changed to 1Mhz and compiled my code and now it works correctly. The led now has a constant faint glow (PWM in higher frequency). The interrupts are firing correctly. I was mistaken thinking it was firing non-stop. And it was probably not triggering sometimes because I had not declared the leds as outputs when I removed that blink library... (I guess)
I'm so sorry to have bothered you with this ... and thanks for all your help.. Without it I couldn't have found out my mistakes..
Best Regards, Rodrigo
Hmmmm, I ought to take a look at that. It should never be that slow by default.
OH! Durrrr...
My sketch overrides main, and to make sure it is able to start at all voltages, has to default to prescale by 8. So the PWM frequency was 1/4th what it should have been. The x7 is actually better able to keep within 500-1khz than most parts.
2.0.0 now has more accurate FPWM (target is 1k, we can always stay within a factor of 2 of that, and the part specific documentation for all parts now lists what speeds are used.
Hi! I'm using Attinycore 1.5.2
I'm trying to trigger a Pin Change Interrupt on my Attiny167. When I use physical pin 9, which is PB1 (PCINT9), it works, I can trigger a Pin Change interrupt. It also works when using PB0, PCINT8.
But when I try to use pin 10, PB2 (PCINT10) with the same code, the Pin Change Interrupt never triggers
I tried using both a bare attiny167 and a Digispark PRO. It happens with both. (in the Digispark I use PB0, instead of PB1, because PB1 is the led.)
I tried also, with the Digispark PRO, using it's own core, Digistump. Things got worse. Neither PCINT9 nor PCINT10 triggered an Pin Change interrupt.
I can read the status of the pin 10 (PB2) using a digitalRead(). It reads normally and detects highs and lows.
But when changing from high to low or the opposite, the interrupt doesn't get triggered.
Am I doing something wrong (or so stupid I can't see...) or Is there anything (in the core) blocking PB2 of being used as a PIn Change Interrupt?
This is the code below: