1-Wire with Leds and Beeps oscar
1-wire-with-leds-and-beeps / software / mod_buzzer.pl
use constant CHILD_LOG_VERBOSE => 1; # Activate verbose logging
$b_new_stdout = FileHandle->new(">> /var/log/".$fname."_child_buz.log") if CHILD_LOG_VERBOSE;
$b_new_stdout->autoflush(1) if CHILD_LOG_VERBOSE;
# These values are cycles numbers: moltiply for Timer_resolution to obtain the timer duration
use constant LONG_DURATION_OFF => 6; # First prealarm duration : MUST BE PAIR
use constant DURATION_OFF => 1; # Pause in second prealarm (quicker)
use constant DURATION_ON => 1; # Beep duration
use constant DURATION_FIRST_PREALARM => 15; # First prealarm duration (about 30" with Timer_Resolution = 250000)
# This var is intentionally very high to avoid unnecessary hi-speed loops when there is no pre/alarm.
# When the status change, the var is lowered.
# Note that the response (audible beep) is almost immediate, thanks to the use of signal interrupt :)
my $Timer_Resolution=15000000 ; # 1'000'000 = 1 sec.
# Legal values accepted in FIFO:
my @Commands = (
"P", # - P - Start slow buzzing (it will be quick after DURATION_FIRST_PREALARM number of cycles)
"A", # - A - Alarm, just buzzer fix to ON
"S" ); # - S - Silence please...
my $status=0; # Alarm level: 0=Silence, 1=pre slow, 2=pre quick, 3=continuous;
my $tmp_command="S"; # Value from FIFO: it will be immediately cleaned
my $cycles=0; # Cycles Counter
my $prealarm_duration=0; # Cycles counter of pre alarm
# Boolean Switch of buzzer status (on, off)
# Denying the value 1 I get a "", so I have to work by difference: 1-Switch ...
my $buzzer=0;
my $owserver_buzz = undef;
sub ow_connection {
$owserver_buzz = OWNet->new( "localhost:4304" ) ;
my $appo_dir_list = $owserver_buzz->dir('/') || die ("Cannot open OWNet connection");
print { $b_new_stdout } (strftime "%b %e %H:%M:%S", localtime). " Initial dir_list to chech owserver connection: $appo_dir_list\n" if CHILD_LOG_VERBOSE;
print { $b_new_stdout } (strftime "%b %e %H:%M:%S", localtime). " Succesfully connected to owserver.\n" if CHILD_LOG_VERBOSE;
}
# FIFO startup.
# It needs a first input, else it rest blocked here.
# Conseguently I don't need to define a starting value: I'll get it from the FIFO!
unless (-p $FIFO_TO_CHILD_BUZ)
{
unlink $FIFO_TO_CHILD_BUZ;
system('mknod', $FIFO_TO_CHILD_BUZ, 'p') && die "can't mknod ".$FIFO_TO_CHILD_BUZ.": $!";
}
open (FIFO, "< ".$FIFO_TO_CHILD_BUZ) || die "can't read ".$FIFO_TO_CHILD_BUZ.": $!";
print { $b_new_stdout } (strftime "%b %e %H:%M:%S", localtime). " Child Buzzer started. \n" if CHILD_LOG_VERBOSE;
# Main !
while (1) {
print { $b_new_stdout } (strftime "%b %e %H:%M:%S", localtime). " Child Buzzer looping. \n" if CHILD_LOG_VERBOSE;
if ( $tmp_command ~~ @Commands ) {
# Usually the buzzer is idle for a long time. When it is time to do something, the connection is gone for timeout.
# So, if you receive a command, it's time to do so something: first of all, start a new connection!
# This "problem" is related just to the buzzer, because both the led and the main are alwais reading/writing with owserver,
# keeping the connection alive... I lost a lot of time on this... :( :( :(
&ow_connection;
if ( $tmp_command =~ /S/ ) {
# Silence Please!!!! :D
$owserver_buzz->write( BUZZER_ID , 0 );
print { $b_new_stdout } (strftime "%b %e %H:%M:%S", localtime). " Child Buzzer: 'S'ilent received. \n" if CHILD_LOG_VERBOSE;
$Timer_Resolution=5000000;
$buzzer=0;
$status=0;
}
if ( $tmp_command =~ /P/ ) {
$Timer_Resolution=250000;
print { $b_new_stdout } (strftime "%b %e %H:%M:%S", localtime). " Child Buzzer: 'P'reAlarm received. \n" if CHILD_LOG_VERBOSE;
$status=1;
}
if ( $tmp_command =~ /A/ ) {
$owserver_buzz->write( BUZZER_ID , 1 );
print { $b_new_stdout } (strftime "%b %e %H:%M:%S", localtime). " Child Buzzer: 'A'larm received. \n" if CHILD_LOG_VERBOSE;
$Timer_Resolution=250000;
$status=3;
$buzzer=1;
}
$tmp_command="";
}
if ($status > 0 && $status < 3 ) { # If $status = 3 buzzer must play continuosly; $status=0 Silent!
if ($cycles==0 ) {
if ( $buzzer ) {
print { $b_new_stdout } (strftime "%b %e %H:%M:%S", localtime). " IF! cycles: $cycles - Buzzer: $buzzer - Duration_pre: $prealarm_duration - Status: $status \n" if CHILD_LOG_VERBOSE;
# ########### Code Game Start ###
# Select the piece of code you prefer: code gaming or more traditional/readable :)
############# THIS ##########
# $cycles=LONG_DURATION_OFF/$status;
# if ($prealarm_duration++ == DURATION_FIRST_PREALARM*$status) {
# $status++
# }
######### OR THIS :) ###########
if ( $status == 1 ) { # Primo Preallarme
$cycles=LONG_DURATION_OFF;
if ($prealarm_duration++ == DURATION_FIRST_PREALARM) {
$status++;
}
} elsif ( $status == 2 ) { # Secondo preallarme
$cycles=DURATION_OFF;
if ($prealarm_duration++ == (2*DURATION_FIRST_PREALARM)) {
$status++;
}
}
############ END of Code Game ############
$buzzer=0;
} else {
print { $b_new_stdout } (strftime "%b %e %H:%M:%S", localtime). " ELSE! cycles: $cycles - Buzzer: $buzzer - Duration_pre: $prealarm_duration - Status: $status \n" if CHILD_LOG_VERBOSE;
$cycles=DURATION_ON;
$buzzer=1;
}
$owserver_buzz->write( BUZZER_ID , $buzzer );
}
print { $b_new_stdout } (strftime "%b %e %H:%M:%S", localtime). " cycles: $cycles - Buzzer: $buzzer - Duration_pre: $prealarm_duration - Status: $status \n" if CHILD_LOG_VERBOSE;
$cycles--;
}
if ($status == 3) {
# I force buzzer to ON without entering in the IF at every cycles
$tmp_command="A";
}
usleep($Timer_Resolution);
}
close(FIFO);
unlink $FIFO_TO_CHILD_BUZ;
use sigtrap qw(handler signal_handler normal-signals error-signals old-interface-signals );
# You got mail! Let's go to read it!
use sigtrap 'handler' => \&Buzzing, 'USR1';
sub Buzzing {
# If the FIFO contains more than one signal, the good one is the last one...
# Others are outdated, so clean all and get last!
while (<FIFO>) {
$tmp_command = $_;
}
chomp $tmp_command;
}