Tips and Tricks (1)

Let’s inaugurate this new section with a records breaking type of puzzler: pointers!

While testing my own, private, unique, ultimate LCD library I faced a strange problem. While the printing of strings passed under various testing conditions, the same test failed for printing a unique character! In my case, an extra character was systematically appended to the desired character…

This is how my string writing routine works:

void PlainLCD::insertString(char, int begin_end, boolean leftAligned) {
// Insert string in the line buffer
// Unprotected
	int characters = strlen(string);
	for (int i = 0; i < characters; i++) {
		int position;
		if (leftAligned) 			
			position = i + begin_end - 1;
		else
			position = i + (begin_end - characters);
		// Copy character in string buffer
		vBuffer[position] = string[i];
	}
}

Few words about this routine: The data to be displayed on LCD is buffered in a vector (global variable); the InsertString routine allows you to insert a specific string at start at any position (left alignment) or ending at any position (right alignment).

Note that it works exactly the same with the following syntax

void PlainLCD::insertString(char *string, int begin_end, boolean leftAligned)

This is because both *string and string[] are pointers to first byte of the array of characters.

The following test passes

LCD.eraseBuffer();
LCD.insertString("Hello world!", 1, true);
LCD.printBuffer(1); // Print buffer content on LCD line 1

This one fails (extra character next to the requested character)

LCD.eraseBuffer();
char letter = 65; // So as to say ‘A’
LCD.insertString(&letter, 1, true);
LCD.printBuffer(1);

And this one fails too (giving even more extra character from an obvious memory location which, in my case, contains a user defined string)

char letter[1];
letter[0] = 65;
LCD.insertString(letter, 1, true);
LCD.printBuffer(1);

But this one works!

LCD.eraseBuffer();
char letter[2];
letter[0] = 65; // So as to say ‘A’
letter[1] = '�'; // End of array
LCD.insertString(letter, 1, true);
LCD.printBuffer(1);

What is so different? Well the routine now points to a properly terminated array, thanks to the ‘�’ (null) character…

Next T&T

2 Comments

  1. weuns says:

    the function strlen() begins counting at the character pointer passed in and stops at the first null character. I suggest you develop another function to handle the single character input mode. A suggestion would look like:

    void PlainLCD::insertString(char, boolean leftAligned)

    Since the parameter lists are different, the compiler won’t have any trouble deciding which to use. The function would look a bit different in that you would be inserting the char into the buffer based on leftAligned, but that’s about it.

  2. Didier says:

    Thanks for your comment. Which makes me realize how much I gained in C programming along the last 3 years! This post looks plain trivial to me now… This should remind all advanced users that they were rookies sometime, and encourage any body to be patient and not pedantic at beginers.

    Here is the list of the public functions available from the latest PlainLCD library, funny enough, it contains exactly your suggestion!

    void ClearDisplay(void);
    void ClearLine(uint8_t line);
    void Enable(void);
    void ClearBuffer(void);
    void InitializeLCD(uint8_t pin_data_4, uint8_t pin_data_5, uint8_t pin_data_6, uint8_t pin_data_7, uint8_t pin_registerSelect, uint8_t pin_enableChip, volatile uint8_t *lcdPort);
    void InitializeLCD(uint8_t pin_data_4, uint8_t pin_data_5, uint8_t pin_data_6, uint8_t pin_data_7, uint8_t pin_registerSelect, uint8_t pin_enableChip, volatile uint8_t *lcdPort, uint8_t lines, uint8_t charPerLine);
    void InsertFloat(double value, uint8_t decimalPlaces, uint8_t anchorPosition, uint8_t alignment);
    void InsertInteger(int32_t value, uint8_t anchorPosition,uint8_t alignment);
    void InsertString(char character, uint8_t position);
    void InsertString(char *string, uint8_t anchorPosition, uint8_t alignment);
    char *FloatToString(double value, uint8_t decimalPlaces);
    char *IntegerToString(int32_t value);
    void PrintBuffer(uint8_t line);
    void PrintString(char *string, uint8_t line);
    void PrintString(char *string, uint8_t line, uint8_t alignment);
    void PrintInteger(int32_t value, uint8_t line);
    void PrintInteger(int32_t value, uint8_t line, uint8_t alignment);
    void PrintFloat(double value, uint8_t decimalPlaces, uint8_t line);
    void PrintFloat(double value, uint8_t decimalPlaces, uint8_t line, uint8_t alignment);
    void ReleaseLCD(void);

Leave a Reply

You must be logged in to post a comment.