Imp Digital Clock

edited November 2012 in Projects

Sparkfun 4-digit 7-segment LED Digital Clock using Electric Imp: A very cool little WiFi-based clock that gets it's time from the Internet.

Parts list consists of Sparkfun Electric Imp Breakout Board (BOB-11400), Electric Imp (WRL-11395), and any one of the following Sparkfun color 7-Segment 4-Digit serial LED displays:
Green (COM-11440)
Red (COM-11441)
Blue (COM-11442)
Yellow (COM-11443)

A 5V USB Wall Charger (TOL-11456) and Sparkfun USB Type-A to Mini-B Cable (CAB-11301) powers the entire setup (breakout power jumper in the USB position).

Only three wires are used to connect the Electric Imp Breakout to the LED Display:
1. GND (BLK) from the breakout to GND (-) on the display
2. VIN (RED) from the breakout to VCC on the display
3. PIN1 (TX) from the breakout to RX on the display
Running the LED display from VIN (+5V) results in a slightly brighter display; for a dimmer LED display the 3V3 (+3.3V) pin can be used. Software commands are also available to adjust the brightness of the LED display; see the Sparkfun data sheet for more information.

Imp source code is below:
Digital Clock.nut.txt


  • Shiny! Blue LEDs! :)

    Looking at the code, you could make it a little bit more readable by naming the UART, eg:

    display <- hardware.uart12;

    ...and then...


    Also, you can queue a wakeup at the start of your function which means then the time spent in the function does not affect the next wakeup time; I can see why you're using the 0.9s wakeup then spin loop to reduce jitter on the second display but am annoyed there's not a better way to address the issue :)
  • am annoyed there's not a better way to address the issue

    Yes, I did wonder about this. One potential solution I came up with, is to remember the time at which a wakeup handler is called, and -- if the wakeup hander itself executes a wakeup() without any intervening sleeps or blocking calls -- use that time to schedule the next wakeup, not the current time at the moment wakeup() is called. But we don't do that yet.

  • edited November 2012
    Thanks Hugo for your input on making the code more readable ... still learning this Squirrel code. I've updated the source code in the original post per your suggestion.
  • edited December 2012
    @ccateora - Mighty fine project. I used your code snippet and instead of updating
    a 7 segment clock display, I sent the "top of the hour" sync to the serial port with Unix "secs" time. This gives my microcontroller precise network time every minute.
    Again, a very nice "got IMP" project!
  • edited December 2012
    BTW ... @ ccateora

    May I suggest an enhancement to your clock?

    To allow your clock to display the proper time "in all cases" you
    would need to add some additional code. This would make your clock super cool.
    You need to compute or calculate for "daylight savings" time to automatically
    compensate the daylight time "spring forward" or "fall back" times. You could do this by using the network GMT or local time and or making a look-up table of the projected time changes. By knowing whether you are in daylight savings time or not and then adding this offset to your clock would be awesome.
  • I like your suggestions. Really dislike hard coding the time zone and daylight savings setting and wish there was a easy/clean way to obtain these settings automatically based on the current location of the clock and the current date. Will look into this further when I have some free time and would encourage anyone else to add to the code posted here with any enhancements.
  • Hi ccateora, thanks for the code. Very nice and useful
    I added
    local blatter = hardware.uart57; // PIN5 = Tx; PIN7 = Rx
    blatter.configure(9600, 8, PARITY_NONE, 1, NO_CTSRTS);

    and now have two counters running. My stats page posts how many sales and how many phone lines in use. The stat page is called on a watch dog and on start up so I now have a full time status running.

    Hadn't spotted the

    server.log(format("WiFi %d dBm", imp.rssi()));

    before, and also included that in another code to provide a portable wifi level mapper. That's a good useful tool to find out where to put the imps in the house!
  • Can't you periodically, like 2 times per day have it synchronize online with NIST time? That would also allow you to get info on daylight savings time.
  • Why is the code gone?
  • edited August 2013
    Here is another idea, mentioned on the Adafruit Show and Tell Saturday night. Adafruit makes the NEO-Pixel ring, and they mentioned that they were asked to make a 12 segment version, which would be awesome for a clock. It would be cool to hook an imp up to such a ring. I was thinking about having the red/green SMT LEDs on it, you could use say red for the hour, and green for the minute, and then if they were at the same location, show orange.

    It would be really cool to have a wristwatch version, if you could make it not bulky.. maybe with an imp002? You would need a WiFi connection, but you could do that by connecting to your smartphone, if you have "Personal Hotspot" or whatever it is called by your carrier. The ring is hollow, so the center could be a solar panel.

    And... I would really like to put NFC/RFID in a wrist watch package, so maybe it could sit under the ring?

    @ccateora Nice work! Keep refining that code. I guarantee there are quite a few of us our here who would love to make use of it. Would you be able to put it in a repository like GitHub?
  • edited August 2013
    The code is still here ... look near the bottom of the very first post. Lots of great ideas being posted here. Looking for a better way to handle Daylight Saving Time, automatically figuring out the local time zone, and re-syncing the time to a NTP server. It doesn't look like the imp is capable of initiating a UDP packet and communicating directly with the NTP server. The 12 segment ring of LED's sounds interesting for a watch, but I immediately jump to a 60 segment ring of LED's for a wall clock that has a seconds hand.
  • edited August 2013
    For DST and timezone offset you might use the Google Maps Geolocation API
  • Just re-read and noticed the Wifi level code. Nice! I'm going to send that to the LED display on my "jTherm" project.
  • @jwehr do you know of anyone who has a working imp / neopixel / WS2812 implementation?

    These look like really nice RGB LED's for a decent price but I'm trying to wrap my head around how to implement them in Squirrel... With such specific timing requirements what would be the best approach to bitbang the protocol? The UART class?

  • Timezone support is coming, and hopefully soon after DST knowledge (based on imp source IP).
  • @deldrid1 you need gapless spi (in the next release) to talk to the neopixel. Currently we have an inter-byte delay which is just too long to keep them veyr happy.
  • edited August 2013
    Great news on timezone support and DST knowledge coming soon.

    @Hugo clock starts with the correct time at start-up, but drifts over 24 hours and tends to run slow, loosing several seconds per day. Any examples or thoughts how to re-sync time to the imp server or a NTP server. Can I sync from the agent side?
  • I wish my Squirrel/ImpOS skills were at that level. I think I may have recently gone from n00b to apprentice, but I've got a lot to learn. I'll probably get a NeoPixel ring and fire it up on an Arduino, and then we the next release is out, we can start looking at Imp-power.
  • @Hugo will there not be problems using SPI based on the fact that "The imp can only generate certain data rates for SPI" ( or is this improved in the next release as well?
  • edited August 2013
    @deldrid1 - I've actually written a class for interacting with the ws2812 / NeoPixels. It requires release 26 (which isn't public yet). Once release 26 goes out I'll move it to the Electric Imp GitHub repo.

    The timings required by the NeoPixels are kind of difficult to hit.. so we use the SPI bus to "fake" the data - at 15MHz the clock cycles are granular enough to *mostly* hit the timings (they fall within the allowable range).

    Since it the timings aren't perfect, on long chains of NeoPixels you'll get some unexpected behaviour. This might actually be a power issue - I'm going to investigate later today and will report back :)

    All in all, it *mostly* works.. and is a good first step :)
  • time() on Imp drifts about 4ms/min. That's not good. millis() can be made much more accurate by multiplying by a constant. I've gotten 10ms/day. You can sync with NIST to get an absolute accuracy of about 10ms. 1/100th of a second. Depending on your internet connection. You can keep this accuracy by syncing again every day. No hardware is needed. Interested?
  • edited August 2013
    @sbright33 Yes, I'm interested. Do you have squirrel code for this?
  • If you disconnect and reconnect from the server, it will resync time. We'll look at adding a less severe way of doing this, though it's usually only a couple of seconds.
  • You'd have to do this every hour, or it will be off by 1/2 additional second. Plus up to 1 second to begin with when you sync time() by reconnecting. Great for some applications, but much greater than 1/100th second if you need that.
  • @beardedinventor were you able to confirm a power supply issue? How many neopixels have you been able to drive without any problems?
  • It was not a power supply issue - it turned out to be another issue with the imp's clock. Right now I'm solving it by setting enableblinkup(true).

    I ran the code on a strip of 120 NeoPixels and it mostly worked - it still occasionally jitters, but that seems to happen mostly when you're updating around 20+ times per second.
Sign In or Register to comment.