mirror of https://github.com/arendst/Tasmota.git
255 lines
6.5 KiB
C++
255 lines
6.5 KiB
C++
|
#include "SevenSegmentFun.h"
|
||
|
|
||
|
const PROGMEM uint8_t levelVerticalMap[4] = {
|
||
|
TM1637_CHAR_HOR_LEVEL_0,
|
||
|
TM1637_CHAR_HOR_LEVEL_1,
|
||
|
TM1637_CHAR_HOR_LEVEL_2,
|
||
|
TM1637_CHAR_HOR_LEVEL_3
|
||
|
};
|
||
|
|
||
|
SevenSegmentFun::SevenSegmentFun(uint8_t pinClk, uint8_t pinDIO) :
|
||
|
SevenSegmentExtended(pinClk, pinDIO)
|
||
|
{
|
||
|
randomSeed(analogRead(0));
|
||
|
};
|
||
|
|
||
|
// 9 levels ( 0, 12.5, 25, 37.4, 50, 62.5, 75.0, 87.5, 100)
|
||
|
void SevenSegmentFun::printLevelVertical(uint8_t level, bool leftToRight) {
|
||
|
|
||
|
level = (level > 100?100:level);
|
||
|
float levelScale = (100 / (TM1637_MAX_COLOM * 2.0));
|
||
|
|
||
|
uint8_t barsOn = float(level) / levelScale;
|
||
|
|
||
|
uint8_t d = leftToRight == true?0:TM1637_MAX_COLOM-1;
|
||
|
|
||
|
for (uint8_t i=0; i < TM1637_MAX_COLOM; i++) {
|
||
|
if (barsOn - (2 * (i + 1)) >= 0) {
|
||
|
_rawBuffer[d] = TM1637_CHAR_VERT_LEVEL_II;
|
||
|
} else if (barsOn - (2 * (i + 1)) >= 1) {
|
||
|
_rawBuffer[d] = (leftToRight == true)?TM1637_CHAR_VERT_LEVEL_I0:TM1637_CHAR_VERT_LEVEL_0I;
|
||
|
} else {
|
||
|
_rawBuffer[d] = 0;
|
||
|
}
|
||
|
if (leftToRight == true) {d++;}
|
||
|
else {d--;};
|
||
|
};
|
||
|
printRaw(_rawBuffer, TM1637_MAX_COLOM, 0);
|
||
|
};
|
||
|
|
||
|
|
||
|
void SevenSegmentFun::printLevelVertical(uint8_t level, bool leftToRight, uint8_t symbol) {
|
||
|
level /= (100 / TM1637_MAX_COLOM);
|
||
|
level = (level > TM1637_MAX_COLOM)?TM1637_MAX_COLOM:level;
|
||
|
|
||
|
for( uint8_t i=0; i < TM1637_MAX_COLOM;i++) {
|
||
|
if ( ( i < level && leftToRight ) || ( i >= ( TM1637_MAX_COLOM - level ) && !leftToRight) ) {
|
||
|
_rawBuffer[i] = symbol;
|
||
|
} else {
|
||
|
_rawBuffer[i] = 0;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
printRaw(_rawBuffer, TM1637_MAX_COLOM, 0);
|
||
|
|
||
|
};
|
||
|
|
||
|
void SevenSegmentFun::nightrider(uint8_t repeats, uint16_t d, uint8_t symbol) {
|
||
|
|
||
|
uint8_t buffer[((TM1637_MAX_COLOM * 2) - 1)] = {0, };
|
||
|
|
||
|
for ( uint8_t i= 0; i < ((TM1637_MAX_COLOM * 2) - 1); i++) {
|
||
|
if ( i == (TM1637_MAX_COLOM - 1) ) {
|
||
|
buffer[i] = symbol;
|
||
|
} else {
|
||
|
buffer[i] = 0;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
for( int8_t r=0; r < repeats; r++) {
|
||
|
for (int8_t i = (TM1637_MAX_COLOM - 1); i > 0; i--) {
|
||
|
printRaw( &buffer[i],4,0);
|
||
|
delay(d);
|
||
|
};
|
||
|
for ( int8_t i = 0; i < (TM1637_MAX_COLOM - 1); i++) {
|
||
|
printRaw( &buffer[i], TM1637_MAX_COLOM, 0);
|
||
|
delay(d);
|
||
|
};
|
||
|
}
|
||
|
}
|
||
|
// 5 levels ( 0, 33, 66, 100)
|
||
|
void SevenSegmentFun::printLevelHorizontal( uint8_t levels[4] ) {
|
||
|
for (uint8_t i=0; i < TM1637_MAX_COLOM;i++) {
|
||
|
levels[i] /= (100 / 3);
|
||
|
levels[i] = ( levels[i] > 3)?3:levels[i];
|
||
|
_rawBuffer[i] = pgm_read_byte_near(levelVerticalMap + levels[i]);
|
||
|
};
|
||
|
printRaw(_rawBuffer, TM1637_MAX_COLOM, 0);
|
||
|
}
|
||
|
|
||
|
void SevenSegmentFun::scrollingText(const char* str, uint8_t repeats) {
|
||
|
|
||
|
uint8_t buffer[TM1637_MAX_CHARS];
|
||
|
|
||
|
size_t length = encode(&buffer[3], str, TM1637_MAX_CHARS);
|
||
|
|
||
|
uint8_t paddingBegin = TM1637_MAX_COLOM - 1;
|
||
|
uint8_t totalPadding = (2 * paddingBegin) + 1;
|
||
|
|
||
|
// padd with three spaces in front
|
||
|
for(uint8_t i=0; i < paddingBegin; i++) {
|
||
|
buffer[i] = 0;
|
||
|
};
|
||
|
// padd with four spaces at the end (empty scree)
|
||
|
for(uint8_t i = length + paddingBegin; i < length + totalPadding ; i++) {
|
||
|
buffer[i] = 0;
|
||
|
};
|
||
|
|
||
|
for( ; repeats != 0; repeats--) {
|
||
|
printRaw(buffer, length + totalPadding);
|
||
|
if ( repeats > 250 ) { // more than 250 -> forever
|
||
|
repeats++;
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
void SevenSegmentFun::snake(uint8_t repeats, uint16_t d) {
|
||
|
|
||
|
uint8_t outerEdges = (4 * TM1637_MAX_LINES) + (TM1637_MAX_COLOM * 2);
|
||
|
uint8_t widthEdged = (TM1637_MAX_COLOM * 2);
|
||
|
|
||
|
// number of repeats/rounds
|
||
|
for ( uint8_t r=0; r < repeats; r++) {
|
||
|
// 12 steps for all outer edges
|
||
|
for (uint8_t i=0; i < outerEdges; i++) {
|
||
|
for (uint8_t j=0; j < TM1637_MAX_COLOM; j++) {
|
||
|
|
||
|
// set segments
|
||
|
// top edges
|
||
|
if ( i == j) {
|
||
|
_rawBuffer[j] =TM1637_CHAR_SNAKE_0;
|
||
|
}
|
||
|
// top right edge
|
||
|
else if ( i == TM1637_MAX_COLOM && j == 3) {
|
||
|
_rawBuffer[j] =TM1637_CHAR_SNAKE_1;
|
||
|
}
|
||
|
// bottom left edge
|
||
|
else if ( i == (TM1637_MAX_COLOM + 1) && j == 3) {
|
||
|
_rawBuffer[j] =TM1637_CHAR_SNAKE_2;
|
||
|
}
|
||
|
// bottom edges
|
||
|
else if ( i + j == (widthEdged + 1) ) {
|
||
|
_rawBuffer[j] =TM1637_CHAR_SNAKE_3;
|
||
|
}
|
||
|
// bottom left edge
|
||
|
else if ( i == (widthEdged + 2) && j == 0) {
|
||
|
_rawBuffer[j] =TM1637_CHAR_SNAKE_4;
|
||
|
}
|
||
|
// top left edge
|
||
|
else if ( i == (widthEdged + 3) && j == 0) {
|
||
|
_rawBuffer[j] =TM1637_CHAR_SNAKE_5;
|
||
|
} else {
|
||
|
_rawBuffer[j] = 0;
|
||
|
};
|
||
|
};
|
||
|
printRaw(_rawBuffer, 4, 0);
|
||
|
delay(d);
|
||
|
}
|
||
|
|
||
|
};
|
||
|
}
|
||
|
|
||
|
void SevenSegmentFun::bombTimer(uint8_t hours, uint8_t min, uint16_t speed) {
|
||
|
|
||
|
// maximum speed is 60000 -> 1min per ms
|
||
|
speed = (speed > 60000)?60000:speed;
|
||
|
uint16_t d = 60000 / speed;
|
||
|
|
||
|
// copy start minute
|
||
|
int8_t m = min;
|
||
|
int8_t h;
|
||
|
for ( h=hours; h >= 0; h--) {
|
||
|
for ( ; m >= 0; m--) {
|
||
|
printTime((uint8_t)h, (uint8_t)m);
|
||
|
delay(d);
|
||
|
};
|
||
|
m = 59; // reset minute timer
|
||
|
};
|
||
|
blink();
|
||
|
};
|
||
|
|
||
|
void SevenSegmentFun::bombTimer(uint8_t hours, uint8_t min, uint16_t speed, char* str) {
|
||
|
bombTimer(hours, min, speed);
|
||
|
print(str);
|
||
|
blink();
|
||
|
};
|
||
|
|
||
|
void SevenSegmentFun::bouncingBall(uint16_t moves, uint16_t d, bool runForever) {
|
||
|
|
||
|
int8_t wallRight = TM1637_MAX_COLOM - 1;
|
||
|
int8_t wallBottom = TM1637_MAX_LINES;
|
||
|
|
||
|
// start at top left
|
||
|
int8_t x = 0; int8_t y = 0;
|
||
|
int8_t newX; int8_t newY;
|
||
|
// default speed is 1 x right and 2 y down
|
||
|
int8_t vx = 1; int8_t vy = 1;
|
||
|
bool flipVx = false; bool flipVy = false;
|
||
|
|
||
|
// print initial state
|
||
|
printBall(x, y);
|
||
|
|
||
|
for ( ; moves != 0; moves--) {
|
||
|
|
||
|
newX = x + vx;
|
||
|
newY = y + vy;
|
||
|
|
||
|
// check if ball has hit the wall
|
||
|
if (newX > wallRight || newX < 0 ) {
|
||
|
vx = vx * -1;
|
||
|
newX = x + vx;
|
||
|
// random flip other direction as well
|
||
|
flipVy = (random(3) == 1);
|
||
|
};
|
||
|
|
||
|
if ( newY > wallBottom || newY < 0) {
|
||
|
vy = vy * -1;
|
||
|
newY = y + vy;
|
||
|
// random flip other direction as well
|
||
|
flipVx = (random(3) == 1);
|
||
|
};
|
||
|
|
||
|
if ( flipVy ) {
|
||
|
newY = y;
|
||
|
} else if ( flipVx ) {
|
||
|
newX = x;
|
||
|
};
|
||
|
// set new coordinates
|
||
|
x = newX; y = newY;
|
||
|
|
||
|
printBall(x, y);
|
||
|
delay(d);
|
||
|
|
||
|
if (runForever) {
|
||
|
moves++;
|
||
|
};
|
||
|
};
|
||
|
}
|
||
|
|
||
|
void SevenSegmentFun::printBall( const int8_t x, const int8_t y ) {
|
||
|
// uint8_t buffer[4] = {0,0,0,0};
|
||
|
// buffer[x] = (y > 0)?TM1637_CHAR_BALL_LOW:TM1637_CHAR_BALL_HIGH;
|
||
|
// printRaw(buffer);
|
||
|
|
||
|
uint8_t symbol = (y > 0)?TM1637_CHAR_BALL_LOW:TM1637_CHAR_BALL_HIGH;
|
||
|
|
||
|
print4Bit(x, y, symbol);
|
||
|
|
||
|
};
|
||
|
|
||
|
void SevenSegmentFun::print4Bit( const uint8_t x, const uint8_t y, uint8_t symbol) {
|
||
|
uint8_t buffer[4] = {0,0,0,0};
|
||
|
buffer[x] = symbol;
|
||
|
printRaw(buffer);
|
||
|
}
|