Electric Imp in a Peter Jensen clock

132 views
Skip to first unread message

Zandr Milewski

unread,
Nov 4, 2013, 1:57:46 PM11/4/13
to neoni...@googlegroups.com
Here you go, guys.

I converted my Peter Jensen IN-14 clock (tubeclock.com) from a PIC to an
Electric Imp.

The clock (scroll down):
http://store.tubeclock.com/index.php/nixie-tube-clocks/clocks

The Imp: http://electricimp.com/

I built a small daughtercard that plugs into the PIC socket and itself
has a socket for an April, which is the minimum breakout board for the
Imp. It's really just a power supply and the socket for the imp.

April: http://www.adafruit.com/products/1130


The schematic of the daughtercard is extraordinary simple:

April Pin PIC PIN
1 -------- Button 1 --- 4
2 -------- Button 2 --- 12
5 -------- SCLK ------- 8
7 -------- DATA ------- 6
8 -------- LATCH ------ 7
9 -------- BLANK ------ 5
Vin ------ 12V -------------------- To fuse
GND ------ GND -------- 14

The Imp has pretty high instantaneous current requirements. The average
power consumption is quite low, but the worst-case WiFi transmit event
can require 400mA. The tubeclock 5V supply is just a 5.1V Zener with a
1k resistor, so it's not up to the task. Fortunately the April power
supply can take up to 17V input, so I just ran a wire to the load side
of the fuse. I added a 100uF cap across the 12V input to help soak up
those transients.

The SD form factor Imp gives you six pins to play with, and they can be
configured in many ways. It's easy to add an i2c I/O expander if you
need one, but we don't in this case.

Pins 1 and 2 are configured as digital inputs connected to the buttons.
I'm not using them for anything yet, right now they just log events to
the server.

Pins 5 and 7 are configured as SPI, and are used to write to the HV5622
shift registers. Pin 8 is a simple digital out connected to the Latch
Enable on the HV5622s. This gives you direct control of the display. The
code below has a function that takes a 6-digit string and two booleans
for the colon bulbs, and creates the bitmapped blob to send to the HV5622s.

Pin 9 is configured as a PWM output, and is connected to the blanking
input on the HV5622s. This gives a brightness control.

That's all there is to the hardware.

I've included the code for a very simple clock, it's just pulling time
from the built-in RTC (which is synched at connect), has a hardcoded
timezone offset, and crossfades the digits.

My next step is to use the Imp agent to create a web control panel for
timezones, and update the clock more frequently (it drifts by a couple
of seconds a day, but corrects if you reboot it)

Here's the device code so far:

// Button Class from github.com/electricimp
//
----------------------------------------------------------------------------
// Name: Button
// Purpose: Show the right way to debounce a button press
//
----------------------------------------------------------------------------

class button{
static NORMALLY_HIGH = 1;
static NORMALLY_LOW = 0;
_pin = null;
_pull = null;
_polarity = null;
_pressCallback = null;
_releaseCallback = null;

constructor(pin, pull, polarity, pressCallback, releaseCallback){
_pin = pin; //Unconfigured IO pin, eg hardware.pin2
_pull = pull; //DIGITAL_IN_PULLDOWN, DIGITAL_IN or
DIGITAL_IN_PULLUP
_polarity = polarity; //Normal button state, ie 1 if button is
pulled up and the button shorts to GND
_pressCallback = pressCallback; //Function to call on a button
press (may be null)
_releaseCallback = releaseCallback; //Function to call on a
button release (may be null)

_pin.configure(_pull, debounce.bindenv(this));
}

function debounce(){
_pin.configure(_pull);
imp.wakeup(0.020, getState.bindenv(this)); //Based on googling,
bounce times are usually limited to 10ms
}

function getState(){
if( _polarity == _pin.read() ){
if(_releaseCallback != null){
_releaseCallback();
}
}else{
if(_pressCallback != null){
_pressCallback();
}
}
_pin.configure(_pull, debounce.bindenv(this));
}
}

//Example Instantiation
minuteButton <- button(hardware.pin1, DIGITAL_IN, button.NORMALLY_HIGH,
function(){server.log("Minutes Button Pressed")},
function(){server.log("Minutes Button Released")}
);
hourButton <- button(hardware.pin2, DIGITAL_IN, button.NORMALLY_HIGH,
function(){server.log("Hours Button Pressed")},
function(){server.log("Hours Button Released")}
);


/* Hardware Configuration
This code is designed to support a tubeclock.com IN-14 clock.
There are two SuperTex HV5622 driver chips, nominally SPI with
latch (!LE) and blanking (!BL) lines. There is a polarity line,
tied high on the tubeclock.com board.
There are also two buttons on the board, currently NC because
they are connected to the 5V supply on the clock.
*/

// SPI to the HV drivers
display <- hardware.spi257;
display.configure(SIMPLEX_TX | MSB_FIRST | CLOCK_2ND_EDGE , 5000);
displaywriter <- display.write.bindenv(display);

// Latch Enable
latch <- hardware.pin8;
latch.configure(DIGITAL_OUT);
latchwriter <- latch.write.bindenv(latch);
latchwriter(1);

// Display Blanking (PWM for brightness control)
blank <- hardware.pin9;
blank.configure(PWM_OUT,(1.0/120.0),0.9);

function displayBuffer (buffer) {
latchwriter(0);
displaywriter(buffer);
latchwriter(1);
}

function renderBuffer(string, colon_left, colon_right) {
local offbits = [0,2,5,0,3,5];
local offbytes = [0,1,2,4,5,6]
local buffer = blob(8);
for (local index=0;index<6;index++) {
local digit = string.slice(index,index+1).tointeger();
local byte0 = (0x80>>(digit+(offbits[index])));
local byte1 = (0x80>>((digit-8)+(offbits[index])));
buffer[(offbytes[index])] = buffer[(offbytes[index])] | byte0;
buffer[(offbytes[index])+1] = buffer[(offbytes[index])+1] | byte1;
}
if (colon_left)
buffer[2] = buffer[2] | 0x08;
if (colon_right)
buffer[5] = buffer[5] | 0x20;
return buffer;
}

imp.configure("Nixie Clock", [], []);
server.log(format("impeeID %s", hardware.getimpeeid()));
server.log(format("Voltage %f", hardware.voltage()));
server.log(format("MAC address %s", imp.getmacaddress()));
server.log(format("WiFi %d dBm", imp.rssi()));
server.log(format("Software Version %s", imp.getsoftwareversion()));

function crossfade (old_buffer, new_buffer, steps) {
for (local i=0;i<steps;i++) {
displayBuffer(old_buffer);
imp.sleep((steps - i)*0.0001);
displayBuffer(new_buffer);
imp.sleep(i * 0.0001);
}
}

function nixieClock() {
local tzoffset = (-8*3600);
local t;
local prev_t=time();
while ((t = time()) == prev_t); // Synchronize seconds
local prev_d = date(((prev_t) + tzoffset),'u');
local prev_d_buffer = renderBuffer(format("%02d%02d%02d",
prev_d.hour, prev_d.min, prev_d.sec) , true, true);
local d = date((t + tzoffset),'u');
local d_buffer = renderBuffer(format("%02d%02d%02d", d.hour, d.min,
d.sec) , true, true);
crossfade(prev_d_buffer,d_buffer,50);
// displayBuffer( renderBuffer(format("%02d%02d%02d", d.hour, d.min,
d.sec) , true, true));
imp.wakeup(0.70, nixieClock);
}

nixieClock();






Zandr Milewski

unread,
Nov 4, 2013, 2:13:21 PM11/4/13
to neoni...@googlegroups.com
On 11/4/13, 10:57 AM, Zandr Milewski wrote:
> Here you go, guys.
>
> I converted my Peter Jensen IN-14 clock (tubeclock.com) from a PIC to an
> Electric Imp.

Here are a couple of photos, one showing the daughtercard, one showing
the finished product.

http://imgur.com/a/YxkoT

-Z

AlexTsekenis

unread,
Nov 4, 2013, 9:22:21 PM11/4/13
to neoni...@googlegroups.com
Great stuff Zandr - thanks for sharing.

Can you tell us a bit about your experience of the development environment and wifi interface?
What sort of wifi range have you achieved?

Alex

za...@milewski.org

unread,
Nov 4, 2013, 9:32:18 PM11/4/13
to neoni...@googlegroups.com
The development environment is so delightful as to be surreal... There
is a web IDE, clicking "Build and Run" is all that's necessary to push
new code to the Imp and start it. No cables, no ISP or JTAG, just wifi. :)

The imp is programmed in Squirrel <http://squirrel-lang.org/>, which
shares a lot of design goals with Lua, but is a bit more C-like.

You configure the WiFi credentials using something called "BlinkUp".
Think Timex DataLink... You enter your credentials on a smartphone or
tablet, and then it "blinks" the parameters to the imp by flashing the
screen. Once that's done, everything else happens from the web.

As far as range, I think the Imp guys have seen 1km from a good access
point over open ground. I've gone for a walk with a battery powered Imp
and was at least 100m from my house before it lost connectivity.


On 11/4/13, 18:22 , AlexTsekenis wrote:
> Great stuff Zandr - thanks for sharing.
>
> Can you tell us a bit about your experience of the development
> environment and wifi interface?
> What sort of wifi range have you achieved?
>
> Alex
>
> On Monday, November 4, 2013 7:13:21 PM UTC, Zandr Milewski wrote:
>
> On 11/4/13, 10:57 AM, Zandr Milewski wrote:
> > Here you go, guys.
> >
> > I converted my Peter Jensen IN-14 clock (tubeclock.com
> <http://tubeclock.com>) from a PIC to an
> > Electric Imp.
>
> Here are a couple of photos, one showing the daughtercard, one showing
> the finished product.
>
> http://imgur.com/a/YxkoT
>
> -Z
>
> --
> You received this message because you are subscribed to the Google
> Groups "neonixie-l" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to neonixie-l+...@googlegroups.com.
> To post to this group, send an email to neoni...@googlegroups.com.
> To view this discussion on the web, visit
> https://groups.google.com/d/msgid/neonixie-l/e28913d3-1bb9-4f8f-bf61-8f4dcb6aec30%40googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

AlexTsekenis

unread,
Nov 4, 2013, 9:47:35 PM11/4/13
to neoni...@googlegroups.com
Thanks, looks like purchasing one or two will not be an imp-ulse buy.

I'm dubious as to the 1km range - maybe in the desert using battery power, 10F decap, 1bit/s and directional antennae. Certainly not at 400mA anyway. 100m is plausible and would seem to imply no corners were cut in the RF section due to its size.

I'm sure more interrogation will follow :-)

Alex

Zandr Milewski

unread,
Nov 4, 2013, 11:36:57 PM11/4/13
to neoni...@googlegroups.com
On 11/4/13, 6:47 PM, AlexTsekenis wrote:
> Thanks, looks like purchasing one or two will not be an imp-ulse buy.
>
> I'm dubious as to the 1km range - maybe in the desert using battery
> power, 10F decap, 1bit/s and directional antennae. Certainly not at
> 400mA anyway. 100m is plausible and would seem to imply no corners were
> cut in the RF section due to its size.

The RF design is exceptionally good. (I've known Hugo for many years, he
knows his stuff.)

Here's the range test, where they lost connectivity at 790m. I know that
the AP they used was a Cradlepoint MBR1400, and while this was an
IMP-002 (the solder-down module), the RF section and antenna are the same.

http://blog.electricimp.com/post/56247500373/going-to-great-lengths-with-the-imp-and-wifi

AlexTsekenis

unread,
Nov 6, 2013, 8:38:19 AM11/6/13
to neoni...@googlegroups.com
Thanks for that link. I was not far off with my exaggerated conditions - in the desert on batteries ;-). Unfortunately the BER and antenna type are not stated, but they were not after a carefully controlled experiment with that post.

Anyway the achievement that matters is the 100+ meters in a typical configuration and, considering the intended applications, it's a winner.

Yeah I went around looking for a module before coming across the 002...which would be great for integrating an imp into a product and more reliable than the sd card connector. I'm trying to get my head around the differences between 001 and 002. Besides the higher number of IO pins,  they say that a developer's edition is not available for 002 and a subscription requirement is mentioned for 002. http://forums.electricimp.com/discussion/comment/2928

Alex

Zandr Milewski

unread,
Nov 6, 2013, 1:47:18 PM11/6/13
to neoni...@googlegroups.com
001 vs. 002:

002 is a solder-down module. It has more I/O than the 001 SD module,
doesn't require the ID chip since it's not going to move from device to
device, and requires that you bring your own phototransistor and LEDs
for status and BlinkUp.

002's are indended for mass production, and mass produced products
require a subscription for the back-end. Having said that, there are
certainly hobby projects using modules, and you can get them in small
quantities from DigiKey and Smartmaker. Smartmaker has breakout boards
for them as well. The "Amber" reference design includes some sample
power supply and opto circuits if you want to go with the 002.
> <http://blog.electricimp.com/post/56247500373/going-to-great-lengths-with-the-imp-and-wifi>
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "neonixie-l" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to neonixie-l+...@googlegroups.com.
> To post to this group, send an email to neoni...@googlegroups.com.
> To view this discussion on the web, visit
> https://groups.google.com/d/msgid/neonixie-l/043dd218-ce63-4a16-9f41-03c5bf6f3804%40googlegroups.com.

Zandr Milewski

unread,
Nov 6, 2013, 2:30:23 PM11/6/13
to neoni...@googlegroups.com
Just confirmed, if you buy an '002 off the shelf and pair it with a dev
account, it's a developer edition. :)

AlexTsekenis

unread,
Nov 6, 2013, 3:20:41 PM11/6/13
to neoni...@googlegroups.com
Ah that's good, because with such substantial HW differences you want to be developing on whatever will be in the final product.

The arrangement for mass production seems to include a commercial clause, so if you are selling commercially then volumes don't matter. The subscription fee is insignificant: http://www.youtube.com/watch?v=HUV-AEB2ZrY around 7:20, but if you commit to using an imp in and entire line of products then they are holding you by the...It would be interesting to see how this develops as the imp is more widely adopted.

Alex
Reply all
Reply to author
Forward
0 new messages