Comments: Transparent Graphical OLED Breakout Hookup Guide

Pages

Looking for answers to technical questions?

We welcome your comments and suggestions below. However, if you are looking for solutions to technical questions please see our Technical Assistance page.

  • Hi, does anyone know if the libraries for this board work with the arduino nano every? I appear to be having several issues compiling the test scripts. After a clean install I am still getting this error :

    "Multiple libraries were found for "hyperdisplay.h" Used: C:\Program"

    If anyone has any suggestions to resolve this issue could you let me know. The issue also persists for four other libraries. Wire, SPI and the other two hyperdisplay libraries needed for this component.

    • Hello, I got the same error message for 'Example1_DisplayTest'. Board: Redboard Artemis loaded with Apollo library (bought a few days ago)

      Please advice when this problem is solved: Teachning my son programming, but I am not familiar with GitHub

    • Could you post more details in an issue on GitHub? I just tried compiling 'Example1_DisplayTest' with 'Arduino Nano' selected as my board in Arduino 1.8.10 and everything completed successfully. By the sound of it I would bet that you have some extra libraries laying around.

      • Hi, no problem I will look at putting together a better report on it for github. I have found that it compiles fine for the Uno and Nano etc. However due to the limited memory of those boards I chose to upgrade to a Nano Every which runs off the ATMega4809 AVR processor. I have read articles online about this processor being incompatable with some OLED libraries like the Adafruit ones. There was a mention of it being something to do with bit shifting or something along those lines.

        If any of this has given you any ideas let me know. I will work on getting a proper report for github now.

        • OH! I thought that was a typo and you meant 'with the arduino nano ever' haha. Okay thanks for clarifying. I'll look forward to your report on GitHub so I can better understand your setup. In the meantime I can't think of a particular reason why this library would be incompatible (it uses strictly Arduino-standard interfaces AFAIK)

  • Hi. I just purchased this OLED display. It's for a wearables project with my Raspberry PI (older generation, it has 26 GPIO pins).

    Question, if I opt for SPI, what are the required pins I need to solder? It's mentioned I have to cut out jumpers too?

    I'm a python coder, tinkering with the physical side of things is new (and exciting!) for me.

    Thanks!

    • Hey there - for SPI you will need to cut all 4 of the jumpers on the back side of the board. Once you've done that you will also need to connect all the SPI pins as labelled on the reverse side of the PCB. They are GND, 3V3, MOSI, SCLK, D/C and CS. All of them are required.

      Will you use the Arduino library as a reference for your Python code?

      By the way here's the section of the hookup guide that explains SPI connections (below I2C connections): https://learn.sparkfun.com/tutorials/transparent-graphical-oled-breakout-hookup-guide/hardware-hookup

      • LS, thanks for the speedy reply. For the display, I thought someone converted the Hyperdisplay c++ into python? If not, I guess I'll write the code from scratch.

        • Hmm as far as I know nobody has done that conversion yet. I wonder if there might be any comparable Python libraries out there. If there are then you could just use the lower-level layers of Hyperdisplay to inform the design of your own driver. Good luck!

          • One more thing, can I solder a 6 pin header instead of connecting the wires straight to the board? Thanks.

            • Yeah totally! That would make it good for use in a breadboard. Just make sure you have the right jumpers to go from the breadboard to your microcontroller :)

              • Last question. I swear. I just received my OLED. I severed the jumpers with an exacto knife. How will I know if the cut was successful? Btw, thanks for enlightening this noob.

                • My pleasure! There are a few ways, some more precise than others. One is to use a multimeter in the continuity mode and touch both sides of the jumper. There should be no tone emitted if they are indeed separate.

                  Another way you can do it is by visually inspecting -- this is easier if you cut the jumper in two places (right along the edge of either pad) and then 'flick' the remaining piece of copper out of there. Sort of like how you chop a tree with an axe... Should leave a large visible clear area.

                  Using an exacto knife or square razor blade is easiest for me. Other tools are too blunt (figuratively and literally).

                  Finally if those methods don't work there is one more way to tell. By symptoms of the board not working. Each jumper has the function explained in the schematic (PDF available on documents tab of the product page). Say, for example, that the I2C lower address bit jumper was not cut - then you could tell by seeing the device respond to I2C calls at the un-modified address. Other jumpers might have less distinct symptoms but they will at least be clues.

                  Fire away questions! We're here to help out and I love it when a cool project comes through.

  • Hello, just picked up this neat little board. I was wading through some examples of using the print functionalities of the HyperDisplay library, however I couldn't successful print any text to the display. Digging a little deeper I found that the getCharInfo() method on both the IIC and SPI classes for this board are commented out (aha!), however un-commenting produced a compile time error(dang!) indicating that the char_info_t struct had no causedNewline member. I commented out this single line and boom, no compile time errors, but I still am getting no output to my display. Does anyone have any advice on this going forward?

    • What microcontroller are you using? HyperDisplay only supports a font by default if your microcontroller has support for <avr/pgmspace.h> For example ESP32 Arduino core does not support that header file while the Teensies do... So on ESP32 Hyperdisplay will require you to implement your own font. Here's more info: https://github.com/sparkfun/SparkFun_HyperDisplay/issues/2

    • I have been trying to reproduce this problem, but I get displays straight out of the gate with each of the examples. Since this feedback section is for explicit issues in the tutorial documentation, can I recommend that you try posting a topic in our forums? You can use the link in the banner above the comment section and our technical support team can get more information and will do their best to assist you. Thank you!

  • Can somebody give some advice, how i could use the display with an Raspberry Pi 3 B+ ?

    • Well, I was just thinking about this and here's my first reaction.... On the B+ you don't have any convenient way to run C++ or Arduino code (right? I haven't really pushed the limits here). So unfortunately you won't be able to use HyperDisplay directly. IMO that leaves you with two options: 1. try reading the code for the driver to understand what I2C commands are used to set it up and draw pixels, then making that happen on the Pi with Python, or 2. Control the graphical OLED with an arduino-compatible microcontroller that runs HyperDisplay, and use a communication protocol of your own to activate the various drawing functions from the Pi. This is a pretty good option for the Transparent Graphical OLED since it is on/off only - you won't need to worry about handling colors in your protocol.

      Let us know what you end up doing, it could be a good resource for others!

      • Sorry for that late answer. Now I found some time for experimenting with this really nice display. Thx for your help !

        I ended up with the luna.oled display driver and an spi connection.

        Maybe if you are interested I can create an tutorial for the usage with a raspberry pi (3 B+).

  • I saw the JPEG to code script and was intrigued. I haven't been able to test it, and it could use a bit of polish, but here is an improved (?) version. The main addition is the ability to handle color images and to scale them; unverified. Here is the Python source: #!/usr/bin/env python3 # -- coding: utf-8 --

    """Convert a JPEG image into a format that can be used by the SparkFun HyperDisplay Transparent Graphical OLED Library.
    
    This code relies on the Pillow module. To get it try $ pip3 install Pillow
    
    Exports:
    * process_image(jpg_file_name, size): Process the JPEG file and return an intermediate format.
    * write_function_to_file(pixel_data, size, file_to_write): Write some C/C++ code to a file.
    """
    import getopt
    import sys
    
    from PIL import Image
    
    __author__ = 'Brent Wilkins'
    __version__ = '0.1.0'
    __license__ = 'Open. Not wasting time looking that up.'
    
    
    def _main(argv):
        """Convert the given input JPEG into the desired output format."""
        input_jpg, output_file, size = _parse_args(argv)
        pixel_states = process_image(input_jpg, size)
        write_function_to_file(pixel_states, size, output_file)
    
    
    def _parse_args(argv):
        """Parse the command ine arguments if any were provided.
    
        Return tuple of input JPG file name (str), output file name (str), and a tuple of hopefully ints specifiying
        the desired output size. Warn and exit if two file names and dimensions weren't provided.
        """
        input_file = None
        output_file = None
        width = None
        height = None
    
        try:
            opts, args = getopt.getopt(argv, 'hi:o:w:t:', ['ifile=', 'ofile=', 'width=', 'height='])
        except getopt.GetoptError:
            _fail(2)  # Didn't have the time to find the best exit status, so magic!
        for opt, arg in opts:
            if opt == '-h':
                _fail()
            elif opt in ('-i', '--ifile'):
                input_file = arg
            elif opt in ('-o', '--ofile'):
                output_file = arg
            elif opt in ('-w', '--width'):
                width = arg
            elif opt in ('-t', '--height'):
                height = arg
    
        if input_file and output_file and width and height:
            try:
                width = int(width)
            except ValueError as err:
                print(f'Invalid value given for width. Only interger values are valid: {err}')
                sys.exit(3)  # 3 is pure magic.
            try:
                height = int(height)
            except ValueError as err:
                print(f'Invalid value given for height. Only interger values are valid: {err}')
                sys.exit(3)  # 3 is pure magic.
            size = width, height
    
            print(f'Input file is "{input_file}"')
            print(f'Output file is "{output_file}"')
            print(f'Output dimensions are specified as {size}')
    
            return input_file, output_file, size
        else:
            _fail(2)
    
    
    def process_image(jpg_file_name, size, threshold=127):
        """Process the JPEG file and return an intermediate format.
    
        Params:
            jpg_file_name (str): Name of the image to open for processing.
            size (tuple): The (width, height) of the desired output.
            threshold (int): Pixels with luminance values greater or equal to this will be set high.
    
        Returns:
            List of pixel states. True means the pixel is on, False means it's off.
        """
        pixels = None
        with Image.open(jpg_file_name) as image:
            print(image)
            try:
                image = image.resize(size)
                print(image)
            except TypeError as err:
                print(f"Couldn't resize image: {err}")
                sys.exit(3)  # Again, 3 is pure magic.
            pixels = list(image.getdata())
            image.close()
        # Calculate luminance based on Photometric/digital ITU BT.709. This is likely overkill, but interesting.
        luma = [0.2126*pixel[0] + 0.7152*pixel[1] + 0.0722*pixel[2] for pixel in pixels]
    
        # This produces a result opposite of the script this is based on. Here bright pixels are on.
        return list(map(lambda lum: True if lum >= threshold else False, luma))
    
    
    def _fail(status=0):
        """Print usage and exit the script."""
        print('Usage: jpg_to_pixels.py -i <inputfile> -o <outputfile> -w <width in pixels> -t <height in pixels>')
        sys.exit(status)
    
    
    def write_function_to_file(pixel_data, size, file_to_write):
        """Write some C/C++ code to a file."""
        with open(file_to_write, 'w') as fp:
            # Write the 'header'.
            fp.write('void ShowLogo(void) {\n  myTOLED.clearDisplay();\n\n')
            # Write the array of values.
            width, height = size
            fp.write(f'  const int width = {width};\n  const int height = {height};\n\n')
            str_list = ['  bool states[width*height] = {']
            for idx, state in enumerate(pixel_data):
                val = 'true, ' if state else 'false, '
                if idx == width*height - 1:  # Replace comma on last entry with closing '}'.
                    val = val[:-2]
                    val += '};\n'
                elif (not idx % 8) and (idx != 0):  # Limit the length of generated lines.
                    val += '\n' + 31*' '  # Need 31 spaces for alignment.
                str_list.append(val)
            fp.write(''.join(str_list))
            # Write the loop.
            fp.write('  for ( int i = 0; i < width*height; ++i ) {\n    if (states[i]) {\n      '
                     'myTOLED.pixelSet(i%width, (int)(i/width));\n    }\n  }\n}')
    
    
    if __name__ == '__main__':
        if len(sys.argv) > 1:
            _main(sys.argv[1:])
        else:
            _fail(2)
    

    Here is the output for ./jpg_to_pixels.py -i sflogo.jpg -o out.c -w 12 -t 6 A next step might be to use bits rather than an array of bools to save space.

    void ShowLogo(void) {
      myTOLED.clearDisplay();
    
      const int width = 12;
      const int height = 6;
    
      bool states[width*height] = {true, true, true, true, true, true, true, true, true, 
                                   true, true, true, true, true, true, true, true, 
                                   true, true, false, false, true, true, true, true, 
                                   true, true, true, true, true, true, true, true, 
                                   true, true, true, false, true, false, true, false, 
                                   false, false, true, false, true, false, false, false, 
                                   false, true, false, false, false, false, true, true, 
                                   true, false, false, true, true, true, true, true, 
                                   true, true, true, true, true, true, true};
      for ( int i = 0; i < width*height; ++i ) {
        if (states[i]) {
          myTOLED.pixelSet(i%width, (int)(i/width));
        }
      }
    }
    


If you've found a bug or have other constructive feedback for our tutorial authors, please send us your feedback!