Thursday, October 20, 2011

Published an ebook called "Small Solar"

Meeting my objective of having the new ham shack powered totally from solar energy proved to be a little less straight forward than I had imagined.

Along the way, I did a lot of research, talked to some very knowledgable people, visited some shops, attended an expo, and did some experimentation of my own.

An outcome of all this is that I've collected all my notes on solar panels, charge controllers, batteries and the sun; and published them as a low cost (under $3) electronic book.

This post is about how I made the book and got it out there.

I wanted to make the book available in the Apple iBookstore and Amazon Kindle. If you are not American it's difficult to publish through Apple's book store, basically you have to get an IRS (tax) number and that seems to involve sending your passport to Texas. They strongly suggest you go through an aggregator, as I already have a paper book on Lulu that was the obvious choice.

If you upload an ePub book, Lulu can distribute to Barnes & Noble Nook as well as Apple.

The book was created from the ePub template in Apple Pages. Pages can use the first page as the cover art but everywhere I've published they basically get you to make a cover design anyhow and ignore that embedded cover.

While Lulu can allocate you one of their ISBNs, your book is then listed as being published by Lulu, so I paid the $55 + $40 to get my own Australian ISBN (the $55 is a one time fee).

Uploading to Lulu is very smooth but I'd make your cover locally as a Jpeg rather than using their simple web-based tool. Lulu has yet to get the book into the iBookstore or B&N even though weeks have gone by. No idea what the hold up is but I'm not alone. Looks like there's a blockage somewhere at the moment.

My book was rejected the first time because I neglected to title the book in the form "Title: subtitle text here exactly as on the isbn". 24 hours later that was sorted.

Customers could buy the book on Lulu, download the ePub, and drag it to iTunes but that's hardly ideal and I look forward to seeing it in the actual store.

To publish to the Kindle store on Amazon you go to Kindle Direct Publishing (KDP). KDP will accept books in Word, ePub, Text, Mobipocket (.mobi), HTML, PDF, and RTF. I uploaded my ePub but Amazon's converter lost the table of contents and either lost or mangled images.

You can download some useful tools from amazon: Kindle Previewer App and KindleGen.

I found that the unspeakably ugly Calibre did a better job of converting ePub to .MOBI and I particularly like the ebook-convert command line tool which makes it as easy as this:

$ ebook-convert Small\ Solar.epub Small\ Solar.mobi
1% Converting input to HTML...
InputFormatPlugin: EPUB Input running
on Small Solar.epub
Parsing all content...
34% Running transforms on ebook...
Merging user specified metadata...
Detecting structure...
Flattening CSS and remapping font sizes...
Source base font size is 9.00000pt
Removing fake margins...
Cleaning up manifest...
Trimming unused files from manifest...
Trimming 'OPS/images/cover-image.png' from manifest
Creating MOBI Output...
67% Creating MOBI Output
Generating in-line TOC...
Applying case-transforming CSS...
Rasterizing SVG images...
Converting XHTML to Mobipocket markup...
Serializing images...
Serializing markup content...
  Compressing markup content...
Generating MOBI index for a book
MOBI output written to Small Solar.mobi
Output saved to   Small Solar.mobi

The output looks pretty good on a small greyscale Kindle although there are things to learn about writing for a small screen, tables aren't supported and titles need to be short to avoid unsightly wrapping.

I'd be charmed if someone would buy a copy. It's available now on Amazon and Lulu. Hopefully it will end up on iBookstore eventually.

Update

I'm happy to report that the book is now available in the iBookstore.





I found it on the iPad and it looks good. (Pardon my excitement). Nook is still pending at this point.

Wednesday, October 05, 2011

Arduino SD data logger with time stamp

I've been learning about powering my ham shack with solar power and have been working on logging battery voltage to get information about how my power budget is going. At first I used an Arduino's A/D to read the voltage and periodically send it out the USB serial port, but as the shed has no mains power the laptop was a major drain on the battery itself. Yes, measuring was really altering the experiment.

An SD Shield Plus, purchased via eBay, has all the things you need for stand alone data logging. An SD slot, a battery backed clock, and even a bit of non-volatile utility ram.

My Arduino is a slightly older model, the Diecimila and I found that as soon as I called SD.begin() the device would reset. It turns out that the SD library code uses more ram than is available in the older models.

The new Arduino Uno looks like a good improvement. Aside from a more spacious Atmel chip, the USB interface is a processor itself and can be set as a HID device which could be handy. I ordered a couple of Uno's from Little Bird Electronics, and they shipped within minutes, but I still couldn't wait and went to Jaycar to pick up an interesting Uno clone called "Eleven" made by Freetronics.



I hacked together the sample code to write a log file to the SD card with a date time stamp from the clock chip in a format that a spreadsheet will parse. It reads three of the analog inputs and writes a line to the file every ten seconds. Here's the code for future reference:


/*
  SD card datalogger
  by Tom Igoe
  hacked by Peter Marks to write time stamps

 This example code is in the public domain.
 */

#include <SD.h>
// For the SD Shield Plus
const int chipSelect = 10;

// This is to talk to the real time clock
#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68  // This is the I2C address

// Global Variables
int i;
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  Serial.print("Initializing SD card...\n");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(chipSelect, OUTPUT);
  Serial.print("chipSelect set to output\n");
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) 
  {
    Serial.println("Card failed, or not present\n");
    // don't do anything more:
    return;
  }
  Serial.println("card initialized.\n");
}

void loop()
{
  // make a string for assembling the data to log:
  String dataString = getDateDs1307();
  dataString += String(",");
  
  // read three sensors and append to the string:
  for (int analogPin = 0; analogPin < 3; analogPin++) 
  {
    int sensor = analogRead(analogPin);
    dataString += String(sensor);
    if (analogPin < 2) 
    {
      dataString += ","; 
    }
  }

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  File dataFile = SD.open("datalog.csv", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) 
  {
    dataFile.println(dataString);
    dataFile.close();
    // print to the serial port too:
    Serial.println(dataString);
  }  
  // if the file isn't open, pop up an error:
  else 
  {
    Serial.println("error opening datalog.csv");
  } 
  delay(1000 * 10);
}


// Gets the date and time from the ds1307 and return
// result in a format a spreadsheet can parse: 06/10/11 15:10:00
String getDateDs1307()
{
  // Reset the register pointer
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0x00);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  // A few of these need masks because certain bits are control bits
  second     = bcdToDec(Wire.receive() & 0x7F);
  minute     = bcdToDec(Wire.receive());
  hour       = bcdToDec(Wire.receive() & 0x3F);  
  dayOfWeek  = bcdToDec(Wire.receive());
  dayOfMonth = bcdToDec(Wire.receive());
  month      = bcdToDec(Wire.receive());
  year       = bcdToDec(Wire.receive());
  
  String dataString = "";
  
  dataString += Print2Digit(dayOfMonth); 
  dataString += String("/");
  dataString += Print2Digit(bcdToDec(month)); 
  dataString += String("/"); // Y2k1 bug!
  dataString += Print2Digit(bcdToDec(year));
  dataString += String(" ");
  dataString += Print2Digit(hour);
  dataString += String(":");
  dataString += Print2Digit(minute);
  dataString += String(":");
  dataString += Print2Digit(second);

  return dataString;
}

// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

String Print2Digit(byte Val)
{
  String dataString = "";
  if (Val < 10)
  {
    dataString = "0";
  }  
  dataString += String(Val, DEC);
  return dataString;
}

The output file looks like this:


06/10/11 15:36:16,555,489,479
06/10/11 15:36:18,461,427,438
06/10/11 15:36:19,419,401,414
06/10/11 15:36:21,397,387,404
06/10/11 15:36:22,394,389,403
06/10/11 15:36:23,380,375,393
06/10/11 15:36:25,386,383,399
06/10/11 15:36:26,382,380,396
06/10/11 15:36:28,380,378,395
06/10/11 15:36:29,387,385,400


Here's a few days of data. Today was partially cloudy but the battery was re-charged in the end.


Plotted with python and matplotlib with this:


#!/usr/local/bin/python

import datetime
import matplotlib
matplotlib.use('Agg')

import matplotlib.pyplot as plt
import csv

INFILENAME = 'datalog.csv'
VOLTSCALE = 665.0 / 13.7

def main():
    datareader = csv.reader(open(INFILENAME,'r'), delimiter=',')
    dates = []
    points = []
    for row in datareader:
        if len(row) > 1:
            #Converts str into a datetime object. 08/10/11 12:23:12
            dates.append(datetime.datetime.strptime(row[0],'%d/%m/%y %H:%M:%S'))
            volts = float(row[1]) / VOLTSCALE
            points.append(volts)
    
    fig = plt.figure()
    plt.plot(dates, points)
    plt.title("Battery Voltage over several days")
    plt.ylabel('Battery Volts')
    fig.autofmt_xdate()
    plt.ylim(ymin=8)
    plt.show()
    plt.savefig('voltgraph')

if __name__ == "__main__":
    main()
    

OMG Steve Jobs

"OMG Steve Jobs" was the SMS from my daughter. I'd been watching Google Reader only minutes before and it was clear this was set to be the biggest, and fastest spreading, story to date.




I feel like I felt in 1980 on hearing that John Lennon was killed.


News has evolved to be super-efficient in the last few years. A few friends and a few family sent SMSs, I chatted with others via instant messenger. Apple's home page was elegant.


I notice the image is called t_hero.png, but maybe that's normal.

The story is the lead everywhere.


Ironically, our prime minister, at today's "Jobs summit" made a statement and the US president quickly had something to say.


Nice of them to pass a "Jobs act" too.

There's some wonderful commentary starting to appear. I like Walt Mossberg's piece in particular.

I watched the iPhone 4S keynote yesterday, (thank goodness he held on until after that was over), Tim Cook did a fine job backed by a solid team. There was a downbeat feeling about the presentations, I wonder if they knew how close the end was, or perhaps they knew the wishful rumours of an iPhone 5 would mean they'd be unveiling something a little disappointing.

Even today, thirty years after Lennon's death, I wonder what he'd say about Occupy Wall Street. I, for one, will be thinking "What would Steve do" for a long time to come.

Tuesday, October 04, 2011

Open wire fed doublet antenna

Since moving the ham radio station to the new shed, which is located in the back corner of our block, it has become practical to use an open wire line feeder to my dipole.

I've often heard that the most versatile and efficient antenna is an open wire feeder to a doublet on the lowest band desired. This antenna can be then tuned to any band. I ordered some nice copper wire and spacers from TTS Systems. I'm using dipole centre pieces from Emtron which I like very much.


The open line runs from the shed out to the back yard. It's not quite as wonky as it looks below.


The wires pass through the wooden wall of the shed and straight in to a 4:1 balun and then to an antenna tuner.


I plan to re-jig things a bit and try to go direct into a balanced line antenna tuner to avoid the co-ax run in the shed.

TTS Systems were good to deal with and they dispatched quickly but I was disappointed to find that three of the spacers were faulty (missing centre hooks on one end) which seems like poor quality control given such a small order.




The dipole doesn't have enough space for 80m so it has substantial drooping ends in order to work on 80m. My plan is to replace these drooping ends with loading coils.

Update

I've cut the dipole for 40m and dispensed with the half size G5RV that's been my main antenna in recent months. I'll have to make other arrangements for 80m, perhaps some sort of end fed system.

It's hard to compare antennas on HF due to the incredible changes in conditions but it sounds good and very low noise to me.