dht22 indoor use only

In my empirical observations experimenting with a dht22 temperature / humidity sensor,  I have come to the conclusion that they are most definitely for INDOOR USE ONLY!  Any time I placed one outside, they quickly max out at 99.9% humidity,  and don’t recover until I dry them out, and place them indoors.  I have ordered a HTU21D-F sensor to replace the dht22 in my rf propagation / humidity experiment.

The dht22 does work pretty well indoors.  I took over 14K samples over a 30 hr period and got clean results.

dht22 sensor temperature and humidity graph
dht22 sensor temperature and humidity graph

The temperature is in red and the humidity in green.  For most of my data logging projects using a pi, I sore the results in CSV format.  I used perl’s CSV database functions to query results and create graphs.  This is the sql query I use on the to csv tables to get the above graph:

select data.index, data.temp, temp_humidity.humidity from data outer join temp_humidity on data.index = temp_humidity.index

piscope is totally AWESOME with perl!

this is a screenshot of piscope running on my laptop analyzing the gpio lines of a raspberry pi over IP that is running my 24-port battery load test analyzer
this is a screenshot of piscope running on my laptop analyzing the gpio lines of a raspberry pi over IP that is running my 24-port battery load test analyzer program

I would assume many makers are familiar with using a logic analyzer in conjunction with sigrok + pulseview.  I love these resources.  They allow you to analyze precisely what is happening on your digital IO pins on whatever microcontroller you are using whether it be arduino, raspberry pi, etc.  They can also analyze signals at the protocol level such as i2c and are so inexpensive every maker should be equipped with these tools.

Pulseview SPI
Pulseview SPI scan

I do not like to reinvent the wheel in most cases.  I wanted to use some dht22 temp / humidity sensors on an RF signal strength project I am still working on.  As I have mentioned in earlier posts, I chose to use the RPi::PIGPIO::Device::DHT22 module on cpan to read my sensor.  This required the pigpiod daemon to be running on the raspberry pi.  I am very impressed with PIGPIO.  It allows you to very easily read / write to a raspberry pi ‘s GPIO lines over TCP/IP.  Just think of the possibilities.

The author of PIGPIO also offers an incredible logic analyzer for the raspberry pi called piscope.  I may never use a standard logic analyzer on a pi ever again.  You can invoke piscope on any linux computer once you have installed it to analyze the gpio on a remote pi.

invoking piscope to monitor the gpio lines on a raspberry pi
invoking piscope to monitor the gpio lines on a raspberry pi

After this, launch piscope:

run piscope logic analyzer
run piscope logic analyzer

I am just beginning to experiment with piscope, but so far it is very user friendly.  This is a trace of the SDA and SCL lines on the pi reading an MCP9808 temperature sensor.

piscope logic analyzer zoomed in on the i2c lines of an MCP9808 temperature sensor
piscope logic analyzer zoomed in on the i2c lines of an MCP9808 temperature sensor

This trace was taken over the net.  I didn’t have to get out my logic analyzer and connect any test leads.  Here is a trace of a poll and response from a dht22 sensor connected to gpio 24.

piscope logic analyzer reading a dht22 via perl
piscope logic analyzer reading a dht22 via perl

You can see it go low, then the sensor sends its reading, and goes high again.  pigpiod is definitely a resource hog, but that is hardly a consideration for my uses of the pi in my projects.  I will definitely be incorporating piscope into my future projects.

piscope by default uses port 8888 on the pi you are monitoring.  Out of curiosity,  I scanned the incoming frames with tcpdump.

analyzing piscope frames on port 8888 using tcpdump
analyzing piscope frames on port 8888 using tcpdump

It sends a lot of traffic over the network.

piscope network traffic on linux mint's system monitor
piscope network traffic on linux mint’s system monitor

Here is a video of me launching piscope, and live traffic from a pi 3B+.

arduino nano bike speedometer

arduino nano bike speedometer and odometer
arduino nano bike speedometer and odometer

I tricked out my dad bike with an arduino nano based speedometer, odometer, clock, and temperature sensor.

A DS3231 RTC keeps the time and temperature.  I implemented a attachInterrupt() function to keep track of tire rotation via a reed switch.

reed switch for a bike speedometer / odomoeter using an arduino nano
reed switch for a bike speedometer / odomoeter using an arduino nano

This way, I do not have to programmatically monitor  the reed switch;  a routine is executed (in this case that calculates the distance traveled) each time the state of the digital pin the switch is connected to changes.

 //bike speedometer
#include "RTClib.h"
RTC_DS3231 rtc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 10;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

float start, finished;
float elapsed, time;
//float circMetric=2.164; // wheel circumference relative to sensor position (in meters)
float circMetric=1; // wheel circumference relative to sensor position (in meters)
float circImperial; // using 1 kilometer = 0.621371192 miles
float speedk, speedm;    // holds calculated speed vales in metric and imperial
float miles_traveled = 0;
float feet_traveled = 0;
char miles[100];

void setup () {
  attachInterrupt(0, speedCalc, CHANGE); //digital pin 2
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("BIKE SPEEDOMETER!");
  circImperial=circMetric*.62137; // convert metric to imperial for MPH calculations

  //rtc stuff
  int temp = 0;

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }//end if

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }//end if rtc lost power
}//end setup

void speedCalc()
  speedk=((3600*circMetric)/elapsed) * 0.12; // km/h
  speedm=((3600*circImperial)/elapsed) * 0.12; // Miles per hour
  feet_traveled += 1.1; 
  miles_traveled = feet_traveled / 5280; 
  //sprintf(miles, "%.2f", miles_traveled);

void loop()
  DateTime now = rtc.now();  
  int temp = 0;

  //lcd.print(" km/h ");
  lcd.print(" MPH   ");
  lcd.print(" mi");;
  //lcd.print(" ms/rev      ");
  lcd.print(now.hour(), DEC);
  lcd.print(now.minute(), DEC);
  lcd.print(now.second(), DEC);
  lcd.print(' ');
  temp = rtc.getTemperature() * 9/5 + 32;
  delay(1000); // adjust for personal preference to minimise flicker


arduino bike speedometer
arduino bike speedometer

“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"
#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)


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() {
  // 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");

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

  //increment sample number

  // 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!"));

  //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(F("%  Temperature: "));
  Serial.print(F("°F  Heat index: "));

  //print to pi
  Serial1.print("Humidity: ");
  Serial1.print(F(" Temp: "));
  Serial1.print("F RSSI: ");

  lcd.print("F ");

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.

use strict;
require "/home/pi/gpio/MCP3004.pl";
use RPi::PIGPIO;
use RPi::PIGPIO::Device::DHT22;

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.  

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

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

#init ADC

#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;
	#formatted date string 
	my $time_str = `date`;
	print "$i\n";
	print $time_str;

	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";

	#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";

		$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;

}#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.