Wziąłem się za moją pierwszą modyfikację latarki. W tym celu między innymi kupiłem driver Nanjg 105C. Muszę go tylko przerobić na sterowanie microswitchem.
Niestety żadnego fajnego softu w internecie się nie znajdzie, więc pozostaje coś wklepać samemu. Znalazłem na stronie http://drjones.nerdcamp.net/mini.html prosty przykład softu do sterowania microswitchem. Po wgraniu go do Attiny w driverze działa bardzo fajnie. I co najważniejsze, rozumiem ten kod, więc będę mógł go pod siebie przerobić.
Mam tylko problem z trybem uśpienia. W tym przykładzie go nie ma i driver przy wyłączonej latarce pobiera około 2mA, więc dużo za dużo.
Niestety nie ogarniam jak zmusić Attiny do uśpienia, gdy latarka jest wyłączona. Znalazłem taki przykład: http://www.eevblog.com/forum/microcontr ... interrupt/ - jedyny który mi zadziałał i udało mi się zejść do 170uA, co już jest wynikiem znacznie lepszym. Jednak z tego co czytam wszystkie te "super softy" w trybie uśpienia pobierają około 5uA. Dlatego mam prośbę, czy ktoś mógłby mi pomóc i dopisać czego mi brakuje, żeby jeszcze zmniejszyć pobór prądu. Mój kod poniżej:
Kod: Zaznacz cały
//MiniMo -- minimalistic driver firmware for momentary buttons (no blinkies) -- DrJones 2014
#define F_CPU 4800000 //use fuses low:0x75 high:0xff
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
//change modes here; just change/add/delete values. The "0" is 'off'
uint8_t modes[]={0, 8,90,255}; //PWM values, 6..255 - LEAVE THE "0" THERE
void powerDown(void)
{
GIFR |= (1<<PCIF); // Clear eventually occurred previous pin change interrupts
GIMSK |= (1<<PCIE); // Activate Pin change interrupts
MCUCR = (MCUCR | (1<<SM1)) & ~(1<<SM0);
MCUCR |= (1<<SE); //Enable Power-Down
sleep_mode();
MCUCR &= ~(1<<SE); //Disable Power-Down
GIMSK &= ~(1<<PCIE); // Deactivate Pin change interrupts
}
ISR(PCINT0_vect)
{
}
int main() {
DDRB=2; PORTB=8; //define PB1 as output and pull-up switch on PB3
PCMSK |= (1<<PCINT3); // Sets the Pin change interrupt mask, only PB3 will trigger the PCINT once it is enabled before sleep
SREG |= (1<<SREG_I); //Enables Interrupts globally after setup
TCCR0A=32+3; TCCR0B=1; //PWM setup, 18kHz
uint8_t count=0,mode=0,waspressed=0, lastmode=1; //define some variables used below
while(1) { //endless loop
if ((PINB&8)==0) { //when the button is pressed (PB3 pulled down)
count++; //count length of button press
if (count==16) { //pressed long (16*25ms=0.4s)
if (mode>0) {lastmode=mode; mode=0;} //was on? -> off, but remember the mode
else mode=lastmode; //was off? -> on, with previous mode.
}
waspressed=1; //remember that the button was pressed, see below
}
else { //button not pressed
if (waspressed) { //but it was pressed, so it has just been released!
waspressed=0; //reset that
if (count<16 && mode>0) { //really was a short press AND the light is on
mode++; if (mode>=sizeof(modes)) mode=1; //next mode, wrap around
}
count=0; //reset counter
}
}
OCR0B=modes[mode]; //set PWM level (0 is off)
if (mode==0 && (PINB&8)!=0) powerDown();
_delay_ms(25); //wait a bit before checking again, important for counting
}
}