Some reliability problems with my DS3231…

I was working on some additional software to power my nascent WSPR project. I’ve been thinking that rather than using an Arduino, it would be better to use the Teensy, so I’ve been experimenting a lot with the Teensy LC. My idea was to wire up my Ultimate GPS and an I2C based DS3231, and then write a sketch that powers up the GPS, attains a fix, and then uses the time to set the time on the DS3231. It then will periodically wake up the GPS and check the time as reported by the DS3231 against the GPS.

But I’m having some difficulty. The GPS part works just fine, but when I try to do the first write to the DS3231 to set the time, it occasionally hangs. The way these libraries are written, the writes never time out, and the exchange grinds to a halt.

I’m not sure what’s going on here. Could be a bug/issue in the library, or something having to do with the Teensy Wire library, or the pull-ups. The rise times seem very slow.

graph2
I’ll keep playing around to figure out what the deal is.

Addendum: This seems relevent but the code is only for real Arduinos, and probably needs some tweaks to work with the Teensy. I am curious as to whether the delay itself may be enough to help.

Farewell…

You’ve probably heard the expression that somebody is a “man of few words”. I’m not that guy. I’m a man of many words. I love to talk. I love to write. And yet, it is an odd paradox that when you actually feel like you have something to say, the words fly from you, leaving you unable or unwilling to communicate.

Today, we had to say goodbye to Scrappy, our little gray striped American shorthair:

IMG_5314

I write this blog (in part) as a kind of a message-in-a-bottle to my future self.  On the anniversary of a post, it recirculates in the side bar on the left.  Usually it reminds me of some project I did (and likely abandoned).  Or something that I was interested in.  A year from now, what am I going to want to remember?

He had the most beautiful green eyes.  He never stopped trying to learn to speak.  He would look you right in the eye and patiently meow at you repeatedly until you understood what he wanted you to do.

He knew he was part of our family.  In the evening when we’d be watching TV, he’d find a place between Carmen and me, either on the couch or on the folding footrest of our recliner and would sit and sleep while we watched TV.   If we went upstairs, he’d do the same, until we turned the TV off and then he’d wander off.

Despite being deadly to birds, lizards, and dangerous to other cats, he never scratched or bit at humans.  Even when when we gave him a bath, or had to put him in a box to take him to the vet, he would struggle, whine, or complain, but never hiss, never bite, never scratch.   And after we’d finish bathing him, he’d get over it immediately, knowing that we were just trying to help him.

He purred a lot.  He could meow loudly and insistently.  Especially in the morning when I was late feeding him.

He was smart.  He learned to raise his paw to beg for special treats.

He loved catnip and to play with his orange shoe lace.

Yesterday he was outside, sniffing at the grass, just sniffing.  He loved sunshine and fresh air.  While we may have converted him from a mostly feral outdoor cat into an indoor kitty, he always loved to be outside.

We were with him at the end.

He was special.  He was loved.  He is missed.

 

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();
            }
        }
    }
}

Phantom Bad Boys…

I mentioned that during yesterday’s aborted attempt to fly quadcopters from a regional park resulted in a visit from the “Can’t Possibly Have Fun Police”, informing us that short sighted regulations against flying had been enacted in Eastbay Regional Parks. The entire incident was recorded remotely from Joachim’s Phantom 2. With soundtrack! (This is what footage from my copter should look like when the gimbal is working properly).



First (and second) flight with the DJI Phantom 2…

Carmen bought a DJI Phantom 2 quadcopter for my birthday, which I’ve been a little too chicken to put into the air so far. But John and Joachim were interested in flying theirs today, so I decided to give it a whirl. Initially, we headed out to Miller/Knox park, out near the old location of Pixar in Point Richmond. Despite some fairly hefty wind, I got enough courage to put mine into the air. Sadly, within a few minutes of launch, the No-Fun Police showed up and informed us that it was illegal to fly quadcopters in Eastbay Regional Parks. Sigh. We did some quick googling on our phone, and at the very end of the park regulations in very small print it was said that quadcopters equipped with video (specifically) were not allowed. Grumble. Anyway, in my excitement of getting the quadcopter in the air, I forgot to start video recording. Carmen did record me operating the quad from the ground: perhaps I’ll put some of that video up later.

We debated going to Cesar Chavez Park in Berkeley, where model rocketry, kites and RC airplanes of all kind seem to be common place, but we were frankly annoyed, and wondered if that park too was at least technically illegal. In the end, we ended up going to a place where were haven’t had any problem: the soccer field at work.

This time, I did remember to turn on the camera, but it appears that my gimbal controller may have some sort of loose connection: it was essentially deactivated for this flight. Thus, the footage is considerably less steady
than it really should be. Nonetheless, we have to document these milestones, even if the result is less than 100% successful. The sound is nothing but motor whine and wind noise, so you might want to turn it down.



When I got home, I tried hooking up the copter to my laptop. Initially, it didn’t see the IMU unit on the gimbal. I powered it down, pulled all the cables and reseated them, and when I powered it back up, it seemed to work okay. I did it a few more times, and did have one situation where it seemed glitchy. Not sure if the issue is really the connection or something else, but I’ll have to try it again in the future.

Thanks a lot for the spiffy birthday present, Carmen! The DJI is really easy to fly: in part because the throttle isn’t actually a throttle: it’s a relative altitude command. When you push the left stick forward, the quad copter goes up. When you pull it back, it does down. If you let go of the stick, it stabilizes at the current attitude. When you push the right stick forward to go forward, you don’t have to increase the throttle to maintain altitude. It’s all designed to stay in the air in the most stable way. When you gain experience, you can switch it to a more complex mode that allows for greater control and riskier maneuvering.

I think I’ll try to send it up (hopefully with a working gimbal) later this week. Stay tuned for more footage.

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.

Weekend Update: Maker Faire, new gadgets, and I ground myself…

Greetings readers. I’m hopefully wishing there is still more than one.

This weekend was the Bay Area Maker Faire 2015, the 10th incarnation of an event which has become increasingly (even frighteningly) popular. I’m tempted to channel Yogi Berra, who said “Nobody goes there. It’s way too crowded.” Anyway, I got out of my house around 9:00AM, with the plan of parking at one of the offsite parking lots and shuttling in. It took me about an hour to get to the Oracle lot on 10 Twin Dolphin Drive, and there were already probably six or eight busses lined up, but probably a thousand people lined up as well. As it happens, it took slightly more than an hour to make it onto a shuttle, drive in and enter the gates. Bleh. Not the most fun, but I had a good nights sleep the night before, so I was mostly in good spirits as I entered the park.

It was very crowded. I was by myself, so I just started wandering. When I go to these things, I am mainly looking for three things:

  • Projects that inspire new projects.
  • Cool new products, especially inexpensive dev boards and gadgets for future projects.
  • Cool artwork that I haven’t seen before.

Sadly, I didn’t see a ton of projects that made me think of new projects, but there were a couple. I had a nice chat with Ben Krasnow who brought some low-tech versions of his excellent rheoscopic coffee table, which were just plastic cells that rotated on a lazy susan. You’ve probably seen identical gadgets in science museums. Fluid flow is always interesting. He said the instructions were already on the Make Magazine site, but I forgot to copy the url, and didn’t find it. He also said it would be in the print edition sometime soon.

I had a nice chat with Erin Tomson of Modulo Labs LLC. She’s a former Pixar colleague, who has gone off and created Modulo, a set of pluggable programmable modules that can be used to assemble modules in a tiny, secure network, without the hassle of routing jumper wires on breadboards. (In fact, a system like this would have prevented a lost hour of my time tonight, I’ll tell that story below.) It’s a very slick little system, and I’d like to see something like this take off. I can particularly see this as useful in education.

Check out her Kickstarter video.

I particularly like optical gadgets like telescopes and microscopes. My buddies Rich and Dave from the Chabot Telescope Makers Workshop were there, grinding away and answering questions about telescopes. Nice to catch up with them. They said that quite a few people came up to them and asked “So, you guys sell telescopes?” Sigh. This is the Maker Faire. If you are in the North Bay and want to learn how to build a telescope, click on the link above, and think about attending one of their free workshops (every Friday!).

I like projects which reuse camera phones, and this microscope project seemed pretty cool. They had a little gadget that allowed you to swap out three different lenses to get different magnifications. Their system seemed pretty cool, but the basic idea is pretty simple (in fact, it’s basically a version of Antonie van Leeuwenhoek’s first microscopes, but instead of holding it close to your eye, it’s held close to your cell phone, which can use nifty features like zoom and exposure adjustments, and can of course record video and stills. I should design such a gadget myself.

I also had a nice chat with Alan Yates who was demonstrating some “Lighthouse” technology that he’s been working on at Valve. The basic idea is to create a set of “beacons” that can be scattered around an environment, and a sensor that can (for instance) be mounted on a VR headset and can be used to figure out the position and orientation of the headset with high accuracy and low latency. I don’t have a link for this work yet (did I miss it, Alan?) but when I do, I’ll try to update it.

That was kind of it. I did poke my nose into various people experimenting with aquaponics, which I find interesting. I had a brief chat with the creators of Chip, the $9 computer currently on Kickstarter (I hope to have more information on that soon, stay tuned.) I didn’t spend much time in the “Dark Room”, the noise and flashing gives me a headache. I did spend some time looking at the various gardening and bee keeping exhibits.

And, I did pick up some new gadgets. Here’s a short video of my purchases, along with some links to the various items mentioned.

And that’s about it. If anyone thinks I missed something super cool, drop me a comment below and I’ll check it out.

Today, I had a bunch of chores to do, but I did start to play around with my AD9850 project a bit more. Since I spent so much time driving around yesterday, I had lots of time to think, and realized that the code the determined the tuning word (the 32 bit value used to select the frequency of the oscillator) was probably going to not work properly, since it used floating point arithmetic, and that probably didn’t have sufficient precision to do the calculation the way that I had coded. Indeed, when I got home, I hooked up and Arduino and found that I was not getting the sub-Hz spacing that I requested. I played around with the math a little bit, and got it working better, and then set it up and started it going. I had the output of the AD9850 going into my oscilloscope, so I could monitor the waveform.

And it was glitchy. Intermittent. Not working properly. Had I made a programming mistake?

I spent the better part of 45 minutes trying to understand how I had broken the program. Nothing made sense. I was cranky. I decided to step back and go buy some cat litter than I had forgotten, and give it a rest.

And of course when I got back, I stared at the board again. And it was immediately obvious. I had the AD9850 module on a breadboard, with all the RESET/CLOCK/LOAD/DATA lines going to the Arduino. And… that was it…

There was no common GND. I had somehow tugged out that little jumper wire. Without a common ground, it was surprising that there was any communications between the module and the Arduino.

Plugged it back in and voila. All works. Sigh. An hour of my life, wasted.

Suddenly, Erin’s Modulo setup seems pretty nifty. 🙂

Time from the ESP8266…

Yesterday, I mentioned the idea of using the cheap ESP8266 as a clock source for a WSPR beacon transmitter. My initial idea was to basically write code for the Arduino that connected to a remote NTP server, formulate UDP packages… sounds like a pain. But then I found that there was alternative software I could upload to the ESP8266 that would implement the NTP client on the ESP8266 module, and then simply fetch it with an “AT” style command.

So, I downloaded the firmware, and gave it a shot.

esptool.py write_flash 0x0000 eagle.app.v6.flash.bin 0x40000 eagle.app.v6.irom0text.bin

I rebooted, and then told it to connect to my local wifi network, and then told it to start the NTP client with the following commands…

AT+CWJAP="ssid","password"
OK

AT+CIPNTP=0

And it works! I can get this connected to the Arduino and write up a simple sketch, and it should be able to update the time really easily. This is cheaper and probably easier than using a GPS as a time source. Very cool.

Screen Shot 2015-05-14 at 9.23.10 PM

It’s about time… (with some WSPR updates)

Yesterday I finally found a copy of the code that I wrote years ago to figure out the tone sequence for messages used by the Weak Signal Propation Reporter system. To avoid losing it again, I decided to put both the C versions and the Python versions on my github page so that even if my servers go down I’ll have the code archived somewhere. If you have need of the code, feel free to use it (it would be nice if you gave an attribution in any derivative works that you distribute, but I won’t go so far as to insist).

When I got home, I found myself thinking about using the AD9850 as a WSPR beacon, using an Arduino (or similar) to generate the tone sequence, telling the AD9850 to switch to those frequencies, and generate the appropriate RF. This was basically a meld of two programs: the genwspr.c code that I listed above, and a simple sketch that can be used to set the AD9850 to different frequencies. It seemed very simple, so I sat down and started tinkering.

I began by copying the genwspr.c program into a new wspr.ino sketch. It pretty much would compile as is (after I added the necessary dummy setup() and loop() entry points needed by the Arduino) but it did not generate the same code sequence as the code did when I ran it on my desktop. A moment’s thought revealed the likely cause: “int” values are only 16 bits on the AVR. It actually took me a bit of time to get the types sorted out (maybe 30 minutes), mostly because I didn’t remember that I should use (1UL< <n) instead of just (1<<n) to get the needed 32 bit values.

Once I got that sorted out, I extracted the needed “setFrequency” routines from an AD9850 sketch, and created a loop that would send the different frequencies at the right time. The four tones needed by WSPR are 12000/8192 (or about 1.465 Hz) apart and are 8192 / 12000 seconds in duration. My initial code simply calculated the frequency for the the given message entry, sent the appropriate tuning word to the AD9850, and then called delay(8192/12) (delay uses microseconds). Because that didn’t take into account the time spent calculating and setting the tuning word, the overall message was a bit long (actually only 22ms long) so instead I did a delay(8192/12-1), and then a delayMicroseconds(22000/162). That put it right at the 110.592 seconds that are specified. (I know it’s silly, the clock in the Arduino could easily be off, but I thought it would be good to be tidy. If you had source to an accurate 1PPS source, you could do a better job of this).

I was a tiny bit concerned that the tuning resolution of the AD9850 was insufficient, but consulting the datasheet, the nominal resolution is about 0.029 Hz. That should be fine. I’ll dig out my SDR-IQ this weekend and try to do some workbench reception tests over the next few days.

The next bit you need to make a functioning beacon is to ensure that the transmissions start one second after even minutes. That requires some accurate time keeping. My initial idea was to hook up an old Parallax PMB-648 GPS module that I had lying around. During slots where it wasn’t transmitting, it could use the time signal from the GPS to ensure that the clock had not drifted. I hadn’t played with this module in a while (it’s listed as obsolete on the Parallax page) so I hooked it up to the Arduino, wrote a simple sketch to read data from it, and let it run.

Frown. It’s just not sensitive enough to get a lock while inside my house. I thought about alternatives for mounting it. Grumble. Didn’t like that idea. External antenna? Newer module? Grumble.

Perhaps a different approach was needed. I considered the various wireless modules that I had lying around. Perhaps I could use the esp8266 modules (which are really cheap) to fetch the time with NTP, and then the Arduino could use that to trigger the transmissions.

Hooking the ESP8266 to the Arduino is not quite as straightforward as the GPS because the Arduino that I use is 5V, and the ESP8266 is a 3.3v device. I have some Sparkfun level converter boards around, but it turns out that you really only need to be careful about the TX from the Arduino. The circuit below uses a little 3.3V Zener diode to drop the voltage to avoid blowing the URXD on the ESP8266. I think I have some 3.3V zeners in my box somewhere. The circuit shows a separate 3.3V low drop out regulator because the ESP8266 can be quite power hungry, and the regulator on your traditional Uno can only supply about 50ma. I believe the Redboard has a better regulator, the MICREL MIC5205 LDO can supply 150ma, so that should be fine. If I can find the Zeners, it should be easy to breadboard.

esp8266_conn

My idea was to use the ESP8266 to send out NTP packets, parse the results… but a little googling revealed a better way. There is
alternative firmware for the ESP8266 that adds support for NTP directly via AT commands. If you send the AT command below, you’ll get the time back:

AT+CIPNTP?
Time: 22:22:42 12/02/2014 GMT+02

That seems awesome. The idea will be that when the Arduino is reset, it will bring up the network and try to get the time and will figure out when the next time slot begins for transmission. When that slots begins, it can decide to either transmit, or wait until the next slot. Easy-peasy.

When I get the completed sketch up, I’ll add it to my github respository.