Ghetto-rigging NAS to keep pushing power button in case of power failure 

by

tl;dr
Have NAS
NAS started randomly (sometimes 3x a hour / every 3 months) shutting itself down, and "auto power on" didn't worked.
Decided to make a watchdog device to turn it on.
Made a watchdog.

Here is a story of something that should took 1hour, and took 5h, because chinkman decided to mix the colors in usb cable, and I've assumed immidiately that I did everything wrong, checking polarisation of usb cable at the very end. Thats 2x 85cent attiny in damages, and 4h of crazy debugging of what was wrong.

Thats beign said:

My QNAP NAS for some time had a weird issue, where it'd shut itself down (thermals are ok, ram is ok, hdds are ok, believe me i've tried everything), and QNAP service after 2 months of pingponging my messages said finally that warranty period is over, sucks to be me. 

I can live with 3-4minute downtimes before it reboots, however, the most annoying problem (connected to the shutdowns I assume) is that power button dont work immidiately - I press it, and there is random chance of it working and booting, or just powering system for a split second, and shutting it down (capacitor issue? Im lacking technological knowledge to diagnose it sadly). Sometimes it works at 3rd press, sometimes at 40th press, and the attempted boot - shutdown cycle takes around 5 seconds, and I really dont want to spent 5 minutes standing near my hardware rack pressing button.

So, a watchdog idea was made:
- it has to be as low invasive as possible
- it should give me ability to swap parts rather quickly, without much desoldering
- it should be inside NAS, no dangling cables outside
- it should be somewhat "smart" - dont just press the button infinitely, but detect if system turned on / shut itself down
- it can be turned on/off from outside without deassembling the case, in case i want to swap disks for example
- must be made using zipties

Schemats is quite simple:

watchdog schematic
watchdog schematic


simple schemat of part connections
So general idea is:
Its powered by step-down converter that makes 5V for attiny85 from NAS 12V, its soldered directly to the motherboard pads to feed power as soon as power connector is plugged in - there is small slide-switch outside so i can cut off power to attiny.
It monitors USB power, resistor is to eliminate noise (randomly picked because im lazy, values are calibrated in code). At first i've used pins from debug interface and check for logical signal of 3.3v, but silly me realised after few minutes, that at some point interface might stop sending things, so after several minutes of beign inactive, watchdogs started pressing power button again, because of inactivity. 
In case no USB power is detected, it starts routine of "pressing" the switch for 200ms through relay breakboard, and gave it some time to finish boot sequence (if it starts)

Few pictures of how it went, with short descriptions.

And code that runs on the watchdog:


#define NUM_SAMPLES 10
#define LED_PIN 1
#define ANALOG_PIN A3
#define POWER_PIN 4
#define RESTART_DELAY 1400
#define WORKING_VOLTAGE 4.1

bool restartingLED = true;
int samplesSum = 0;
unsigned char sample_count = 0;
float voltage = 0.0;

// the setup routine runs once when you press reset:
void setup() {
randomSeed(analogRead(0));
// initialize the digital pin as an output.
//pinMode(0, OUTPUT); //LED on Model B
pinMode(LED_PIN, OUTPUT); //LED on Model A or Pro
pinMode(POWER_PIN, OUTPUT); // relay
pinMode(ANALOG_PIN, INPUT); //

}

// the loop routine runs over and over again forever:
void loop() {

//pressPower(100);
//delay(1000);
while (sample_count < NUM_SAMPLES) {

//samplesSum += debugAnalogRead(300, 100);

samplesSum += analogRead(ANALOG_PIN);
sample_count++;
if (restartingLED == true) {digitalWrite(1, HIGH);}
delay(100);
if (restartingLED == true) {digitalWrite(1, LOW);}

}
voltage = ((float)samplesSum / (float)NUM_SAMPLES * 5.015) / 1024.0;

if (voltage < WORKING_VOLTAGE)
{

restartingLED = true;
pressPower(200);
}
if (voltage >= WORKING_VOLTAGE)
{
restartingLED = false;
}
// wait for a second

sample_count = 0;
samplesSum = 0;
}


void pressPower(float delayVal)
{
digitalWrite( 4, HIGH);
delay(delayVal);
digitalWrite(4, LOW);
delay(RESTART_DELAY - delayVal);

}

void turnLed(int state)
{
if (state == 0)
{
digitalWrite(1, LOW);
}
if (state == 1)
{
digitalWrite(1, HIGH);
}
}

float debugAnalogRead(float voltage, float range)
{
float voltageReturn = 0;
voltageReturn = voltage + random(-1 * range, range);

return voltageReturn;
}

 What I've learned during making this, is that to never trust chinesse manufacturers - my usb cable that i've used had colors swapped for ground and vcc, so i've managed to burn 2 attinys before checking EVERYTHING on my side, only to find this issue after 5h of debugging.

Anyway, it works, and by frantical clicking it lets me know IF the server actually died ;-)