-
Another mechanism for this
05/03/2021 at 15:39 • 0 commentsIt occurs to me that the Pi-with-watchdog-script isn't the only way you could make this work. You could also use some type of cellular modem device capable of receiving text messages. If the router was stuck, you could send a text message to the watchdog that would cause it to engage the open drain output for 2 seconds and reply with an acknowledgement.
I might see if I can come up with a way to connect an Adafruit FONA 3G to the Pi.
-
Better transistors
07/18/2020 at 23:56 • 0 commentsOne of the reasons I added the two zener diodes to the design was that the P-MOSFETs I had on hand had only an 8 volt maximum Vgs and I needed to run the system at 12 volts.
You can get better transistors, though. The DMP3099L-7 is an excellent candidate. It has a maximum Vgs of 20 volts, a maximum Vds of 30 volts and a maximum drain current of almost 3 amps at 70ºC. If you use that part, then you can leave out D2 and D3 and use 0Ω for R2 (though it does no harm to leave it at 10kΩ).
EDIT: In addition to better transistors, I've also discovered a SOT23-5 5 volt LDO that has an ultra wide input range. It was a little extravagant to use the D2PAK packaged 7805 for this job, given that the ATTiny9 draws maybe 1 mA total. Even if it were 1 and you were running the whole thing on the maximum input voltage of 20 volts, that's a dissipation of less than 15 mW. That's 3ºC above ambient (given the 235 ºC/W to-ambient dissipation rating for the chip), which is not a big deal (and that's the worst case).
-
Attiny9
06/07/2020 at 03:43 • 0 commentsI've taken a shine of late to the ATTiny9. It's a microcontroller in a SOT23-6. Like, the size of a grain of Arborio rice. You only get 4 I/O pins (and really only 3 unless you repurpose !RESET), but projects like this only need 2.
So I don't have a need to do so, but I think I will spin a rev of this project to use the tiny9 just to see if it can be done. I hacked up the firmware with "if defined" to differentiate between the tiny85 and tiny9 versions of the code. I haven't checked any of that in yet because it's not tested, but I will do so once I confirm that it all works.
The hardest part is going to be TPI based programming. The ATMelICE can do TPI, but avrdude doesn't support TPI on it (just ISP and PDI). So I am probably going to start with ATPROGRAM on a Windows vm (ugh). If it's possible to hack avrdude to add TPI support for the ICE, I'll do so.
EDIT: The programming problem has been put completely to bed.
-
The root cause
12/12/2019 at 21:13 • 0 commentsThis isn't really related to this project, but we did figure out the root cause of the router instability. It's the fault of our Samsung smart TV. It's apparently using the hostname "localhost" in its DHCP requests. That causes a bunch of logging and other complaints from the DHCP server built in to the router's dnsmasq instance. What then causes that to result in the interfaces wedging is unclear, but giving the TV a static address made the problem go away.
EDIT: Well, it turns that the jury has not yet entirely returned a verdict yet...
-
First shot fired in anger
11/29/2019 at 18:53 • 0 commentsWe're up at the vacation villa this week and I installed the watchdog and set up the Pi that's in residence to take care of business. Well, last night in the middle of the night the router wedged itself and the Pi and box did their job flawlessly and brought everything back.
I've decided to run the script every 2 hours instead of 4 (so the cron spec is 0 */2 * * * $HOME/watchdog.py), and I've reduced the testing timeout to 30 minutes from 60 (a firmware update should take no longer than 15 minutes including time to get the system back up).
Of course, it would be better if this sort of thing just simply didn't happen and the router was reliable, but I don't think any router is going to be reliable enough that I'd not want to keep this system in place, frankly.
-
New firmware rules
11/15/2019 at 17:41 • 0 commentsI've changed the firmware so that the holdoff interval is no longer restarted when there's an input pulse. Before, if you pulsed every 59 minutes, then the reset would never happen. The more I thought about that, the less I liked it.
Now if you pulse during the holdoff it won't do anything, but if did it every 59 minutes then every other one would still work.
In addition, just tying the line permanently to ground will reset the system once and never again. The input has to be successfully debounced to "off" before any attempt to turn it "on" will be recognized. And, again, the debounce interval is one second. The line has to stay either "on" or "off" for a full second before any change is recognized. And for "on," that state change is recognized exactly once and then it has to transition successfully to "off" before it can be recognized as "on" again (note that this description is of the input to the circuit - where "on" is shorted-to-ground and off is open).
That's about as robust a system as I can envision that doesn't involve sending commands or stuff like that.
-
Oops
11/15/2019 at 05:44 • 0 commentsIt's occurred to me that if you power the circuit at 12 volts, Vgs for the P MOSFETs will be the full 12 volts when they're turned on. This is problematic as the MOSFETs I've designed with have an absolute maximum Vgs of ±8 volts. The fix is simple - each of the P MOSFETs needs a zener diode to limit Vgs. For the output MOSFET it's as simple as placing a zener diode from the gate to the positive rail. There's no need for a pull-up because the gate is normally pulled-down and the switching is across the zener. For the switching P MOSFET, we need to add the same zener to the positive rail, but also must add a pull-up across the zener because the switch pulls the gate momentarily down. There also needs to be a current limiting resistor added in series with the switch to limit the zener current. When the supply voltage is less than the zener voltage, then you can imagine that they're just not installed. When the supply voltage is higher, then you can sort of assume that the voltage on the anode is lower than the cathode by the zener voltage amount.
-
Build report
10/31/2019 at 21:13 • 0 commentsIt works!
I checked in the watchdog script into the firmware repository. It now uses syslog rather than standard out/err for some rudimentary logging. My recommendation is that you run this from cron every 4-6 hours. You can't really run it more than hourly, since there's a one hour hold-off in the firmware that is reset if you try to do the reset before the hour is elapsed (so if you pulse the action pin every 59 minutes, it will never actually work after the first time).
The reason you don't want to run it more frequently is that if everything goes terribly wrong and it's doing something crazy, you want to have a chance to get in and stop it. The one-hour firmware hold-off should give you a chance even if everything else goes sour.
The only thing left would be to make a 3D printed case for it, but I don't know if I care that much. We'll see.
-
A better cut at the watchdog script
10/24/2019 at 15:57 • 0 commentsI thought of a couple of issues with the first script.
If the router is performing a firmware update, the internet may be unreachable for 10 minutes or so, and it would be a disaster to power-cycle the router then. So the script should keep trying for a solid hour to reach an external host before giving up.
I've also expanded the list of hosts. These are all public DNS servers. Again, using them as ping targets is probably not what their owners had in mind, but the script as written is being very gentle (and answering a ping is a lot less work than answering a DNS query). As long as you only run this no more than once every 6 hours or so (and as long as everybody and their brother doesn't run it), I would think it would be acceptable.
#!/usr/bin/python import RPi.GPIO as GPIO import sys import time import subprocess import os import random hosts = ["1.1.1.1", "1.0.0.1", "8.8.8.8", "8.8.4.4", "8.26.56.26", "8.20.247.20", "9.9.9.9", "149.112.112.112", "64.6.64.6", "64.6.65.6"] random.shuffle(hosts) FNULL = open(os.devnull) start = time.time() while True: for host in hosts: res = subprocess.call(["ping", "-c", "3", "-W", "5", host], stdout=FNULL, stderr=FNULL) if (res == 0): print(host + " is up.") sys.exit(0) # it worked. Bail else: print(host + " is down.") if time.time() - start > 60*60: break time.sleep(5 * 60) # wait 5 minutes print "All hosts unreachable for 60 minutes - resetting router" # physical pin 7 reset_pin = 4 # Perform the reset operation GPIO.setmode(GPIO.BCM) GPIO.setup(pin, GPIO.OUT, initial=GPIO.LOW) time.sleep(2) GPIO.cleanup() sys.exit(1)
-
Depletion mode MOSFETs
10/23/2019 at 23:29 • 4 commentsJust before someone brings it up... the two P MOSFETs could be replaced by a depletion mode P MOSFET. Depletion mode MOSFETs work just like the more ordinary enhancement mode devices, with the sense of the gate being backwards. Where increasing the amplitude of the gate-source voltage would turn an enhancement mode MOSFET on, doing so with a depletion mode device turns it off instead.
Unfortunately, depletion mode devices are out of the ordinary, so the prospects of using one - particularly one that can pass 2 apps continuous - are poor.