WakeUp Pi
SleePiみたいなボード
RaspiberryPiの電源コントローラ&リアルタイムクロック基板です。
アメーバブログへ投稿していたけど回路図がうまく入らないのでこちらへ投稿します。
元記事 http://ameblo.jp/tamesuke-goto/entry-12266987870.html
/*
* 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;
}