Streaming to twitch.tv with ffmpeg…

I was trying to figure out how to screencast to twitch.tv using ffmpeg. A couple of hours of tinkering resulted in the following command line which does a bunch of stuff.

  • It captures the X desktop at 15 fps and 1920×1080 resolution.
  • It grabs frames from my webcam (a Logitech Pro 9000) at 320×240 resolution.
  • It then combines the two into a 1024×576 image, with the video overlayed at the top right and a banner at the bottom that displays a couple of lines of text.
  • It then ships it to the twitch.tv server.  If you grab this code, you need to add your own streaming URL for your own channel.
#!/bin/bash

/home/markv/bin/ffmpeg 	\
	-y -thread_queue_size 64 -f x11grab -s 1920x1080 -framerate 15 -i :0.0+0,0 \
	-thread_queue_size 64 -f v4l2 -input_format mjpeg -framerate 5 -video_size 320x240 -i /dev/video0 \
	-filter_complex \
	"[0:v] scale=1024:576, setpts=PTS-STARTPTS  [bg]; \
	 [1:v] setpts=PTS-STARTPTS [fg]; \
	 color=0x336699cc:1024x64, drawtext=textfile=twitch.txt:fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf:x=10:y=16:fontsize=16:fontcolor=white [bottom] ; \
	 [bg][fg] overlay=W-w-16:16 [out2]; \
	 [out2][bottom] overlay=0:H-64, format=yuv420p [out]" \
	-map "[out]" \
	-vsync 1 \
	-c:v libx264 -b:v 500k -maxrate 500k -bufsize 1000k -framerate 15 -g 30 -crf 30 -preset fast -pix_fmt yuv420p -tune zerolatency \
	-f flv rtmp://live.twitch.tv/app/live_XXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

A few additional notes:

  • The default DNS server for my ISP don’t serve DNS requests for the live.twitch.tv server.   I fixed this by adding the Google DNS servers to my router (8.8.8.8 and 8.8.4.4).
  • The script appears to work pretty well, but sometimes has difficulty starting up.  And, when the script crashes, the remote clients don’t time out for a considerable time.
  • I haven’t tested this extensively.

Buyer beware, but I hope it is useful.

 

Recommendations for tech to create a virtual hacker space?

Most of my hacking occurs in a vacuum: where I sit in my living room or in my home office and toil away silently on projects which occasionally get documented here, but which all too often are just my way of passing the time. On the way to work, I was asking myself what I could do to boost my own excitement about these projects, and provide some incentive to do more, and on a more regular basis.

So, I had an idea which is almost certainly not new: the idea of a virtual hackerspace.

For years, I used to donate my Friday evenings to the Chabot Amateur Telescope Makers workshop. I’d go down and spend three or four hours showing up, seeing who needed help on a telescope project, or I’d bring my own and work on that. I want to create a more generic “workshop network”, where people can meet regularly for a kind of hackerspace parallel play using video conferencing technology.

In some sense, it’s just an extension of Google Hangouts. The idea would be that each participant would have a webcam/microphone setup, and at the appointed time, we could all just open our cameras and mics, say “hi” to one another and then go about our business, potentially sharing our projects or asking questions of the group at large. I’ve mostly used Hangouts for simple one-to-one conversations, and have little experience with larger groups, and didn’t really find any obvious links about how to manage larger groups. Does anyone have any recommendations on how to setup such a network? I am not really interested in creating a “show”, but really more of a set of spaces which encourage mutual collaboration and interest.

I’m willing to entertain other technologies as well, if people have better suggestions.

And, if you would be interested in joining in this kind of “network”, drop me a note here or on twitter (@brainwagon). I’ll try to do an update of what I learn.

More on Caxton Foster’s Blue Architecture…

Okay, it’s been a long time since I wrote anything here. Not really a lot dramatic going on in life, I just have been spending my free time writing for Quora rather than my own blog. But I still am nerding out from time to time. Last night I dusted off an old project of mine and carried it a bit further…

I had written a short post before about a simulator I wrote for Caxton Foster’s “Blue” computer architecture described in his book Computer Architecture. I have the third edition published in 1985. The “Blue” architecture is ridiculously simple: only sixteen instructions, 4096 words of memory, and only one addressing mode. If you click back to my previous post, you’ll see a complete behavioral simulator for it, written in less than an hour.

Somehow this came back up, and I was suddenly intrigued by the idea of trying to write a simple program for it, just to test my ideas about how awful such a machine would be. Ultimately, my goal is to write a simple program that can compute the value of pi to around 100 decimal places. Such a program seems doable, but it’s not a complete cakewalk. But to achieve this, I thought it might be fun to write a simple assembler.

So, I shook the cobwebs that have covered the bits of my brain that understood yacc/lex/bison/flex and wrote a simple assembler for the architecture. It totals only about 250 lines of code, but can handle symbolic labels and all the instructions. It took me about two hours of wall clock time, with my attention split between programming and watching the latest episode of Grimm.

I doubt the assembler is of any real interest, but eventually I’ll get the code onto github.

I then sat down this morning, and wrote this simple program to take the signed value at the memory location VALUE and print it as a signed decimal number. It prints the sign then five digits, with leading zeros if necessary. I didn’t bother to comment
the code, but here it is…

PRINTVALUE:
	LDA VALUE
	JMA NEG
	LDA PLUS
	OUT
POS:
	LDA S0
	STA TMP0
	SRJ DODIGIT
	LDA S1
	STA TMP0
	SRJ DODIGIT
	LDA S2
	STA TMP0
	SRJ DODIGIT
	LDA S3
	STA TMP0
	SRJ DODIGIT
	LDA S4
	STA TMP0
	SRJ DODIGIT
	HLT

DODIGIT:
	IOR JMPBIT
	STA RETURN
	LDA ZERO
	STA DIGIT
LOOP:	LDA VALUE
	ADD TMP0
	JMA DONE
	STA VALUE
	LDA DIGIT
	ADD ONE
	STA DIGIT
	JMP LOOP
DONE:
	LDA DIGIT
	ADD FE
	OUT
RETURN:
	JMP 0

NEG:
	LDA MINUS
	OUT
	LDA VALUE
	XOR ONES
	ADD ONE
	STA VALUE
	JMP POS

VALUE:	.WORD 12323
TMP0:	.WORD 0
DIGIT:	.WORD 0
S0:	.WORD -10000
S1:	.WORD -1000
S2:	.WORD -100
S3:	.WORD -10
S4:	.WORD -1
ZERO:	.WORD 0
ONE:	.WORD 1
ONES:	.WORD $FFFF
JMPBIT:	.WORD $A000
MINUS:	.STRING "-"
PLUS:	.STRING "+"
FE:	.WORD 48

The assembler spits out a series of 16 bit words which can be loaded into my
simulator…

0x602B, 0x9024, 0x6038, 0xC000, 0x602E, 0x702C, 0x8014, 0x602F, 
0x702C, 0x8014, 0x6030, 0x702C, 0x8014, 0x6031, 0x702C, 0x8014, 
0x6032, 0x702C, 0x8014, 0x0000, 0x4036, 0x7023, 0x6033, 0x702D, 
0x602B, 0x102C, 0x9020, 0x702B, 0x602D, 0x1034, 0x702D, 0xA018, 
0x602D, 0x1039, 0xC000, 0xA000, 0x6037, 0xC000, 0x602B, 0x2035, 
0x1034, 0x702B, 0xA004, 0x3023, 0x0000, 0x0000, 0xD8F0, 0xFC18, 
0xFF9C, 0xFFF6, 0xFFFF, 0x0000, 0x0001, 0xFFFF, 0xA000, 0x002D, 
0x002B, 0x0030, 

The data above gets simply compiled into my simulator and runs.

Screen Shot 2016-03-26 at 10.57.16 AM

Okay, so what’s fun to note about this?

There is only a single register, the accumulator. You spend a LOT of time loading things, modifying the value, and storing them back into main memory. There is no “immediate mode”, so you have to create memory locations to store common values like “1” and “0”. DODIGIT is a subroutine, which is called by the SRJ instruction. SRJ puts the PC into the accumulator, and then jumps to the specified address. To “return”, you OR in the bits to the accumulator to form a JMP instruction, and then store that at the end of your subroutine. There is no call stack. Although not demonstrated particularly here, the processor does not implement indexing or indirection. There is also no real condition registers such as CARRY or OVERFLOW, so implementing multi-precision arithmetic might be a challenge.

Foster’s book also details additions to this architecture, eventually becoming INDIGO, an architecture which is rather similar to a PDP-8.

Sure, if you are going to really learn computer archtictures, Patterson and Hennessy is probably a better path, but there is something like of pleasing in this archaic trip down memory lane. My pi computing program will percolate in my brain for a bit, and will find implementation on some other evening.

Addendum: Hackaday recently posted about Al Williams’ FPGA implementation of an architecture which is based upon Foster’s Blue machine. I believe he made a number of changes that make it more practical, but it might be worth looking at. He wrote a monitor, which seems to use opcodes which aren’t compatible with mine.

Addendum2: Pondering it some more throughout the day, it seems difficult to implement my idea of a pi computing program for this virtual machine. All of the algorithms that I can think of require 32 bit numbers, and the Blue architecture simply lacks the capabilities needed to implement it. It also is pretty weak on conditional statements: the only condition that you can branch on is the sign bit of the accumulator.

Quadcopter Survey with my DJI Phantom 2/GoPro

I hadn’t been flying my DJI Phantom 2 since last year (before I herniated two disks in my neck) but I’ve been meaning to take it out and get it in the the air. This week, two different things happened which provided some incentives to get it in the air, for reasons which weren’t entirely frivolous:

  • My new next door neighbor mentioned that there was debris in the drainage ditches up on the hill that drain from his yard to my yard. I thought that it had been cleaned out, so I wanted to be sure, but frankly, hiking up there when the ground is wet is asking for a new herniated disk.
  • I had a small roof leak which caused a call to my roofers to come out and have a peek. They mentioned that I had a fair number of busted tiles on my roof (annoying, perhaps broken by our contractors during last years remodel?).

I hadn’t flown in a while, so I decided that rather than flying over my house, I’d begin by just getting the view of the drainage ditches. I got the copter charged up again, reviewed my checklists, and took it out into the backyard.

Oddly, I heard a familiar droning: one of my neighbors had a quadcopter up doing a high pass over the neighborhood. By the time I was ready though, it had sailed back off to the south. I got it up in the air and tried to get my coordination back. It was a beautiful day for flying.

Here’s a nice high view to the north east from my house, fairly high up.

vlcsnap-2016-01-24-16h43m07s108

But that wasn’t what I was after: I aimed the GoPro down and flew fairly low over my hill to get these pictures. This is the view of the lower of the two drainage ditches. It’s got a little silt in it, but is pretty clear. It might be worthwhile to do a concrete patch of the seam. You can also see a fair number of gopher holes up on the hill.

vlcsnap-2016-01-24-16h42m37s703

The other ditch is at the top of the hill. It actually gets a lot less water, so the silt settles out pretty well up there, and I’ve got some grass growing it. It could definitely use some work to clear it.

vlcsnap-2016-01-24-16h42m21s229

Very nice! Perhaps next weekend I’ll do a flight over the house and see if I can identify broken roof tiles. I’m pretty glad I didn’t have to hike up there to check it out. Kind of wish I had an FPV setup. Perhaps I’ll get that going in the not-too-distant future.

On calculators, Space Invaders and Binary Coded Decimal Arithmetic…

A couple days ago, one of my Twitter or Facebook friends (sadly, I forgot who, comment if it was you, and I’ll give you credit) pointed out this awesome page:

Reversing Sinclair’s amazing 1974 calculator hack – half the ROM of the HP-35

It documented an interesting calculator made by Sinclair in the 1970s. It is an awesome hack that was used to create a full scientific calculator with logarithms and trigonometric functions out of an inexpensive chip from TI which could (only barely) do add, subtract, multiply and divide. The page’s author, Ken Shirriff, wrote a nifty little simulator for the calculator that runs in the browser. Very cute. It got me thinking about the bizarre little chip that was at the center of this device.

I’m kind of back in an emulator kick. I recently had dusted off my code that I had started for emulating the 8080 processor. I had originally wanted to implement a version of CP/M, but I remembered that the 1978 game Space Invaders was also based upon the 8080. It wasn’t hard to find a ROM file for it, and with a little bit of hacking, research and debugging, I had my own version of Space Invaders written in C and using SDL2, running on my Mac laptop.

Screen Shot 2015-09-16 at 12.46.01 PM

Fun stuff.  The sound is a little crude: most of the sound in the original game was generated by a series of discrete circuits which you can find on this page archived via the Wayback Machine. I briefly played around with simulating some of the sounds using LTSpice based upon these circuits (it appears to work fairly well), but I haven’t got that fully integrated into my simulator yet. For now, it just queues up some recorded sounds and plays them at the appropriate time. Everything is currently working except for the classic “thump… thump…” of their marching. I’ll get that working sometime soon.

Anyway, back to calculators. One thing on Ken’s page kind of made me think: he mentioned that the HP-35 had taken two years, twenty engineers, and a million dollars to develop. Mind you, the HP-35 was pretty revolutionary for its time. But I thought to myself “isn’t a calculator an easy hobby project now?”

After all, I had assembled a KIM-Uno, Oscar’s awesome little $10 board that emulates the KIM-1 microcomputer:

In fact, the KIM-Uno implements a floating point calculator as well. It’s brains are just an ordinary Arduino Pro Mini wired on the back. Arduino Pro Minis can be had for less than $3 from China. Could I make a fun little calculator using that as the basis?

My mind is obviously skipping around a lot at this point.

Of course, a bit more googling revealed that someone had done something very similar using the MSP430 chips from (appropriately enough, also manufactured by Texas Instruments). Check out the build thread here.. It’s pretty nifty, and uses a coin cell to drive it, as well as some very classic looking “bubble LED displays”, which you can get from Sparkfun. Pretty cool.

Anyway…

For fun, I thought it might be fun to write some routines to do binary coded decimal arithmetic. My last real experience with it was on the 6502 decades ago, and I had never done anything very sophisticated with it. I understood the basic ideas, but I needed some refresher, and was wondering what kind of bit twiddling hacks could be used to implement the basic operations. Luckily, I stumbled onto Douglas Jones’ page on implementing BCD arithmetic, which is just what the doctor ordered. He pointed out some cool tricks and wrinkles associated with various bits of padding and the like. I thought I’d code up a simple set of routines that stored 8 BCD digits in a standard 32 bit integer. His page didn’t include multiplication or division. Multiplication was simple enough to do (at least in this slightly crazy “repeated addition” way) but I’ll have to work a bit harder to make division work. I’m not sure I really know the proper way to handle overflow and the sign bits (my multiplication currently multiplies two 8 digit numbers, and only returns the low 8 digits of the result). But.. it seems to work.

And since I haven’t been posting stuff to my blog lately, this is an attempt to get back to it.

Without further ado, here is some code:

/*
 * A simple implementation of the ideas/algorithms in 
 * http://homepage.cs.uiowa.edu/~jones/bcd/bcd.html
 *
 * Written with the idea of potentially doing a simple calculator that
 * uses BCD arithmetic.
 */

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

typedef uint32_t bcd8 ;         /* 8 digits packed bcd */

int
valid(bcd8 a)
{
    bcd8 t1, t2, t3, t4 ;
    t1 = a + 0x06666666 ;
    t2 = a ^ 0x06666666 ;
    t3 = t1 ^ t2 ;
    t4 = t3 & 0x111111110 ;
    return t4 ? 0 : 1 ;
}

bcd8
add(bcd8 a, bcd8 b)
{
    bcd8 t1, t2, t3, t4, t5, t6 ;

    t1 = a + 0x06666666 ;
    t2 = t1 + b ;
    t3 = t1 ^ b ;
    t4 = t2 ^ t3 ;
    t5 = ~t4 & 0x11111110 ;
    t6 = (t5 >> 2) | (t5 >> 3) ;
    return t2 - t6 ;
}

bcd8
tencomp(bcd8 a)
{
    bcd8 t1 ;

    t1 = 0xF9999999 - a ;
    return add(t1, 0x00000001) ;
}

bcd8
sub(bcd8 a, bcd8 b)
{
    return add(a, tencomp(b)) ;
}

bcd8
mult(bcd8 a, bcd8 b)
{
    bcd8 result = 0 ;
    bcd8 tmp = a ;
    bcd8 digit ;
    int i, j ;

    for (i=0; i<8; i++) {

        digit = b & 0xF ;
        b >>= 4 ;

        for (j=0; j<digit; j++)
            result = add(result, tmp) ;

        tmp <<= 4 ;
    }
    return result ;
}

int 
main(int argc, char *argv[])
{
    bcd8 t = 0x00009134 ;
    bcd8 u = 0x00005147 ;
    bcd8 r ;

    r = mult(t, u) ;
    printf("%X * %X = %X\n", t, u, r) ;
}

I’ll have to play around with this some more. It shouldn’t be hard to move code like this to run on the Arduino Pro Mini, and drive 3 bubble displays (yielding 11 digits plus a sign bit) of precision. And I may not use this 8 digits packed into 32 bit format: since I want 12 digits, maybe packing only 4 digits into a 32 bit word would work out better.

Anyway, it’s all kind of fun to think about the clanking clockwork that lived inside these primitive machines.

I’ll try to post more often soon.

The Kim-Uno — a Kim-1 simulator

Ken Boak had mentioned on twitter that someone was creating a blinken-lights front end for the simh simulator of the PDP-8, called the PiDP-8, since you can power the entire thing from a Raspberry Pi. Very cool, but not quite available yet. What was available from Oscar is the Kim-Uno, a simulator for the old KIM-1 computer, a single board computer based upon the MOS6502 with a simple LED display and a whopping 1K of memory, first shipped in 1977 or so for about $245. The simulator is incredibly simple: a board, buttons, leds, and an Arduino Micro to drive it all. I went ahead and ordered one, just for kicks.

But you don’t actually need the hardware to play with this: you can get the code running on an ordinary Arduino Uno. So I did. It’s setup to run Microchess out of the box. Microchess is cool because it can play chess in less than 1K of code, and probably was the first commercial game software produced for hobbyist computers.

The Kim-Uno sketch is a little bit odd though. I’ve begun tinkering with it, and cleaning it up a bit. First of all, I thought it was confusing the way it tried to include the 6502 core emulation (written by Mike Chambers). It is written in C, and to merge it into the sketch required a bit of chicanery using ‘extern “C”‘ directives. Bleh, I renamed cpu.c to cpu.cpp, and cleaned that up. I fixed some forward declarations. I uncovered a couple of bugs by paying attention to compiler warnings. It won’t even come close to compiling on non-Arduino platforms, so I deleted lots of conditional definitions. And I generally just tidied things up. Along the way, I checked out the code that Oscar put in to scan the six digit display, which took a lot of pins. As is happens, I had an 8 digit display which used the 74HC595, which I had gotten working before using an interrupt driven display driver. I merged that code in, and now I had a hardware display like the Kim wired to my Uno. Probably refreshes more often than the original, but looks great!

When I get my code tidied up more, you’ll be able to download it on github. Stay tuned.

Driving an 8 digit, 7 segment display based upon the 74HC595…

A few weeks ago, I was scanning the Deal Extreme website, and ordered a few different LED displays, not because of any pressing need, but because I wanted to have some display options available if I needed some for a project. I was especially interested in cheap LED displays. One of the ones I ordered was this 8 digit, 7 segment display, which seemed to have a five pin interface. Without thinking about it too much, I went ahead and ordered it.

Today, they arrived. Like a lot of things that come from dealextreme, this one had been shipped somewhat haphazardly: the right angle header pins were significantly bent, but a little gentle prodding moved them back into place. I then spent a few minutes trying to decide what the module actually needed.

Unlike the modules I’ve had previously based upon the TM1637/TM1638/TM1640, these modules did not have a controller onboard that could latch all the segments and hold values. Instead, this board has 2 8 bit shift registers (namely, the 74HC595). Basically, one shift register controls which of the 8 digits are powered up (a high value in the 8 bit word indicates that the corresponding digit has a power on its cathode (which is common to all the segments of the LED) and the other 8 bit word tells it which segment is turned on (actually, it’s inverted: a 1 indicates the corresponding segment is off).

But here lies the rub: you only have 8+8 control lines, but you have to control 56 (actually 64 if you include the decimal points) segments. The way you get around this is to display a single digit at a time, but only do it for a short period of time. If you flip between digits fast enough, your persistence of vision will merge them into a consistent display.

The usual way to do this with an Arduino would be to use the shiftOut statement to clock the data out on some serial pins, and then call delay (or delayMicrosecond) to wait a bit, then shift the data out for the next digit, etc… But that makes the loop() difficult to write: you have to interleave both the display and all the other work that you have to do, with careful attention to timing.

There is a better way: interrupts. In particular, I used the TimerOne library (available on the Teensy as well as the Arduino libraries) to setup a timer interrupt. The idea is to contain a display buffer of 8 bytes, one byte per digit, which specifies which of the 8 segments is on. When the interrupt occurs, it clocks out the cathode and then the segments for the specified digit as quickly as it can, and then increments the display digit by one, wrapping around if necessary. Because this happens in an interrupt, it means that display happens without any real use intervention. When you want to change what is displayed on the display, you just change the contents of the segment buffer and then the interrupt fires next time, the appropriate digit will
be displayed.

The basic code worked the first time I typed it in (modulo plugging jumpers into the wrong pins on the Teensy, and with the digits occurring in the reverse order than I desired). A moments tweaking yielded this nice, steady display:

I’ve decided that rather than posting code fragments embedded here, I will instead post links to a github repository that holds the necessary code. As I extend and make improvements, you’ll be able to get updated code there.

A 4 digit, 7 segment display board based upon the TM1637 chipset…

Yesterday, I got a small 4 digit, 7 segment LED display board in the mail from dx.com. Cost was around $3 shipped, and the module uses a 4 pin interface (power, ground, clock and data). Originally, I thought it was I2C, but like other modules I have received based upon chipsets made by Titan Micro (using the TM1638 and TM1640) it looks superficially like I2C, but doesn’t use the open collector bus and addressing scheme of I2C. You end up clocking commands to the board using two dedicated pins.

The driver that I’m using comes from here. It is based upon the driver from avishorp, but includes support for the colon that separates the two pairs of digits on this display, which I wanted to allow blinking to help indicate that the clock was running. This was my example sketch, which is completely unremarkable. It doesn’t set the time from a real source, I just hard coded it to set the time to a specific constant near when I compiled it.

#include <Time.h>
#include <TM1637Display.h>

#define CLK 2
#define DIO 3

TM1637Display display(CLK, DIO);

void setup() {
  Serial.begin(9600);
  // put your setup code here, to run once:
  setTime(1432823831UL);
  display.setBrightness(0xF);

}

boolean colon = true ;

void loop() {
  
  // put your main code here, to run repeatedly:
  int t = hour() * 100 + minute() ;
  display.setColon(colon);
  colon = !colon ;
  display.showNumberDec(t, true);
  delay(1000) ;
}

It works reasonably well.


Addendum: I received this tweet:


Not a bad little trick to archive. Instead of using the Time library, you need to use the RTClib library. I modified my program above to do it. Here’s the new version:

#include <Wire.h>
#include <RTClib.h>
#include <TM1637Display.h>

RTC_Millis rtc;

#define CLK 2
#define DIO 3

TM1637Display display(CLK, DIO);

void setup() {
  Serial.begin(9600);
  display.setBrightness(0xF);
  rtc.begin(DateTime(F(__DATE__), F(__TIME__))) ;
}

boolean colon = true ;

void loop() {
  DateTime now = rtc.now() ;
  int t = now.hour() * 100 + now.minute() ;
  ;
  display.setColon(colon);
  colon = !colon ;
  display.showNumberDec(t, true);
  delay(1000) ;
}

Note: the time gets set to the time when the code is compiled. If you compile and install it, it will likely be a couple of seconds off. And when the Arduino gets reset, it will get reset to that same time. This is most useful in setting the time on an external time keeping module.

Progress Report: Big Box O’ RF

Previously, I wrote about a project I called the Big Box O’ RF. I’ve shifted goals a bit, and done some experimentation, and have changed some of my goals and approach.

First of all, I’ve changed the goal a bit. Instead of being a piece of test equipment, I’m actually more interested in using it to implement a beacon transmitter. It’s been quite some time since I have done any QRSS (slow speed Morse) or WSPR (Weak Signal Propagation Reporter) but I still find it to be a pretty interesting thing to do. What I’ve wanted to have for a while was a dedicated beacon transmitter that didn’t require the cooperation of my laptop and FT-817 to send out a modest signal. It seems to me that this totally doable mostly with parts I have on hand.

Goals:

  • Output power between 250mw and 500mw
  • Controlled by an inexpensive microcontroller. While the Arduino would be an obvious choice, the Teensy LC or Teensy 3.1 are as easy to program, and offer some interesting improvements for similar cost.
  • Able to integrate multiple methods to keep accurate type of time. Initial prototype will probably use the Ultimate GPS I’ve been playing with. Alternatives include clock boards based upon the DS1307 or DS3231, or synchronization via Wifi/SNTP (almost certainly using the ESP8266).
  • Able to support multiple modes: at least WSPR, DFCW, and Slow Feld.
  • LCD panel to display information. Text based interface supplied via USB, allowing you to change message, frequency, timing, etc…
  • RF generated by my AD9850 module.

I’ve been tinkering with most of the modules independently, making sure I can interface with each of them. They all seem to work fairly well. As soon as I find an appropriate box, I’ll start getting them put together. I’ve built a harmonic filter for 30m (where I plan to do most of my operation). I need to work on the amplifier chain, as well as a little transmatch (I don’t want to dedicate one of my antenna tuners to this operation either).

More to come soon.

Teensy LC hooked to an Adafruit Ultimate GPS…

One of the things that I really like about the Teensy LC (besides its low price) is that it has three hardware serial ports. Hardware serial ports are just nicer than the SoftwareSerial ports that you see on the ordinary Arduino platform. While the latest support for SoftwareSerial ports on digital pins work reasonably well at low baud rates, they aren’t especially good or reliable at higher baud rates. The Adafruit UltimateGPS I have supports data output at 10Hz, which requires serial rates of 115200, which isn’t especially reliable.

But I’m still inexperienced with the Teensy. To test my understanding, I wrote this little program for the Teensy LC, after hooking my GPS up to pins 0/1 as RX/TX. Note: the Serial object does not route to any of these three outputs: the Serial object is a distinct USB object that is not mapped directly to digital pins.

This was also an attempt to test the TinyGPS library with the Teensy LC. It worked the very first time I got it to compile.

I’m definitely leaning toward using the Teensy (either the cheaper LC version, or the more expensive but more faster/more capable 3.1, which includes FIFOs for serial ports) on my WSPR project.

//   __                                        
//  / /____ ___ ___  ___ __ _________ ____  ___
// / __/ -_) -_) _ \(_-</ // /___/ _ `/ _ \(_-<
// \__/\__/\__/_//_/___/\_, /    \_, / .__/___/
//                     /___/    /___/_/        
//
// On the Teensy LC, there are three hardware supported serial ports.
//
// Port    Rx  Tx
// -------+--+--+
// Serial1| 0| 1|
// -------+--+--+
// Serial2| 9|10|
// -------+--+--+
// Serial3| 7| 8|
// -------+--+--+
//
// It appears (as yet unverified) that these are distinct from the serial
// port which is connected to the Serial object.  This program is designed
// to test that theory.

#include <TinyGPS.h>

TinyGPS gps;

void
setup()
{
    Serial.begin(9600);
    Serial1.begin(9600);
}

void
loop()
{
    unsigned long date, time, age;
    long lat, lng ;
    for (;;) {
        while (Serial1.available()) {
            char c = Serial1.read();
            if (gps.encode(c)) {
                gps.get_datetime(&date, &time, &age);
                Serial.print("Date: ");
                Serial.println(date);
                Serial.print("Time: ");
                Serial.println(time);
                gps.get_position(&lat, &lng) ;
                Serial.print("LAT: ");
                Serial.println(lat);
                Serial.print("LNG: ");
                Serial.println(lng);
                Serial.println();
            }
        }
    }
}

Testing the DS3231 module… I’m impressed!

I hooked up my new DS3231 clock module to an Arduino that was being fed with the one pulse per second input from a locked GPS, and counted the number of pulses from each. In 3170 seconds, the clock module generated 103874565 pulses, for an average pulse per second of 32768.0015773 pulses per second. That’s really good, only about 2 seconds per year. Of course this was a short term test, under relatively stable temperature conditions, but still, I’m highly impressed. I’m thinking that using this to drive my WSPR radio beacon is likely to work out very well.

New (more accurate) clock module…

As I mentioned in a previous post, I was not enormously satisfied with the accuracy of the DS1307 clock module that I got from China. It was hard to argue with the less than three dollar price tag, but I was hoping that the accuracy might achieve 20ppm (less than two seconds of drift per day). My measured drift was over ten times that, about 25 seconds per day. Ungood.

Toward that end, I picked up a different clock module based upon the DS3231 chip. I didn’t have much time to play with it, but I did power it up.

IMG_0114


IMG_0115

A couple of quick notes:

  • It seems to have a dedicated 32KHz output, but it doesn’t run when solely on battery power.
  • The rise time of the 32kHz signal is pretty slow.
  • The duty cycle of the 32Khz signal is significantly below 50%.
  • The frequency as reported by my (not terribly accurate) oscilloscope’s built in frequency meter seems very close to the nominal 32768 Hz signal.

When I get time tonight, I’ll test it against my GPS and see what really works. My initial impression? Positive. If you care about even reasonable accuracy, paying a couple of bucks more for a clock module will probably be a good idea.

Accuracy of the DS1307

My tinkering with using the Adafruit GPS as a time base has yielded some results. I’m still getting a few spurious interrupts when I feed my buffered PPS signal into the interrupt pin on the Arduino, but they are relatively few and far between (and quite regular in appearance).

A few short notes, followed by my conclusions.

The PPS signal from the GPS is a pulse at 1Hz, which remains high for 100ms and then drops back to the ground state. The voltage peaks out at 2.8 volts.

The SQ signal from the Tiny RTC board is a (nominal) 32768 Hz signal. it’s a 5v square wave, with a 50% duty cycle.

foo

(This screen capture is actually for a 4096 Hz signal which I experimented with earlier, but have since changed to a 32768 Hz signal).

I wrote this code to use the 1PPS as a signal to count the number of clock pulses per second.

//

volatile uint32_t clk_cnt = 0UL ;
volatile uint32_t pps_cnt = 0UL ;
volatile bool dirty = false ;

void
pps_interrupt()
{
    pps_cnt ++ ;
    dirty = true ;
}

void
clk_interrupt()
{
    clk_cnt ++ ;
}

void
setup()
{
    Serial.begin(9600) ;
    Serial.println("CLOCK");
    pinMode(2, INPUT_PULLUP);
    pinMode(3, INPUT_PULLUP);

    attachInterrupt(0, pps_interrupt, FALLING);
    attachInterrupt(1, clk_interrupt, RISING);
}

void
loop()
{
    for (;;) {
        if (dirty) {
            dirty = false;
            Serial.print(pps_cnt);
            Serial.print(" ");
            Serial.println(clk_cnt);
            
        }
    }
}

I encountered a couple of odd problems though.

Initially, I seemed to be getting spurious calls to the pps_interrupt. In particular, while the PPS signal was high, transitions of the CLK signal seemed to trigger spurious calls to pps_interrupt. Thus, I’d get about 3270 additional calls to pps_interrupt.

I was suspicious that perhaps the 2.8v PPS signal was causing some problems somehow. I constructed a simple inverter (1K ohm resistor into the base of a 2N3904, with a 10K resistor connecting the collector to the 5v supply, output tapped below the resistor). When I hooked up the output of the inverter to the Arduino interrupt input, I got much better results, although there still seemed to be an odd transition or two when the PPS swapped state. You can see the result in this graph:

raw

The low end of measurements are all approximately (nearly exactly) 10% of the average value. In looking at the raw data, you can see these low values are followed by a value which is 90% of the average value: in other words, they sum to the average value, which indicates that the interrupts were spurious, and likely happened when the pps signal returned to the HIGH level (remember, we now have a buffer inverter in place).

If we ignore the spurious interrupts, we can calculate the accuracy of the DS1307.

Using this data, we find that the clock is running a bit fast: there are 32777.652 transitions per second, instead of the nominal 32768. If you multiply this out, you get that the DS1307 runs about 25.44 seconds fast per day. That’s pretty miserable, about 300ppm. I’ll double check the math again, but so far, I’m suspecting that perhaps paying more than $3 per module would be fruitful if accurate time keeping is required.

Capsule Review: The Adafruit Ultimate GPS Module

I picked up an Adafruit GPS module while at the Maker Faire. It’s a cool little module. I had a couple of old GPS modules: a Parallax PMB 648 and a Garmin 89, but this one is pretty nifty:

  • It is small.
  • It is breadboard friendly.
  • It has a one pulse per second (1PPS) output for timing applications.
  • It can output position/velocity information at up to 10Hz.
  • It has a u.FL connector external antennas.
  • It can be powered down by pulling an ENABLE pin low.

Lots of good features. I hooked it up tonight. My previous modules had a difficult time getting a lock inside, but this module had no difficulty at all. From a cold start, it had no problem locking. I hooked up the 1PPS output to my oscilloscope. It generates a nice 100ms positive pulse. The specifications say the timing jitter would be around 10ns. Very nice! That should be able to make a nice timebase to test the accuracy of the DS1307 module I was playing with yesterday. Data to come soon.

Rheoscopic Fluid (mica in suspension)

I mentioned in my Maker Faire wrap up post that I had spoken with Ben Krasnow, the science guru behind the Applied Science Youtube channel. If you haven’t watched his videos, by all means, go over there and give it a whirl. Between playing with chemicals, low temperatures, rockets, X rays, and electron microscope, it’s simply humbling.

He’s also a skilled woodworker, and build this rheoscopic coffee table. What is a rheoscope, you ask? A rheoscope is a device for measuring or detecting currents, usually in fluids. His table includes a spinning disk filled with a fluid that makes it easy to see the turbulence that goes on. If you go to as many science museums as I do, you’ll recognize the gadget. If you’ve tried to build furniture, you’ll recognize the craftsmenship.

This year, Ben brought some simpler fluid cells that are easier for people to construct. I cornered him and asked him what people used for the fluid that was in the cell. He mentioned that all sorts of particulates and fluids were used, including mica. I got home, and did a little web searching, and found that you could get a small container of powdered mica via Amazon Prime for under $10, so on Sunday I ordered some, and it arrived during my lunch hour. I couldn’t resist. I dumped about 1/4 of a teaspoon into a Smart Water bottle (purchased from the cafeteria) and filmed a quick demonstration.



And then recorded a longer explanatory video (only two minutes):



I suspect that the addition of some blue food coloring would enhance the contrast of the flow significantly.

Anyway, a kind of fun science fair project for a ten year old, or an aging computer scientist.