Skip to content

Instantly share code, notes, and snippets.

@pdh11

pdh11/impoclock Secret

Last active August 29, 2015 14:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pdh11/1fb7f96189daec54dbf4 to your computer and use it in GitHub Desktop.
Save pdh11/1fb7f96189daec54dbf4 to your computer and use it in GitHub Desktop.
Analogue clock using Electric Imp and Neopixels
const NEOPIXELS_BYTESPERPIXEL = 24;
class NeoPixels {
// Driver for the World Semi WS2812 - aka Adafruit NeoPixel
// By Matt Haines (@beardedinventor)
// See https://electricimp.com/docs/resources/neopixels/
// Availibility: Device
// Copyright 2014 Electric Imp
// Issued under the MIT license (MIT)
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
// This class uses SPI to emulate the newpixels' one-wire protocol.
// This requires one byte per bit to send data at 7.5 MHz via SPI.
// These consts define the "waveform" to represent a zero or one
ZERO = 0xC0;
ONE = 0xF8;
// when instantiated, the neopixel class will fill this array with blobs to
// represent the waveforms to send the numbers 0 to 255. This allows the blobs to be
// copied in directly, instead of being built for each pixel - which makes the class faster.
bits = null;
// Like bits, this blob holds the waveform to send the color [0,0,0], to clear pixels faster
clearblob = blob(12);
// private variables passed into the constructor
spi = null; // imp SPI interface (pre-configured)
frameSize = null; // number of pixels per frame
frame = null; // a blob to hold the current frame
pixelWriter = null;
writeFrame = null;
// _spi - A configured spi (MSB_FIRST, 7.5MHz)
// _frameSize - Number of Pixels per frame
constructor(_spi, _frameSize) {
this.spi = _spi;
this.frameSize = _frameSize;
this.frame = blob(frameSize*NEOPIXELS_BYTESPERPIXEL + 1);
this.frame[frameSize*NEOPIXELS_BYTESPERPIXEL] = 0;
local spiWriter = _spi.write.bindenv(_spi);
local refFrame = frame;
// writes the frame buffer to the pixel strip
// ie - this function changes the pixel strip
this.writeFrame = function() {
spiWriter(refFrame);
}
// prepare the bits array and the clearblob blob
initialize();
clearFrame();
writeFrame();
local frameSeeker = frame.seek.bindenv(frame);
local frameWriter = frame.writeblob.bindenv(frame);
local refBits = bits;
this.pixelWriter = function(p, r,g,b) {
frameSeeker(p*NEOPIXELS_BYTESPERPIXEL);
// red and green are swapped for some reason, so swizzle them back
frameWriter(refBits[g]);
frameWriter(refBits[r]);
frameWriter(refBits[b]);
}
}
// fill the array of representative 1-wire waveforms.
// done by the constructor at instantiation.
function initialize() {
// fill the bits array first
bits = array(256);
for (local i = 0; i < 256; i++) {
local valblob = blob(NEOPIXELS_BYTESPERPIXEL / 3);
valblob.writen((i & 0x80) ? ONE:ZERO,'b');
valblob.writen((i & 0x40) ? ONE:ZERO,'b');
valblob.writen((i & 0x20) ? ONE:ZERO,'b');
valblob.writen((i & 0x10) ? ONE:ZERO,'b');
valblob.writen((i & 0x08) ? ONE:ZERO,'b');
valblob.writen((i & 0x04) ? ONE:ZERO,'b');
valblob.writen((i & 0x02) ? ONE:ZERO,'b');
valblob.writen((i & 0x01) ? ONE:ZERO,'b');
bits[i] = valblob;
}
// now fill the clearblob
for(local j = 0; j < NEOPIXELS_BYTESPERPIXEL; j++) {
clearblob.writen(ZERO, 'b');
}
}
// sets a pixel in the frame buffer
// but does not write it to the pixel strip
// color is an array of the form [r, g, b]
function writePixel(p, color) {
pixelWriter(p, color[0], color[1], color[2]);
}
// Clears the frame buffer
// but does not write it to the pixel strip
function clearFrame() {
frame.seek(0);
for (local p = 0; p < frameSize; p++) frame.writeblob(clearblob);
}
}
const NUM_PIXELS = 60
spi <- hardware.spi257
spi.configure(MSB_FIRST, 7500)
local pixel = NeoPixels(spi, NUM_PIXELS)
local pixelWriter = pixel.pixelWriter;
local frameWriter = pixel.writeFrame;
server.log(imp.getsoftwareversion() + " / " + imp.getmacaddress())
server.disconnect();
local background = [0,0,0];
local gettime = time;
local impwaker = imp.wakeup.bindenv(imp);
local function proximity(a, b, limit) {
local diff = a-b;
if (diff < 0) {
diff = -diff;
}
if (diff > 30) {
diff = 60 - diff
}
if (diff <= limit) {
return (limit != 0) ? 1.0 - diff / limit : 1
}
return 0
}
local displaytime;
displaytime = function(){
local now = gettime();
local hour = (now/3600)%12;
local min = (now/60)%60;
local sec = now%60;
local hourled = (hour + 0) * 5 + (min / 12.0) + (sec/720.0)
local minled = min + (sec/60.0)
local bgred = background[0];
local bggreen = background[1];
local bgblue = background[2];
for(local i = 0; i<NUM_PIXELS; i++){
local red = bgred, green = bggreen, blue = bgblue;
local hourprox, minprox;
if (proximity(i, sec, 0)) {
red = 100
green = 0
blue = 100
} else if ((minprox = proximity(i, minled, 2.0)) != 0) {
red = 0
green = (100 * minprox * minprox)
blue = (100 * minprox * minprox)
} else if ((hourprox = proximity(i, hourled, 3.0)) != 0) {
red = (100 * hourprox * hourprox)
green= (100 * hourprox * hourprox)
blue = 0
}
pixelWriter(i,red,green,blue);
}
frameWriter();
impwaker(0.1,displaytime)
}
local getus = hardware.micros.bindenv(hardware);
local us = getus();
displaytime()
us = getus() - us;
local freemem = imp.getmemoryfree();
server.log(us+" "+freemem);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment