Skip to content

Commit 0c1ec43

Browse files
authored
Draw bitmaps with defined width (#17)
1 parent 94a4ac4 commit 0c1ec43

3 files changed

Lines changed: 79 additions & 35 deletions

File tree

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=Nokia 5110 LCD library
2-
version=2.5.0
2+
version=2.6.0
33
author=Dimitris Platis
44
maintainer=Dimitris Platis <dimitris@plat.is>
55
sentence=Arduino library for driving the Nokia 5110 LCD

src/Nokia_LCD.cpp

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,16 @@
1313
#include "Nokia_LCD_Fonts.h"
1414

1515
namespace {
16-
const uint8_t kDisplay_max_width = 84;
17-
const uint8_t kDisplay_max_height = 48;
18-
1916
// Instantiate the default font
2017
const LcdFont nokiaFont{
2118
[](char c) { return Nokia_LCD_Fonts::kDefault_font[c - 0x20]; },
2219
Nokia_LCD_Fonts::kColumns_per_character, Nokia_LCD_Fonts::hSpace, 1};
2320

2421
// Each row is made of 8-bit columns
2522
const unsigned int kTotal_rows =
26-
kDisplay_max_height / Nokia_LCD_Fonts::kRows_per_character;
27-
const unsigned int kTotal_columns = kDisplay_max_width;
28-
const unsigned int kTotal_bits = kDisplay_max_width * kTotal_rows;
23+
nokia_lcd::kDisplay_max_height / Nokia_LCD_Fonts::kRows_per_character;
24+
const unsigned int kTotal_columns = nokia_lcd::kDisplay_max_width;
25+
const unsigned int kTotal_bits = nokia_lcd::kDisplay_max_width * kTotal_rows;
2926
const char kNull_char = '\0';
3027
const uint8_t kMax_number_length = 11; // Size of unsigned long (10) + null
3128
} // namespace
@@ -136,7 +133,7 @@ void Nokia_LCD::setBacklight(bool enabled) {
136133
}
137134

138135
bool Nokia_LCD::setCursor(uint8_t x, uint8_t y) {
139-
if (x >= kDisplay_max_width || y >= kTotal_rows) {
136+
if (x >= nokia_lcd::kDisplay_max_width || y >= kTotal_rows) {
140137
return false;
141138
}
142139

@@ -227,16 +224,19 @@ bool Nokia_LCD::printCharacter(char character) {
227224
}
228225

229226
bool Nokia_LCD::draw(const unsigned char bitmap[],
230-
const unsigned int bitmap_size,
231-
const bool read_from_progmem) {
227+
const unsigned int bitmap_size,
228+
const bool read_from_progmem,
229+
const unsigned int bitmap_width) {
232230
bool out_of_bounds = false;
231+
const unsigned int initialX = mX_cursor;
233232
for (unsigned int i = 0; i < bitmap_size; i++) {
234233
unsigned char pixel =
235234
read_from_progmem ? pgm_read_byte_near(bitmap + i) : bitmap[i];
236235
if (mInverted) {
237236
pixel = ~pixel;
238237
}
239-
out_of_bounds = sendData(pixel) || out_of_bounds;
238+
sendData(pixel, false);
239+
out_of_bounds = updateCursorPosition(initialX, bitmap_width) || out_of_bounds;
240240
}
241241

242242
return out_of_bounds;
@@ -246,9 +246,32 @@ void Nokia_LCD::sendCommand(const unsigned char command) {
246246
send(command, false);
247247
}
248248

249-
bool Nokia_LCD::sendData(const unsigned char data) { return send(data, true); }
249+
bool Nokia_LCD::sendData(const unsigned char data) { return sendData(data, true); }
250+
251+
bool Nokia_LCD::sendData(const unsigned char data, const bool update_cursor) { return send(data, true, update_cursor); }
252+
253+
bool Nokia_LCD::updateCursorPosition(const unsigned int x_start_position, const unsigned int x_end_position) {
254+
bool out_of_bounds = false;
255+
256+
mX_cursor = (mX_cursor + 1) % (x_start_position + x_end_position); // Used to determine if X reached the right margin.
257+
// E.g. starts drawing on column 10, an image of 25px width,
258+
// X will reach the right margin at 35px, so we have to break line
259+
// Calculate the cursor position after the byte being sent
260+
if (mX_cursor == 0) {
261+
mX_cursor = x_start_position; // return X to the initial position
262+
// If the column just became 0, this means the row should change
263+
mY_cursor = (mY_cursor + 1) % kTotal_rows; // Row
264+
if (mY_cursor == 0) {
265+
// If we are back to row 0 again, then we just went out of bounds
266+
out_of_bounds = true;
267+
}
268+
}
250269

251-
bool Nokia_LCD::send(const unsigned char lcd_byte, const bool is_data) {
270+
setCursor(mX_cursor, mY_cursor); // updates the cursor position
271+
return out_of_bounds;
272+
}
273+
274+
bool Nokia_LCD::send(const unsigned char lcd_byte, const bool is_data, const bool update_cursor) {
252275
// Tell the LCD that we are writing either to data or a command
253276
digitalWrite(kDc_pin, is_data);
254277

@@ -269,22 +292,11 @@ bool Nokia_LCD::send(const unsigned char lcd_byte, const bool is_data) {
269292

270293
// If we just sent the command, there was no out-of-bounds error
271294
// and we don't have to calculate the new cursor position
272-
if (!is_data) {
295+
if (!is_data || !update_cursor) {
273296
return false;
274297
}
275298

276-
// Calculate the cursor position after the byte being sent
277-
mX_cursor = (mX_cursor + 1) % kTotal_columns; // Column
278-
if (mX_cursor == 0) {
279-
// If the column just became 0, this means the row should change
280-
mY_cursor = (mY_cursor + 1) % kTotal_rows; // Row
281-
if (mY_cursor == 0) {
282-
// If we are back to row 0 again, then we just went out of bounds
283-
return true;
284-
}
285-
}
286-
287-
return false;
299+
return updateCursorPosition();
288300
}
289301

290302
bool Nokia_LCD::print(int number) {

src/Nokia_LCD.h

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@
1414
#include <stdint.h>
1515
#include "LCD_Fonts.h"
1616

17+
namespace nokia_lcd {
18+
// Display constants
19+
const uint8_t kDisplay_max_width = 84;
20+
const uint8_t kDisplay_max_height = 48;
21+
}
22+
1723
class Nokia_LCD {
1824
public:
1925
/**
@@ -178,11 +184,15 @@ class Nokia_LCD {
178184
* 504 bits
179185
* @param read_from_progmem Whether the bitmap is stored in flash memory
180186
* instead of SRAM. Default read from flash.
187+
* @param bitmap_width The bitmap width.
181188
* @return True if out of bounds error | False otherwise
189+
*
182190
*/
183-
bool draw(const unsigned char bitmap[], const unsigned int bitmap_size,
184-
const bool read_from_progmem = true);
185-
191+
bool draw(const unsigned char bitmap[],
192+
const unsigned int bitmap_size,
193+
const bool read_from_progmem = true,
194+
const unsigned int bitmap_width = nokia_lcd::kDisplay_max_width);
195+
186196
/**
187197
* Sends the specified byte as a command to the display.
188198
* @param command The byte to be sent as a command.
@@ -191,8 +201,8 @@ class Nokia_LCD {
191201

192202
/**
193203
* Sends the specified byte as (presentable) data to the display.
194-
* @param data The byte to be sent as presentable data.
195-
* @return True if out of bounds error | False otherwise
204+
* @param data The byte to be sent as presentable data.
205+
* @return True if out of bounds error | False otherwise
196206
*/
197207
bool sendData(const unsigned char data);
198208

@@ -225,11 +235,33 @@ class Nokia_LCD {
225235
/**
226236
* Sends the specified byte to the LCD via software SPI as data or a
227237
* command.
228-
* @param lcd_byte The byte to be send to the LCD
229-
* @param is_data Whether the byte to be send is data (or a command)
230-
* @return True if out of bounds error | False otherwise
238+
* @param lcd_byte The byte to be send to the LCD
239+
* @param is_data Whether the byte to be send is data (or a command)
240+
* @param update_cursor If false, the cursor position will be updated by the caller
241+
* @return True if out of bounds error | False otherwise
242+
*/
243+
bool send(const unsigned char lcd_byte, const bool is_data, const bool update_cursor = true);
244+
245+
/**
246+
* Sends the specified byte as (presentable) data to the display.
247+
* @param data The byte to be sent as presentable data.
248+
* @param update_cursor If false, the cursor position will be updated by the caller
249+
* @return True if out of bounds error | False otherwise
250+
*/
251+
bool sendData(const unsigned char data, const bool update_cursor);
252+
253+
/**
254+
* Updates mX_cursor and mY_cursor position. By default it uses the whole
255+
* screen width in order to calculate row changing and out of bounds.
256+
*
257+
* @param x_start_position Left alignment position. Used for drawing
258+
* bitmaps smaller than screen width. Defaults to zero.
259+
* Defaults to zero.
260+
* @param x_end_position Position where the cursor will consider a line
261+
* breaking. When drawing a bitmap, it is the image width.
262+
* Defaults to screen width.
231263
*/
232-
bool send(const unsigned char lcd_byte, const bool is_data);
264+
bool updateCursorPosition(const unsigned int x_start_position = 0, const unsigned int x_end_position = nokia_lcd::kDisplay_max_width);
233265

234266
/**
235267
* Prints the specified character

0 commit comments

Comments
 (0)