From a1be7244163720881eb190da822262077c800aa7 Mon Sep 17 00:00:00 2001 From: dagwoodland Date: Tue, 17 Sep 2019 08:57:28 +0100 Subject: [PATCH] Added setTubeSegments() Added the setTubeSegments(TubeNum tube_num,uint16_t segments); which allows you to set specific segments on or off for a given tube. --- .../display_specific_segments.ino | 110 ++++++++++++++++++ grove_alphanumeric_display.cpp | 33 ++++++ grove_alphanumeric_display.h | 37 ++++++ 3 files changed, 180 insertions(+) create mode 100644 examples/display_specific_segments/display_specific_segments.ino diff --git a/examples/display_specific_segments/display_specific_segments.ino b/examples/display_specific_segments/display_specific_segments.ino new file mode 100644 index 0000000..f4a8397 --- /dev/null +++ b/examples/display_specific_segments/display_specific_segments.ino @@ -0,0 +1,110 @@ +/* + display_basic.ino + Example for displaying specific segments on a tube. + + + Author : dagwoodland + Create Time: Sep 2019 + + 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. +*/ + +#include "Wire.h" +#include "grove_alphanumeric_display.h" + +// Keeps track of the current stage of tube 2's animation. +int currentSegment = 0; + +// The frames of tube 2's animation. +uint16_t tubeTwoFrames[] = { + SEGMENT_TOP, + SEGMENT_TOP_LEFT, + SEGMENT_TOP_LEFT_DIAGONAL, + SEGMENT_TOP_VERTICAL, + SEGMENT_TOP_RIGHT_DIAGONAL, + SEGMENT_TOP_RIGHT, + SEGMENT_MIDDLE_LEFT, + SEGMENT_MIDDLE_RIGHT, + SEGMENT_BOTTOM_LEFT, + SEGMENT_BOTTOM_LEFT_DIAGONAL, + SEGMENT_BOTTOM_VERTICAL, + SEGMENT_BOTTOM_RIGHT_DIAGONAL, + SEGMENT_BOTTOM_RIGHT, + SEGMENT_BOTTOM +}; + +// ----------------------------------------------------------- +// TIP - You can use shorthand notation to avoid long lines. +// Shorthand is simply 'SEG_' and then the first letter of each +// word. Eg. 'SEGMENT_TOP_LEFT_DIAGANOL' becomes 'SEG_TLD'. +// ----------------------------------------------------------- + +// Reference to the Seeed_Digital_Tube. +Seeed_Digital_Tube tube; + +void setup() { + // Setup wire using default I2C pins. + Wire.begin(); + + // If using four digital tubes, use this configuration. + tube.setTubeType(TYPE_4, TYPE_4_DEFAULT_I2C_ADDR); + + // If using two digital tubes, use this configuration. + // tube.setTubeType(TYPE_2,TYPE_2_DEFAULT_I2C_ADDR); + + tube.setBrightness(15); + tube.setBlinkRate(BLINK_OFF); +} + +// Display the top and bottom segments on the first tube. +void displayTubeOne() { + // To display specific segments add together their values. + tube.setTubeSegments(FIRST_TUBE, SEGMENT_TOP + SEGMENT_BOTTOM); +} + +// Display an animation going through all 14 segments in turn. +void displayTubeTwo() { + // Increment tube 2's animation frame. + currentSegment += 1; + + // Restart the animation if it has finished. + if (currentSegment >= 14) { + currentSegment = 0; + } + + // Display the current frame of tube 2's animation. + tube.setTubeSegments(SECOND_TUBE, tubeTwoFrames[currentSegment]); +} + +void loop() { + // Clear the tube's buffer. Using tube.clearBuf() prevents + // the display blinking because the display is not updated + // until tube.display() is called, unlike tube.clear() + tube.clearBuf(); + + displayTubeOne(); + displayTubeTwo(); + + // Display the new contents of both tube's buffers. + tube.display(); + + delay(200); +} diff --git a/grove_alphanumeric_display.cpp b/grove_alphanumeric_display.cpp index fa23252..b026372 100644 --- a/grove_alphanumeric_display.cpp +++ b/grove_alphanumeric_display.cpp @@ -129,6 +129,8 @@ uint16_t g_display_font2[]={ 0x0000, // ilegal num }; +uint16_t segments4Tubes[] = {0x10,0x4000,0x80,0x40,0x2,0x2000,0x200,0x100,0x400,0x8,0x1000,0x20,0x4,0x800}; +uint16_t segments2Tubes[] = {0x4,0x40,0x20,0x1,0x8,0x10,0x2,0x1000,0x2000,0x100,0x200,0x8000,0x800,0x400}; Seeed_Digital_Tube::Seeed_Digital_Tube() { @@ -316,6 +318,37 @@ void Seeed_Digital_Tube::setPoint(bool first_dot,bool second_dot) else{} } +void Seeed_Digital_Tube::setTubeSegments(TubeNum tube_num,uint16_t segments) +{ + uint16_t value = 0; + + if( TYPE_4 == _type ) + { + for (int i=0; i<16; i++) { + if (bitRead(segments, i) == 1) { + value += segments4Tubes[i]; + } + } + + _buffer[tube_num*2] = value; + _buffer[tube_num*2+1] = value >> 8; + replace_bit12(tube_num,value&0x02,value&0x04); + } + else if (TYPE_2 == _type) + { + for (int i=0; i<16; i++) { + if (bitRead(segments, i) == 1) { + value += segments2Tubes[i]; + } + } + + // Set tube_num to 1 if it's 2, and 2 if it's 1, so that it's compatible with the hardware. + tube_num = (TubeNum) (((int)tube_num+1) & (~(int)tube_num)); + + _buffer[tube_num*2] = value >> 8; + _buffer[tube_num*2+1] = value; + } +} void Seeed_Digital_Tube::setTubeBuf(TubeNum tube_num,char byte) { diff --git a/grove_alphanumeric_display.h b/grove_alphanumeric_display.h index df88c25..b45e6c8 100644 --- a/grove_alphanumeric_display.h +++ b/grove_alphanumeric_display.h @@ -51,7 +51,37 @@ #define MAX_TUBE_COUNT 4 +// Long hand segment definitions. +#define SEGMENT_TOP 0x1 +#define SEGMENT_TOP_LEFT 0x2 +#define SEGMENT_TOP_LEFT_DIAGONAL 0x4 +#define SEGMENT_TOP_RIGHT 0x8 +#define SEGMENT_TOP_RIGHT_DIAGONAL 0x10 +#define SEGMENT_TOP_VERTICAL 0x20 +#define SEGMENT_MIDDLE_LEFT 0x40 +#define SEGMENT_MIDDLE_RIGHT 0x80 +#define SEGMENT_BOTTOM 0x100 +#define SEGMENT_BOTTOM_LEFT 0x200 +#define SEGMENT_BOTTOM_LEFT_DIAGONAL 0x400 +#define SEGMENT_BOTTOM_RIGHT 0x800 +#define SEGMENT_BOTTOM_RIGHT_DIAGONAL 0x1000 +#define SEGMENT_BOTTOM_VERTICAL 0x2000 +// Short hand segment definitions. +#define SEG_T 0x1 +#define SEG_TL 0x2 +#define SEG_TLD 0x4 +#define SEG_TR 0x8 +#define SEG_TRD 0x10 +#define SEG_TV 0x20 +#define SEG_ML 0x40 +#define SEG_MR 0x80 +#define SEG_B 0x100 +#define SEG_BL 0x200 +#define SEG_BLD 0x400 +#define SEG_BR 0x800 +#define SEG_BRD 0x1000 +#define SEG_BV 0x2000 typedef enum { @@ -127,6 +157,13 @@ public: * @prarm lower_on if true,the second point light on ,otherwise turn off; * */ void setPoint(bool first_dot,bool second_dot); + + /**@brief Set the values of tube_num's segments. + * @param tube_num The number of tube, depending on the device you are using (2 or 4). + * @prarm segments The segments that should be turned on. + * */ + void setTubeSegments(TubeNum tube_num,uint16_t segments); + private: void display_one_tube(TubeNum tube_num,uint16_t value); void replace_bit12(TubeNum tube_num,bool bit1,bool bit2);