“When Morning Guilds the Skies” arranged by Mark Hayes

Bach said music’s purpose is, “for the glory of God, and the refreshment of the Human spirit”.  I am playing this arrangement of ‘When Morning Guilds the Skies’ for offertory at Cathedral Baptist Church on 10-27-2019.  I am thankful for every opportunity I have to do music in God’s house.

1   Rejoice in the LORD, O ye righteous: for praise is comely for the upright.
2 Praise the LORD with harp: sing unto him with the psaltery and an instrument of ten strings.
3 Sing unto him a new song; play skillfully with a loud noise.
Psalms 33:1-3

homemade bluetooth work speaker that kicks

home made 25W stereo bluetooth speaker project
home made 25W stereo bluetooth speaker project

I have a huge project going on at work right now, and loud music is absolutely essential.  I ordered some Boss CH3220 140W speakers and used a 25W bluetooth audio amplifier board and whipped up in one evening a killer work speaker that kicks hard.

It is working great as is, but I am totally not done.  I am going to add a raspberry pi to play my saved mp3’s and roll some of my own features.

25W bluetooth audio amplifier board
25W bluetooth audio amplifier board

I am very impressed with the quality of the sound and how easy it was to pair with this board.  I tested the speakers with ‘dont tread on me’ by metallica.  The frequency response of these 3.5″ speakers is surprisingly very good.

data logging rssi on a GE MDS9710 with perl, dht22, and raspberry pi

pi zero w data logging temperature, rssi, and humidity
pi zero w data logging temperature, rssi, and humidity

I work on 900MHz point to multi-point data radio systems.  Humidity can greatly affect the propagation of rf waves at this frequency.  I wanted to do some data logging and analysis of how moisture in the air affected the received signal strength indication over time.

The GE MDS 9710 P70 radio system has an analog voltage test point that corresponds to the rssi on it’s interface board.  I used a DHT22 to measure the temperature and humidity,  an MCP3004  10-bit analog to digital converter to read the rssi voltage, and a pi zero W for the brains.

arduino nano every and DHT22. Readings displayed on 16X2 LCD
arduino nano every and DHT22. Readings displayed on 16X2 LCD

I originally implemented this project with an arduino nano every.   It worked great.  I was going to log the data by connecting the nano every to a pi zero via UART while a screen session was running on the pi with the screen output (STDOUT) saved to a file .  This method would require a logic level converter which I did not have on hand at the time, so I decided to implement the whole project on my pi zero.

It is much easier to use a DHT22 sensor with arduino using adafruit’s unified sensor library.

adafruit unified sensor library for DHT22
adafruit unified sensor library for DHT22

Here is the source:

 
// REQUIRES the following Arduino libraries:
// - DHT Sensor Library: https://github.com/adafruit/DHT-sensor-library
// - Adafruit Unified Sensor Lib: https://github.com/adafruit/Adafruit_Sensor

#include "DHT.h"
#include 
#define DHTPIN 2     // Digital pin connected to the DHT sensor

// Uncomment whatever type you're using!
//#define DHTTYPE DHT11   // DHT 11
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

DHT dht(DHTPIN, DHTTYPE);

const int rs = 12, en = 11, d4 = 10, d5 = 9, d6 = 8, d7 = 7;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

//number of samples
int sn = 0;

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("MDS RSSI Data   Logger");
  delay(2000);
  dht.begin();
}

void loop() {
  // Wait a few seconds between measurements.
  delay(2000);

  //increment sample number
  sn++;

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht.readHumidity();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(f)) {
    Serial.println(F("Failed to read from DHT sensor!"));
    Serial1.println(F("Failed to read from DHT sensor!"));
    return;
  }

  //read rssi voltage
  int bv = analogRead(A0);
  float v = (5 * bv) / 1023.0;
  float rssi = v - 1.5;
  rssi = (rssi/0.8) * 20 - 120; 
  
  // Compute heat index in Fahrenheit (the default)
  float hif = dht.computeHeatIndex(f, h);

  //print to console
  Serial.print(F("Humidity: "));
  Serial.print(h);
  Serial.print(F("%  Temperature: "));
  Serial.print(f);
  Serial.print(F("°F  Heat index: "));
  Serial.print(hif);
  Serial.println(F("°F"));

  //print to pi
  Serial1.print("Humidity: ");
  Serial1.print(h);
  Serial1.print(F(" Temp: "));
  Serial1.print(f);
  Serial1.print("F RSSI: ");
  Serial1.print(rssi);
  Serial1.print("dBm");
  Serial1.print("\n");

  lcd.clear();
  lcd.print("Humidity:");
  lcd.print(h);
  lcd.print("%");
  lcd.setCursor(0,1);
  lcd.print(f);
  lcd.print("F ");
  //lcd.print(v);
  //lcd.print("V");
  lcd.print(rssi);
  lcd.print("dBm");
}

To use perl to interface with the DHT22 on my pi required the RPi::PIGPIO::Device::DHT22 module on cpan.  Before I could use this,  I needed to install PIGPIO and run it as sudo before executing my script.  PIGPIO is a VERY interesting library for controlling a pi’s gpio’s locally or remotely via socket, and I will hopefully find the time to explore more possibilities in the near future.  It is, however, somewhat of a resource hog.

pigpiod daemon cpu resources on a raspberry pi
pigpiod daemon cpu resources on a raspberry pi

Once all the modules are loaded on the pi and the PIGPIO daemon is fired up,  I just had to translate the ardino C code into perl.

 
#!/usr/bin/perl 
use strict;
require "/home/pi/gpio/MCP3004.pl";
use RPi::PIGPIO;
use RPi::PIGPIO::Device::DHT22;

=pod
loggs the temperature, humidity, and rssi of a
control point radio using a DHT22.  requires
PIGPIO daemon to be started first.  from home dir, 
cd/PIGPIO.  then, sudo pigpiod.  cd back into
gpio dir, and sudo perl CTC_datalogger.pl.  
=cut

my $pi = RPi::PIGPIO->connect('127.0.0.1');
my $dht22 = RPi::PIGPIO::Device::DHT22->new($pi,23);

#ADC channel
my @ch0 = (1,1,0,0,0);

#init ADC
init3004(3,4,5,6);

#open log file
open RD, ">", "ctc_data.log" or die $!;
#print table description
print RD "index,epoch,date,humidity,temperature,voltage,rssi\n";

my $i = 0;
for(;;){
	#formatted date string 
	my $time_str = `date`;
	print "$i\n";
	print $time_str;
	chomp($time_str);

	$dht22->trigger();
	my $deg_f = ($dht22->temperature * (9/5)) + 32;
	#$deg_f = sprintf("%.1f", $deg_f);
	$deg_f = int($deg_f);

	print "Temp: $deg_f \n";
	my $humidity = $dht22->humidity;
	$humidity = sprintf("%.1f", $humidity);
	print "Humidity: ".$dht22->humidity."%\n";
	int($deg_f);

	#take 5 samples from ADC and avg
	my $v_avg = 0;
	my $v_accum = 0;
	for(my $s=0;$s<5;$s++){
		my ($reading, $binval, $voltage ) = read3004(\@ch0, 50, 4.966);
		#print "binval: $binval\tvoltage: $voltage vdc\n";
		#print RD "$s\n$voltage\n";
		usleep(1000);

		$v_accum += $voltage; 
	}#end for
	$v_avg = $v_accum / 5;
	$v_avg = sprintf("%.2f", $v_avg);
	#print "avg: $v_avg\n";
	
	#calculate RSSI
	my $rssi = 0;
	$rssi = $v_avg - 1.5;
	$rssi = ($rssi / 0.8) * 20;
	$rssi -= 120;
	
	#format rssi
	$rssi = sprintf("%.2f", $rssi);
	print "rssi: $rssi dBm \n";
	print "-----------------------------------\n";

	#print to LCD
	`./lcd "Humidity: $humidity%     $deg_f F $rssi dBm"`;

	#print to log file
	my $log_str = '';
	my $uts = time;
	my $hr_time = localtime();
	$log_str = "$i,$uts,$hr_time,$humidity,$deg_f,$v_avg,$rssi\n";	
	select((select(RD), $|=1)[0]);
	print RD $log_str;

	sleep(2);
	
	$i++;
}#end for

close RD;

So far, it’s working great on the test bench.

pi zero rssi humidity data logger
pi zero rssi humidity data logger

Forgot to mention.  I used a DS3231 real time clock to keep time on the pi.  It works great and was easy to set up using this tutorial.

DS3231 RTC on pi zero
DS3231 RTC on pi zero

I will be deploying the data logger in the field this week and will post the results.  My bench test results are as follows.  Here is my humidity graph after nearly 9K samples.

dht22 humidity readings with pi zero w
dht22 humidity readings with pi zero w

And here is the rssi over the same dataset.  You can definitely see a higher rssi when the humidity is lower as expected.

rssi readings using raspberry pi
rssi readings using raspberry pi

review of ‘The Reversal Switch’ by Ronald Joseph Vaden

The Reversal Switch by Ronald Joseph Vaden.  A spiritual short story
The Reversal Switch by Ronald Joseph Vaden. A spiritual short story

I just read ‘The Reversal Switch‘ by a co-worker of mine, Ronald Vaden.  I’ve worked with Ron for over a decade.  I’ve known him as a seasoned IT professional.  A Navy submarine veteran.  A professional basketball player (Navy).  A coach.  A motivational speaker.  A deacon with an awesome singing voice.  Beloved father.  Motorcycle enthusiast.  A published author?  I didn’t know that, but am not the least bit surprised.

In his words..
After watching the stars on June 26 1999, life will never be the same for this amateur astronomer.  He will encounter a stone that will have a great effect on his life as well as the life of others.  This is a journey into the past which he will take on a mysterious mission that even he can’t quite understand.  The Reversal is a journey that will take you back into time.  You will be in someone else’s shoes, a journey which you will not soon forget!

The Reversal Switch by Ronald Vaden back cover
The Reversal Switch by Ronald Vaden back cover

The time-traveling stone is a creative and entertaining plot device Mr. Vaden uses to deliver a very powerful and much needed message of humanity towards others. In each travel through time a prejudiced, oppressive person experiences what it feels like to be mistreated from the perspective of the person they are abusing. What is so different about Mr. Vaden’s message is the compassion he feels for the oppressors. He doesn’t want revenge; he just wants them to see how it feels so that they will change their ways, and to see that they are hurting themselves by their lack of empathy for a fellow human being. Hardly anyone nowadays is approaching these issues in this way. It definitely made me examine myself and areas that I need to work on. The story ends with a compelling Gospel message. This book is guaranteed to have a profound impact on anyone who reads it. I highly recommend this book for anyone, and it would be a great gift for young people, friends, church members, etc. I was lucky enough to get an autographed copy! Thank you Ron. Please keep writing!

Autographed copy of 'The Reversal Switch'
Autographed copy of ‘The Reversal Switch’

Review of ‘Gulag Archipelago’

Gulag Archipelago
Gulag Archipelago

I have just completed the unabridged, nearly 2,000 page,  version of Aleksandr Solzhenitsyn’s ‘Gulag Archipelago.’   For some time now, I have been reading through Jordan Peterson’s reading list.  So far I have read Dostoyevsky’s ‘Crime & Punishment’, ‘The brothers Karamazov‘, and ‘The Possessed‘.  ‘The Possessed’ was prophetic.  Dostoyevsky, a devout Russian Orthodox Christian,  predicted nearly 50 years before the Bolshevik Revolution the chaos and injustice that would arise if society abandoned God and embraced socialism.  He saw the effects of fatherlessness, abandonment of faith in God,  and the disintegration of the home in his time and prognosticated about how it would affect future generations.  Boy, was he right!

It took me four months to read / listen to this book in it’s entirety. At home I read.  While  driving, I listened to the amazing recording of Frederick Davidson on the internet archive.   The sardonic tone of Mr. Davidson, in my mind, captures perfectly the sensibility of Solzhenitsyn. It was very hard for me to stick with this to the end. Not because it wasn’t interesting, but because the true events were so terrifyingly depressing. To think, that so many innocent people were unjustly oppressed by their own government in a modern time is hard to comprehend. I found the first book to be especially difficult to listen to. Starving, confused men receiving a ladle of ‘dishwater’ gruel in the flap of a jacket or in their hands for lack of a bowl or utensils!? Latrine buckets!? Stolypin cars!?  And still, people want to embrace communism saying it was never ‘done right.’ At times, this section was hard to follow and seemed disorganized.  He would reference events that happened anywhere from Czarist Russia, then to 1917, and then to the 1950’s all in one paragraph with no consistent chronology.  I am, however, glad that I stuck with it till the end.

Solzhenitsyn’s transformation from the privileged artillery officer to the humbled ‘Zek’ is profound. His path from atheist to a grateful believer that is thankful for his 11 years in the gulag is instructive and inspiring. Human beings were a commodity during this time in the USSR. Stalin had his five-year plans, which relied heavily on the de facto slave labor from Gulag prisoners producing industrial goods.  Soviet citizens were falsely denounced by their friends, neighbors, even family members and sentenced to ‘tenners’ (10 years in Gulag) under article 58 (anti-Soviet activity) fueling the voracious appetite  of the Gulags for prisoners.  There would literally  be quotas sent to cities for say, 250 people to be arrested, and the local NKVD would produce them by pressuring informers to supply them with denunciations.  No truth.  No virtue.  Only lies, cruelty, and injustice.

There seemed to be some national shame that Russia was always behind Western European countries.  It is undeniable that Stalin was able to rival Western powers by developing nuclear weapons and a modern space program.  Many advances in science and engineering were indeed achieved.  But at what cost: the death of tens of millions of their own citizens; the destruction of countless families, and the moral degradation of society.

When a society forgets God, when the state is more important than the divine spark within each individual, there is no bottom to the suffering and depravity which follows. Solzhenitsyn routinely calls out the arrogant errors of western thinkers such as Bertrand Russell who praised the USSR in his day while he and millions of innocents were rotting away in Gulag unjustly. We are no wiser in this generation. Hey Russell Brand! Have you read the Gulag Archipelago? Likewise, I seriously doubt today’s SJW’s have any idea of what happens each time this political system is tried. You guys ever heard of Pol Pot? How the population of a beautiful, modern city like Phenom Penh is deported to work in archaic farms? No. Let us support western society, the sovereign individual, and religious freedom.

DigitalOcean the best VPS

digitalOcean the best ubuntu VPS service
digitalOcean the best ubuntu VPS service

This site is hosted on a VPS that I rent from the best doggone VPS service there is, DigitialOcean.  I’ve been a long time customer, and while I have tried other services, they are the best in my opinion.

I first started using DigitalOcean back in 2013.  I was developing my biggest, most ambitious, and ultimately least profitable website iJonesboroHomes.com.  I was using Hostgator for most of my customers at the time,  but for this local real estate website,  I needed complete control over my LAMP server because HostGator would not install many of the modules that I wanted to use.

iJonesboroHomes.com failed local FSBO real estate website
iJonesboroHomes.com failed local FSBO real estate website

It got tons of use by the local community, but no one ever bought any ads.  I eventually shut it down when my VPS was hacked by spammers and was disabled by DigitalOcean.  I accept responsibility for this failure.  I know a great deal about securing a web server and writing secure code, but I was running an email server (the vector of my particular hacking attack) and knew very little about plugging security holes.

I do a lot with this VPS besides a web server like file storage, backups,  experementation, etc., and did not want to loose my work.   I recently lost an email address I had for 12 years through my ISP (moved and went with another ISP) and was locked out of my DigitalOcean account because they are very serious about security and often email access codes to log in to your account in addition to a username and password.  At the same time, my credit card on file expired, and my VPS was disabled.  I freaked out a little bit, but opened a support ticket (no phone support) and got my VPS  unlocked while I resolved my issues.

I am modestly indexed on google especially for pine64 and perl.  There seem to be so few of us developing on SBC’s using perl, so I didn’t want my server to have any significant down time.  Thanks to the great support at DigitalOcean,  I didn’t have much.  I’m a customer for life!

Me performing Chopin’s Fantasie-Impromptu in c-sharp minor Op. 66

 

I’m a classically-trained amateur pianist.  This is me performing Chopin’s Fantasie-Impromptu in c sharp minor Op. 66.  Certainly not a nuanced interpretation, but a big deal for me to just get the notes under my fingers to the degree that I achieved it.

I had a recording of this on my very first cassette tape of Chopin’s popular works.  That first tape inspired me to practice.  My tastes for classical music have developed since then (i.e. Buxtehude, Busoni) but Chopin was my gateway drug and I still deeply admire his genius.  Studying this piece was very refreshing to my spirit.

perl + curl hyperlink parser

I go through seasons where I struggle to find ideas for projects that I am interested in.  Now is not one of those times.  I am finding it hard to make time to work on my ideas.  I like that.  I wanted to see how hard it would be to implement my own web crawler.  At the core of this idea is the ability to find all the hyperlinks in a given web page.  After some trial and error (not googling)  I have a pretty decent hyperlink finder.  My script involves getting the content using curl.  It then redirects the output of curl to a text file.  I use perl to parse the text file and a regular expression to locate the hyperlinks.  At first I was using anchor tags to find links.  It was somewhat effective, unless there were multiple links on a single  line of text.  I scrapped this approach because I used the ‘.+’ method of getting the inner contents of the anchor. It had the undesirable (but predictable) effect of mushing multiple links in a single line together.   I had more luck looking for the inner text of the href=”” attributes of the anchor tags.

Here is a hyperlink finder script.

 
#/usr/bin/perl -w
use strict;

my $url = $ARGV[0];

print "looking up $url...\n";

`curl $url > pl.txt`;

print "analyzing $url...\n";

my $wc = `wc  pl.txt`;

print $wc;

open XL, "pl.txt" or die $!;
my $nlink = 0;
while(){
	while($_ =~ /\shref="(\S+)"/g){
		$nlink++;
		print "$nlink\t$1\n";
	}#end if	
}#end while

print "num links on page: $nlink\n";

close XL;

Here is a sample output using my homepage.

hyperlink parser using cURL and perl regular expressions
hyperlink parser using cURL and perl regular expressions

building a telecom Transmission Impairment Measuring Set (TIMS) with arduino nano III

Telecom frequency generator and counter using arduino nano
Telecom frequency generator and counter using arduino nano

I have a working hand-held arduino based telecom test set made out of a plastic capacitor kit case.  It generates audio frequency tones from 0-3000 Hz.  The tone() function produces  audio frequencies at about -9.5dBm from what I have observed.  That level is very useful to my for my intended purposes.  I also need it to generate tones at a level of -16dBm.  To achieve this,  I put a selector switch to attenuate the level to -16dBm by putting the output of the tone() pin in series with 30K Ohms of resistance.

It measures the frequencies that it generates in TX mode, but also measures frequencies from other devices from it’s RX port.   The RX port must have a level of -3dBm or greater to work at this time.  I will be experimenting with an amplifier stage to measure weaker signals.

Arduino telecom frequency counter and generator
Arduino telecom frequency counter and generator
Schematic of telecom test set using arduino nano
Schematic of telecom test set using arduino nano

building a telecom Transmission Impairment Measuring Set (TIMS) with arduino nano II

arduino nano frequency counter
arduino nano frequency counter

I have considered several design possibilities for myTIMS project.  I was going to use the TimerFreeTone library because of the timer conflict between tone() and the FreqCount library, and have the user type in the desired frequency using a keypad.  I do not have enough GPIO on my nano for this as I need 6 pins for my LCD and seven for my 4-column 3-row keypad.  (I know I could get an i2c display, but I’m using what I have laying around!)

Anyway, the two nano approach is acutally looking better.  I am using one nano to generate the desired frequency when the TIMS is in transmit / generate mode.  I am using a 10-K potentiometer to tune to the desired frequency and basically copied and pasted the tonePitchFollower example sketch with a few modifications.  The other nano does the frequency counting and drives the LCD.  As you can see above, the nano frequency counter is only off by 1 Hz from a professional TIMS.

Here is the frequency counter sketch ->

     
     1	#include \<FreqCount.h\>
     2	#include \<LiquidCrystal.h\>
       
     3	const int rs = 12, en = 11, d4 = 10, d5 = 4, d6 = 3, d7 = 2;
     4	LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
       
       
     5	void setup() {
     6	  lcd.begin(16, 2);
     7	  lcd.print("Freq:");
     8	  FreqCount.begin(1000);
     9	}
       
    10	void loop() {
    11	  if (FreqCount.available()) {
    12	    unsigned long count = FreqCount.read();
    13	    lcd.setCursor(0, 1);
    14	    lcd.print(count);
    15	    lcd.print(" Hz       ");
    16	  }
    17	}