Får inte SleepMode att fungera korrekt - Arduino MEGA

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
fosfor
Inlägg: 453
Blev medlem: 13 februari 2013, 05:43:15
Kontakt:

Re: Får inte SleepMode att fungera korrekt - Arduino MEGA

Inlägg av fosfor »

ToPNoTCH skrev:Nää...18 är väl interrupt 5

Kolla här så klarnar det..

https://www.arduino.cc/reference/en/lan ... interrupt/

Det här var väl väldigt förvirrande?? :shock:
Först står det "For historical reasons, this numbering does not always correspond directly to the interrupt numbering on the ATmega chip (e.g. int.0 corresponds to INT4 on the ATmega2560 chip)."
Sen i listan står det att Ext int 3 går till pinne 20.
Men på min Arduino MEGA står det att Ext int 3 går till pinne 18...

????
snigelen
Inlägg: 815
Blev medlem: 8 maj 2009, 11:02:14
Ort: Lund

Re: Får inte SleepMode att fungera korrekt - Arduino MEGA

Inlägg av snigelen »

Jo det är förvirrande att gå mellan Arduino-språk till mega2560-datablad-språk. Skall man använda datablad med arduino behöver man typ en sån här bild: https://www.arduino.cc/en/Hacking/PinMapping2560
Men när det gäller externa interrupt är det ju ännu mer förvirrat.

T.ex INT4-7 finns på PE4-PE7, där de två sista inte är utdragna på Arduino mega. Dessutom kallas INT4 för INT0 och INT5 för INT1 i arduino.

Men skall man vakna med en knapptryckning kan man även välja PCINTx (Pin Change Int.) som finns på lite fler pinnar. Men då funkar bara "idle-sleep" och att vakna på ändring av pinnens tillstånd. Jag vet inte om det finns stöd för det i Arduino-miljön, men det går att fixa till ändå. Kan visa ett exempel om du vill.
Användarvisningsbild
fosfor
Inlägg: 453
Blev medlem: 13 februari 2013, 05:43:15
Kontakt:

Re: Får inte SleepMode att fungera korrekt - Arduino MEGA

Inlägg av fosfor »

Snigelen:
Ja jag ser jättegärna exempel.

Det jag är ute efter är att när jag trycker på en knapp så ska den spara positionen som rotary encodern är på, och sedan gå i viloläge.
Sen vill jag ju ha en uppvakningsknapp för detta, som tar den Ur viloläget.
Till och med ennu bättre vore om den kunde spara position och gå ner i viloläge själv efter en viss tids inaktivitet.

Har fått det att "halvfungera", nu kan den om man trycker på en knapp spara sin position och sen gå in i Sleep Mode.
Men trots att jag går via en interrupt (pinne 19 på Arduino MEGA, Ext int 2 tror jag) så vill den inte vakna igen.
Så man måste hard-resetta den.

Här är koden som jag smusslat in ang Sleep Mode
(baserat på https://arduino.stackexchange.com/quest ... n-mega2560)

Kod: Markera allt

#include <avr/sleep.h>

Kod: Markera allt

int WakeUpPin = 19;           // KNAPP        ---        Väcker maskinen
int GoToSleepPin = 18;        // KNAPP        ---        Knapp som försätter MEGA i SLEEP MODE - Ext Int 3

Kod: Markera allt

void wakeUpNow() {  
}  

Kod: Markera allt

  pinMode(WakeUpPin, INPUT);                //Declarar denna som input     MEGA's  input är 19        Knapp       -        VÄCKER
  pinMode(GoToSleepPin, INPUT);          //Declarar denna som input     MEGA's  input är 18        Knapp       -        Sparar pos och försätter i SLEEP MODE

Kod: Markera allt

{  
  //  pinMode(WakeUpPin, INPUT_PULLUP);       // originalraden
  //  attachInterrupt(2, wakeUpNow, LOW);     // originalraden - use interrupt 0 (pin 2) and run function wakeUpNow when pin 2 gets LOW  
  
  pinMode(WakeUpPin, INPUT_PULLUP);   
  attachInterrupt(2, wakeUpNow, HIGH);        // use interrupt 0 (pin 2) and run function wakeUpNow when pin 2 gets LOW  
}  


}

// SLEEP MODE - SleepNow måste declareras, raden nedan gör detta, annars blir det 'sleepNow' was not declared in this scope
void sleepNow() {  
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);        // sleep mode is set here  
    sleep_enable();                             // enables the sleep bit in the mcucr register 
    sleep_mode();                               // here the device is actually put to sleep!!  
    
attachInterrupt(2, wakeUpNow, HIGH);             // use interrupt 0 (pin 2) and run function 
     
    
    // THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP  
    sleep_disable();                            // first thing after waking from sleep: disable sleep...  
    detachInterrupt(2);                         // disables interrupt 0 on pin 2 so the wakeUpNow code will not be executed during normal running time.  
}

Kod: Markera allt

  // ------------------------------------------------------------------------------------------------------------------------******************************************
  // ------------------------------------------------------------------------------------------------------------------------******************************************
  // -------- Denna ska väcka upp Arduinon från SLEEP MODE --------

  {
    val = digitalRead(WakeUpPin);              // Knapp som sparar position
    if (val == HIGH) {                         // Kollar om knappen är tryckt

// HÄR NEDANFÖR SKA KOD FÖR UPPVÄCKNING LIGGA

    wakeUpNow();  
    sleep_disable();                            // first thing after waking from sleep: disable sleep...  
    detachInterrupt(2);                         // disables interrupt 0 on pin 2 so the wakeUpNow code will not be executed during normal running time.  
  

      delay(750);
      lcd.setCursor(0, 1);
      lcd.print("ARISE!");
      Serial.println("Waking up the machine");
      delay(750);
    }
  }




  // ------------------------------------------------------------------------------------------------------------------------******************************************
  // ------------------------------------------------------------------------------------------------------------------------******************************************
  // -------- SPARAR POSITION OCH FÖRSÄTTER MEGA I SLEEP MODE --------

  {
    val = digitalRead(GoToSleepPin);           // Knapp som sparar position och går in i SLEEP MODE
    if (val == HIGH) {                         // Kollar om knappen är tryckt
      UserStopPulseCount4 = PulseCount;
      EEPROM.put(24, UserStopPulseCount4);     // Skriver PulseCount numret till minnet, adressen är 24
      EEPROM.put(28, UserStopPulseCount4 + 1); //
      lcd.setCursor(0, 1);                     // Dessa två rader skriver till LCD, 0, 1 ärrad 2 och 1, 0 vore rad 1
      lcd.print(PulseCount);
      delay(750);
      lcd.setCursor(0, 1);
      lcd.print("OffOn SLEEP");
      Serial.println("Saving Off to On position to memory and initiates SLEEP MODE Zzzz...");
      delay(750);
      lcd.clear();                              // Tömmer skärmen
      lcd.setCursor(1, 0);                      // Visar Goodbye... på första raden av LCD
      lcd.print("Goodbye...");                  // Sista meddelandet innan den stänger ner
      delay(750);                               // Väntar lite
      lcd.clear();                              // Tömmer skärmen

// SOV FUNKTION HÄRUNDER

    sleepNow();                                 // Aktiverar SLEEP MODE - Kommer behöva interrupt wake up för att vakna från detta


    }
  }


snigelen
Inlägg: 815
Blev medlem: 8 maj 2009, 11:02:14
Ort: Lund

Re: Får inte SleepMode att fungera korrekt - Arduino MEGA

Inlägg av snigelen »

Du kan inte använda power down med INT3 det funkar bara med INT4-7. Med INT3 funkar bara Idle.

Edit: Glöm det jag skrev, se mitt nästa inlägg.
Senast redigerad av snigelen 14 maj 2019, 16:55:43, redigerad totalt 1 gång.
Användarvisningsbild
fosfor
Inlägg: 453
Blev medlem: 13 februari 2013, 05:43:15
Kontakt:

Re: Får inte SleepMode att fungera korrekt - Arduino MEGA

Inlägg av fosfor »

Idle, vad är det?

Int 7!?!

Av vad jag kan se på min MEGA ritning här så har jag bara Int 0 till 5 ?!
snigelen
Inlägg: 815
Blev medlem: 8 maj 2009, 11:02:14
Ort: Lund

Re: Får inte SleepMode att fungera korrekt - Arduino MEGA

Inlägg av snigelen »

Det finns INT0-7, men de två sista är inte utragna till någon hylslist på Arduino Mega.

Men det verkar funka med INT3 också, som du har. Det är jag som missuppfattat fotnot 3 i den här bilden:
sleep.png
Det fotnot 3 egentligen menar är att INT4-7 bara funkar med låg nivå, medan de andra (INT0-3, PCINTx) kan trigga även kan använda änding av porten (hög-till låg och tvärt om).
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
fosfor
Inlägg: 453
Blev medlem: 13 februari 2013, 05:43:15
Kontakt:

Re: Får inte SleepMode att fungera korrekt - Arduino MEGA

Inlägg av fosfor »

Här är koden för uppväckning som jag har just nu.
Den går till pinne 19 på MEGA'n, och är External Interrupt nr 2.
Kör med #include <avr/sleep.h> som biblioteket.
Detta fungerar inte, Arduinon vaknar inte vid knapptryckning.
Syns det något uppenbart konstigt?

Kod: Markera allt

  {
    val = digitalRead(WakeUpPin);        // Knapp som ska väcka upp
    if (val == HIGH) {                         // Kollar om knappen är tryckt

// HÄR NEDANFÖR SKA KOD FÖR UPPVÄCKNING LIGGA

    wakeUpNow();  
    sleep_disable();                            // first thing after waking from sleep: disable sleep...  
    detachInterrupt(2);                       // disables interrupt 0 on pin 2 so the wakeUpNow code will not be executed during normal running time.  


// Här nedanför är meddelande till LCD och Serial Monitor
      delay(750);
      lcd.setCursor(0, 1);
      lcd.print("Waking up");
      Serial.println("Waking up the machine");
      delay(750);
    }
  }
snigelen
Inlägg: 815
Blev medlem: 8 maj 2009, 11:02:14
Ort: Lund

Re: Får inte SleepMode att fungera korrekt - Arduino MEGA

Inlägg av snigelen »

Hej,

Du kan inte använda HIGH, det finns inget sådant i AVR. Du kan använda LOW och koppla knappen så att den drar pinnen låg då den trycks in.
The Due, Zero and MKR1000 boards allows also:

HIGH to trigger the interrupt whenever the pin is high.
Sedan behöver du inte läsa wakup-knappen eller anropa WakeUpNow(), det sker ju automatiskt av avbrottet.
snigelen
Inlägg: 815
Blev medlem: 8 maj 2009, 11:02:14
Ort: Lund

Re: Får inte SleepMode att fungera korrekt - Arduino MEGA

Inlägg av snigelen »

Jag kan försöka förklara varför vissa kombinationer fungerar och andra inte.

Externa interrupt kan konfigureras för falling edge, rising edge eller low level. Om avbrotten skall användas när MCU'n är igång så är det väl bara de två första som är aktuella eftersom den sista fortsätter att generera avbrott så länge nivån är låg, vilket inte är något problem för uppvakning eftersom man direkt kan stänga av avbrottet så fort man vaknat. Men för att falling/rising edge skall fungera[1] så måste IO-klockan vara igång och den enda sleep-mode som har det är Idle. Vill man sova djupare än så så stängs IO-klockan av och då kan inte edge-interrupten användas för att vakna utan bara LOW-level.

Ett alternativ är att använda pin-change-interrupt eftersom de fungerar assynkront, dvs utan klocka. Men de har lite andra begränsningar, särskilt om man behöver använda flera av dem.

Fotnot:
[1] Nu funkar förvisso INT0-3 att använda assynkront på just 2560 och dess släktingar (i samma datablad). Men byter men till t.ex mega328P så fungerar det inte, så det är väl smartast att trigga på low-level för uppvakning eftersom det funkar på alla (icke antika) AVR.
Användarvisningsbild
fosfor
Inlägg: 453
Blev medlem: 13 februari 2013, 05:43:15
Kontakt:

Re: Får inte SleepMode att fungera korrekt - Arduino MEGA

Inlägg av fosfor »

Snigelen:

Ok, tack! Vad tycker du spontant jag skulle kunna göra med vad jag har tillgängligt?
Jag har bara ext int 3 och ext int 2 (pinne 18 och 19) tillgängliga. De andra är upptagna.
Jag behöver inte gå ner i något superdjupt energilågt viloläge, eftersom Arduino MEGA'n sitter på ett stort batteri.
Men ett enklare viloläge vore kul, och att jag kan väcka den med en knapptryckning.
snigelen
Inlägg: 815
Blev medlem: 8 maj 2009, 11:02:14
Ort: Lund

Re: Får inte SleepMode att fungera korrekt - Arduino MEGA

Inlägg av snigelen »

Använd vilken som helst av dem och välj att trigga på LOW-level så kan du använda vilken sleep-mode som helst, t.ex power-down som stänger av det mesta. Stäng av avbrottet i din avbrottsrutin. Koppla uppvakningsknappen från vald pinne till GND. Använd intern eller extern pull-up på pinnen.
SeniorLemuren
Inlägg: 7779
Blev medlem: 26 maj 2009, 12:20:37
Ort: Kristinehamn

Re: Får inte SleepMode att fungera korrekt - Arduino MEGA

Inlägg av SeniorLemuren »

Men om du har Mega 2560 så är väl inte pinne 18 och 19 avbrott 3 och 2? eller har jag helt fattat fel?
avbrot pinne.JPG
Här har du sedan ett exempel som beskriver hur man gör på ett tydligt sätt.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
snigelen
Inlägg: 815
Blev medlem: 8 maj 2009, 11:02:14
Ort: Lund

Re: Får inte SleepMode att fungera korrekt - Arduino MEGA

Inlägg av snigelen »

INT2 och INT3 gäller numreringen i databladet. Att sedan Arduino valt att kalla dessa INT.4 och INT.5 blir det ju inte mindre förvirrande av (vilket dessutom är pinne 45 och 46 på MCU-kapseln) :shock:
SeniorLemuren
Inlägg: 7779
Blev medlem: 26 maj 2009, 12:20:37
Ort: Kristinehamn

Re: Får inte SleepMode att fungera korrekt - Arduino MEGA

Inlägg av SeniorLemuren »

Precis, det är detta jag inte förstår. Om TS har ett Arduino Mega 2560 kort där man tydligt anger vilka pinnummer som hanterar respektive avbrott så fattar jag inte varför man inte skall gå efter detta. Alltså att INT2 är pin #21 och INT3 är pin #20 på Megakortet? Jag förutsätter förstås att TS använder Arduino IDE för att programmera Megan, kanske där jag missat? Ovanför tabellen med avbrottsnr/pinnummer står att
Note that in the table below, the interrupt numbers refer to the number to be passed to attachInterrupt().
och attachInterrupt() är ju det som TS använder i programmet.
snigelen
Inlägg: 815
Blev medlem: 8 maj 2009, 11:02:14
Ort: Lund

Re: Får inte SleepMode att fungera korrekt - Arduino MEGA

Inlägg av snigelen »

Läs nästa mening också (över tabellen). Det är ju det vi konstaterade för några inlägg sedan. Men visst man kan vara tydligare. INT2_D, INT4_A, PIN53_A osv skulle kanske funka (för datablad resp. arduino). Men när det gäller t.ex sleep-modes så är det databladet som gäller, inte Arduino-dokumentationen eftersom den inte nämner det (och mycket annat, vilket väl är poängen med Arduino).
Skriv svar