Last active
August 5, 2020 14:30
-
-
Save ElectricImpSampleCode/a73fb20c95336996074a6dc33c41976f to your computer and use it in GitHub Desktop.
imp006 Breakout Kit Example Code: sensor and Grove display
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// IMPORTS | |
// Get the temperature sensor library | |
#require "HTS221.device.lib.nut:2.0.2" | |
// CLASSES | |
// The following driver class and enum provides support | |
// for the TM1637 display chip | |
enum TM1637_LED_CLASS { | |
ADDR_AUTO = 0x40, | |
CMD_SET_ADDR = 0xC0, | |
CMD_DISP_CTRL = 0x88, | |
// Character constants | |
BLANK_CHAR = 16, | |
MINUS_CHAR = 17, | |
DEGREE_CHAR = 18, | |
CHAR_COUNT = 19, | |
// Display specific constants | |
LED_MAX_ROWS = 4 | |
} | |
/** | |
* Hardware driver for Seeed Grove 4-digit LED. | |
* | |
* Availibility Device | |
* @author Tony Smith (@smittytone) | |
* @license MIT | |
* | |
* @class | |
* | |
*/ | |
class TM1637 { | |
/** | |
* @property {string} VERSION - The library version | |
* | |
*/ | |
static VERSION = "1.0.0"; | |
// *********** Private Properties ********** | |
_digits = null; | |
_buffer = null; | |
_clk = null; | |
_dio = null; | |
_brightness = 2; | |
_showColon = false; | |
/** | |
* Initialize the segment LED | |
* | |
* @constructor | |
* | |
* @param {imp::hardwar::pin} dataPin - The imp pin connected to Grove WHITE | |
* @param {imp::hardwar::pin} clockPin - The imp pin connected to Grove YELLOW | |
* | |
* @returns {instance} The instance | |
* | |
*/ | |
constructor(dataPin, clockPin) { | |
// 'dataPin' and 'clockPin' are the imp API hardware.pin | |
// objects connected to, respectively, the Grove white and | |
// yellow lines. We set these initally LOW | |
_clk = clockPin; | |
_dio = dataPin; | |
_clk.configure(DIGITAL_OUT, 0); | |
_dio.configure(DIGITAL_OUT, 0); | |
// _buffer stores the character matrix values for each row of the display | |
// | |
// buffer index 0 1 2 3 | |
// [ ] [ ] [ ] [ ] | |
// character - - . - - | |
// [ ] [ ] . [ ] [ ] | |
_buffer = blob(TM1637_LED_CLASS.LED_MAX_ROWS); | |
// '_digits' stores character matrices for 0-9, A-F, blank and minus | |
_digits = "\x3F\x06\x5B\x4F\x66\x6D\x7D\x07\x7F\x6F"; // 0-9 | |
_digits += "\x5F\x7C\x58\x5E\x7B\x71"; // A-F | |
_digits += "\x00\x40\x63"; // Space, minus, degree signs | |
} | |
/** | |
* Clear each row in the segment LED buffer. Requires 'display()' to be called | |
* | |
* @returns {instance} this | |
* | |
*/ | |
function clear() { | |
for (local i = 0 ; i < TM1637_LED_CLASS.LED_MAX_ROWS ; i++) { | |
_buffer[i] = TM1637_LED_CLASS.BLANK_CHAR; | |
} | |
return this; | |
} | |
/** | |
* Set the specified segment LED buffer row to a given numeric character. Requires 'display()' | |
* | |
* @param {integer} [digit] - The display digit to be written to (0 - 4) | |
* @param {integer} [number] - The integer required (0 - 16, 0x00 - 0x0F) | |
* | |
* @returns {intance} this | |
* | |
*/ | |
function writeNumber(digit, number) { | |
if (digit < 0 || digit >= TM1637_LED_CLASS.LED_MAX_ROWS) return null; | |
if (number < 0 || number > 15) return null; | |
_buffer[digit] = _digits[number]; | |
return this; | |
} | |
/** | |
* Set or unset the segment LED display's central colon symbol | |
* | |
* @param {bool} [showColon] - Whether the central colon should be lit. Default: true | |
* | |
* @returns {instance} this | |
* | |
*/ | |
function setColon(set = true) { | |
if (typeof set != "bool") set = true; | |
_showColon = set; | |
return this; | |
} | |
/** | |
* Write the segment LED buffer to the display | |
* | |
*/ | |
function display() { | |
// Signal the start of data | |
_start(); | |
_writeByte(TM1637_LED_CLASS.ADDR_AUTO); | |
_stop(); | |
// Signal the data | |
_start(); | |
_writeByte(TM1637_LED_CLASS.CMD_SET_ADDR); | |
for (local i = 0 ; i < TM1637_LED_CLASS.LED_MAX_ROWS ; i++) { | |
_writeByte(_buffer[i] + (_showColon ? 0x80 : 0x00)); | |
} | |
_stop(); | |
// Tell the display to update | |
_start(); | |
_writeByte(TM1637_LED_CLASS.CMD_DISP_CTRL + _brightness); | |
_stop(); | |
} | |
// *********** Private Functions ********** | |
/** | |
* Write a single byte to the display | |
* | |
* @param {int} data — The 8-bit value to write | |
* | |
* @returns {int} The ACK value | |
* | |
* @private | |
* | |
*/ | |
function _writeByte(data) { | |
// Write a single byte to the display, signalling its bits | |
// LSB first out on the line | |
data = data & 0xFF; | |
for (local i = 0 ; i < 8 ; i++) { | |
_clk.write(0); | |
_dio.write(data & 0x01 ? 1 : 0); | |
data = data >> 1; | |
_clk.write(1); | |
} | |
// What follows is the signalling required by the TM1637 | |
_clk.write(0); | |
_dio.write(1); | |
_clk.write(1); | |
_dio.configure(DIGITAL_IN); | |
_delay(); | |
local ack = _dio.read(); | |
if (ack == 0) _dio.configure(DIGITAL_OUT, 0); | |
_delay(); | |
_dio.configure(DIGITAL_OUT, 0); | |
_delay(); | |
// Return whether the data was ACK'd | |
return ack; | |
} | |
/** | |
* Delay for 50 microseconds | |
* | |
* @private | |
* | |
*/ | |
function _delay() { | |
imp.sleep(0.00005); | |
} | |
/** | |
* Send START signal (both pins go low) | |
* | |
* @private | |
* | |
*/ | |
function _start() { | |
_clk.write(1); | |
_dio.write(1); | |
_dio.write(0); | |
_clk.write(0); | |
} | |
/** | |
* Send STOP signal (both pins go high) | |
* | |
* @private | |
* | |
*/ | |
function _stop() { | |
_clk.write(0); | |
_dio.write(0); | |
_clk.write(1); | |
_dio.write(1); | |
} | |
} | |
// GLOBALS | |
// Set up our global variables, 'sensor' and 'led' | |
// Configure the sensor's I2C bus | |
hardware.i2cLM.configure(CLOCK_SPEED_400_KHZ); | |
// Instantiate a sensor object and set its operational mode | |
sensor <- HTS221(hardware.i2cLM); | |
sensor.setMode(HTS221_MODE.ONE_SHOT); | |
// Instantiate a TM1637 display object on the inner Grove connectpr | |
led <- TM1637(hardware.pinU, hardware.pinT); | |
// This function is the core loop: it runs every second, taking a | |
// reading and displaying the temperature on the LED. For details | |
// of the 'read()' function, see the HTS221 library doc in the Dev Center: | |
// https://developer.electricimp.com/libraries/hardware/hts221 | |
function loop() { | |
// Get and display the reading | |
sensor.read(function(reading) { | |
if (!("error" in reading)) { | |
local tempString = format("%0.1f", reading.temperature); | |
local tempParts = split(tempString, "."); | |
// The first three digits show the temperature | |
// (we use the colon for a decimal point) | |
led.writeNumber(0, tempParts[0][0].tointeger() - '0'); | |
led.writeNumber(1, tempParts[0][1].tointeger() - '0'); | |
led.writeNumber(2, tempParts[1][0].tointeger() - '0'); | |
// Set final digit as c for Celsius and trigger the display | |
led.writeNumber(3, 12); | |
led.setColon().display(); | |
} | |
}); | |
// Call the loop function again in 1 second | |
imp.wakeup(1.0, loop); | |
} | |
// Power the Grove connectors | |
hardware.pinXU.configure(DIGITAL_OUT, 1); | |
// Start the sensor reading loop | |
loop(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment