Welcome to the Pycom forum Forum
    • \[\[global:header.categories\]\]
    • \[\[global:header.recent\]\]
    • \[\[global:header.tags\]\]
    • \[\[global:header.popular\]\]
    • Login

    Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

    I2C LCD: code inside

    Scheduled Pinned Locked Moved LoPy
    41 Posts 8 Posters 27.8k Views 8 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • R Offline
      rdixey @brotherdust
      last edited by

      @brotherdust I appreciate the straightforward answer. I'm thinking that by using SPI, I will avoid the I2C primitives issues that you encountered. And hopefully not run into other SPI related issues.
      Since I've not ever recompiled the firmware before, this will be an adventure that should keep me occupied and out of trouble for a while.

      B 1 Reply Last reply Reply Quote 0
      • B Offline
        brotherdust @rdixey
        last edited by

        @rdixey :
        Here's the code I've been using. It's meant as more of a stress test on the I2C bus and the LoPy itself (watchdog issues over time). It does the following:

        Set up I2C bus at 400,000 bps
        Initialize BME280 sensor on default I2C address
        Initialize SSD1306 display on secondary I2C address 0x3D

        While True:

        • Read sensor data
        • Blank the display buffer
        • Write some text to the buffer
        • Write the buffer to the display
        • Sleep for 1ms
        # MicroPython SSD1306 OLED driver, I2C and SPI interfaces
        
        from micropython import const
        import time
        import framebuf
        
        
        # register definitions
        SET_CONTRAST        = const(0x81)
        SET_ENTIRE_ON       = const(0xa4)
        SET_NORM_INV        = const(0xa6)
        SET_DISP            = const(0xae)
        SET_MEM_ADDR        = const(0x20)
        SET_COL_ADDR        = const(0x21)
        SET_PAGE_ADDR       = const(0x22)
        SET_DISP_START_LINE = const(0x40)
        SET_SEG_REMAP       = const(0xa0)
        SET_MUX_RATIO       = const(0xa8)
        SET_COM_OUT_DIR     = const(0xc0)
        SET_DISP_OFFSET     = const(0xd3)
        SET_COM_PIN_CFG     = const(0xda)
        SET_DISP_CLK_DIV    = const(0xd5)
        SET_PRECHARGE       = const(0xd9)
        SET_VCOM_DESEL      = const(0xdb)
        SET_CHARGE_PUMP     = const(0x8d)
        
        
        class SSD1306:
            def __init__(self, width, height, external_vcc):
                self.width = width
                self.height = height
                self.external_vcc = external_vcc
                self.pages = self.height // 8
                self.buffer = bytearray(self.pages * self.width)
                self.framebuf = framebuf.FrameBuffer1(self.buffer, self.width, self.height)
                self.poweron()
                self.init_display()
        
            def init_display(self):
                for cmd in (
                    SET_DISP | 0x00, # off
                    # address setting
                    SET_MEM_ADDR, 0x00, # horizontal
                    # resolution and layout
                    SET_DISP_START_LINE | 0x00,
                    SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0
                    SET_MUX_RATIO, self.height - 1,
                    SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0
                    SET_DISP_OFFSET, 0x00,
                    SET_COM_PIN_CFG, 0x02 if self.height == 32 else 0x12,
                    # timing and driving scheme
                    SET_DISP_CLK_DIV, 0x80,
                    SET_PRECHARGE, 0x22 if self.external_vcc else 0xf1,
                    SET_VCOM_DESEL, 0x30, # 0.83*Vcc
                    # display
                    SET_CONTRAST, 0xff, # maximum
                    SET_ENTIRE_ON, # output follows RAM contents
                    SET_NORM_INV, # not inverted
                    # charge pump
                    SET_CHARGE_PUMP, 0x10 if self.external_vcc else 0x14,
                    SET_DISP | 0x01): # on
                    self.write_cmd(cmd)
                self.fill(0)
                self.show()
        
            def poweroff(self):
                self.write_cmd(SET_DISP | 0x00)
        
            def contrast(self, contrast):
                self.write_cmd(SET_CONTRAST)
                self.write_cmd(contrast)
        
            def invert(self, invert):
                self.write_cmd(SET_NORM_INV | (invert & 1))
        
            def show(self):
                x0 = 0
                x1 = self.width - 1
                if self.width == 64:
                    # displays with width of 64 pixels are shifted by 32
                    x0 += 32
                    x1 += 32
                self.write_cmd(SET_COL_ADDR)
                self.write_cmd(x0)
                self.write_cmd(x1)
                self.write_cmd(SET_PAGE_ADDR)
                self.write_cmd(0)
                self.write_cmd(self.pages - 1)
                self.write_data(self.buffer)
        
            def fill(self, col):
                self.framebuf.fill(col)
        
            def pixel(self, x, y, col):
                self.framebuf.pixel(x, y, col)
        
            def scroll(self, dx, dy):
                self.framebuf.scroll(dx, dy)
        
            def text(self, string, x, y, col=1):
                self.framebuf.text(string, x, y, col)
        
        
        class SSD1306_I2C(SSD1306):
            def __init__(self, width, height, i2c, addr=0x3c, external_vcc=False):
                self.i2c = i2c
                self.addr = addr
                self.temp = bytearray(2)
                super().__init__(width, height, external_vcc)
        
            def write_cmd(self, cmd):
                self.temp[0] = 0x80 # Co=1, D/C#=0
                self.temp[1] = cmd
                self.i2c.writeto(self.addr, self.temp)
        
            def write_data(self, buf):
                self.temp[0] = self.addr << 1
                self.temp[1] = 0x40 # Co=0, D/C#=1
                self.i2c.start()
                self.i2c.write(self.temp)
                self.i2c.write(buf)
                self.i2c.stop()
        
            def poweron(self):
                pass
        
        
        class SSD1306_SPI(SSD1306):
            def __init__(self, width, height, spi, dc, res, cs, external_vcc=False):
                self.rate = 10 * 1024 * 1024
                dc.init(dc.OUT, value=0)
                res.init(res.OUT, value=0)
                cs.init(cs.OUT, value=1)
                self.spi = spi
                self.dc = dc
                self.res = res
                self.cs = cs
                super().__init__(width, height, external_vcc)
        
            def write_cmd(self, cmd):
                self.spi.init(baudrate=self.rate, polarity=0, phase=0)
                self.cs.high()
                self.dc.low()
                self.cs.low()
                self.spi.write(bytearray([cmd]))
                self.cs.high()
        
            def write_data(self, buf):
                self.spi.init(baudrate=self.rate, polarity=0, phase=0)
                self.cs.high()
                self.dc.high()
                self.cs.low()
                self.spi.write(buf)
                self.cs.high()
        
            def poweron(self):
                self.res.high()
                time.sleep_ms(1)
                self.res.low()
                time.sleep_ms(10)
                self.res.high()
        
        # Author: Paul Cunnane 2016
        #
        # This module borrows heavily from the Adafruit BME280 Python library
        # and the Adafruit GPIO/I2C library. Original copyright notices are reproduced
        # below.
        #
        # Those libraries were written for the Raspberry Pi. This modification is
        # intended for the MicroPython and WiPy boards.
        #
        #
        # Copyright (c) 2014 Adafruit Industries
        # Author: Tony DiCola
        #
        # Based on the BMP280 driver with BME280 changes provided by
        # David J Taylor, Edinburgh (www.satsignal.eu)
        #
        # Based on Adafruit_I2C.py created by Kevin Townsend.
        #
        # Permission is hereby granted, free of charge, to any person obtaining a copy
        # of this software and associated documentation files (the "Software"), to deal
        # in the Software without restriction, including without limitation the rights
        # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        # copies of the Software, and to permit persons to whom the Software is
        # furnished to do so, subject to the following conditions:
        #
        # The above copyright notice and this permission notice shall be included in
        # all copies or substantial portions of the Software.
        #
        # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
        # THE SOFTWARE.
        
        import time
        
        
        # BME280 default address.
        BME280_I2CADDR = 0x77
        
        # Operating Modes
        BME280_OSAMPLE_1 = 1
        BME280_OSAMPLE_2 = 2
        BME280_OSAMPLE_4 = 3
        BME280_OSAMPLE_8 = 4
        BME280_OSAMPLE_16 = 5
        
        # BME280 Registers
        
        BME280_REGISTER_DIG_T1 = 0x88  # Trimming parameter registers
        BME280_REGISTER_DIG_T2 = 0x8A
        BME280_REGISTER_DIG_T3 = 0x8C
        
        BME280_REGISTER_DIG_P1 = 0x8E
        BME280_REGISTER_DIG_P2 = 0x90
        BME280_REGISTER_DIG_P3 = 0x92
        BME280_REGISTER_DIG_P4 = 0x94
        BME280_REGISTER_DIG_P5 = 0x96
        BME280_REGISTER_DIG_P6 = 0x98
        BME280_REGISTER_DIG_P7 = 0x9A
        BME280_REGISTER_DIG_P8 = 0x9C
        BME280_REGISTER_DIG_P9 = 0x9E
        
        BME280_REGISTER_DIG_H1 = 0xA1
        BME280_REGISTER_DIG_H2 = 0xE1
        BME280_REGISTER_DIG_H3 = 0xE3
        BME280_REGISTER_DIG_H4 = 0xE4
        BME280_REGISTER_DIG_H5 = 0xE5
        BME280_REGISTER_DIG_H6 = 0xE6
        BME280_REGISTER_DIG_H7 = 0xE7
        
        BME280_REGISTER_CHIPID = 0xD0
        BME280_REGISTER_VERSION = 0xD1
        BME280_REGISTER_SOFTRESET = 0xE0
        
        BME280_REGISTER_CONTROL_HUM = 0xF2
        BME280_REGISTER_CONTROL = 0xF4
        BME280_REGISTER_CONFIG = 0xF5
        BME280_REGISTER_PRESSURE_DATA = 0xF7
        BME280_REGISTER_TEMP_DATA = 0xFA
        BME280_REGISTER_HUMIDITY_DATA = 0xFD
        
        
        class Device:
            """Class for communicating with an I2C device.
        
            Allows reading and writing 8-bit, 16-bit, and byte array values to
            registers on the device."""
        
            def __init__(self, address, i2c):
                """Create an instance of the I2C device at the specified address using
                the specified I2C interface object."""
                self._address = address
                self._i2c = i2c
        
            def writeRaw8(self, value):
                """Write an 8-bit value on the bus (without register)."""
                value = value & 0xFF
                self._i2c.writeto(self._address, value.to_bytes(1))
        
            def write8(self, register, value):
                """Write an 8-bit value to the specified register."""
                value = value & 0xFF
                self._i2c.writeto_mem(self._address, register, value.to_bytes(1))
        
            def write16(self, register, value):
                """Write a 16-bit value to the specified register."""
                value = value & 0xFFFF
                self.i2c.writeto_mem(self._address, register, value)
        
            def readRaw8(self):
                """Read an 8-bit value on the bus (without register)."""
                return int.from_bytes(self._i2c.readfrom(self._address, 1)) & 0xFF
        
            def readU8(self, register):
                """Read an unsigned byte from the specified register."""
                return int.from_bytes(
                    self._i2c.readfrom_mem(self._address, register, 1)) & 0xFF
        
            def readS8(self, register):
                """Read a signed byte from the specified register."""
                result = self.readU8(register)
                if result > 127:
                    result -= 256
                return result
        
            def readU16(self, register, little_endian=True):
                """Read an unsigned 16-bit value from the specified register, with the
                specified endianness (default little endian, or least significant byte
                first)."""
                result = int.from_bytes(
                    self._i2c.readfrom_mem(self._address, register, 2)) & 0xFFFF
                if not little_endian:
                    result = ((result << 8) & 0xFF00) + (result >> 8)
                return result
        
            def readS16(self, register, little_endian=True):
                """Read a signed 16-bit value from the specified register, with the
                specified endianness (default little endian, or least significant byte
                first)."""
                result = self.readU16(register, little_endian)
                if result > 32767:
                    result -= 65536
                return result
        
            def readU16LE(self, register):
                """Read an unsigned 16-bit value from the specified register, in little
                endian byte order."""
                return self.readU16(register, little_endian=True)
        
            def readU16BE(self, register):
                """Read an unsigned 16-bit value from the specified register, in big
                endian byte order."""
                return self.readU16(register, little_endian=False)
        
            def readS16LE(self, register):
                """Read a signed 16-bit value from the specified register, in little
                endian byte order."""
                return self.readS16(register, little_endian=True)
        
            def readS16BE(self, register):
                """Read a signed 16-bit value from the specified register, in big
                endian byte order."""
                return self.readS16(register, little_endian=False)
        
        
        class BME280:
            def __init__(self, mode=BME280_OSAMPLE_1, address=BME280_I2CADDR, i2c=None,
                         **kwargs):
                # Check that mode is valid.
                if mode not in [BME280_OSAMPLE_1, BME280_OSAMPLE_2, BME280_OSAMPLE_4,
                                BME280_OSAMPLE_8, BME280_OSAMPLE_16]:
                    raise ValueError(
                        'Unexpected mode value {0}. Set mode to one of '
                        'BME280_ULTRALOWPOWER, BME280_STANDARD, BME280_HIGHRES, or '
                        'BME280_ULTRAHIGHRES'.format(mode))
                self._mode = mode
                # Create I2C device.
                if i2c is None:
                    raise ValueError('An I2C object is required.')
                self._device = Device(address, i2c)
                # Load calibration values.
                self._load_calibration()
                self._device.write8(BME280_REGISTER_CONTROL, 0x3F)
                self.t_fine = 0
        
            def _load_calibration(self):
        
                self.dig_T1 = self._device.readU16LE(BME280_REGISTER_DIG_T1)
                self.dig_T2 = self._device.readS16LE(BME280_REGISTER_DIG_T2)
                self.dig_T3 = self._device.readS16LE(BME280_REGISTER_DIG_T3)
        
                self.dig_P1 = self._device.readU16LE(BME280_REGISTER_DIG_P1)
                self.dig_P2 = self._device.readS16LE(BME280_REGISTER_DIG_P2)
                self.dig_P3 = self._device.readS16LE(BME280_REGISTER_DIG_P3)
                self.dig_P4 = self._device.readS16LE(BME280_REGISTER_DIG_P4)
                self.dig_P5 = self._device.readS16LE(BME280_REGISTER_DIG_P5)
                self.dig_P6 = self._device.readS16LE(BME280_REGISTER_DIG_P6)
                self.dig_P7 = self._device.readS16LE(BME280_REGISTER_DIG_P7)
                self.dig_P8 = self._device.readS16LE(BME280_REGISTER_DIG_P8)
                self.dig_P9 = self._device.readS16LE(BME280_REGISTER_DIG_P9)
        
                self.dig_H1 = self._device.readU8(BME280_REGISTER_DIG_H1)
                self.dig_H2 = self._device.readS16LE(BME280_REGISTER_DIG_H2)
                self.dig_H3 = self._device.readU8(BME280_REGISTER_DIG_H3)
                self.dig_H6 = self._device.readS8(BME280_REGISTER_DIG_H7)
        
                h4 = self._device.readS8(BME280_REGISTER_DIG_H4)
                h4 = (h4 << 24) >> 20
                self.dig_H4 = h4 | (self._device.readU8(BME280_REGISTER_DIG_H5) & 0x0F)
        
                h5 = self._device.readS8(BME280_REGISTER_DIG_H6)
                h5 = (h5 << 24) >> 20
                self.dig_H5 = h5 | (
                    self._device.readU8(BME280_REGISTER_DIG_H5) >> 4 & 0x0F)
        
            def read_raw_temp(self):
                """Reads the raw (uncompensated) temperature from the sensor."""
                meas = self._mode
                self._device.write8(BME280_REGISTER_CONTROL_HUM, meas)
                meas = self._mode << 5 | self._mode << 2 | 1
                self._device.write8(BME280_REGISTER_CONTROL, meas)
                sleep_time = 1250 + 2300 * (1 << self._mode)
                sleep_time = sleep_time + 2300 * (1 << self._mode) + 575
                sleep_time = sleep_time + 2300 * (1 << self._mode) + 575
                time.sleep_us(sleep_time)  # Wait the required time
                msb = self._device.readU8(BME280_REGISTER_TEMP_DATA)
                lsb = self._device.readU8(BME280_REGISTER_TEMP_DATA + 1)
                xlsb = self._device.readU8(BME280_REGISTER_TEMP_DATA + 2)
                raw = ((msb << 16) | (lsb << 8) | xlsb) >> 4
                return raw
        
            def read_raw_pressure(self):
                """Reads the raw (uncompensated) pressure level from the sensor."""
                """Assumes that the temperature has already been read """
                """i.e. that enough delay has been provided"""
                msb = self._device.readU8(BME280_REGISTER_PRESSURE_DATA)
                lsb = self._device.readU8(BME280_REGISTER_PRESSURE_DATA + 1)
                xlsb = self._device.readU8(BME280_REGISTER_PRESSURE_DATA + 2)
                raw = ((msb << 16) | (lsb << 8) | xlsb) >> 4
                return raw
        
            def read_raw_humidity(self):
                """Assumes that the temperature has already been read """
                """i.e. that enough delay has been provided"""
                msb = self._device.readU8(BME280_REGISTER_HUMIDITY_DATA)
                lsb = self._device.readU8(BME280_REGISTER_HUMIDITY_DATA + 1)
                raw = (msb << 8) | lsb
                return raw
        
            def read_temperature(self):
                """Get the compensated temperature in 0.01 of a degree celsius."""
                adc = self.read_raw_temp()
                var1 = ((adc >> 3) - (self.dig_T1 << 1)) * (self.dig_T2 >> 11)
                var2 = ((
                    (((adc >> 4) - self.dig_T1) * ((adc >> 4) - self.dig_T1)) >> 12) *
                    self.dig_T3) >> 14
                self.t_fine = var1 + var2
                return (self.t_fine * 5 + 128) >> 8
        
            def read_pressure(self):
                """Gets the compensated pressure in Pascals."""
                adc = self.read_raw_pressure()
                var1 = self.t_fine - 128000
                var2 = var1 * var1 * self.dig_P6
                var2 = var2 + ((var1 * self.dig_P5) << 17)
                var2 = var2 + (self.dig_P4 << 35)
                var1 = (((var1 * var1 * self.dig_P3) >> 8) +
                        ((var1 * self.dig_P2) >> 12))
                var1 = (((1 << 47) + var1) * self.dig_P1) >> 33
                if var1 == 0:
                    return 0
                p = 1048576 - adc
                p = (((p << 31) - var2) * 3125) // var1
                var1 = (self.dig_P9 * (p >> 13) * (p >> 13)) >> 25
                var2 = (self.dig_P8 * p) >> 19
                return ((p + var1 + var2) >> 8) + (self.dig_P7 << 4)
        
            def read_humidity(self):
                adc = self.read_raw_humidity()
                # print 'Raw humidity = {0:d}'.format (adc)
                h = self.t_fine - 76800
                h = (((((adc << 14) - (self.dig_H4 << 20) - (self.dig_H5 * h)) +
                     16384) >> 15) * (((((((h * self.dig_H6) >> 10) * (((h *
                                      self.dig_H3) >> 11) + 32768)) >> 10) + 2097152) *
                                      self.dig_H2 + 8192) >> 14))
                h = h - (((((h >> 15) * (h >> 15)) >> 7) * self.dig_H1) >> 4)
                h = 0 if h < 0 else h
                h = 419430400 if h > 419430400 else h
                return h >> 12
        
            @property
            def temperature(self):
                "Return the temperature in degrees."
                t = self.read_temperature()
                ti = t // 100
                td = t - ti * 100
                return "{}.{:02d}C".format(ti, td)
        
            @property
            def pressure(self):
                "Return the temperature in hPa."
                p = self.read_pressure() // 256
                pi = p // 100
                pd = p - pi * 100
                return "{}.{:02d}hPa".format(pi, pd)
        
            @property
            def humidity(self):
                "Return the humidity in percent."
                h = self.read_humidity()
                hi = h // 1024
                hd = h * 100 // 1024 - hi * 100
                return "{}.{:02d}%".format(hi, hd)
        
        from machine import I2C
        i2c = I2C(0, I2C.MASTER, baudrate=400000)
        
        sensor = BME280(address=119, i2c=i2c)
        display = SSD1306_I2C(width=128, height=64, i2c=i2c, addr=0x3d)
        
        
        while True:
        	temperature = "T: {}".format(sensor.temperature)
        	humidity = "H: {}".format(sensor.humidity)
        	pressure = "P: {}".format(sensor.pressure)
        	display.fill(0)
        	display.text(temperature, 0, 0)
        	display.text(humidity, 0, 28)
        	display.text(pressure, 0, 56)
        	display.show()
        	time.sleep_ms(1)
        

        I left it running for a couple of days and it's proven pretty stable. One thing to note is that the SSD1306 (at least mine) requires additional initialization before it will start working. It took me a while to puzzle it out! What happens on startup is the display will show the contents of the memory buffer. If it's unpowered for more than a few seconds, it just looks like static. Setting the RESET pin to LOW clears this and makes the display ready.

        I'm curious to know why you selected SPI over I2C. I haven't had a chance to play with SPI yet because all my stuff supports I2C and it's sufficient for my purposes. What are your thoughts @rdixey ?

        R 1 Reply Last reply Reply Quote 0
        • D Offline
          DVE
          last edited by

          2 All:
          Hardware SPI support was added to the library. Now the library should support SPI/IIC displays as well.

          Sources address is the same: https://github.com/dmitryelj/LoPyI2CLCD

          R 1 Reply Last reply Reply Quote 0
          • R Offline
            rdixey @brotherdust
            last edited by

            @brotherdust Hey Brother...I appreciate you sharing your Python code and the advice on recompiling the microcode to add framebuf. Have not had a chance to try it yet since I am still trying to understand how to recompile the microcode. Once I've done that I'll let you know how this worked out for me. BTW - chose to use SPI for this display as a way to learn SPI. Could not get SPI to work on my Gumstix Overo running OMAP Linux / Yocto. Thought it might be easier to learn on the LoPy.

            1 Reply Last reply Reply Quote 0
            • R Offline
              rdixey @DVE
              last edited by

              @DVE Hey Dmitrii ...... I see your 128X64 OLED has a SPI CS Pin but when I look at your code it appears that you do not connect it to a GPIO Pin. The Adafruit ssd1306 lib sequences the OLED CS signal high to low to do write operations. How did you eliminate having to do that with your configuration? I ask because I have tried your code using your default pin config (no connection to OLED CS) but it will not turn on for me. On my OLED pcb the CS pin is high (3.3V) by default, did you pull it low all the time on your OLED pcb?

              R 1 Reply Last reply Reply Quote 0
              • R Offline
                rdixey @rdixey
                last edited by

                @rdixey Dmitri.....I went ahead and tied my 128X64 OLED CS Pin to ground, and now the code you provided is working for me as SPI Master. I'm now able to write text to the display. Nice Job :) Many Thanks!

                1 Reply Last reply Reply Quote 0
                • D Offline
                  DVE
                  last edited by

                  Cool :) I didn't connect CS pin at all, maybe ground is really better.

                  1 Reply Last reply Reply Quote 0
                  • L Offline
                    leelive
                    last edited by

                    I tried this code on the i2c 128x64 version of this oled. All the characters are missing the top and bottom pixels. They're the correct characters, but are clipped. Example: The capital 'L' in LoPy is just 3 vertical pixels, and the lower case 'o' is just 2 vertical pixels on for each side. Been messing with it all day and haven't found an obvious problem in the code. I don't have another display to try, but don't think the displays the problem. Any ideas?

                    1 Reply Last reply Reply Quote 0
                    • D Offline
                      DVE
                      last edited by DVE

                      Finaly I got 128x64 I2C screen from Ebay. No visible problems, all works nice on standard firmware.
                      alt text

                      And I don't see any cropping, btw.

                      @leelive, did you try the last version from my library?

                      J 1 Reply Last reply Reply Quote 0
                      • J Offline
                        Jiemde Pybytes Beta @DVE
                        last edited by

                        @DVE I have the same result when the WiPy2 have the right main.py, but in my case it's the transfert of the main.py by Pymakr or by FTP who don't work !

                        D 1 Reply Last reply Reply Quote 0
                        • D Offline
                          daniel @Jiemde
                          last edited by

                          @Jiemde have you tried with the latest firmware (1.5.0.b2)? We have increased the memory available which was the main reason syncing with Pymakr was not working...

                          J 1 Reply Last reply Reply Quote 0
                          • J Offline
                            Jiemde Pybytes Beta @daniel
                            last edited by

                            @daniel Yes it's with that release! but it's also the same with FTP there is modification of the original file like I explain in an other post like "bytearray" who became "dytearray" and some part of the code who are missing
                            Jiemde

                            D 1 Reply Last reply Reply Quote 0
                            • D Offline
                              daniel @Jiemde
                              last edited by

                              @Jiemde have you tried formatting the file system?

                              import os
                              os.mkfs('/flash')
                              
                              J L 2 Replies Last reply Reply Quote 0
                              • J Offline
                                Jiemde Pybytes Beta @daniel
                                last edited by Jiemde

                                @daniel Just do it, but nothing change!
                                Changed the WiPy with an other and the result is the same!

                                1 Reply Last reply Reply Quote 0
                                • L Offline
                                  livius @daniel
                                  last edited by livius

                                  @daniel
                                  if you look at my post
                                  https://forum.pycom.io/post/3254
                                  it looks same as @Jiemde problem
                                  i have also malformed files - look for line oryginal file in my post

                                  think about people first, then computers

                                  1 Reply Last reply Reply Quote 0

                                  Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                                  Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                                  With your input, this post could be even better 💗

                                  Register Login
                                  • 1
                                  • 2
                                  • 3
                                  • 2 / 3
                                  • First post
                                    Last post

                                  Pycom on Twitter

                                  Pycom