The photo doesn't look like it is working (maybe that's what you meant?)
The sample code you posted attempts to set the text to start at column=2, row=2
which according to their documentation is the 2nd position from the left and the 2nd
row down from the top, since they stated that their rows and columns are 1 based vs 0 based.
The text on the display in your photo does not look like it is column 2 row 2 and
then there is a "G" and two odd characters.
My guess is the "G" and those characters are from the setCursor() function
as 0x47 is a capital G, then the two "garbage" characters are the row and the column bytes which are
both the character 0x2 which is a custom character.
So the real question is why is the backpack is not properly interpreting your "Set Cursor"
One likely possibility is that you are getting out of sync with the backpack by not sending the proper
number of bytes on previous command(s).
This looks likely by your displayON() function. You are not sending the "minutes" parameter.
No telling what that does to the firmware in the backpack but
it might mean that the next byte received will be interpreted as the minutes parameter.
In you sample code that would be the 0xfe command code from the set cursor position.
Which if the photo you are showing is the non working state, that would explain
why the G and the 2 garbage bytes show up.
The 0xfe being sent for the set cursor command would be interpreted as the minutes
parameter and enable the display for 254 minutes which then changes the state
back to normal characters and the G and two 0x2 bytes then get displayed.
I'd recommend updating your displayON() function to send the minutes parameter.
If you don't want to send displayON() the value, i.e. displayON(minutes),
then send the backpack a zero byte which is supposed to leave it on forever.
I see you are using i2c address 0x28, the default address seems to be 0x80 in the documentation.
Have you changed the default i2c address?
Maybe during some of your initial testing the device ended up in some strange state.
Have you tried doing the reset procedure to put everything back to defaults?