{"id":239,"date":"2006-10-16T12:44:00","date_gmt":"2006-10-16T12:44:00","guid":{"rendered":"http:\/\/www.bolis.com\/testwp\/story\/serial-port-control-of-power-switch\/"},"modified":"2017-01-22T00:47:50","modified_gmt":"2017-01-22T00:47:50","slug":"serial-port-control-power-switch","status":"publish","type":"post","link":"http:\/\/www.bolis.com\/amillar\/serial-port-control-power-switch\/","title":{"rendered":"Serial port control of power switch"},"content":{"rendered":"<figure style=\"width: 200px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" src=\"\/amillar\/wp-content\/uploads\/projects\/20061021_serial_power_switch_img_0235.jpg\" alt=\"Power switch controlled by computer\" width=\"200\" height=\"150\" \/><figcaption class=\"wp-caption-text\">Power switch controlled by computer<\/figcaption><\/figure>\n<p>I have an old laser printer which does not have a decent standby power-saving mode.\u00a0 I built a computer-controlled power switch for it, so the computer turns on the printer when there is a print job, then turns it off again later.<\/p>\n<p>The printer is not near to the family computer, but in an out-of-the-way place in the basement.\u00a0 Because it doesn&#8217;t have a power-saver mode, it has been on a mechanical timer switch.\u00a0 Turn the knob, and the printer will stay on for 45 minutes.\u00a0 We had to go down and turn on the printer, go back up to the computer and print, then go down and get the printout from the printer.\u00a0 Good exercise, but annoying.<\/p>\n<h3>Existing solutions<\/h3>\n<p>I could have used off-the-shelf units from the X10 control system.\u00a0 This home automation system has been around for\u00a0years and is well known and reliable.\u00a0 Since I don&#8217;t know much about electronics and have not built a computer-controlled real-world interface before, this would have been a good simple solution to the problem.\u00a0 But I have more fun breaking, I mean making things myself, so I built my own solution.\u00a0 Other people have done similar things, and I&#8217;m learning from their examples.<\/p>\n<h3>Design parameters<\/h3>\n<p>My\u00a0laser printer is an Apple LaserWriter Pro 630.\u00a0 Its label says it can pull up to 5 amps of current.\u00a0 This would represent the highest load possible, most likely at power-on when the fuser is warming up.\u00a0\u00a0I\u00a0want\u00a0my switch\u00a0to accommodate this\u00a0plus some safety margin, so I&#8217;m using 7 amps as a minimum figure to be extra safe.<\/p>\n<p>I send print jobs to\u00a0the printer from my Linux server, using the CUPS print spooler system\u00a0and the\u00a0NetAtalk software.\u00a0 It\u00a0sends\u00a0the print jobs over Ethernet to the LaserWriter using the AppleTalk PAP protocol.<\/p>\n<p>The software needs to turn on the power switch, wait until the printer is ready to respond, send the print job, and then turn off the power switch afterwards.<\/p>\n<h3>Serial port<\/h3>\n<p>There are many ways that a computer can interface to the outside world.\u00a0 Two common and popular choices on PC hardware are the RS232 serial port (&#8220;COM&#8221;)\u00a0and the Centronics parallel port (&#8220;LPT&#8221;). I selected the serial port, since my server has two available and I&#8217;m not using them for anything else.<\/p>\n<p>In reading up on serial ports, people caution that you should not try to draw too much current from the serial port or you could burn it out.\u00a0 A number of references said that you should not draw more than about 5 milliamps.\u00a0 This is a very small amount of electricity, and is not going to be enough to drive a good-size relay big enough to switch 7 amps.\u00a0 Therefore I will need something in between the RS232 signal and the 7A relay coil.<\/p>\n<p>Electrically, the RS232 signal is interesting.\u00a0 The voltage can vary anywhere from around 4V to 20V.\u00a0 A binary one is a positive voltage, and a binary zero is a negative voltage.<\/p>\n<p>If I knew more about electronics, I&#8217;d cook up a\u00a0circuit with a voltage regulator and transistor and some other neat gizmos to drive a big relay.\u00a0 But I took the easy way out and just selected a solid-state relay in series with a diode.\u00a0 The diode makes sure the RS232 negative voltage for the binary zero is filtered out, so only a binary one will activate the solid-state relay.\u00a0 The SSR takes very little current, and operates from 3V to 24V input, which matches RS232 nicely.\u00a0 I bought the SSR from the local electronics store, and I pulled the diode out of a broken radio.<\/p>\n<figure style=\"width: 200px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" src=\"\/amillar\/wp-content\/uploads\/projects\/20061021_serial_power_switch_img_0234.jpg\" alt=\"Solid state and mechanical relays\" width=\"200\" height=\"150\" \/><figcaption class=\"wp-caption-text\">Solid state and mechanical relays<\/figcaption><\/figure>\n<p>The solid-state relay, in turn, activates the mechanical relay with the high-current contacts.\u00a0 I used an SSR with 120VAC output, and a mechanical relay with a 120VAC coil, so I didn&#8217;t need any power source other than the RS232 signal and the 120VAC line power.<\/p>\n<h3>Software<\/h3>\n<p>To drive the switch, I need to turn on the DTR signal of the serial port when the printer should turn on, and turn off the DTR pin when the printer should turn off.\u00a0 I decided to\u00a0activate the printer at the start of a print job, and\u00a0deactivate it after a fixed period of time (30 minutes by default), if no new print jobs have shown up.<\/p>\n<p>I found that the Linux serial port device drivers will control the DTR signal according to their own whims when a program opens or closes the port.\u00a0 Therefore I need a constantly-running background daemon to open the port, and then toggle the DTR signal as needed.<\/p>\n<p>There are many ways\u00a0to communicate with\u00a0a background\u00a0daemon.\u00a0 I chose the simple approach of a control file.\u00a0 When the file is created, the daemon turns on DTR.\u00a0 When the file is deleted, or the timestamp of the file is too old, the daemon turns off DTR.\u00a0 So when a print job needs to turn on the printer, a simple &#8220;touch&#8221; of the control file will turn it on.<\/p>\n<h3>Construction<\/h3>\n<figure style=\"width: 200px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" src=\"\/amillar\/wp-content\/uploads\/projects\/20061011_serial_power_switch_img_0220.jpg\" alt=\"Assembling the parts to test\" width=\"200\" height=\"150\" \/><figcaption class=\"wp-caption-text\">Assembling the parts to test<\/figcaption><\/figure>\n<p>With the software working, I assembled the hardware.\u00a0 I first connected the components together with alligator clips to make sure it worked.\u00a0 The big relay clicked on and off to match the DTR signal, as I had hoped.<\/p>\n<p>I used a clear plastic mayonaise jar as a case, and cut holes in the lid for the power outlet and master switch.\u00a0 The two-pole master switch allows the power output to be always off, always on, or controlled by the relay.<\/p>\n<h3>Silicone sealer<\/h3>\n<p>To keep things neat, I mounted the two relays and the diode on a piece of plastic (actually a lid from a can).\u00a0 I was short on shrink-wrap tubing, so I covered the exposed wire connections with clear silicone sealer to prevent shorts.<\/p>\n<p>I tested it one more time, and made a strange discovery.\u00a0 The power output was stuck on, regardless of the state of the DTR line.\u00a0 Somehow my circuit was shorted out.\u00a0 I double-checked my connections, and could not find any wires out of place.\u00a0 Then I found the culprit:\u00a0 I had not used silicone sealer.\u00a0 I had used clear latex caulk.\u00a0 Latex caulking is water-based, and water conducts electricity.\u00a0 Even after drying for more than a day, it still was conducting electricity and shorting my circuit.\u00a0 I scraped off all of the latex caulk, and then it worked.<\/p>\n<h3>End result<\/h3>\n<figure style=\"width: 200px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" src=\"\/amillar\/wp-content\/uploads\/projects\/20061021_serial_power_switch_img_0230.jpg\" alt=\"Completed switch\" width=\"200\" height=\"150\" \/><figcaption class=\"wp-caption-text\">Completed switch<\/figcaption><\/figure>\n<p>The end result was a nice power switch that works as well as I had hoped.\u00a0 My daughter the artist helped me make a fancy label using <a title=\"the GIMP\" href=\"http:\/\/www.gimp.org\">the GIMP<\/a>, which we printed on photo paper and stuck inside.\u00a0 Success!<\/p>\n<h3>Code listing<\/h3>\n<p>Here is the Perl code for the background daemon which monitors the control file and sets the DTR line to match.<\/p>\n<hr \/>\n<p><strong>port-handler.pl<\/strong><\/p>\n<hr \/>\n<p>#!\/usr\/bin\/perl -w<br \/>\n# Serial port line control<br \/>\n# Control a relay hooked to the serial port using DTR line.\u00a0 # Run as a daemon.# Monitor file for control action# &#8211; If file created recently, turn on line.# &#8211; If file deleted or too old, turn off line.<br \/>\n#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;# Modules\/directivesuse strict;use Device::SerialPort qw( :PARAM :STAT 0.07 );use Getopt::Long;<br \/>\n#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br \/>\nmy $CheckTimeSeconds=10; \u00a0\u00a0\u00a0 # seconds between file checksmy $ControlFileName=&#8221;\/var\/run\/port-dtr&#8221;; # file to monitormy $TimeoutMinutes=45;\u00a0\u00a0\u00a0 # turn off after this much time- 30 minutesmy $SerialPort=&#8221;\/dev\/ttyS0&#8243;;my $debug=0;<br \/>\nmy (\u00a0\u00a0\u00a0 $result,\u00a0\u00a0\u00a0 @filestat,\u00a0\u00a0\u00a0 $filetime,\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 # last mod timestamp of control file\u00a0\u00a0 );<br \/>\n$result=GetOptions (\u00a0\u00a0\u00a0 &#8220;checktimeseconds=i&#8221; =&gt; $CheckTimeSeconds,\u00a0\u00a0\u00a0 &#8220;timeoutminutes=i&#8221;\u00a0\u00a0 =&gt; $TimeoutMinutes,\u00a0\u00a0\u00a0 &#8220;portname=i&#8221;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 =&gt; $SerialPort,\u00a0\u00a0\u00a0 &#8220;debug=i&#8221;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 =&gt; $debug,\u00a0\u00a0\u00a0 &#8220;controlfile=i&#8221;\u00a0\u00a0\u00a0\u00a0\u00a0 =&gt; $ControlFileName );<br \/>\n# Open portDebugMsg ( &#8220;Starting with:n&#8221;,\u00a0\u00a0\u00a0 &#8221;\u00a0 checktimeseconds=$CheckTimeSecondsn&#8221;,\u00a0\u00a0\u00a0 &#8221;\u00a0 timeoutminutes\u00a0 =$TimeoutMinutesn&#8221;,\u00a0\u00a0\u00a0 &#8221;\u00a0 portname\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 =$SerialPortn&#8221;,\u00a0\u00a0\u00a0 &#8221;\u00a0 controlfile\u00a0\u00a0\u00a0\u00a0 =$ControlFileNamen&#8221;);<br \/>\nDebugMsg ( &#8220;Open portn&#8221;);<br \/>\nmy $PortObj = Device::SerialPort-&gt;new($SerialPort)\u00a0\u00a0\u00a0\u00a0\u00a0 or die &#8220;Error: cannot open serial port: $! n&#8221;; ;<br \/>\n# Turn off status$result=$PortObj-&gt;dtr_active(0);<br \/>\nwhile (1) {<br \/>\nif ( -f $ControlFileName ) {\u00a0\u00a0\u00a0 @filestat = stat $ControlFileName;\u00a0\u00a0\u00a0 $filetime = $filestat[9];\u00a0\u00a0\u00a0 if ( ( time &#8211; $filetime)\u00a0 &gt; ( $TimeoutMinutes * 60 ) ) {\u00a0\u00a0\u00a0\u00a0 \u00a0 # file expired; turn off\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 DebugMsg ( &#8220;File expired; Turn off dtrn&#8221;);\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $result=$PortObj-&gt;dtr_active(0);\u00a0\u00a0\u00a0 } else {\u00a0\u00a0\u00a0 \u00a0 # file is recent; turn on\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 DebugMsg ( &#8220;File is recent; Turn on dtrn&#8221;);\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $result=$PortObj-&gt;dtr_active(1);\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 } # if time\u00a0\u00a0\u00a0 } else {\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 DebugMsg ( &#8220;File is gone; Turn off dtrn&#8221;);\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 $result=$PortObj-&gt;dtr_active(0);\u00a0\u00a0\u00a0 } # if controlfile exists<br \/>\nsleep $CheckTimeSeconds;<br \/>\n} # while<br \/>\n#&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;sub DebugMsg {\u00a0 my @Message =@_;<br \/>\nif ( $debug ) {\u00a0\u00a0\u00a0 print STDERR &#8220;@Messagen&#8221;;\u00a0 } } # sub DebugMsg<\/p>\n<hr \/>\n<p><strong>\/usr\/lib\/cups\/backend\/pap<\/strong><\/p>\n<p>added just before the pap command is run:<\/p>\n<hr \/>\n<p># Turn on power switchtouch \/var\/run\/port-dtr# See if printer is therePrinterFound=` $nbplkup $nbpname | wc -l `while [ $PrinterFound -eq 0 ] ; do\u00a0 sleep 20\u00a0 PrinterFound=` $nbplkup $nbpname | wc -l `\u00a0 sleep 10done<\/p>\n<hr \/>\n<p>&nbsp;<\/p>\n<ul class=\"links inline\">\n<li class=\"taxonomy_term_41 first\"><a title=\"\" href=\"\/amillar\/category\/primary-topic\/electronics\" rel=\"tag\">Electronics<\/a><\/li>\n<li class=\"taxonomy_term_28\"><a title=\"\" href=\"\/amillar\/topic\/computer-hardware\" rel=\"tag\">Computer hardware<\/a><\/li>\n<li class=\"taxonomy_term_17\"><a title=\"Computers are a significant hobby of mine, as well as being the primary focus of my career.  I enjoy many aspects of it, especially making older, marginalized, or obsolete technology do things people would not expect was still doable.  In some ways I am sort of a &quot;bottom feeder in the cyberspace food chain&quot;.\" href=\"\/amillar\/topic\/computers\" rel=\"tag\">Computers<\/a><\/li>\n<li class=\"taxonomy_term_29\"><a title=\"\" href=\"\/amillar\/topic\/electronics\" rel=\"tag\">Electronics<\/a><\/li>\n<li class=\"taxonomy_term_23\"><a title=\"Energy efficiency and conservation\" href=\"\/amillar\/topic\/energy\" rel=\"tag\">Energy<\/a><\/li>\n<li class=\"taxonomy_term_52 last\"><a title=\"Home improvements to save energy\" href=\"\/amillar\/project\/energy-efficiency\" rel=\"tag\">Energy efficiency<\/a><\/li>\n<\/ul>\n<p>Submitted by amillar on Mon, 2006-10-16 05:44<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I have an old laser printer which does not have a decent standby power-saving mode.\u00a0 I built a computer-controlled power switch for it, so the computer turns on the printer when there is a print job, then turns it off again later. The printer is not near to the family computer, but in an out-of-the-way &hellip; <a href=\"http:\/\/www.bolis.com\/amillar\/serial-port-control-power-switch\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Serial port control of power switch&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[11,7],"class_list":["post-239","post","type-post","status-publish","format-standard","hentry","category-project","tag-electrical","tag-electronics"],"acf":[],"_links":{"self":[{"href":"http:\/\/www.bolis.com\/amillar\/wp-json\/wp\/v2\/posts\/239","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.bolis.com\/amillar\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.bolis.com\/amillar\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.bolis.com\/amillar\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.bolis.com\/amillar\/wp-json\/wp\/v2\/comments?post=239"}],"version-history":[{"count":2,"href":"http:\/\/www.bolis.com\/amillar\/wp-json\/wp\/v2\/posts\/239\/revisions"}],"predecessor-version":[{"id":379,"href":"http:\/\/www.bolis.com\/amillar\/wp-json\/wp\/v2\/posts\/239\/revisions\/379"}],"wp:attachment":[{"href":"http:\/\/www.bolis.com\/amillar\/wp-json\/wp\/v2\/media?parent=239"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.bolis.com\/amillar\/wp-json\/wp\/v2\/categories?post=239"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.bolis.com\/amillar\/wp-json\/wp\/v2\/tags?post=239"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}