Skip to content

Commit e3605d7

Browse files
committed
Merge pull request ThingPulse#43 from squix78/implement-print-class
Implement basic print interface
2 parents 48226c9 + 72ec74e commit e3605d7

File tree

2 files changed

+129
-2
lines changed

2 files changed

+129
-2
lines changed

OLEDDisplay.cpp

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,111 @@ void OLEDDisplay::clear(void) {
506506
memset(buffer, 0, DISPLAY_BUFFER_SIZE);
507507
}
508508

509+
void OLEDDisplay::drawLogBuffer(uint16_t xMove, uint16_t yMove) {
510+
uint16_t lineHeight = pgm_read_byte(fontData + HEIGHT_POS);
511+
// Always align left
512+
setTextAlignment(TEXT_ALIGN_LEFT);
513+
514+
// State values
515+
uint16_t length = 0;
516+
uint16_t line = 0;
517+
uint16_t lastPos = 0;
518+
519+
for (uint16_t i=0;i<this->logBufferFilled;i++){
520+
// Everytime we have a \n print
521+
if (this->logBuffer[i] == 10) {
522+
length++;
523+
// Draw string on line `line` from lastPos to length
524+
// Passing 0 as the lenght because we are in TEXT_ALIGN_LEFT
525+
drawStringInternal(xMove, yMove + (line++) * lineHeight, &this->logBuffer[lastPos], length, 0);
526+
// Remember last pos
527+
lastPos = i;
528+
// Reset length
529+
length = 0;
530+
} else {
531+
// Count chars until next linebreak
532+
length++;
533+
}
534+
}
535+
// Draw the remaining string
536+
if (length > 0) {
537+
drawStringInternal(xMove, yMove + line * lineHeight, &this->logBuffer[lastPos], length, 0);
538+
}
539+
}
540+
541+
bool OLEDDisplay::setLogBuffer(uint16_t lines, uint16_t chars){
542+
if (logBuffer != NULL) free(logBuffer);
543+
uint16_t size = lines * chars;
544+
if (size > 0) {
545+
this->logBufferLine = 0; // Lines printed
546+
this->logBufferMaxLines = lines; // Lines max printable
547+
this->logBufferSize = size; // Total number of characters the buffer can hold
548+
this->logBuffer = (char *) malloc(size * sizeof(uint8_t));
549+
if(!this->logBuffer) {
550+
DEBUG_OLEDDISPLAY("[OLEDDISPLAY][setLogBuffer] Not enough memory to create log buffer\n");
551+
return false;
552+
}
553+
}
554+
return true;
555+
}
556+
557+
size_t OLEDDisplay::write(uint8_t c) {
558+
if (this->logBufferSize > 0) {
559+
// Don't waste space on \r\n line endings, dropping \r
560+
if (c == 13) return 1;
561+
562+
bool maxLineNotReached = this->logBufferLine < this->logBufferMaxLines;
563+
bool bufferNotFull = this->logBufferFilled < this->logBufferSize;
564+
565+
// Can we write to the buffer?
566+
if (bufferNotFull && maxLineNotReached) {
567+
this->logBuffer[logBufferFilled] = utf8ascii(c);
568+
this->logBufferFilled++;
569+
// Keep track of lines written
570+
if (c == 10) this->logBufferLine++;
571+
} else {
572+
// Max line number is reached
573+
if (!maxLineNotReached) this->logBufferLine--;
574+
575+
// Find the end of the first line
576+
uint16_t firstLineEnd = 0;
577+
for (uint16_t i=0;i<this->logBufferFilled;i++) {
578+
if (this->logBuffer[i] == 10){
579+
// Include last char too
580+
firstLineEnd = i + 1;
581+
break;
582+
}
583+
}
584+
// If there was a line ending
585+
if (firstLineEnd > 0) {
586+
// Calculate the new logBufferFilled value
587+
this->logBufferFilled = logBufferFilled - firstLineEnd;
588+
// Now we move the lines infront of the buffer
589+
memcpy(this->logBuffer, &this->logBuffer[firstLineEnd], logBufferFilled);
590+
} else {
591+
// Let's reuse the buffer if it was full
592+
if (!bufferNotFull) {
593+
this->logBufferFilled = 0;
594+
}// else {
595+
// Nothing to do here
596+
//}
597+
}
598+
write(c);
599+
}
600+
}
601+
// We are always writing all uint8_t to the buffer
602+
return 1;
603+
}
604+
605+
size_t OLEDDisplay::write(const char* str) {
606+
if (str == NULL) return 0;
607+
size_t length = strlen(str);
608+
for (size_t i = 0; i < length; i++) {
609+
write(str[i]);
610+
}
611+
return length;
612+
}
613+
509614
// Private functions
510615
void OLEDDisplay::sendInitCommands(void) {
511616
sendCommand(DISPLAYOFF);

OLEDDisplay.h

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ enum OLEDDISPLAY_TEXT_ALIGNMENT {
108108
};
109109

110110

111-
class OLEDDisplay {
111+
class OLEDDisplay : public Print {
112112
public:
113113
// Initialize the display
114114
bool init();
@@ -209,17 +209,39 @@ class OLEDDisplay {
209209
// Clear the local pixel buffer
210210
void clear(void);
211211

212+
// Log buffer implementation
213+
214+
// This will define the lines and characters you can
215+
// print to the screen. When you exeed the buffer size (lines * chars)
216+
// the output may be truncated due to the size constraint.
217+
bool setLogBuffer(uint16_t lines, uint16_t chars);
218+
219+
// Draw the log buffer at position (x, y)
220+
void drawLogBuffer(uint16_t x, uint16_t y);
221+
222+
// Implementent needed function to be compatible with Print class
223+
size_t write(uint8_t c);
224+
size_t write(const char* s);
225+
212226
uint8_t *buffer;
213227

214228
#ifdef OLEDDISPLAY_DOUBLE_BUFFER
215229
uint8_t *buffer_back;
216230
#endif
217231

218232
protected:
233+
219234
OLEDDISPLAY_TEXT_ALIGNMENT textAlignment = TEXT_ALIGN_LEFT;
220235
OLEDDISPLAY_COLOR color = WHITE;
221236

222-
const char *fontData = ArialMT_Plain_10;
237+
const char *fontData = ArialMT_Plain_10;
238+
239+
// State values for logBuffer
240+
uint16_t logBufferSize = 0;
241+
uint16_t logBufferFilled = 0;
242+
uint16_t logBufferLine = 0;
243+
uint16_t logBufferMaxLines = 0;
244+
char *logBuffer = NULL;
223245

224246
// Send a command to the display (low level function)
225247
virtual void sendCommand(uint8_t com);

0 commit comments

Comments
 (0)