ATtiny13A power button - Page 1
Forum section: electronics / projects

author: Kuusou
author_rank: Regular Contributor
timestamp: December 05, 2020, 10:23:03 pm
content: I have an Arduino project that is using an ATtiny13A to control a power button. The system is powered using a single cell lipo with a nominal voltage of 3.7V. Here is the schematic and layout of the area in question, they are both clickable to see the full image (the usb charger system on the far left of the schematic image and the boost converter are not shown in the layout image as both of those system have been tested and work properly).In the image above my board design is a two layer board. Most of signal traces are on the top layer where most of the components are placed (red), and the bottom layer is a universal ground layer for every component on the board, shown in green. As the title says I'm using anATtiny13Aand I am using ICSP to upload code to the chip. The BMS is ran using aFS312F-Gas the IC, and aFS8205AN-channel MOSFET. I'm using aKIA3415P-channel MOSFET to control whether power reaches the boost converter or not using the ATtiny13A pin 3, labeled "GATE" with pin 2 labeled "BTN" acting as the external interrupt pin which is connected to the power switch located on the back side of the board.The ATtiny13A is programmed with the following code:Code:#include <avr/io.h>#include <util/delay.h>#include <avr/interrupt.h>#include <avr/sleep.h>#include <avr/wdt.h>#define BTN 3#define GATE 4#define timer_init() (TIMSK0 |= (1 << OCIE0A))#define BTN_HOLD_MS 1500 // Press button for 1 secondenum Device_Status{POWER_OFF,RUNNING};enum Btn_Status{BTN_UP,BTN_DOWN,BTN_IGNORE};void setup(){sei(); // Enable interruptsPORTB |= (1 << BTN); // Enable PULL_UP resistorGIMSK |= (1 << PCIE); // Enable Pin Change InterruptsPCMSK |= (1 << BTN); // Use PCINTn as interrupt pin (Button I/O pin)TCCR0A |= (1 << WGM01); // Set CTC mode on Timer 1TIMSK0 |= (1 << OCIE0A); // Enable the Timer/Counter0 Compare Match A interruptTCCR0B |= (1 << CS01); // Set prescaler to 8OCR0A = 125; // Set the output compare reg so tops at 1 msDDRB |= (1 << GATE); // replaces pinMode(GATE, OUTPUT);PORTB |= (1 << GATE); // replaces digitalWrite(GATE, HIGH);}void power_off(){PORTB |= (1 << GATE);cli(); // Disable interrupts before next commandswdt_disable(); // Disable watch dog timer to save powerset_sleep_mode(SLEEP_MODE_PWR_DOWN); // Set sleep mode power downsleep_enable();sleep_bod_disable(); // Disable brown-out detectorsei(); // Enable interruptssleep_cpu();sleep_disable();}volatile unsigned int timer; // milliseconds counterBtn_Status btn_status; // Status of the buttonint main(){setup();Device_Status status = POWER_OFF; // Set start ON or OFF when power is connectedbtn_status = BTN_UP;DDRB |= (1 << GATE); // Set as outputfor (;;){if (btn_status == BTN_DOWN){if (timer > BTN_HOLD_MS) // Check if button has been pressed enough{if (status == RUNNING)status = POWER_OFF;else{status = RUNNING;// setup of the device here if needed;PORTB &= ~(1 << GATE); // ON}btn_status = BTN_IGNORE; // If status already changed don't swap it again}}else{if (status) // Is status RUNNING?{/* main code here */PORTB &= ~(1 << GATE); // ON/* -------------- */}else{PORTB |= (1 << GATE); // OFFpower_off();}}}}ISR(PCINT0_vect){if (!((PINB >> BTN) & 0x01)) // Check if button is down{btn_status = BTN_DOWN;timer_init();timer = 0;}elsebtn_status = BTN_UP;}ISR(TIM0_COMPA_vect){timer++;}The code above is suppose to allow my power button to act as a soft latching switch. When the button is pressed it triggers an external inturrpt on pin 2, waking the chip from sleep and counting how long its been pressed. If it reaches the threshold it then drives pin 3 labeled "GATE" low, which in turn would allow the P-channel fet to switch and allow power to flow from the battery to the boost converter, thus powering the rest of the system. If the button is depressed again for a certain length of time, the gate pin is driven high, turning off the fet, and putting the ATtiny13A into sleep until pressed again. I found the code above online and was able to get it working with a ATtiny13A DIP package on a breadboard. I was using a different MOSFET than the one listed above but it appeared to function properly. I'm not sure if there is some blatantly obvious issue with my code above. I'm rather new to coding, especially when dealing with registers and chips in this way.The issue I'm having is that when I connect a lipo to the board the ATtiny13a doesn't turn on the MOSFET. If I short the drain pin of the MOSFET to the positive side of the battery pad it turns on the board and THEN the ATtiny13a controls it as expected. If I disconnect the battery and reconnect, the same issue arises....WHY? What is causing this issue???Any help or guidance on this problem of mine would be greatly appreciated!

author: Kuusou
author_rank: Regular Contributor
timestamp: December 07, 2020, 12:23:49 am
content: Quick update, when I disconnect and reconnect the lipo the BTN pin is reading about 2.85V and when I press the power button it's going low as expected. However the GATE pin is reading the same voltage as the lipo but when I press the power button it's not going low to turn on the MOSFET. Why would shorting the drain pin of the MOSFET to the positive battery terminal change this?Upon further testing it appears the BTN is actually going from 2.8V to 3.14V when pressedI have no idea why its showing stranger behavior like this.

author: sleemanj
author_rank: Super Contributor
timestamp: December 07, 2020, 02:41:20 am
content: See the Note on page 8 of the datasheet for your protection IChttps://ic-fortune.com/upload/Download/FS312F-G-DS-12_EN.pdfthis is what I would look at as the cause of your "acts weird when I first connect the battery" issue.It is common for such protection chips to start in an uncertain state and require charge connection or shorting to get them into a known state.

author: Kuusou
author_rank: Regular Contributor
timestamp: December 07, 2020, 02:52:07 am
content: Quote from: sleemanj on December 07, 2020, 02:41:20 amWOW! You're absolutely correct, that solved my issue. THANK YOU SO MUCH.