WakeUp Pi

##WakeUp Pi
SleePiみたいなボード　
RaspiberryPiの電源コントローラ＆リアルタイムクロック基板です。

アメーバブログへ投稿していたけど回路図がうまく入らないのでこちらへ投稿します。
元記事　http://ameblo.jp/tamesuke-goto/entry-12266987870.html

![WakeuPi 85.png](https://qiita-image-store.s3.amazonaws.com/0/158760/13ffab1f-0419-e2c3-4a71-b3797d058872.png)

```
/*
 * WakeUp Pi ATtiny85
 * 2017/4/14
 * 
 * 

                 ATTiny85  
            RST |1---O---8| VCC
   PCINT3/A3/D3 |2       7| D2/A1/INT0/PCINT2
   PCINT4/A2/D4 |3       6| D1/PWM/PCINT1
            GND |4-------5| D0/PWM/A0/PCINT0
 
 */


#include <TinyWireS.h>

#define I2C_SLAVE_ADDRESS 0x5B // the 7-bit address

#include "TinyWireS.h"
// #include <TimeLib.h>

#ifndef TWI_RX_BUFFER_SIZE
#define TWI_RX_BUFFER_SIZE ( 16 )
#endif


#define FET  3      // GPIO FET pin 
#define SW1  1   // PowerON SW

#define DOWN 4  // Shutdown DIO for Rpi
#define SW2  4  // Option SW or DIO

struct led {
  int pin;   //  PIN No.
  bool on;   // ON/OFF status
  int cont;  // time count
  int ontime; // ON time (msec)
  int intval; // interval time (msec)
};

struct led waitled={DOWN,0,0,50,3000};
struct led wakeled={DOWN,0,0,50,1000};
struct led stopled={DOWN,0,0,1500,1600};

bool powon=false;
char stopping=0;

/* 
 *  byt0 ...  min
 *  byt1 ...  hour
 *  byt2 ...  day
 *  byt3 ...  WakeupSTART
 *  byt4 ...  ShutDownTimer
 */

enum {mins,hours,days,wakereg,downreg};

volatile uint8_t i2c_regs[] =
{
    0x01, 
    0x00, 
    0x00, 
    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
    0x00,
};


volatile byte reg_position;
const byte reg_size = sizeof(i2c_regs);

uint32_t  tim;
uint32_t  last;
uint32_t  mtim;
uint32_t  mlast;

uint32_t downtimer;
uint32_t waketimer;

void requestEvent()
{  
    reg_position %= reg_size;
    TinyWireS.send(i2c_regs[reg_position]);
    reg_position++;
}

void receiveEvent(uint8_t howMany)
{
    // Sanity check
    if ((howMany < 1) || (howMany > TWI_RX_BUFFER_SIZE)) return;
    
    reg_position = TinyWireS.receive();
    howMany--;

    while(howMany--)
    {
        reg_position %= reg_size;
        i2c_regs[reg_position] = TinyWireS.receive();
        reg_position++;
    }

    if(i2c_regs[downreg]){
      downtimer=i2c_regs[downreg];
    }

    if(i2c_regs[wakereg]){
      waketimer = i2c_regs[mins]*60L+i2c_regs[hours]*60L*60L+i2c_regs[days]*60L*60L*24L;
    } else {waketimer=0;}


}

void blinkled(int p,int c,int dly);
void blinkled2(struct led);
void poweron(void);

void setup(){
    mlast = mtim = millis();
    tim = millis()/1000;
    last =tim;
    pinMode(FET,OUTPUT);
    digitalWrite(FET ,LOW);   // Normal Power OFF
    pinMode(DOWN,OUTPUT);
    pinMode(SW1, INPUT_PULLUP);  // power on sw
    
    TinyWireS.begin(I2C_SLAVE_ADDRESS);
    TinyWireS.onReceive(receiveEvent);
    TinyWireS.onRequest(requestEvent);
}

bool timchk()
{
  tim = millis()/1000;
  if(tim==last)
    return false;
  last=tim;
  return true;  
}
/*   msec check NON Use
 *    
bool mtimchk()
{
  mtim = millis();
  if(mtim==mlast)
    return false;
  mlast=mtim;
  return true;  
}
*/

/*
 * Main Loop
 * 
 */

#define INTERVAL  40
void loop()
{
    static int intv=0;
  
    if(powon){
      TinyWireS_stop_check();
    }


    if((intv++ % INTERVAL)){
      return;
    }
      
    if(!stopping && !powon && !digitalRead(SW1)){
      delay(200);
      if(!digitalRead(SW1)){
        poweron();
        }
     }

      
//--------- Blink LED ---------//
    
      if(!powon && !i2c_regs[wakereg])
         blinkled(&waitled);
      if(i2c_regs[wakereg])
        blinkled(&wakeled);
      if(stopping){
        blinkled(&stopled);
       }

    if(!timchk())
        return;

    if(powon && downtimer){
      downtimer--;
      i2c_regs[downreg] = (unsigned char)downtimer;
      if(downtimer==0){
        stopping=10;
        digitalWrite(DOWN,HIGH);
      }
    }

    if(!powon && waketimer){
      waketimer=waketimer-1;

      if(waketimer==0){
        i2c_regs[wakereg]=0;
        poweron();
      }
    }
      
        
    if(stopping){
      stopping--;
      if(stopping==0){
        digitalWrite(FET, LOW);
        digitalWrite(DOWN, LOW);
        powon=false;
        downtimer=0;
        i2c_regs[downreg] = 0;
        }
    }

    if(powon && !digitalRead(SW1)&& !stopping ){
      delay(2500);
      if(!digitalRead(SW1)){
        digitalWrite(DOWN, HIGH);
        stopping=15;
        } else {stopping = 0;}    
     }

    if(powon){
      TinyWireS_stop_check();
    }
}

/*
 * Sub funcitons...
 */

void poweron()
{
   digitalWrite(FET, HIGH);
   digitalWrite(DOWN, LOW);  
   powon=true;
   stopping=0;
   downtimer=0;

}

void blinkled(struct led *myled)
{
  int pin=myled->pin;
  if(myled->cont++ == myled->ontime){
    digitalWrite(pin,false);
    myled->on=false;
    } else if(myled->cont >= myled->intval){
      digitalWrite(pin,true);
      myled->cont=0;
      myled->on=true;
    }
//  return myled->on;
}


```