attachinterrupt not working on ATTiny85 - Page 1
Forum section: electronics / general

author: paul_g_787
author_rank: Frequent Contributor
timestamp: June 20, 2022, 08:36:57 pm
content: Hey. I am hoping someone can help me as I am completely stuck with this problem on the ATTiny85 in the Arduino IDE.I have built a DIY Xbox 360 USB receiver:https://techocd.blogspot.com/2014/01/xbox-360-wireless-controller-to-pc-via.htmlI have this working great using my Arduino UNO!!! On the UNO this code works perfectly fine.So now I am trying to slim the device down by using an STTiny85 instead of an Arduino UNO. But I keep getting this error (see attached image).I have found a few posts online that mention the ATTiny85 does not support attachInterrupt or detachInterrupt. However I cannot find a simple way to replace this part of the code to work with the ATTiny.Could anyone help me to get this code to work on the ATTIny85?Here is the code:The problem is in the function sleepNowCode:/* Arduino code to communicate with xbox 360 RF module.Original work by (yaywoop) / additional ideas from Alexander Martinez - modified by dilandou ([url=http://www.dilandou.com]www.dilandou.com, [url=http://www.diru.org/wordpress]www.diru.org/wordpress)First sends LED initialisation code followed by LED startup animation code, then sleeps until a button press for sync command.RF module must be powered with 3.3V, two diodes in series with USB 5v will do. Connect the USB wires to a host computer, and the data and serial wires to Arduino.of course, make sure to have a common ground */#include <avr/sleep.h>#define sync_pin 2 //power button repurposed for sync button (pin 5 on the module)#define data_pin 1 //data line (pin 6 on the module)#define clock_pin 0 //clock line (pin 7 on module)int led_cmd = {0,0,1,0,0,0,0,1,0,0}; //Activates/initialises the LEDs, leaving the center LED lit.int anim_cmd = {0,0,1,0,0,0,0,1,0,1}; //Makes the startup animation on the ring of light.int sync_cmd = {0,0,0,0,0,0,0,1,0,0}; //Initiates the sync process.volatile boolean sync_enable = 0;void sendData(int cmd_do[]) {pinMode(data_pin, OUTPUT);digitalWrite(data_pin, LOW); //start sending data.int prev = 1;for(int i = 0; i < 10; i++){while (prev == digitalRead(clock_pin)){} //detects change in clockprev = digitalRead(clock_pin);// should be after downward edge of clock, so send bit of data nowdigitalWrite(data_pin, cmd_do);while (prev == digitalRead(clock_pin)){} //detects upward edge of clockprev = digitalRead(clock_pin);}digitalWrite(data_pin, HIGH);pinMode(data_pin, INPUT);}void initLEDs(){sendData(led_cmd);delay(50);sendData(anim_cmd);delay(50);}void wakeUp(){sync_enable = 1;}void sleepNow() {set_sleep_mode(SLEEP_MODE_PWR_DOWN); // set sleep modesleep_enable(); //enable sleep bitattachInterrupt(0, wakeUp, LOW);sleep_mode();sleep_disable(); //disable sleep bitdetachInterrupt(0); // disables interrupt 0 on pin 2}void setup() {//Serial.begin(9600);pinMode(sync_pin, INPUT);digitalWrite(sync_pin,HIGH);pinMode(data_pin, INPUT);pinMode(clock_pin, INPUT);delay(2000);initLEDs();// sendData(sync_cmd);}void loop(){//Serial.println("Sleeping.");sleepNow();delay(200);if(sync_enable==1) {//Serial.println("Syncing.");sendData(sync_cmd);sync_enable = 0;}}

author: cv007
author_rank: Frequent Contributor
timestamp: June 21, 2022, 01:17:03 am
content: I do not know Arduino, but you are getting an ISR created that does not exist for your mcu. Comment out the second line below (WInterrupts.c) so the macro does not creat an ISR for INT1_vect.Code:#elseIMPLEMENT_ISR(INT0_vect, EXTERNAL_INT_0)IMPLEMENT_ISR(INT1_vect, EXTERNAL_INT_1)I would assume there is a 'special' version of arduino for a tiny85 that specifically deals with its hardware, but the above fix may be fine.

author: floobydust
author_rank: Super Contributor
timestamp: June 21, 2022, 02:00:46 am
content: I have these snippets of my ATtiny85 and '328 sleep code from years ago. I never use "attach interrupt", just the reserved labels for them. Note for min. current draw I had to shut off the A/D and BOD. The code is not pretty but works. Wakes up due to a pin (ignition key or pushbutton) interrrupt. I was testing on '328 Uno and the final H/W is Tiny 85, so I left both MCU-specific routines in the source, just commented it out as not needed.Code://------------------------------------------------------------------------void SleepSession328(void) {// http://www.nongnu.org/avr-libc/user-manual/group__avr__sleep.html// configure and enter sleep mode, only pin change interrupt (ign switch or pushbutton press) wakes usADCSRA &= ~(1 << ADEN); // shutoff ADCMCUCR |= (1 << BODS); // disable BOD 328P only, override fuses for sleep// config and enable pin-change interruptscli(); // disable global interrupts as we are reconfiguring themPCMSK2 |= (1 << PCINT21) | (1 << PCINT23); // unmask pin-change int for D5, D7- the switch inputsPCIFR &= ~(1 << PCIF2); // clear flag for any outstanding pin-change interrupt 2 flag PCINT[23:16] for D0-D7PCICR |= (1 << PCIE2); // enable pin-change interrupt group2set_sleep_mode(SLEEP_MODE_PWR_DOWN);sleep_enable();// sleep_bod_disable(); // time limited, have to trysei(); // re-enable global interrupts, sleep is set up nowDEBUG_PRINTLN("** SLEEP **"); delay(100); // to empty serial buffersleep_cpu(); // go to sleep//---------------------- W A K E ---------/* Upon waking, the program will continue from here. */sleep_disable(); // now that we've woken up, stay up;// BOD is automatically turned on after sleep,, A/D left offPCICR &= ~(1 << PCIE2); // disable pin-change interrupt group2, left pcmsk aloneDEBUG_PRINTLN("** WAKE **");}//------------------------------------------------------------------------void SleepSession(void) { // Tiny85// http://www.nongnu.org/avr-libc/user-manual/group__avr__sleep.html// configure and enter sleep mode, only pin change interrupt (ign switch or pushbutton press) wakes usADCSRA &= ~(1 << ADEN); // shutoff ADC if it was on and save power ~0.3mA at 5V;// not sure if BOD (fuse) is used, analog comparator if used may need to disconnect too to save power.// config and enable pin-change interruptscli(); // disable global interrupts as we are reconfiguring themPCMSK = 0b00011000; // allow pin-change interrupts on pins PB3, PB4- the switch inputs; Interrupt unmaskGIMSK |= (1 << PCIE); // enable pin-change interrupts; Interrupt source// not sure if timer interrupts happenin on Arduino with Attiny85set_sleep_mode(SLEEP_MODE_PWR_DOWN);sleep_enable();// sleep_bod_disable(); // time limited, have to trysei(); // re-enable global interrupts, sleep is set up now//state = sSLEEPING;DEBUG_PRINTLN("** SLEEP **"); delay(100); // to empty serial buffersleep_cpu(); // go to sleep//---------------------- W A K E ---------// Upon waking due to Pin Change Interrupt, program execution will continue from here.sleep_disable(); // now that we've woken up, stay up;// disable further pin-change interrupts, so no spurious interruptGIMSK &= ~(1 << PCIE); // turn off pin-change interrupts offDEBUG_PRINTLN("** WAKE **");}//------------------------------------------------------------------------ISR (PCINT0_vect) { // Pin Change Interrupt for Tiny85// GIFR automatically cleared here; hope timers don't use them//clear the pin change interrupt, good to wake and run now; or no change if spurious interrupt// do nothing here, other than wake up and resume Main// old code: GIMSK &= ~(1 << PCIE); // We are awake, no more Pin Change interrupts; mask them off}//------------------------------------------------------------------------ISR (PCINT2_vect) { // '328 Uno Pin Change Interrupt for D0-D7// GIFR automatically cleared here; hope timers don't use them//clear the pin change interrupt, good to wake and run now; or no change if spurious interrupt// do nothing here, other than wake up and resume Main// old GIMSK &= ~(1 << PCIE); // We are awake, no more Pin Change interrupts; mask them off// who woke us up?ign.wake = digitalRead(IgnSwitchPin); //PB.wake = !digitalRead(Power_ButtonPin); //}

author: paul_g_787
author_rank: Frequent Contributor
timestamp: June 21, 2022, 02:14:22 pm
content: Quote from: cv007 on June 21, 2022, 01:17:03 amI commented out that line as you said and it solved my error, but now I have another error (see screenshot).it says attachInterrupt / detachInterrupt may need some more work for this CPU (case 1)

author: paul_g_787
author_rank: Frequent Contributor
timestamp: June 21, 2022, 02:53:19 pm
content: Alright it seems to work fine regardless of that final error??I have just tested the device and it is working great now!Attached an image of the modded board. Just plug it into USB and install the official Microsoft Driver. Press button to pair controllers. It works with up to 4 controllers.The ATTiny85 is just listening for the button press (blue wire) and sending the pairing command via serial (yellow wire data, brown wire clock) to the board to make it go into pairing mode.And the code also sends the startup LED animation command at power-up yo make it mimic the Xbox 360 power up sequence.

author: cv007
author_rank: Frequent Contributor
timestamp: June 21, 2022, 04:53:49 pm
content: QuoteIf you look at the code where the error says there is a problem, it shows they assume the mcu has an INT1 so although the warning is harmless you could simply do as they do for the INT2 case and change-Code:#else#warning detachInterrupt may need some more work for this cpu (case 1)toCode:#elif defined(INT1)#warning detachInterrupt may need some more work for this cpu (case 1)There is also a 'EXTERNAL_NUM_INTERRUPTS' define which defaults to 2 which could also be changed to suit the tiny85. Also harmless until you try to use '1' for attachInterrupt, Eventually if you use the tiny85 for more things, you may want to look into getting a version specifically for a tiny85 series, which I assume there is.

author: paul_g_787
author_rank: Frequent Contributor
timestamp: June 21, 2022, 06:06:14 pm
content: For those interested here is a quick schematic of my mod board and the pinout diagram from the internet.