The perl script below uses the BV4141 display controller in order to draw the current time onto the BV4141 display. The image shows the time 2:50
.
The equation of the circle gives us any mobile point on the perimeter of a circle centered in and radius
. The equations to obtain the points on the perimeter of the circle are as follows:
where represents an angle, measured counter-clockwise on the circle (following trigonometric rules).
We know that, for clocks, the hours divide the clock-face into equal angles, such that every
, when divided corresponds to
. Conversely, for hours, the clock-face is divided into
equal angles, such that every
, when divided corresponds to
.
We also know that the starting point of the clock is at 12
hours sharp and continues to grow, clockwise, to 1
, 2
and so on. Thus, every clock-wise step can be considered as an addition of angles, such that hour
1
represents , hour
2
represents .
The problem is when we reach hour 4
, because gives us a negative angle
. For that, we use modulo arithmetic:
in order to wrap the value back to positive values.
The code requires that the BV4141 display controller is copied into the $PATH
of the user running this script. This can be done by just copying vacctl.pl
to /usr/local/bin
(preferably) or /usr/bin
.
#!/usr/bin/perl ########################################################################### ## Copyright (C) Wizardry and Steamworks 2012 - License: GNU GPLv3 ## ## Please see: http://www.gnu.org/licenses/gpl.html for legal details, ## ## rights of fair usage, the disclaimer and warranty conditions. ## ########################################################################### # Returns the angles that correspond to the current # number of hours and minutes. It does that by using # clock arithmetic and wrapping the angles into a circle. # For hours, the clock face divides into 12 equal # angles.For minutes, the clock face divides into 60 # equal angles. sub angles { my @time = split(/:/, shift); return %a = ( 'h' => (90-$time[0]*360/12) % 360, 'm' => (90-$time[1]*360/60) % 360 ); } my $pi = 3.14159265358979; sub deg_to_rad { ($_[0]/180) * $pi } sub rad_to_deg { ($_[0]/$pi) * 180 } # Get hour and minutes. @time = ((localtime)[2],(localtime)[1]); # If military time, change to conventional time. if($hour > 12) { $hour -= 12; } # Get the angles corresponding to the current time. %a = &angles("$time[0]:$time[1]"); # x,y for hours. @xy_h=(int(62+32*cos(deg_to_rad($a{'h'}))), int(62+32*sin(deg_to_rad($a{'h'})))); # x,y for minutes. @xy_m=(int(62+62*cos(deg_to_rad($a{'m'}))), int(62+62*sin(deg_to_rad($a{'m'})))); # Clear display. `vacctl.pl --clear`; # Draw clock face. `vacctl.pl --circle=62,62,62`; # Draw hours. `vacctl.pl --line=62,62,$xy_h[0],$xy_h[1]`; # Draw minutes. `vacctl.pl --line=62,62,$xy_m[0],$xy_m[1]`;