Attiny412 Arduino megatinyCore sleepMode

Gast #6709915
Lesenswert?

Hallo zusammen,

ich mache gerade die ersten Schritte mit dem Attiny412 und der 
megaTinyCore in Arduino.

Ich habe leider ein Problem mit dem "aufwachen" aus dem Sleep-Mode mit 
einer steigenden Flanke an einem Pin.

https://cdn.tindiemedia.com/images/resize/PrhuQ78RWdU0AKZwkpfWuOkc2gk=/p/full-fit-in/2336x1752/i/77443/products/2019-08-25T00%3A37%3A05.079Z-ATtiny_xy2.png?1606306133

An Pin 2 (also PA1) habe ich einen Taster. Dieser ist an der einen Seite 
an 5V und an der anderen Seite an Pin 2 (PA1) angeschlossen.

Normal sollte ja beim drücken der Taste ein High anliegen und damit der 
Mikrocontroller aufwachen. Doch leider macht er das nicht.
Später würde ich gerne auch noch einen Wert eines Sensors mittels ADC 
auslesen, aber da bis jetzt nicht einmal das aufwachen klappt, habe ich 
den Code mal auf das Minimum reduziert.

Die Pixel LEDs hängen an der 5V Versorgungsspannung und GND hängt am 
"Collector" eines NPN Transistor. Die Basis mit 10kOhm an Pin 1 (PA7) 
und der Emitter ist mit Masse verbunden.
Die Datenleitung ist mit einem 300Ohm widerstand mit Pin 3 (PA2) 
verbunden.

In Zeile 28, habe ich es eigentlich mit RISING versucht, aber das klappt 
leider nicht. Mit BOTHEDGES klappt es ein paar mal, dann hängt sich der 
uC irgendwie auf und ich bekomme Ihn nicht mehr geweckt.
Zeile 29 benötige ich zum ausschalten der Pixel LEDs. Diese verbinden 
sich sonst über die Datenleitung mit der Masse und ich benötige zu viel 
Strom.

Ifrgendwie bin ich ratlos. Ich suche schon die ganze Zeit im Internet 
aber finde leider nichts gescheites.

Hier habe ich mich schon eingelesen:
http://www.technoblogy.com/show?2RA3
https://github.com/SpenceKonde/megaTinyCore/blob/master/megaavr/extras/PowerSave.md

1
#include <tinyNeoPixel.h>
2
#include <avr/sleep.h>
3

4
// Which pin on the Arduino is connected to the NeoPixels?
5
#define PIN            3
6
// How many NeoPixels are attached to the Arduino?
7
#define NUMPIXELS      3
8
tinyNeoPixel strip = tinyNeoPixel(NUMPIXELS, PIN, NEO_GRBW + NEO_KHZ800);
9

10
ISR(PORTA_PORT_vect) {
11
  PORTA.INTFLAGS = PORT_INT1_bm;
12
}
13

14
void setup() {
15
   pinMode(4, INPUT_PULLUP);
16
   PORTA.PIN1CTRL = PORT_PULLUPEN_bm;
17
   delay(100);
18
   strip.begin();
19

20
   set_sleep_mode(SLEEP_MODE_PWR_DOWN);
21
   sleep_enable();
22
}
23

24
void loop() {
25
   LightLEDColor(100, 0, 0, 0);
26
   delay(5000);
27
   LightLEDColor(0,0,0,0);
28
   PORTA.PIN1CTRL = PORT_PULLUPEN_bm | PORT_ISC_BOTHEDGES_gc;
29
   digitalWrite(3, HIGH);
30
   pinMode(3,INPUT);
31
   sleep_cpu();
32
   strip.begin();
33
   PORTA.PIN1CTRL = PORT_PULLUPEN_bm; 
34
   strip.begin();   
35
}
36

37
void LightLEDColor(int R, int G, int B, int W)
38
{
39
   for (int i = 0; i < NUMPIXELS; i++) {
40
    strip.setPixelColor(i, strip.Color(R, G, B, W));
41
    delay(1);
42
  }
43
  strip.show();
44
}
#6709943
Lesenswert?

<An Pin 2 (also PA1) habe ich einen Taster. Dieser ist an der einen 
Seite
an 5V und an der anderen Seite an Pin 2 (PA1) angeschlossen>

PA1 liegt durch Pullup auf Vcc . Leg den Taster auf Masse.

Unbenutzte Pins ziehen im Deepsleep 1mA, also abschalten:
PORTA.PINxCTRL =4;    //INPUT_DISABLE  ,Digital input buffer disabled
Gast #6710146
Lesenswert?

Hallo,
danke für den Hinweis. Habe es ausprobiert mit Taster auf GND und das 
hat auch funktioniert.
Dann habe ich noch weiter versucht und habe es nochmal mit dem Taster an 
5V versucht.
So hat das dann auch geklappt. Änderung in Zeile 23.

Jetzt wollte ich zum ausprobieren mal einen AM312 Bewegungsmelder als 
Auslöser verwenden.
https://i.stack.imgur.com/qWMTw.jpg

Dieser hat mit dem Multimeter ein 3V ausgangssignal bei Bewegung für 2 
Sekunden.
Nun dachte ich, ich kann einfach das OUT an den Pin 2 (PA1) anschliessen 
kann und damit den Mikrocontroller aufwecken kann.
Leider nicht. Mit dem Multimeter iegen jetzt an OUT nur noch 0V an bei 
Bewegung. Löse ich die Verbindung zwischen Sensor OUT und uC Pin 2 
(PA1), dann messe ich an OUT des Sensors wieder 3V bei Bewegung.

Liegt dies am Pullup des PIN 2 ???
Ich dachte ich könnte mir si vielleicht sogar noch den Taster sparen, 
aber ist doch nicht so einfach. Oder doch und ich mache es falsch?
1
#include <tinyNeoPixel.h>
2
#include <avr/sleep.h>
3
// Which pin on the Arduino is connected to the NeoPixels?
4
#define PIN            3
5
// How many NeoPixels are attached to the Arduino?
6
#define NUMPIXELS      3
7
tinyNeoPixel strip = tinyNeoPixel(NUMPIXELS, PIN, NEO_GRBW + NEO_KHZ800);
8
ISR(PORTA_PORT_vect) {
9
  PORTA.INTFLAGS = PORT_INT1_bm;
10
}
11
void setup() {
12
   pinMode(4, INPUT_PULLUP);
13
   PORTA.PIN1CTRL = PORT_PULLUPEN_bm;
14
   delay(100);
15
   strip.begin();
16
   set_sleep_mode(SLEEP_MODE_PWR_DOWN);
17
   sleep_enable();
18
}
19
void loop() {
20
   LightLEDColor(100, 0, 0, 0);
21
   delay(5000);
22
   LightLEDColor(0,0,0,0);
23
   PORTA.PIN1CTRL = PORT_ISC_LEVEL_gc | PORT_INVEN_bm;
24
   digitalWrite(3, HIGH);
25
   pinMode(3,INPUT);
26
   sleep_cpu();
27
   strip.begin();
28
   PORTA.PIN1CTRL = PORT_PULLUPEN_bm; 
29
   strip.begin();   
30
}
31
void LightLEDColor(int R, int G, int B, int W)
32
{
33
   for (int i = 0; i < NUMPIXELS; i++) {
34
    strip.setPixelColor(i, strip.Color(R, G, B, W));
35
    delay(1);
36
  }
37
  strip.show();
38
}
#6710174
Lesenswert?

DerNeue schrieb:
> Nun dachte ich, ich kann einfach das OUT an den Pin 2 (PA1) anschliessen
> kann und damit den Mikrocontroller aufwecken kann.
> Leider nicht.

Doch.


DerNeue schrieb:
> Mit dem Multimeter iegen jetzt an OUT nur noch 0V an bei
> Bewegung. Löse ich die Verbindung zwischen Sensor OUT und uC Pin 2
> (PA1), dann messe ich an OUT des Sensors wieder 3V bei Bewegung.
>
> Liegt dies am Pullup des PIN 2 ???

Mit dem AM312 brauchst du keinen Pullup.

Trotzdem ist etwas falsch. Der Pullup liefert eine positive Spannung und 
der AM312 auch. Woher dann 0V?
Gast #6711009
Lesenswert?

Hallo zusammen,

also Danke schonmal für eure Antworten.

Ich habe jetzt mal ein ganz einfachen Code geschrieben. Die LEDs 
leuchten bei einem HIGH des AM312 auf und gehen aus, wenn dieser auf LOW 
ist.

Also der elektrische Aufbau scheint erstmal zu klappen.

Wenn ich in Zeile 13 von INPUT auf INPUT_PULLUP Wechsel, dann klappt es 
nicht mehr. Dann gehen einmal die LEDs an und nicht mehr aus.

Nun ist die Frage. Wie kann ich das in den Sleep Code implementieren?
1
#include <tinyNeoPixel.h>
2

3
// Which pin on the Arduino is connected to the NeoPixels?
4
#define PIN            3
5

6
// How many NeoPixels are attached to the Arduino?
7
#define NUMPIXELS      3
8

9
int StatusMotionOld = 0;
10
tinyNeoPixel strip = tinyNeoPixel(NUMPIXELS, PIN, NEO_GRBW + NEO_KHZ800);
11

12
void setup() {
13
  pinMode(2, INPUT);
14
  strip.begin(); // This initializes the NeoPixel library.
15
}
16

17
void loop() {
18
   int StatusMotion = digitalRead(2);
19
   if (StatusMotion == StatusMotionOld)
20
   {}
21
   else{
22
   if (StatusMotion == HIGH) {
23
      strip.begin();
24
      LightLEDColor(100, 0, 0, 0);
25
      }
26
    else
27
    {
28
      pinMode(3, INPUT);
29
      digitalWrite(3, HIGH);
30
      delay(1000);
31
      }
32
    StatusMotionOld = StatusMotion;
33
   }
34
}
35

36
void LightLEDColor(int R, int G, int B, int W)
37
{
38
  for (int i = 0; i < NUMPIXELS; i++) {
39
    // pixels.Color takes RGBW values, from 0,0,0,0 up to 255,255,255,255
40
    strip.setPixelColor(i, strip.Color(R, G, B, W)); // Moderately bright green color.
41
    delay(1);
42
  }
43
  strip.show();
44
}
#6711261
Lesenswert?

Hallo,

ernst gemeinter Tipp. Gehe bitte nochmal die Bsp. der IDE durch. Deine 
ständige Konfiguration vom Taster macht keinen Sinn. Eingänge und 
Ausgänge werden in der Regel zu 99% einmal konfiguriert. Danach werden 
nur noch Pegel eingelesen und bei Ausgängen Pegel umgeschalten.
#6711278
Lesenswert?

DerNeue schrieb:
> Nun ist die Frage. Wie kann ich das in den Sleep Code implementieren?

Der hybride Code ist etwas verwirrend, aber AVR ohne Arduino sieht 
ungefähr so aus:
1
/*------------------------------------------------
2
  ATtiny412 simple PIR LED control
3

4
         VDD 1|‾‾‾‾‾‾‾|8 GND 
5
         PA6 2|       |7 PA3
6
         PA7 3|       |6 UPDI 
7
 PIR --- PA1 4|_______|5 PA2 --- LED
8

9
 (PIR Sensor Output Voltage = VDD)
10
--------------------------------------------------*/
11

12
#include <avr/io.h>
13
#define F_CPU 3333333UL                      // default
14
#include <util/delay.h>
15
#include <avr/interrupt.h>
16
#include <avr/sleep.h>
17

18
ISR(PORTA_PORT_vect) 
19
{
20
  PORTA.INTFLAGS = PORT_INT1_bm;             // clear the interrupt flag
21
}
22

23
int main(void)
24
{
25
  PORTA.PIN1CTRL = PORT_INVEN_bm;             // invert PA1 input
26
  PORTA.DIRSET = PIN2_bm;                     // set PA2 as output
27
  SLPCTRL.CTRLA = SLPCTRL_SMODE_PDOWN_gc;     // select Power-Down sleep mode
28
  sei();                                      // enable global interrupts
29

30
  while (1)
31
  {
32
    PORTA.OUTSET = PIN2_bm;                   // PA2 ON
33
    _delay_ms(5000);                          // 5s ON
34
    PORTA.OUTCLR = PIN2_bm;                   // PA2 OFF
35

36
    PORTA.PIN1CTRL &= ~PORT_ISC_gm;           // clear ISC field
37
    PORTA.PIN1CTRL |= PORT_ISC_LEVEL_gc;      // level interrupt on PA1
38
    sleep_mode();                             // sleep
39
                                              // waked if PA1=HIGH
40
    PORTA.PIN1CTRL &= ~PORT_ISC_gm;           // clear ISC field
41
    PORTA.PIN1CTRL |= PORT_ISC_INTDISABLE_gc; // disable interrupt on PA1
42
  }
43
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren