Making a Raspberry Pi based Amateur Radio WSPR Go-Kit

A couple of weeks back I got a Raspberry Pi setup with TAPR’s QRPi low pass/band pass filter board, running WsprryPi, providing a low-cost, low power, WSPR transmitter. For my first attempt everything was hooked together temporarily. I wanted to see if I could get the Pi and a USB battery pack packaged in a weatherproof box with connectors for an antenna so I can take it out and leave it outside in the yard transmitting for a day (or at least as long as my USB battery pack will last for – I currently have 10000mAh USB pack that seems to last at least 8 hrs or so with a 1/4 charge remaining).

This is what my second attempt looks like:

  • 10″ Tactical Weatherproof Equipment Case, from MCM
  • on the sides of the case I drilled through and added banana jacks to connect each side of the wire dipole on the outside of the case. On the inside I soldered a short wire from each jack which connects into the QRPi board connector
  • the battery is a 10000mAh Anker USB battery pack (hard to see in the photo but it’s at the back of the case)
  • battery and the Pi are velcro’d into the case

There’s plenty of free space on the inside of this case, I probably could have gone with a smaller one. I have some other Pi related projects in mind though, so will probably use this size case again for another Pi + Packet radio related project.

So, the results, how does it perform. Well the first couple of weekends I ran this I didn’t get any spots, so I suspected something was up with my antenna connections. I had already run with the same wire dipole connected directly to the board, so I knew it would radiate a signal. The first test I roughly cut the wire dipole using the 468/MHz formula but I didn’t bother to check it on an antenna analyzer. So next step, where is the resonant point of this antenna?

Hooking up my YouKits analyzer, the center line is showing 14.1 MHz, but the low point is clearly to the left, so the wire is too long:

 

 

 

 

 

Trimming off about 6 inches from each side got us more in the ballpark – now we’re looking good: wp-1464669440438.jpg

Getting the Pi back out in the yard, I hung the antenna from a couple of bushes at approx 5ft off the ground. This is very low for a dipole on 20m, but I know from previously running with this antenna at the same height that I still got spots all the way out to the East coast, so I’m not too worried about getting it up higher.

To keep things in perspective, remember we’ve only running 100mW, so we’re running low power, definitely QRP by any definition. At this low power, any spot is a good spot for me.

So, what about the spots? I didn’t get anything all afternoon, but then I got a number of spots from Texas, so if anything, there was a good propagation path between California and Texas early evening, but the spots dropped out shortly after sunset:

Since every day on HF is different, this is definitely an ongoing experiment 🙂 So far, this works pretty good and I’m happy with the setup!

NOTE: to transmit on Amateur Radio frequencies requires an Amateur Radio license, with the appropriate privileges for the frequency/band you are using. Also, per recommendations for the WsprryPi software, ensure you are using appropriate low pass/band pass filters so the Pi is not generating unexpected harmonics on other frequencies. 

For future reference, current solar conditions (from http://www.hamqsl.com/solar3.html ):

SFI=86, SN=25, A11, K=2. 20m day/night was fair

Fixing unresponsive touch on PiTFT with PyGame

I have a 2.8 PiTFT which I’ve used on my Pi 1 and just set it up on a Pi 2. I tried to get Adafruit’s FreqShow working with the screen, and it would display, but was unresponsive to any touch inputs. I know touch was working in X Windows otherwise, and had ran through all the calibration tools in the PiTFT setup instructions, so something else was wrong.

Some Googling later, turns out the PiTFT and PyGame (used by FreqShow) works ok on Raspbian Wheezy (which I have on my Pi 1), but not on Jessie (which I have on my Pi 2).

Trick is to replace libsdl with the prior/older version from Jessie – a script to do the replacement is in the post linked about. Ran the script, and now FreqShow works on the PiTFT 2.8 great. Shame there’s no audio out as well, but a cool use for the small screen.

Fixing wifi dropouts on Raspbian / Raspberry Pi

From this article, if you’re using one of the Wifi dongles on a Pi 1 or 2 (Pi3 has built in wifi), you can prevent the random dropouts during periods of inactivity by:

sudo nano /etc/modprobe.d/8192cu.conf

and then paste in and save this:

options 8192cu rtw_power_mgnt=0 rtw_enusbss=1 rtw_ips_mode=1

and then reboot.

Getting started with node.js, Express and Mongoose

I started tinkering with some test data creation scripts using Node.js a while back, but it’s been on my todo list to dig deeper into some Node. I recently walked through this very good article, and got a REST based backend using Node.js, Express and a MongoDB up and running in less than an hour. Pretty good going for learning a new tech stack 🙂

After putting together the app from the steps in the article, I realized there was a few steps that could have been simplified. For example, instead of hand coding the package.json as in the article, you can let npm update it for you by passing the –save option. So, to create an initial package.json:

npm init

and walk through the prompts.

Next, instead of manually adding the dependencies for Express, Mongoose and body-parser, again, use npm to install and add them to the package.json file with –save:

npm install express --save

npm install mongoose --save

npm install body-parser --save

That saves some work – no need to edit the package.json file by hand when the tool maintains it for you. Without the –save option npm still downloads the dependency, but –save writes the details into your package.json as well.

Using Mongoose with Express certainly gets you up and running with basic CRUD using REST pretty quick and easy with minimal coding. I was surprised how little code it takes to get the basics implemented. I’ve shared my version of the completed app to GitHub for future reference here, and for quick reference below:

[code]

var express = require(‘express’);
var app = express(); //init Express
var bodyParser = require(‘body-parser’);
var mongoose = require(‘mongoose’);
var Contact = require(‘./app/models/Contact’);
mongoose.connect(‘mongodb://nodetest:yourpassword@localhost:27017/nodetest’);
//init bodyParser to extract properties from POST data
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

var port = process.env.PORT || 8080;

//init Express Router
var router = express.Router();

//default/test route
router.get(‘/’, function(req, res) {
res.json({ message: ‘App is running!’ });
});

router.route(‘/contacts/:contact_id’)
// retrieve contact: GET http://localhost:8080/api/bears/:bear_id)
.get(function(req, res) {
Contact.findById(req.params.contact_id, function(err, contact) {
if (err)
res.send(err);
res.json(contact);
});
})
// update contact: PUT http://localhost:8080/api/contacts/{id}
.put(function(req, res) {
Contact.findById(req.params.contact_id, function(err, contact) {
if (err) {
res.send(err);
}
else {
contact.firstName = req.body.firstname;
contact.lastName = req.body.lastname;
contact.save(function(err) {
if (err)
res.send(err);

res.json({ message: ‘Contact updated!’ });
})
}
});
})
//delete a contact
.delete(function(req, res) {
Contact.remove({
_id: req.params.contact_id
}, function(err, contact) {
if (err)
res.send(err);

res.json({ message: ‘Successfully deleted contact’ });
});
});

router.route(‘/contacts’)
// create contact: POST http://localhost:8080/api/contacts
.post(function(req, res) {
var contact = new Contact();
contact.firstName = req.body.firstname;
contact.lastName = req.body.lastname;

contact.save(function(err) {
if (err)
res.send(err);

res.json({ message: ‘Contact created!’ });
});
})
//GET all contacts: http://localhost:8080/api/contacts
.get(function(req, res) {
Contact.find(function(err, contacts) {
if (err)
res.send(err);

res.json(contacts);
});
});

//associate router to url path
app.use(‘/api’, router);

//start the Express server
app.listen(port);
console.log(‘Listening on port ‘ + port);
[/code]