attiny op batterijen

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • sweebee
  • Registratie: Oktober 2008
  • Laatst online: 14:24
Ik ben bezig om een 433mhz pir sensor te maken met behulp van een attiny45/85. Nu moet dit natuurlijk zo efficiënt mogelijk omdat ik die wil laten draaien op 2 aaa batterijen.

Dit is mijn huidige code:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <avr/sleep.h>
#include <avr/interrupt.h>
#include <NewRemoteTransmitter.h>

int TxPin   =   0;       // 433Mhz transmitter pin
int inPin  =   1;       // Sensor input pin
int address =   349384;  // KAKU adres

int value = 0; 
int state = 0;
int state2 = 0;     
            
NewRemoteTransmitter transmitter(address, TxPin, 260, 3);

void setup() {
    pinMode(inPin, INPUT);
}


void loop() {

    value = digitalRead(inPin);   // read the input pin

    if(value == 1 and state == 0) {
      transmitter.sendUnit(1, true);
      state = 1;
      state2 = 0;
    }

    if(value == 0 and state2 == 0) {
      transmitter.sendUnit(1, false);
      state2 = 1;
      state = 0;
    }
 }


Ik heb avr sleep al ingeladen en interrupt (om met een input de attiny wakker te maken?) Maar ik kom er verder niet helemaal uit.

Op pin 1 van de attiny komt de pir sensor en op pin 0 komt de zender.

wat de attiny moet doen:

slapen
pir stuurt hoog signaal dan moet attiny wakker worden, signaal sturen en weer slapen
stuurt de pir vervolgens weer een laag signaal dat moet de attiny weer wakker worden, signaal sturen en gaan slapen.
etc.

Ik had al wel het volgende gevonden:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
const int switchPin = 3; // Interrupt pin

void sleep() {

    GIMSK |= _BV(PCIE);                     // Enable Pin Change Interrupts
    PCMSK |= _BV(PCINT3);                   // Use PB3 as interrupt pin
    ADCSRA &= ~_BV(ADEN);                   // ADC off
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);    // replaces above statement

    sleep_enable();                         // Sets the Sleep Enable bit in the MCUCR Register (SE BIT)
    sei();                                  // Enable interrupts
    sleep_cpu();                            // sleep

    cli();                                  // Disable interrupts
    PCMSK &= ~_BV(PCINT3);                  // Turn off PB3 as interrupt pin
    sleep_disable();                        // Clear SE bit
    ADCSRA |= _BV(ADEN);                    // ADC on

    sei();                                  // Enable interrupts
    } // sleep

ISR(PCINT0_vect) {
    // This is called when the interrupt occurs, but I don't need to do anything in it
    }

void loop() {
    sleep();
}

[ Voor 7% gewijzigd door sweebee op 10-03-2015 19:59 ]


Acties:
  • 0 Henk 'm!

  • jeroen3
  • Registratie: Mei 2010
  • Laatst online: 20:55
Je kunt meestal alleen uit deep-sleep komen met hardware level interrupt pinnen.
INT0 bijvoorbeeld.

_wfi laat alle overige clocks wel actief, zodat gpio pinchange interrupts nog werken. Als de tiny dat kan.

[ Voor 5% gewijzigd door jeroen3 op 10-03-2015 20:07 ]


Acties:
  • 0 Henk 'm!

  • Sissors
  • Registratie: Mei 2005
  • Niet online
Maar dan zal hij ook slechts een fractie van de mogelijke tijd op die batterijen werken.

Acties:
  • 0 Henk 'm!

  • sweebee
  • Registratie: Oktober 2008
  • Laatst online: 14:24
Het komt er op neer dat de attiny op pin 1 wakker moet worden, 1 functie moet uitvoeren en weer gaan slapen. Dus zodra pin 1 veranderd (hoog > laag of laag > hoog) moet die 1 functie uitvoeren en weer gaan slapen.

Ik heb nu dit, maar ik weet niet precies wat de interrupt/sleep nu precies doet.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// KAKU sensor

#include <avr/sleep.h>
#include <avr/interrupt.h>
#include <NewRemoteTransmitter.h>

int TxPin   =   0;       // 433Mhz transmitter pin
int inPin   =   1;       // Sensor input pin
int address =   349384;  // KAKU adres

int value  = 0; 
int state  = 0;
int state2 = 0;     
            
NewRemoteTransmitter transmitter(address, TxPin, 260, 3);

void setup() {
    pinMode(inPin, INPUT);
}


void sleep() {

    GIMSK |= _BV(PCIE);                     // Enable Pin Change Interrupts
    PCMSK |= _BV(PCINT1);                   // Use PB1 as interrupt pin
    ADCSRA &= ~_BV(ADEN);                   // ADC off
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);    // replaces above statement

    sleep_enable();                         // Sets the Sleep Enable bit in the MCUCR Register (SE BIT)
    sei();                                  // Enable interrupts
    sleep_cpu();                            // sleep

    cli();                                  // Disable interrupts
    PCMSK &= ~_BV(PCINT1);                  // Turn off PB1 as interrupt pin
    sleep_disable();                        // Clear SE bit
    ADCSRA |= _BV(ADEN);                    // ADC on

    sei();                                  // Enable interrupts
} // sleep

ISR(PCINT0_vect) {
    // This is called when the interrupt occurs, but I don't need to do anything in it
    }


void loop() {
    sleep();
    
    value = digitalRead(inPin);   // read the input pin

    if(value == 1 and state == 0) {
      transmitter.sendUnit(1, true);
      state = 1;
      state2 = 0;
    }

    if(value == 0 and state2 == 0) {
      transmitter.sendUnit(1, false);
      state2 = 1;
      state = 0;
    }
    
 }

Acties:
  • 0 Henk 'm!

  • jeroen3
  • Registratie: Mei 2010
  • Laatst online: 20:55
Als je de manual leest staat er wat je moet doen, wat er gebeurt, en wat wel en niet aan blijft tijdens sleep.
http://www.atmel.com/Imag...45-ATtiny85_Datasheet.pdf
Afbeeldingslocatie: https://dl.dropbox.com/s/htjz2rj2xefl7sv/2015-03-10%2021_14_19-www.atmel.com_Images_Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATti.png
PinChange interrupts werken dus niet. PinLevel interrupts wel. Bijvoorbeeld INT0 laag maken. Zie dat Other I/O niet werkt.

Pin 1 is nRESET*, PB5 fucnties moet je activeren met fuses volgens mij. (let op, je brickt hem met die fuse)
Pin 7 (PB2) is INT0, er is geen INT1. Alle overige pinnen kun je gebruiken.

*nRESET is nodig voor ISP. Ik raad je aan deze pin niet te gebruiken omdat programmeren dan niet meer makkelijk gaat. Let ook op bij mosi/miso, deze zijn ook voor ISP. Geen belasting aan deze pinnen als je ISP wil gebruiken op je uitendelijke bordje. (LEDs .o.i.d.) nRESET uiteraard voorzien van pullup.

Acties:
  • 0 Henk 'm!

  • sweebee
  • Registratie: Oktober 2008
  • Laatst online: 14:24
Dus pin 7 als input van pir gebruiken en als interrupt int0?

Level interrupt werkt bijv alleen van low > High of high> low? En niet beide?

Acties:
  • 0 Henk 'm!

  • sweebee
  • Registratie: Oktober 2008
  • Laatst online: 14:24
Oke, ik heb het aan de praat gekregen:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// ATMEL ATTINY 25/45/85 / ARDUINO
//
//                  +-\/-+
// Ain0 (D 5) PB5  1|o   |8  Vcc
// Ain3 (D 3) PB3  2|    |7  PB2 (D 2) Ain1
// Ain2 (D 4) PB4  3|    |6  PB1 (D 1) pwm1
//            GND  4|    |5  PB0 (D 0) pwm0
//                  +----+

#include <avr/sleep.h>
#include <avr/power.h>
#include <NewRemoteTransmitter.h>

const byte txPin = 3;  // pin 2          | 433Mhz zend pin
const byte inPin = 4; // pin 3 / PCINT4  | PIR pin

int address =   27951;  // KAKU adres

boolean input = false;
boolean state  = false;

NewRemoteTransmitter transmitter(address, txPin, 260, 3);

ISR (PCINT0_vect)
{
  // do something interesting here
}

void setup () {
  
  pinMode (txPin, OUTPUT);
  pinMode (inPin, INPUT);
  digitalWrite (inPin, HIGH);  // internal pull-up

  // pin change interrupt (example for D4)
  PCMSK  |= bit (PCINT4);  // want pin D4 / pin 3
  GIFR   |= bit (PCIF);    // clear any outstanding interrupts
  GIMSK  |= bit (PCIE);    // enable pin change interrupts

}

void loop () {

  input = digitalRead(inPin);   // read the input pin
  
  if(input == true && state == false) {
       transmitter.sendUnit(1, true);
       state = true;
       
     }

  if(input == false && state == true) {
       transmitter.sendUnit(1, false);
       state = false;
  }
  
  delay (10);
  goToSleep ();

}


void goToSleep () {
  
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  ADCSRA = 0;            // turn off ADC
  power_all_disable ();  // power off ADC, Timer 0 and 1, serial interface
  sleep_enable();
  sleep_cpu();
  sleep_disable();
  power_all_enable();    // power everything back on

}

Acties:
  • 0 Henk 'm!

  • jeroen3
  • Registratie: Mei 2010
  • Laatst online: 20:55
sweebee schreef op dinsdag 10 maart 2015 @ 22:29:
Level interrupt werkt bijv alleen van low > High of high> low? En niet beide?
Nee. Level interrupt werkt wanneer een pin laag is. Niet op de flank. De interrupt zal zich blijven herhalen zolang INT0 laag is. Iets om rekening mee te houden.
Level interrupts zijn asynchroon. Dat houdt in dat deze werkt, ongeacht of er clocks actief zijn.
Voor flankgevoeligheid is clock nodig. En die wil je graag uit hebben uit energiebesparing.
Pin levels om uit powerdown te komen dienen ook een minimale duur te hebben. Dit is vrij belangrijk.
Maar waarschijnlijk heeft de PIR zelf ook al een vertraging van enkele seconden. Dus dat is geen probleem.
De herhalende interrupts dan natuurlijk wel!

Alternatief is dat je in de interrupt, de interrupt zelf uitschakelt. Doet wat je moet doen, en daarna via de watchdog nogmaals wakker wordt om de interrupt weer in te schakelen. Mits natuurlijk INT0 weer hoog is geworden. Daarna ook de watchdog+oscillator weer uitzetten. Je kunt de watchdog dan ook gebruiken om nogmaals iets te sturen als de PIR nog steeds iets waarneemt.

Acties:
  • 0 Henk 'm!

  • sweebee
  • Registratie: Oktober 2008
  • Laatst online: 14:24
Met de sketch die ik net gepost heb, heb ik het volgende:

Pir inactief > vrijwel geen stroom
Pir actief > 0,098 mA volgens mijn meter.

Te doen op batterijen? Of kan ik hem nog zuiniger maken?

De pir geeft geen puls maar blijft een actief signaal sturen zolang er beweging is, die zit achter de interrupt.

[ Voor 31% gewijzigd door sweebee op 11-03-2015 18:24 ]


Acties:
  • 0 Henk 'm!

  • Sibylle
  • Registratie: Juli 2006
  • Laatst online: 13-07-2023
sweebee schreef op woensdag 11 maart 2015 @ 18:16:
Met de sketch die ik net gepost heb, heb ik het volgende:

Pir inactief > vrijwel geen stroom
Pir actief > 0,098 mA volgens mijn meter.

Te doen op batterijen? Of kan ik hem nog zuiniger maken?

De pir geeft geen puls maar blijft een actief signaal sturen zolang er beweging is, die zit achter de interrupt.
Wat is vrijwel geen stroom?
Want de meeste tijd zal hij zoveel gebruiken...dus dat is de meest relevante informatie die je wilt hebben.

Stel hij is continue actief, dan is het verbruik van de attiny dus 0,098 mA, als je dan 1000mAh lek vrije batterijen hebt, kun je dus 10204 uur draaien oftewel 425 dagen continue (dus zonder sleep mode).
Je kunt het beste zelf bepalen of dat genoeg is.

Ctrl+k


Acties:
  • 0 Henk 'm!

  • sweebee
  • Registratie: Oktober 2008
  • Laatst online: 14:24
Inactief geeft de meter 0,1 uA aan.

Edit: het hogere stroom verbruik komt door de pull-up weerstand. De interne pull up heeft een weerstand van 10K? Hoe kan ik dit stroomverbruik verminderen? tot hoe hoog mag de waarde zij van een pull up weerstand?

[ Voor 75% gewijzigd door sweebee op 11-03-2015 20:10 ]


Acties:
  • 0 Henk 'm!

  • DavidZH
  • Registratie: Oktober 2008
  • Laatst online: 20:23
Ik heb voor Pimatic een kaku-achtige schakelaar gemaakt (eentje die niet 12 keer de code verstuurt en dus de 433MHz bezet houd...) met een Tiny45.
Met een gewone aan-uit schakelaar is het verbruik:
uit: 60nA.
aan: 8µA vanwege de stroom door de pull-up van 35kΩ

De bedoeling is om er een hotelschakelaar van maken, maar omdat het dan niet te berekenen is in welke stand de schakelaar blijft staan, weet je dus ook het verbruik niet. Dit was trouwens op 2,7V en ik wil het gaan voeden met 3AAA's.

Ik wil ook nog kijken of een grotere weerstand het verbruik kan verkleinen zonder een zwevende input te veroorzaken.

Acties:
  • 0 Henk 'm!

  • sweebee
  • Registratie: Oktober 2008
  • Laatst online: 14:24
De schakelaar van KAKU zelf zend overigens niet zo vaak als die van elro. Heb zelf een paar kaku wandschakelaars icm met pimatic en dat werkt goed. De elro's werken niet lekker doordat ze heel veel zenden.

Zou jij eventueel je code willen sturen? Ik heb precies het zelfde nodig, en volgens mij is die van jou nog wat zuiniger dan de mijne? Alleen komt er bij mij een pir achter ipv een schakelaar (in principe het zelfde).

Acties:
  • 0 Henk 'm!

  • a.d.s
  • Registratie: Juni 2010
  • Laatst online: 27-09 17:52
sweebee schreef op woensdag 11 maart 2015 @ 18:53:
Edit: het hogere stroom verbruik komt door de pull-up weerstand. De interne pull up heeft een weerstand van 10K? Hoe kan ik dit stroomverbruik verminderen? tot hoe hoog mag de waarde zij van een pull up weerstand?
De interne pull-up van de ATtiny kun je uitschakelen, en extern een grotere gebruiken. Ik denk dat 100K nog wel werkt. Je zou ook kunnen gaan pollen door gebruik te maken van de watchdog timer om periodiek wakker te worden. Je kunt dan de pull-up alleen even inschakelen tijdens het testen van de input pin, en hem daarna weer uitzetten

[ Voor 12% gewijzigd door a.d.s op 18-03-2015 12:36 . Reden: polling optie ]


Acties:
  • 0 Henk 'm!

  • Dazzyreil
  • Registratie: November 2013
  • Laatst online: 24-09 23:31
sweebee schreef op woensdag 11 maart 2015 @ 18:16:
Met de sketch die ik net gepost heb, heb ik het volgende:

Pir inactief > vrijwel geen stroom
Pir actief > 0,098 mA volgens mijn meter.

Te doen op batterijen? Of kan ik hem nog zuiniger maken?

De pir geeft geen puls maar blijft een actief signaal sturen zolang er beweging is, die zit achter de interrupt.
Bedoel je niet 98mA? Zover ik weet gebruikt een PIR sensor minimaal 12mA.
Pagina: 1