एटीटीनी वॉचडॉग और बाधा

मैं रिले के साथ एक Arduino से एक Arduino Barebone को नियंत्रित करने की कोशिश कर रहा हूँ। मूल रूप से जब attiny शुरू होता है तो इसे 4 सेकंड के लिए arduino पर स्विच करना चाहिए। Arduino attiny के एक डिजिटल पिन पर एक सिग्नल भेजता है और जब तक यह ऊंचा करने के लिए सेट है, इसे काम छोड़ देना चाहिए। यदि यह कम है तो attiny के रिले स्विच करना चाहिए।

समस्या यह है कि इस मामले में कोड में कुछ बदलाव इंटरप्ट को एटिनी (जो arduino का स्विच करेगा) को रीसेट कर देगा। बाधा बिल्कुल काम नहीं करती है।

#include 
#include 
#include 
#include 

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

int pinBoard = 0;
bool boardOn = false;
bool startBoard_flag = false;
int pinBoardReturn = 3;

volatile boolean f_wdt = 1;

void setup() {
  cli();//disable interrupts during setup
  pinMode(pinBoard, OUTPUT);
  pinMode(pinBoardReturn, INPUT);
  setup_watchdog(9);
  cbi(ADCSRA, ADEN);                  //switch Analog to Digitalconverter OFF
 //cli();//disable interrupts during setup
  for (int i = 0; i < 10; i++) {
    digitalWrite(pinBoard, HIGH);
    delay(100);
    digitalWrite(pinBoard, LOW);
    delay(100);
  }

  PCMSK |= (1 << PCINT1); //sbi(PCMSK,INTERRUPTPIN) also works but I think this is more clear//tell pin change mask to listen to pin2 /pb3 //SBI
  GIMSK |= (1 << PCIE);  //enable PCINT interrupt in the general interrupt mask //SBI

  startBoard();

  DDRB &= ~(1 << DDB1); //cbi(DDRB, DATADIRECTIONPIN);//  set up as input  - pin2 clear bit  - set to zero
  PORTB |= (1 << PB1); //cbi(PORTB, PORTPIN);// disable pull-up. hook up pulldown resistor. - set to zero
}


void startBoard() {
  digitalWrite(pinBoard, HIGH);
  boardOn = true;
  startBoard_flag = false;
  cli();                                 //Disable interrupts
  delay(4000);
}

void shutdownBoard() {
  digitalWrite(pinBoard, LOW);
  boardOn = false;
}

void loop() {
  if (f_wdt == 1) {//wait for timed out watchdog/flag is set when a watchdog timeout occurs
    f_wdt = 0;    //reset flag
    if (startBoard_flag) {
      startBoard();
    }
    bool boardReturn = digitalRead(pinBoardReturn);
    if (boardOn && !boardReturn) {
      shutdownBoard();
    }
    system_sleep();
  }
}

//****************************************************************
// set system into the sleep state
// system wakes up when wtchdog is timed out
void system_sleep() {

 //GIMSK |= _BV(PCIE);                    //Enable Pin Change Interrupts
 //PCMSK |= _BV(PCINT3);                  //Use PB3 as interrupt pin

  set_sleep_mode(SLEEP_MODE_PWR_DOWN);   //replaces above statement
  sleep_enable();                        //Sets the Sleep Enable bit in the MCUCR Register (SE BIT)
  sleep_cpu();                           //sleep

 //PCMSK &= ~_BV(PCINT3);                 //Turn off PB3 as interrupt pin
  sleep_disable();                       //Clear SE bit

 //sei();                                 //Enable interrupts
}

//****************************************************************
// 0=16ms, 1=32ms,2=64ms,3=128ms,4=250ms,5=500ms
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
void setup_watchdog(int ii) {

  byte bb;
  int ww;
  if (ii > 9 ) ii = 9;
  bb = ii & 7;
  if (ii > 7) bb |= (1 << 5);
  bb |= (1 << WDCE);
  ww = bb;

  MCUSR &= ~(1 << WDRF);
 //start timed sequence
  WDTCR  |= (1 << WDCE) | (1 << WDE);
 //set new watchdog timeout value
  WDTCR  = bb;
  WDTCR  |= _BV(WDIE);
}
//****************************************************************
// Watchdog Interrupt Service/is executed when  watchdog timed out
ISR(WDT_vect) {
  f_wdt = 1;//set global flag
}

ISR(PCINT_VECTOR) {
  for (int i = 0; i < 4; i++) {
    digitalWrite(pinBoard, HIGH);
    delay(1000);
    digitalWrite(pinBoard, LOW);
    delay(1000);
  }
  startBoard_flag = true;
  f_wdt = 1;//set global flag
}
1
@MikaelPatel यह है? मेरा मानना ​​है कि यह सिर्फ "एनओपी" निर्देशों के साथ एक लूप है? प्रतीक्षा करें, यह: forum.arduino.cc/index.php?topic=46452.0 - मुझे बताता है कि यह मिलिज़ का उपयोग करता है, जो मुझे लगता है कि एक टाइमर का उपयोग करता है! (एवीआर विलंब कार्यों ने टाइमर का उपयोग नहीं किया)।
जोड़ा लेखक dotnetengineer, स्रोत
अनुक्रम "क्ली (); देरी (...);" देरी के रूप में बहुत अच्छा विचार नहीं है() टाइमर इंटरप्ट पर निर्भर करता है।
जोड़ा लेखक Mikael Patel, स्रोत
@ पॉल एक अच्छी तरह से स्रोत कोड की जांच कर सकते हैं। क्या आपके पास एटीटीनी कोर का एक लिंक है जिसका आप उपयोग कर रहे हैं? चलो देरी() की जांच करें।
जोड़ा लेखक Mikael Patel, स्रोत
इसलिए निर्दिष्ट समय की प्रतीक्षा करने के लिए मुझे वॉचडॉग के लिए काउंटर होगा?
जोड़ा लेखक Rex Kerr, स्रोत

1 उत्तर

देरी कोड को अलग करना इंगित करता है कि यह micros का उपयोग करता है जिसे काम पर इंटरप्ट की आवश्यकता होती है।

void delay(unsigned long ms)
{
 27a:   cf 92           push    r12
 27c:   df 92           push    r13
 27e:   ef 92           push    r14
 280:   ff 92           push    r15
 282:   cf 93           push    r28
 284:   df 93           push    r29
 286:   6b 01           movw    r12, r22
 288:   7c 01           movw    r14, r24
    uint16_t start = (uint16_t)micros();
 28a:   d3 df           rcall   .-90        ; 0x232 
 28c:   eb 01           movw    r28, r22

    while (ms > 0) {
 28e:   c1 14           cp  r12, r1
 290:   d1 04           cpc r13, r1
 292:   e1 04           cpc r14, r1
 294:   f1 04           cpc r15, r1
 296:   79 f0           breq    .+30        ; 0x2b6 
        yield();
 298:   ea d0           rcall   .+468       ; 0x46e 
        if (((uint16_t)micros() - start) >= 1000) {
 29a:   cb df           rcall   .-106       ; 0x232 
 29c:   6c 1b           sub r22, r28
 29e:   7d 0b           sbc r23, r29
 2a0:   68 3e           cpi r22, 0xE8   ; 232
 2a2:   73 40           sbci    r23, 0x03   ; 3
 2a4:   a0 f3           brcs    .-24        ; 0x28e 
            ms--;
 2a6:   81 e0           ldi r24, 0x01   ; 1
 2a8:   c8 1a           sub r12, r24
 2aa:   d1 08           sbc r13, r1
 2ac:   e1 08           sbc r14, r1
 2ae:   f1 08           sbc r15, r1
            start += 1000;
 2b0:   c8 51           subi    r28, 0x18   ; 24
 2b2:   dc 4f           sbci    r29, 0xFC   ; 252
 2b4:   ec cf           rjmp    .-40        ; 0x28e 
        }
    }
}
 2b6:   df 91           pop r29
 2b8:   cf 91           pop r28
 2ba:   ff 90           pop r15
 2bc:   ef 90           pop r14
 2be:   df 90           pop r13
 2c0:   cf 90           pop r12
 2c2:   08 95           ret

ऐसा लगता है कि wiring.c में कोड वास्तव में ATTiny85 कोर पर उपयोग किया जा रहा है:

void delay(unsigned long ms)
{
    uint16_t start = (uint16_t)micros();

    while (ms > 0) {
        yield();
        if (((uint16_t)micros() - start) >= 1000) {
            ms--;
            start += 1000;
        }
    }
}

इंटरप्ट को बंद करना और फिर देरी करना एक बुरा विचार TM है।


तो निर्दिष्ट समय के लिए प्रतीक्षा करने के लिए मुझे वॉचडॉग के लिए काउंटर होगा?

वॉचडॉग टाइमर का उपयोग निश्चित रूप से 4 सेकंड के लिए प्रतीक्षा करने का एक तरीका है।

3
जोड़ा
खराब विचार (टीएम) के लिए +1। मुझें यह पसंद है! बाकी का जवाब भी निश्चित रूप से इसके लायक है।
जोड़ा लेखक Louis Rhys, स्रोत
उत्कृष्ट प्रयास और विवरण।
जोड़ा लेखक Chetan Bhargava, स्रोत