commit 64c8e88536b5d526b88d9f5f2d25457f7ac0ab19 Author: GhassanYusuf Date: Sun Jul 13 15:44:13 2025 +0300 first upload diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/SevenSegmentNeoPixel.cpp b/SevenSegmentNeoPixel.cpp new file mode 100644 index 0000000..1146930 --- /dev/null +++ b/SevenSegmentNeoPixel.cpp @@ -0,0 +1,94 @@ +#include "SevenSegmentNeoPixel.h" +#include + +// Standard digit segment patterns +const uint8_t SevenSegmentNeoPixel::_segmentPatterns[10][7] = { + {1,1,1,1,1,1,0}, // 0 + {0,0,1,1,0,0,0}, // 1 + {0,1,1,0,1,1,1}, // 2 + {0,1,1,1,1,0,1}, // 3 + {1,0,1,1,0,0,1}, // 4 + {1,1,0,1,1,0,1}, // 5 + {1,1,0,1,1,1,1}, // 6 + {0,1,1,1,0,0,0}, // 7 + {1,1,1,1,1,1,1}, // 8 + {1,1,1,1,1,0,1} // 9 +}; + +SevenSegmentNeoPixel::SevenSegmentNeoPixel(uint8_t digits, uint8_t pixelsPerSegment, uint8_t pin, const uint8_t* segmentOrder, neoPixelType type) + : _digits(digits), + _pixelsPerSegment(pixelsPerSegment), + _pixelsPerDigit(pixelsPerSegment * _segmentsPerDigit), + _numPixels(digits * pixelsPerSegment * _segmentsPerDigit), + _strip(_numPixels, pin, type) +{ + if (segmentOrder) { + memcpy(_segmentOrder, segmentOrder, 7); + } else { + for (uint8_t i = 0; i < 7; ++i) _segmentOrder[i] = i; + } +} + +void SevenSegmentNeoPixel::begin() { + _strip.begin(); + _strip.show(); +} + +void SevenSegmentNeoPixel::clear() { + _strip.clear(); +} + +void SevenSegmentNeoPixel::show() { + _strip.show(); +} + +void SevenSegmentNeoPixel::setBrightness(uint8_t brightness) { + _strip.setBrightness(brightness); +} + +void SevenSegmentNeoPixel::setDigit(uint8_t digitIndex, uint8_t value, uint32_t color) { + if (digitIndex >= _digits || value > 9) return; + for (uint8_t seg = 0; seg < _segmentsPerDigit; ++seg) { + uint8_t physSeg = _segmentOrder[seg]; + uint16_t start = getPixelOffset(digitIndex, physSeg); + if (_segmentPatterns[value][seg]) { + for (uint8_t i = 0; i < _pixelsPerSegment; ++i) { + _strip.setPixelColor(start + i, color); + } + } else { + for (uint8_t i = 0; i < _pixelsPerSegment; ++i) { + _strip.setPixelColor(start + i, 0); + } + } + } +} + +void SevenSegmentNeoPixel::setAll(uint8_t value, uint32_t color) { + for (uint8_t d = 0; d < _digits; ++d) { + setDigit(d, value, color); + } +} + +void SevenSegmentNeoPixel::setSegments(uint8_t digitIndex, const uint8_t segments[7], uint32_t color) { + if (digitIndex >= _digits) return; + for (uint8_t seg = 0; seg < _segmentsPerDigit; ++seg) { + uint8_t physSeg = _segmentOrder[seg]; + uint16_t start = getPixelOffset(digitIndex, physSeg); + for (uint8_t i = 0; i < _pixelsPerSegment; ++i) { + _strip.setPixelColor(start + i, segments[seg] ? color : 0); + } + } +} + +Adafruit_NeoPixel& SevenSegmentNeoPixel::getStrip() { + return _strip; +} + +const uint8_t* SevenSegmentNeoPixel::getSegmentPattern(uint8_t digit) { + if (digit < 10) return _segmentPatterns[digit]; + else return nullptr; +} + +uint16_t SevenSegmentNeoPixel::getPixelOffset(uint8_t digitIndex, uint8_t segmentIndex) const { + return digitIndex * _pixelsPerDigit + segmentIndex * _pixelsPerSegment; +} diff --git a/SevenSegmentNeoPixel.h b/SevenSegmentNeoPixel.h new file mode 100644 index 0000000..2ee14e8 --- /dev/null +++ b/SevenSegmentNeoPixel.h @@ -0,0 +1,37 @@ +#ifndef SEVENSEGMENTNEOPIXEL_H +#define SEVENSEGMENTNEOPIXEL_H + +#include + +class SevenSegmentNeoPixel { +public: + // Constructor with optional segment order + SevenSegmentNeoPixel(uint8_t digits, uint8_t pixelsPerSegment, uint8_t pin, + const uint8_t* segmentOrder = nullptr, + neoPixelType type = NEO_GRB + NEO_KHZ800); + + void begin(); + void clear(); + void show(); + void setBrightness(uint8_t brightness); + void setDigit(uint8_t digitIndex, uint8_t value, uint32_t color); + void setAll(uint8_t value, uint32_t color); + void setSegments(uint8_t digitIndex, const uint8_t segments[7], uint32_t color); + Adafruit_NeoPixel& getStrip(); + + static const uint8_t* getSegmentPattern(uint8_t digit); + +private: + uint8_t _digits; + uint8_t _pixelsPerSegment; + uint8_t _segmentsPerDigit = 7; + uint16_t _pixelsPerDigit; + uint16_t _numPixels; + Adafruit_NeoPixel _strip; + uint8_t _segmentOrder[7]; // <-- Add this line + + static const uint8_t _segmentPatterns[10][7]; + uint16_t getPixelOffset(uint8_t digitIndex, uint8_t segmentIndex) const; +}; + +#endif diff --git a/examples/BasicUsage/BasicUsage.ino b/examples/BasicUsage/BasicUsage.ino new file mode 100644 index 0000000..0e5873f --- /dev/null +++ b/examples/BasicUsage/BasicUsage.ino @@ -0,0 +1,23 @@ +#include "SevenSegmentNeoPixel.h" + +#define DIGITS 4 +#define PIXELS_PER_SEGMENT 7 +#define PIN 0 + +SevenSegmentNeoPixel display(DIGITS, PIXELS_PER_SEGMENT, PIN); + +void setup() { + display.begin(); + display.setBrightness(50); +} + +void loop() { + for (uint8_t d = 0; d < DIGITS; ++d) { + display.setDigit(d, d, display.getStrip().Color(255, 0, 0)); // Show digit index in red + } + display.show(); + delay(1000); + display.clear(); + display.show(); + delay(500); +} diff --git a/examples/Counter/Counter.ino b/examples/Counter/Counter.ino new file mode 100644 index 0000000..f49aa78 --- /dev/null +++ b/examples/Counter/Counter.ino @@ -0,0 +1,35 @@ +#include + +// Adjust these for your hardware setup +#define DIGITS 1 +#define PIXELS_PER_SEGMENT 7 +#define PIN 0 + +SevenSegmentNeoPixel display(DIGITS, PIXELS_PER_SEGMENT, PIN); + +void setup() { + display.begin(); + display.setBrightness(50); // Adjust brightness as needed +} + +void loop() { + static unsigned long lastUpdate = 0; + static unsigned long counter = 0; + unsigned long now = millis(); + + if (now - lastUpdate >= 1000) { // Update every second + lastUpdate = now; + + // Display the counter value, right-aligned, with leading zeros + unsigned long value = counter; + for (int d = DIGITS - 1; d >= 0; d--) { + uint8_t digit = value % 10; + display.setDigit(d, digit, display.getStrip().Color(0, 150, 0)); // Green color + value /= 10; + } + display.show(); + + counter++; + if (counter >= pow(10, DIGITS)) counter = 0; // Roll over when max digits reached + } +} diff --git a/examples/RainbowCounter/RainbowCounter.ino b/examples/RainbowCounter/RainbowCounter.ino new file mode 100644 index 0000000..feb1c61 --- /dev/null +++ b/examples/RainbowCounter/RainbowCounter.ino @@ -0,0 +1,67 @@ +#include + +#define DIGITS 1 +#define PIXELS_PER_SEGMENT 7 +#define PIN 0 + +SevenSegmentNeoPixel display(DIGITS, PIXELS_PER_SEGMENT, PIN); + +uint32_t colorWheel(byte pos) { + pos = 255 - pos; + if (pos < 85) { + return display.getStrip().Color(255 - pos * 3, 0, pos * 3); + } + if (pos < 170) { + pos -= 85; + return display.getStrip().Color(0, pos * 3, 255 - pos * 3); + } + pos -= 170; + return display.getStrip().Color(pos * 3, 255 - pos * 3, 0); +} + +void setup() { + display.begin(); + display.setBrightness(50); +} + +void loop() { + static unsigned long lastAnim = 0; + static unsigned long lastCount = 0; + static unsigned long counter = 0; + static uint16_t rainbowOffset = 0; + unsigned long now = millis(); + + // Animate rainbow every 50ms + if (now - lastAnim >= 50) { + lastAnim = now; + + display.clear(); + + unsigned long value = counter; + for (int d = DIGITS - 1; d >= 0; d--) { + uint8_t digit = value % 10; + value /= 10; + const uint8_t* segPattern = SevenSegmentNeoPixel::getSegmentPattern(digit); + for (uint8_t seg = 0; seg < 7; seg++) { + if (segPattern && segPattern[seg]) { + for (uint8_t px = 0; px < PIXELS_PER_SEGMENT; px++) { + uint16_t globalPixel = d * 7 * PIXELS_PER_SEGMENT + seg * PIXELS_PER_SEGMENT + px; + uint8_t colorPos = (globalPixel * 256 / (DIGITS * 7 * PIXELS_PER_SEGMENT) + rainbowOffset) & 0xFF; + uint32_t color = colorWheel(colorPos); + display.getStrip().setPixelColor(globalPixel, color); + } + } + } + } + display.show(); + + rainbowOffset += 4; // Wave speed + } + + // Increment counter every 1000ms (1 second) + if (now - lastCount >= 1000) { + lastCount = now; + counter++; + if (counter >= pow(10, DIGITS)) counter = 0; + } +} \ No newline at end of file diff --git a/keywords.txt b/keywords.txt new file mode 100644 index 0000000..65b26ab --- /dev/null +++ b/keywords.txt @@ -0,0 +1,9 @@ +SevenSegmentNeoPixel KEYWORD1 +begin KEYWORD2 +clear KEYWORD2 +show KEYWORD2 +setBrightness KEYWORD2 +setDigit KEYWORD2 +setAll KEYWORD2 +setSegments KEYWORD2 +getStrip KEYWORD2 \ No newline at end of file diff --git a/library.properties b/library.properties new file mode 100644 index 0000000..1cb94e9 --- /dev/null +++ b/library.properties @@ -0,0 +1,10 @@ +name=FABLAB Bahrain - Neo Seven Segment +version=1.0.0 +author=Ghassan Yusuf +maintainer=Ghassan Yusuf +sentence=Seven segment display driver for NeoPixel LED strips. +paragraph=Easily control one or more seven-segment displays made from NeoPixel (WS2812) LED strips. Code ownership: FABLAB BAHRAIN. Visit us at https://fablab.bh/ +category=Display +url=https://git.innovator.bh/ghassan/NeoSevenSegment +architectures=* +includes=SevenSegmentNeoPixel.h