ModuleNotFoundError: No module named 'bme680'

Hi,
–I’m very new to all this…–
I went through the full installation described on Pimoroni’s BME688 instructions. Although the board is an 688 I understand the installation and software are the same.

After installation I tried to run the examples:

cd /home/fer/Pimoroni/bme680/examples

then to execute the read-all.py and I get the following:

fer@raspberrypi:~/Pimoroni/bme680/examples $ python read-all.py
Traceback (most recent call last):
File “/home/fer/Pimoroni/bme680/examples/read-all.py”, line 5, in
import bme680
ModuleNotFoundError: No module named ‘bme680’

I’m not sure what it really means ‘No module named bme680’ What am I doing wrong?

The board is soldered and installed on the named pins, traced with

fer@raspberrypi:~ $ i2cdetect -y 1

returns 76 (I read somewhere the default is 77; is the problem here?

Can anyone help me find out what is the problem?

Thank you very much.

Is it connected to a Raspberry Pi?
0x76 should be the default.

Yes, it is connected.

Ok, just wanted to make sure it was connected to a Raspberry Pi and not a Pico.
What model pi and what OS version is on it?
You did this?

git clone https://github.com/pimoroni/bme680-python
cd bme680-python
./install.sh

and

source ~/.virtualenvs/pimoroni/bin/activate

Thank you alphanumeric,
the card is in a Pi 4 bu destined to a Pi Zero.
Raspbian GNU/Linux 11 (bullseye)
I’m sure I did the git clone script. I don’t think I did the source one.
I tried, and it reads
(pimoroni) fer@raspberrypi:~ $

Try running you example after you enable the virtual environment. I think you will have to run it from the terminal (command line) to get it to work.

Something happened! Although not the intended, it is a move forward. Thank you alphanumeric.

I entered this: (pimoroni) fer@raspberrypi:~/bme680-python $ /home/fer/Pimoroni/bme680/examples/read-all.py

In return I got

Traceback (most recent call last):
File “/home/fer/.virtualenvs/pimoroni/lib/python3.9/site-packages/bme680/init.py”, line 46, in init
self.chip_id = self._get_regs(constants.CHIP_ID_ADDR, 1)
File “/home/fer/.virtualenvs/pimoroni/lib/python3.9/site-packages/bme680/init.py”, line 352, in _get_regs
return self._i2c.read_byte_data(self.i2c_addr, register)
File “/home/fer/.virtualenvs/pimoroni/lib/python3.9/site-packages/smbus2/smbus2.py”, line 433, in read_byte_data
ioctl(self.fd, I2C_SMBUS, msg)
OSError: [Errno 121] Remote I/O error

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/home/fer/Pimoroni/bme680/examples/read-all.py”, line 14, in
sensor = bme680.BME680(bme680.I2C_ADDR_PRIMARY)
File “/home/fer/.virtualenvs/pimoroni/lib/python3.9/site-packages/bme680/init.py”, line 50, in init
raise RuntimeError(“Unable to identify BME680 at 0x{:02x} (IOError)”.format(self.i2c_addr))
RuntimeError: Unable to identify BME680 at 0x76 (IOError)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/home/fer/.virtualenvs/pimoroni/lib/python3.9/site-packages/bme680/init.py”, line 46, in init
self.chip_id = self._get_regs(constants.CHIP_ID_ADDR, 1)
File “/home/fer/.virtualenvs/pimoroni/lib/python3.9/site-packages/bme680/init.py”, line 352, in _get_regs
return self._i2c.read_byte_data(self.i2c_addr, register)
File “/home/fer/.virtualenvs/pimoroni/lib/python3.9/site-packages/smbus2/smbus2.py”, line 433, in read_byte_data
ioctl(self.fd, I2C_SMBUS, msg)
OSError: [Errno 121] Remote I/O error

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “/home/fer/Pimoroni/bme680/examples/read-all.py”, line 16, in
sensor = bme680.BME680(bme680.I2C_ADDR_SECONDARY)
File “/home/fer/.virtualenvs/pimoroni/lib/python3.9/site-packages/bme680/init.py”, line 50, in init
raise RuntimeError(“Unable to identify BME680 at 0x{:02x} (IOError)”.format(self.i2c_addr))
RuntimeError: Unable to identify BME680 at 0x77 (IOError)


There are a ‘RuntimeError: Unable to identify BME680 at 0x76 (IOError)’ and a RuntimeError: Unable to identify BME680 at 0x77 (IOError)’

I guess it doesn’t see the board.

I have no idea what that all means, but I know somebody that might be able to help.
@hel

Alphanumeric, thanks a million!
I neither know wht that all means but my guess was that it couldn’t detect the board.
I took the soldering iron out and re-solder. Now it seems to be working and it is printing numbers like there are no end to them.

Mybe you know:
to get stared the board I always need to activate the source (fer@raspberrypi:~/bme680-python $ source ~/.virtualenvs/pimoroni/bin/activate)

Then to start reading the board’s readings, what script is needed?
And,
Do you have any idea where can I find instructions to capture the readings and print on a screen?

Thanks again for your help

1 Like

What screen? I display my readings on the SPI LCD screens.
There are some examples here for the Enviro + LCD. I’ve adapted them for larger screens etc.
enviroplus-python/examples at main · pimoroni/enviroplus-python (github.com)

Thanks Alpha. How do you collect or retrieve the data and print on a screen (like a weather station would do)? Do you know if there are instructions somewhere I can read and follow?
An small LCD sounds a good idea, but before I need to figure out how to use the sensors and their data. Eventually I want to make a standalone unit with its own rechargeable batteries and a small solar panel that can show readings on a screen and collect data. Later on investigate if it can be trained to recognise certain smells from nature.

Right now most of my weather monitoring setups are Pico based. It’s still the same procedure, I take a reading, then display it.
This is an old thread, that setup has been upgraded a few times.
Pi Pico based Weather Station Project - Discussion / Projects - Pimoroni Buccaneers
This is the original Pi based setup I started with that morphed into the above.
My Enviro (code) based Weather Station Build - Discussion / Projects - Pimoroni Buccaneers
This one I still have, it’s sitting on my desk in front of me. At some point I want to make a new one with bigger displays.
Three display weather graphing setup - Discussion / Projects - Pimoroni Buccaneers

Some of these might help.
Projects, tutorials, reviews, and more for todays digital Makers

Thank you Alpha. I’m going to take good look. If I get stuck [or when :) ] I’ll come back.

Hi Alpha,
the two links you printed there lead to a : Error: 500 Internal Server Error :)

Not sure why they didn’t work. What I did was go to the Pimoroni Learn section.
Then I did a search for weather and Enviro. I fixed the link to take you to the learn section.

Thank you nevertheless. I did find the Enviro project. I am now researching what I need and how to connect things. I will probably get a Pimoroni display hat and figure out how to display data on it. I looked at your project. Looking at the code scares me…

1 Like

I’m self taught as far as Python and Micro Python go. I borrow a lot of my code from the Pimoroni examples. I try to start with code that works, then modify it to do what I want. I also try to save a backup file of the last working bit of code. That way when i break it, I have something to go back too that worked.

May I pick your brains again?
(Please, do say enough if you rather I begin a different post).

I purchased a I2C OLED Display Module
( 1.3-inch I2C IIC OLED Display SH1106),
a breadboard to build my test project and a bunch of cables.

I found some great instructions to install the display module (Using an I2C OLED Display Module with the Raspberry Pi - Raspberry Pi Spy)

I’m unsure if I need something else (another board or hardware interface) to display the data from the bme688 sensors on the display module. Or if I need
a software package that captures the data and send it to the display. Or where to get code examples on how to capture the sensor’s data in order for the display to show the temp, pressure and so on.
I looked at your weather station code but there are many things I don’t really know if they’re relevant to y project. Also there are many instructions about how to relay the at to a web page, but, this is just a stand alone installation.
Any suggestions where to start/look.
Many thanks.

I’ve been using Pimoroni’s 1.12" white/black i2c OLED display (128x128 pixels) on a Pico. I haven’t used one in Python on a Pi though.
This a file I’m running on a weather station build. It’s Micro Python, not Python. The Oled is just there as a quick hookup to check my sensor data.

import time, math, os
import network
import pimoroni_bus
import veml6075
import breakout_icp10125
import breakout_bh1745

from machine import ADC, Pin, PWM, RTC
from pimoroni import Analog
from pimoroni_i2c import PimoroniI2C
from breakout_ltr559 import BreakoutLTR559
from breakout_bme280 import BreakoutBME280
from breakout_rtc import BreakoutRTC

i2cbus = PimoroniI2C(4, 5)
bme = BreakoutBME280(i2cbus)
ltr = BreakoutLTR559(i2cbus)
bh1745 = breakout_bh1745.BreakoutBH1745(i2cbus)
uv = veml6075.VEML6075(i2cbus)
connected = uv.initUV()
icp10125 = breakout_icp10125.BreakoutICP10125(i2cbus)

bh1745.leds(False)

from picographics import PicoGraphics, DISPLAY_I2C_OLED_128X128
display = PicoGraphics(display=DISPLAY_I2C_OLED_128X128, bus=i2cbus)
display.clear()
display.set_font("bitmap8")
display.set_pen(15)  # White


rtc = BreakoutRTC(i2cbus)

if rtc.is_12_hour:
    rtc.set_24_hour()

start_time = time.time()
temp, press, hum = bme.read()
time.sleep(0.3)
temp, press, hum = bme.read()
time.sleep(0.3)
temp, press, hum = bme.read()
time.sleep(0.3)

if rtc.read_periodic_update_interrupt_flag():
    rtc.clear_periodic_update_interrupt_flag()

if rtc.update_time():
    rtc_date = rtc.string_date()
    rtc_time = rtc.string_time()
    
RAIN_MM_PER_TICK = 0.2794    
WIND_CM_RADIUS = 7.0
WIND_FACTOR = 0.0218

wind_direction_pin = Analog(26)
wind_speed_pin = Pin(9, Pin.IN, Pin.PULL_UP)
rain_pin = Pin(10, Pin.IN, Pin.PULL_DOWN)
last_rain_trigger = False

def wind_speed(sample_time_ms=1000):
  # get initial sensor state
  state = wind_speed_pin.value()

  # create an array for each sensor to log the times when the sensor state changed
  # then we can use those values to calculate an average tick time for each sensor
  ticks = []

  start = time.ticks_ms()
  while time.ticks_diff(time.ticks_ms(), start) <= sample_time_ms:
    now = wind_speed_pin.value()
    if now != state: # sensor output changed
      # record the time of the change and update the state
      ticks.append(time.ticks_ms())
      state = now

  # if no sensor connected then we have no readings, skip
  if len(ticks) < 2:
    return 0

  # calculate the average tick between transitions in ms
  average_tick_ms = (time.ticks_diff(ticks[-1], ticks[0])) / (len(ticks) - 1)

  if average_tick_ms == 0:
    return 0
  # work out rotation speed in hz (two ticks per rotation)
  rotation_hz = (1000 / average_tick_ms) / 2

  # calculate the wind speed in metres per second
  circumference = WIND_CM_RADIUS * 2.0 * math.pi
  wind_m_s = rotation_hz * circumference * WIND_FACTOR

  return wind_m_s

def wind_direction():
  # adc reading voltage to cardinal direction taken from our python
  # library - each array index represents a 45 degree step around
  # the compass (index 0 == 0, 1 == 45, 2 == 90, etc.)
  # we find the closest matching value in the array and use the index
  # to determine the heading
  ADC_TO_DEGREES = (0.9, 2.0, 3.0, 2.8, 2.5, 1.5, 0.3, 0.6)

  closest_index = -1
  last_index = None

  # ensure we have two readings that match in a row as otherwise if
  # you read during transition between two values it can glitch
  # fixes https://github.com/pimoroni/enviro/issues/20    
    
def get_vsys():
    conversion_factor = 3 * 3.3 / 65535
    wlan = network.WLAN(network.STA_IF)
    wlan_active = wlan.active()

    try:
        wlan.active(False)
        Pin(25, mode=Pin.OUT, pull=Pin.PULL_DOWN).high()
        Pin(29, Pin.IN)
        vsys = ADC(29)
        return vsys.read_u16() * conversion_factor

    finally:
        Pin(29, Pin.ALT, pull=Pin.PULL_DOWN, alt=7)
        wlan.active(wlan_active)

power = Pin('WL_GPIO2', Pin.IN)
charging = Pin(22, mode=Pin.IN, pull=Pin.PULL_UP)

full_battery = 4.2
empty_battery = 2.8


while True:
    display.set_pen(0)
    display.clear()
    display.set_pen(15)

    time_elapsed = time.time() - start_time
    hour = rtc.get_hours()
    minute = rtc.get_minutes()
    month = rtc.get_month()
    date = rtc.get_date()        
        
    if rtc.read_periodic_update_interrupt_flag():
        rtc.clear_periodic_update_interrupt_flag()

        if rtc.update_time():
            rtc_date = rtc.string_date()
            rtc_time = rtc.string_time()



    #print("Date: ", rtc_date, ", Time: ", rtc_time, sep="")
    
    display.text(rtc_date, 0, 0, scale=2)
    #display.text(rtc_time, 30, 18, 1)
    if hour == 0:
        display.text(f"{12}:{minute:02}:AM", 0, 18, scale=2)    
    elif 0 < hour < 10:
        display.text(f"{hour:1}:{minute:02}:AM", 0, 18, scale=2)
    elif 10 <= hour < 12:
        display.text(f"{hour:2}:{minute:02}:AM", 0, 18, scale=2)
    elif hour == 12:
        display.text(f"{hour:2}:{minute:02}:PM", 0, 18, scale=2)    
    elif hour > 12:
        hour = hour - 12
        if hour <10:
            display.text(f"{hour:1}:{minute:02}:PM", 0, 18, scale=2)
        elif 10 <= hour < 12:
            display.text(f"{hour:2}:{minute:02}:PM", 0, 18, scale =2)
        elif hour == 12:
            display.text(f"{hour:2}:{minute:02}:AM", 0, 18, scale=2)
    
    
        
    temp, press, hum = bme.read()
    reading = bme.read()
    pressmb = press / 100
   
    #print('Temperature {:05.2f}*C'.format(temp))       
    #print('Humididty {:05.2f}%'.format(hum))
    #print('Pressure {:05.2f}hPa'.format(pressmb))
        
    t, p, status = icp10125.measure(icp10125.NORMAL)
    if status == icp10125.STATUS_OK:
        icptemp = t
        icppress = p / 100
        #print('ICP Pressure {:05.2f}mb'.format(icppress))
        
        display.text("{:.0f}C".format(icptemp), 0, 36, scale=2)
        display.text("{:.0f}%".format(hum), 50, 36, scale=2)
        display.text("{:.0f}mb".format(icppress), 0, 54, scale=2)  
                         
    rgbl_raw = bh1745.rgbc_raw()
    rgbl_clamped = bh1745.rgbc_clamped()
    rgb_scaled = bh1745.rgbc_scaled()
    print("Raw: {}, {}, {}, {}".format(*rgbl_raw))
    print("Clamped: {}, {}, {}, {}".format(*rgbl_clamped))
    print("Scaled: #{:02x}{:02x}{:02x}".format(*rgb_scaled))
    '''
    display.set_pen(BLACK)
    display.clear()
    display.set_pen(WHITE)
    display.text("Raw: R, G, B, L", 0, 20, scale = 3)
    display.text("{}, {}, {}, {}".format(*rgbl_raw), 0, 50, scale = 3)
    display.text("Clamped: R, G, B, L", 0, 110, scale = 3)
    display.text("{}, {}, {}, {}".format(*rgbl_clamped), 0, 140, scale = 3)
    display.text("Scaled: {:02x} {:02x} {:02x}".format(*rgb_scaled), 0, 210, scale = 3)
    display.update()
    '''
    #display.text("Lux {:.0f}".format(reading[BreakoutLTR559.LUX]), 0, 90, scale=2) 
                 
  
    UVI, UVIA, UVIB = uv.readUV()
                
    print('UV {:05.1f} '.format(UVI))    
    print('UVA {:05.1f}'.format(UVIA))
    print('UVB {:05.1f}'.format(UVIB))
    
    display.text("UV {:.0f}".format(UVI), 0, 72, scale=2)    
        
    percentage = 100 * ((get_vsys() - empty_battery) / (full_battery - empty_battery))
    if percentage > 100:
        percentage = 100.00
        
    if power.value() == True:
        
        if charging.value() == 0:
            #print ("Charging!")
            display.text("Charging!", 0, 108, scale=2)
            
        else:
            #print ("USB Powered")
            display.text("USB Powered", 0, 108, scale=2)
                
    else:
        #print('{:.2f}V'.format(get_vsys()))
        #print('{:.0f}%'.format(percentage))
        display.text("{:.1f}V".format(get_vsys()), 0, 108, scale=2)
        display.text("{:.0f}%".format(percentage), 50, 108, scale=2)
                
        
    display.update()  
    time.sleep(1)    
1 Like