4

I try to define a new character (a capital german umlaut "Ä") on my 2004 lcd on a raspberry pi using wiringPi's lcdCharDef()

This is my code

import wiringpi2 as wiringpi

# Ä
cap_umlaut_a = [
    int('0b01010', 2),
    int('0b00100', 2),
    int('0b01010', 2),
    int('0b10001', 2),
    int('0b11111', 2),
    int('0b10001', 2),
    int('0b10001', 2),
    int('0b00000', 2)
]

print(cap_umlaut_a) # [10, 4, 10, 17, 31, 17, 17, 0]

wiringpi.lcdCharDef(lcd_handle, 0, cap_umlaut_a)

When I run this code I get the following error:

TypeError: in method 'lcdCharDef', argument 3 of type 'unsigned char [8]'

I expected these ints to be the same as unsigned chars

[edit]
In a different part of the code I use ord(char) to convert only one character to an unsigned int. Can this lead to the correct anser?

How can I cast/convert the array to a type that can be accepted?

P.S. (Note that (as far as I understand it) the python wiringPi library simply wraps the C functions of wiringPi)

[edit]
I opened an issue on github: https://github.com/WiringPi/WiringPi2-Python/issues/20

speendo
  • 13,045
  • 22
  • 71
  • 107
  • you mean something like `wiringpi.lcdCharDef(self.lcd_handle, 0, array.array('B',cap_umlaut_a))`? Sorry, that gives me the same error... – speendo Jul 29 '15 at 22:26
  • Have you tried using chr() or byte() instead of int()? Also, you will need to join them together into a string (python 2) or byte string (python 3) and then decode() them into the Unicode you want. But why not just use the Unicode \Uxxxxx definition? – Patrick Maupin Jul 29 '15 at 22:26
  • @PatrickMaupin I think the Unicode would not work, as I have to define the pixels of the new character myself (the Hitachi HD44780U LCDs are not very smart - they don't know capital umlauts themselves). Or did I get you wrong? However, `chr()` did not work and `byte()` is not a built-in type in python – speendo Jul 29 '15 at 22:34
  • chr() doesn't take a string, but it would take your actual number... – Patrick Maupin Jul 29 '15 at 22:35
  • Maybe it takes a bytestring. can you try `wiringpi.lcdCharDef(self.lcd_handle, 0, struct.pack('8B', *cap_umlaut_a))` – WorldSEnder Jul 29 '15 at 22:40
  • Thank you, @PatrickMaupin! I tried `chr(int('0b01010', 2))` (also with the other `ints`. However, I got the same error message :( – speendo Jul 29 '15 at 22:41
  • Thank you @WorldSEnder. Same error, regretfully... In a different part of the program I use `ord(char)` - for only one character. Does this maybe help? – speendo Jul 29 '15 at 22:44
  • Did you join() them into a string? `"".join(cap_umlaut_a)` – Patrick Maupin Jul 29 '15 at 22:45
  • @PatrickMaupin yes. this gives a different error: TypeError: sequence item 0: expected str instance, int found – speendo Jul 29 '15 at 22:48
  • Is it Python 2 or 3? – Patrick Maupin Jul 29 '15 at 22:50
  • @PatrickMaupin Python 3 - sorry I didn't mention that earlier... – speendo Jul 29 '15 at 22:51
  • according to [the source](http://www.gossamer-threads.com/lists/python/dev/644529) and [this](http://www.gossamer-threads.com/lists/python/dev/644529) it should work with a byte-string. – WorldSEnder Jul 29 '15 at 22:56
  • I think that error occurs when you do the conversion -- you have to join() chr(). In other words, if you define a list of integers like you did above, you should then be able to do `cap_umlaut_a = ''.join(chr(x) for x in cap_umlaut_a)` as a separate step. See if that works. – Patrick Maupin Jul 29 '15 at 22:58
  • My mistake previously -- it's bytes, not byte. Try getting your list of bytes like you do above ([int(),...]) and then try this `cap_umlaut_a = b''.join(bytes(x) for x in cap_umlaut_a)` – Patrick Maupin Jul 29 '15 at 23:02
  • Oops, the source is here: https://github.com/Gadgetoid/WiringPi2-Python/blob/7e1c18325ba7d56fe4a0a77a280e444c5e8a3c10/wiringpi_wrap.c#L5393 – WorldSEnder Jul 29 '15 at 23:03
  • so you both think I need a byte string... hmmm I tried what you suggested, @PatrickMaupin. `print(cap_umlaut_a)` now gives b'\x00\x00\x00...\x00\x00\x0' however, I still get the same TypeError... :( – speendo Jul 29 '15 at 23:14

1 Answers1

1

I did a bit of research and found the source of the relevant python binding at this github repo.

The line in question is

res3 = SWIG_ConvertPtr(obj2, &argp3,SWIGTYPE_p_unsigned_char, 0 | 0 );

as you can see, you have to pass in the python equivalent of a pointer to unsigned char. According to this thread, the equivalent is a byte-string. This means that the correct call would be

import struct
wiringpi.lcdCharDef(lcd_handle, 0, struct.pack('8B', *cap_umlaut_a))

which should be equivalent to

wiringpi.lcdCharDef(lcd_handle, 0, b'\x0A\x04\x0A\x11\x1F\x11\x11\x00')
WorldSEnder
  • 4,875
  • 2
  • 28
  • 64
  • Thank you for the answer. I really appreciate that! I just tried it. `wiringpi.lcdCharDef(self.lcd_handle, 0, b'\x0A\x04\x0A\x11\x1F\x11\x11\x0')` gives an error "ValueError: invalid \x escape" and `wiringpi.lcdCharDef(lcd_handle, 0, struct.pack('8B', *cap_umlaut_a))` gives "struct.error: pack requires exactly 8 arguments" – speendo Jul 29 '15 at 23:42
  • 1
    I fixed the first error, but I *can't* reproduce the second one (with the definitions from your question) – WorldSEnder Jul 29 '15 at 23:45
  • hm. thanks for fixing the first one - I've seen it myself now :) now I also get the TypeError here... Maybe there is something else wrong in my code. I will try to make a running minimal example tomorrow and either post it or accept your answer, if I can locate the mistake. – speendo Jul 29 '15 at 23:50
  • ... well, who needs sleep anyway. I just created the minimal example. Still get the same error. You can find it here: https://gist.github.com/anonymous/0fd82d376cd22763faf1 – speendo Jul 29 '15 at 23:58
  • @speendo, can you try with a normal string instead of a byte string? : – WorldSEnder Jul 30 '15 at 00:24
  • I just tried `wiringpi.lcdCharDef(lcd_handle, 0, 'AAAAAAAA')`. Same result. I think I'll ask the maintainer on github... – speendo Jul 30 '15 at 06:21
  • I opened an issue on github: https://github.com/WiringPi/WiringPi2-Python/issues/20 – speendo Jul 30 '15 at 09:27