[CentralOH] 2016-03-28 會議 Scribbles 落書/惡文?: xrandr, leap day challenge; new challenge; raspberry pi 0 sense hat; C versus Python; Unix Philosophy camera, macro seek thermal

jep200404 at columbus.rr.com jep200404 at columbus.rr.com
Tue Mar 29 17:41:33 EDT 2016


Thanks again to Pillar Technology and Chris for hosting us.
Thanks to Chris for acquiring a VGA to HDMI adapter. We will need it.
Thanks to Don and Mike for helping with the early video setup.

Pillar has completely redone how one connects to the displays.
The old way was terribly confusing.
The new way is much easier. It is mostly better.

New way:

Three HDMI input jacks. One each near a display.
HDMI input jack on concrete column seems dead
    (or do I just not know how to select it?)
Control panel in middle of north wall has:
    source buttons on left
    destination buttons on right
        (audio is a destination, speakers are somewhere far right)

    FIRST: push a source button
    SECOND: push a destination button

    HDMI audio worked.

I suspect that the display resolution reported is not of any actual
display, but of the control system between one's computer and the
actual displays. Resolution mismatches resolution reported to computers
and actual displays caused edges of video to not be displayed ala
overscanning.

pi at raspberrypi:~ $ cat xrandr
xrandr: Failed to get size of gamma for output default
Screen 0: minimum 1280 x 720, current 1280 x 720, maximum 1280 x 720
default connected 1280x720+0+0 0mm x 0mm
   1280x720       0.00*
pi at raspberrypi:~ $ cat xrandr-verbose
xrandr: Failed to get size of gamma for output default
Screen 0: minimum 1280 x 720, current 1280 x 720, maximum 1280 x 720
default connected 1280x720+0+0 (0x1d1) normal (normal) 0mm x 0mm
        Identifier: 0x1d0
        Timestamp:  6466
        Subpixel:   unknown
        Clones:
        CRTC:       0
        CRTCs:      0
        Transform:  1.000000 0.000000 0.000000
                    0.000000 1.000000 0.000000
                    0.000000 0.000000 1.000000
                   filter:
  1280x720 (0x1d1)  0.000MHz *current
        h: width  1280 start    0 end    0 total 1280 skew    0 clock   0.00KHz
        v: height  720 start    0 end    0 total  720           clock   0.00Hz
pi at raspberrypi:~ $

###############################################################################

Eric Floehr presented the entries for last month's challenge to write
Python code to figure out when the next COhPy meeting will be on a leap day.

    https://github.com/efloehr/cohpy_leapday_challenge

    There are many little good details to learn from the entries.
        calendar.MONDAY is much much better than magic number 0!!!
    There was also some spectacularly ugly code that works.

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

Eric's challenge for the next month:

    1. find the date of every past COhPy meeting that met in a given month

        --  COhPy started September 2009
        --  COhPy meets the last Monday of the month, except:
            -- No COhPy's in November
            -- December COhPy is first Monday
            -- next to last Monday in May (to avoid Memorial Day)
        --  For example, passing in March, it would return the dates of COhPy
            for 2010-2015.
        --  For example, passing in July, it would return the dates of COhPy
            for 2010-2014.

    2. Collect and present high temperatures for those dates.

    3. BONUS: Predict the high temperature for the next COhPy in
       that month. For exaple, passing in May would predict the
       high for May 2016 COhPy meeting.

    meetings are last monday, except
        no meeting in November
        first Monday in December
        next to last monday in May

    submit code by next meeting

    weatherunderground.com/weather/api/
    weatherunderground.com/weather/api/d/docs
    weatherunderground.com/weather/api/d/docs?d=data/almanac
    weatherunderground.com/weather/api/d/docs?d=data/history

###############################################################################

Ethan Dicks presented about Raspberry Pi Sense Hat,
which has example Python programs where small programs do much.

    https://www.raspberrypi.org/products/sense-hat/
    http://pythonhosted.org/sense-hat/
    https://github.com/RPi-Distro/python-sense-hat
    https://www.raspberrypi.org/documentation/hardware/sense-hat/README.md
    https://www.raspberrypi.org/documentation/hardware/sense-hat/images/Sense-HAT-V1_0.pdf

    All of the I/O devices use I²C.
    Most of them use the main I²C bus.
    Only the EEPROM uses the other I²C bus,
    which is only for board identification and configuration.
    The microcontroller for the LEDs, also uses SPI interface.
    Is that SPI used during normal use, or just for in-circuit programming?
        Does it have to be programmed after each cold boot?

###############################################################################

Jim Prior presented about C versus Python for a practical real-world use of a
Raspberry Pi. Got a Sense Hat for its Python examples of using I²C[4] bus. The
MLX90620[1] needed to use I²C in way that required ioctl[2] calls. He was not
having good experience with Python libraries for I²C, so he changed to C. Later
partially converted back to Python and compared the two. Getting data from chip
one program. Number crunching was done by a separate program. Communication
between the two programs was plain text, ala the Unix Philosophy. This eases
development, testing, and debugging.

    This is the Unix philosophy: Write programs that do one thing and do it
    well. Write programs to work together. Write programs to handle text
    streams, because that is a universal interface.[3]

Whole presentation was done from the Raspberry Pi 3, not a laptop.
It drove HDMI for big displays. Its Wifi worked fine with Pillar's Wifi.
Raspberry Pi camera worked well for showing board on big displays for everyone
to see. Held eye loupe over camera for macro shots. Crude, but worked.

Seek thermal camera for smartphone is very cool.
http://www.thermal.com/
http://www.thermal.com/products/compactxr

Because of resolution mismatch between HDMI output and actual displays,
enabled "overscan" in Raspberry Pi Configuration, which actually underscans.
That worked.

Colorized text with ANSI escape sequences to roughly indicate temperature range.
Crude, but looks better than plain text. Well received.

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

python versus c

    structs of binary data
        c: rocks
        python: sucks

    printing
        python rocks
        c is tedious

    array number crunching
        python's numpy rocks
        c is tedious

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

structs of binary data

    python:

        struct library works, but sucks
        cryptic format string:

            '<64B64b64B20B...BhhhHBB2Bh13B2BB8B'

            format string hard to read
            no names
            hard to debug
            easy to make mistakes
            hard to maintain

        will probably write a new struct library
            read C struct to figure out format and element names
                already did first part
            attributes of object? (like I already did)
            dictionary?
            named tuple?
                no, because that would not understand arrays
        https://docs.python.org/3/library/struct.html

    c:

        struct eeprom_struct {
            /* The order of columns and rows is made to match the chip datasheet.
            *  This is contrary to typical C convention. */

            // This structure requires little endian byte order.
            // It is prudent to check this with eeprom_struct_is_ok().
            // Python struct magic: little-endian standard-size no-alignment
            byte delta_ai[N_COLUMNS][N_ROWS]; /* IR pixels individual offset
                                              *  coefficients */
            s_byte bi[N_COLUMNS][N_ROWS]; /* individual Ta dependence (slope)
                                          *  of IR pixels offset */
            byte delta_alpha[N_COLUMNS][N_ROWS]; // individual sensitivity coefficients
            byte reserved_1[0x14];
            ...
            byte bi_scale;
            s_word vth0; // of absolute sensor
            s_word kt1; // of absolute sensor
            s_word kt2; // of absolute sensor
            word alpha_0;
            byte alpha_0_scale_exponent;
            byte delta_alpha_scale_exponent;
            byte emissivity[2];
            s_word ksta;
            byte melexis_reserved_3[13];
            byte configuration_bytes[sizeof(word)]; /* bad alignment!!! */
            byte oscillator_trim;
            byte chip_id[8];
        };

    c:

        struct eeprom_struct eeprom;
        ...
        read_whole_eeprom(I2C_BUS_PATH, (byte *)&eeprom);
        ...
        eeprom.delta_ai[column][row]
        eeprom.ks4

    python:

        struct.unpack(fmt, raw_eeprom)
        returns outrageous terrible monster tuple with unnamed elements:

        (0, 13, 7, 15, 3, 10, 18, 8, 22, 13, 17, 17, 16, 25, 20, 26, 15, 25, 19, 29, 29, 22, 35, 34, 16, 25, 25, 25, 21, 23, 19, 29, 31, 36, 35, 32, 27, 39, 33, 37, 28, 23, 25, 38, 19, 33, 31, 39, 31, 22, 41, 46, 36, 29, 41, 46, 16, 24, 34, 53, 11, 20, 25, 35, -64, -55, -60, -64, -64, -55, -60, -81, -60, -60, -60, -60, -60, -55, -55, -55, -47, -51, -43, -55, -47, -51, -47, -51, -60, -55, -51, -55, -55, -51, -51, -55, -55, -43, -47, -51, -55, -47, -43, -43, -60, -47, -51, -43, -51, -47, -38, -43, -55, -47, -47, -34, -51, -51, -43, -38, -60, -55, -47, -43, -68, -60, -55, -47, 94, 96, 66, 0, 127, 129, 101, 45, 159, 170, 142, 78, 179, 200, 175, 114, 203, 223, 205, 142, 209, 230, 223, 163, 211, 242, 235, 185, 201, 246, 238, 200, 199, 246, 250, 204, 188, 230, 251, 214, 171, 226, 242, 215, 157, 207, 221, 207, 129, 181, 214, 203, 104, 157, 181, 168, 73, 125, 155, 150, 33, 87, 116, 116, 0, 0, 0, 0, 0, 0, 0, 0, [truncated for email]

        # Ugly frail solution:
        def eeprom_from_hex_bytes(fmt, hex_bytes):
            # print('efhb0')
            raw_eeprom = bytes(int(i, 0x10) for i in hex_bytes)
            # print('efhb1 raw_eeprom %r', raw_eeprom)
            # print('struct %r', struct.unpack(fmt, raw_eeprom))
            i = iter(struct.unpack(fmt, raw_eeprom))

            eeprom = Namespace()
            eeprom.delta_ai = np.array(
                [[next(i) for row in range(N_ROWS)]
                for column in range(N_COLUMNS)])
            # print(eeprom.delta_ai)
            eeprom.bi = np.array(
                [[next(i) for row in range(N_ROWS)]
                for column in range(N_COLUMNS)])
            # print(eeprom.bi)
            eeprom.delta_alpha = np.array(
                [[next(i) for row in range(N_ROWS)]
                for column in range(N_COLUMNS)])
            # print(eeprom.delta_alpha)
            eeprom.reserved_1 = [next(i) for _ in range(0x14)]
            ...
            eeprom.bi_scale = next(i)
            eeprom.vth0 = next(i)
            eeprom.kt1 = next(i)
            eeprom.kt2 = next(i)
            eeprom.alpha_0 = next(i)
            eeprom.alpha_0_scale_exponent = next(i)
            eeprom.delta_alpha_scale_exponent = next(i)
            lsb = next(i)
            msb = next(i)
            eeprom.emissivity = (msb << 8) | (lsb << 0)
            eeprom.ksta = next(i)
            eeprom.melexis_reserved_3 = [next(i) for _ in range(13)]
            lsb = next(i)
            msb = next(i)
            eeprom.configuration = (msb << 8) | (lsb << 0)
            eeprom.oscillator_trim = next(i)
            eeprom.chip_id = [next(i) for _ in range(8)]
            # print('eeprom.chip_id %r' % eeprom.chip_id)
            try:
                next(i)
            except StopIteration:
                pass
            else:
                assert False, 'too much data'
            return eeprom

        eeprom = eeprom_from_hex_bytes(eeprom_struct_format, tokens[3:])

################################################################################

    printing

        c not bad, but tedious

            Debug && printf("kt2 %.14g\n", kt2);
            printing arrays requires loops

        python easy:

            %s and %r do what I want most of the time
            They worked better than I expected.

            Debug and print('kt2 %s' % kt2)
            Debug and print('t0 %s' % t0)  # prints whole array nicely

                t0 [[ 21.433938    21.45769127  22.12212847  22.06982896]
                 [ 21.71642774  21.47742728  21.81028965  22.36326052]
                 [ 21.46166744  21.46738832  21.75716622  21.80972404]
                 [ 21.78738954  21.55695391  21.63291729  22.0962512 ]
                 [ 21.5838179   21.67025737  21.60192474  22.00316293]
                 [ 21.43384675  21.33803613  21.26758049  21.73715358]
                 [ 21.45780122  21.54859802  21.28838303  21.18152489]
                 [ 21.14258288  21.29744953  21.41436173  21.23811497]
                 [ 21.33403794  21.39038393  21.05018548  21.38457984]
                 [ 21.21516439  21.23793759  21.34195015  21.48188631]
                 [ 21.01884282  21.29754758  21.54742971  21.28679332]
                 [ 20.9576762   20.89032065  21.34561205  21.09876444]
                 [ 20.3055047   21.13309269  21.38052634  21.36885682]
                 [ 20.57731035  21.07738869  21.35537015  20.8579475 ]
                 [ 20.01025302  20.76977517  21.2911712   20.61779808]
                 [ 20.35203675  20.88424896  21.44563054  21.44234485]]

################################################################################

    array number crunching

        python rocks:

            t0 = (
                vir_compensated / alpha + (ta + Zero_Celsius_in_Kelvin) ** 4
            ) ** 0.25 - Zero_Celsius_in_Kelvin

        c not bad, but tedious:

            tak = ta + Zero_Celsius_in_Kelvin;
            tak_squared = tak * tak;
            tak_to_the_4th = tak_squared * tak_squared;

            for (column=0;column<N_COLUMNS;column++) {
                for (row=0;row<N_ROWS;row++) {
                    t0[column][row] = sqrt(sqrt(
                    vir_compensated[column][row] / (alpha_comp[column][row]
                    + tak_to_the_4th)
                    ))
                    - Zero_Celsius_in_Kelvin;
                }
            }

The CPU of a heavily loaded Raspberry Pi 3 can get very hot.

    watch 'cat /sys/class/thermal/thermal_zone0/temp;echo "scale=2;`cat /sys/class/thermal/thermal_zone0/temp` * 9 / 5000 + 32" | bc'

wp: prefix means Wikipedia
To get good answers, consider following the advice in the links below.
http://catb.org/~esr/faqs/smart-questions.html
http://web.archive.org/web/20090627155454/www.greenend.org.uk/rjk/2000/06/14/quoting.html

wp:Mathematica
(by a heavy stone)
wolfram.com/raspi
Free! (For non-commercial use)

    Wolfram Language & Mathematica for Raspberry Pi is free for hobbyist use.
    View license agreement »
    Interested in deploying commercial devices with the Raspberry Pi?
    Please contact us.

Ethan recommended checking out pygame for colorizing GUI. Thanks Ethan.

[1] MLX90620 http://www1.futureelectronics.com/doc/MELEXIS/MLX90620ESF-BAB-000-TU.pdf
[2] man 2 ioctl
[3] wp:Unix_philosophy#Doug_McIlroy_on_Unix_programming
[4] wp:I²C

hack by wp:deadmau5


More information about the CentralOH mailing list