The Raspberry Pi Thread [6]


  1. Posts : 15,062
    Windows 10 IoT
    Thread Starter
       #1641

    Also tinkered a bit with these.
    The Raspberry Pi Thread [6]-capture.png
    The top one is an Omnibus With a Display Pack, Pico, and Proto Pack board. Something to mess with when I'm board.
    The bottom one is an Adafruit Can Bus PicoBell, Pico, and Adafruit PicoBell Proto Board. I want to eventually try to use this to connect to my Cars CanBuss diagnostics port. You can't see it but The Adafruit Proto board has a Reset Button and a Run Switch. I think I'll be switching to these over what Pimoorni offers.
    Adafruit PiCowbell CAN Bus for Pico - MCP2515 CAN Controller : ID 5728 : Adafruit Industries, Unique & fun DIY electronics and kits
    Adafruit PiCowbell Proto for Pico - Reset Button & STEMMA QT : ID 5200 : Adafruit Industries, Unique & fun DIY electronics and kits
      My Computer


  2. Posts : 15,062
    Windows 10 IoT
    Thread Starter
       #1642

    This the current state of my Inventor 2040 W (Pico W Aboard) Rover project.
    The Raspberry Pi Thread [6]-capture.png

    It's a bit hard to see but there is a VL53L5CX 8x8 Time of Flight (ToF) Array Sensor Breakout mounted up front and center. The plan is to use this for collision avoidance. The rest is the motors wheels, and a speaker for Beep Beeps, lol.
      My Computer


  3. Posts : 15,062
    Windows 10 IoT
    Thread Starter
       #1643

    This is a second build based on an Inventor 2040 W. It's going to be a test station for servos and motors.
    The Raspberry Pi Thread [6]-capture.png
    It has a 1.12" Mono OLED (128x128, white/black) Breakout – I2C, and an i2c RGB Encoder Breakout attached. Needs a lot of work code wise. I have tested a single server with some basic code, but that's about it. I should get back at it as this one could be a lot of fun. Moving the servo via the Encoder and displaying the position on the OLED.
      My Computer


  4. Posts : 5,715
    insider build 10586.3 win10 pro 64
       #1644

    cool stuff ,your a busy Pi Guy
      My Computer


  5. Posts : 317
    Win 10 and 11
       #1645

    I only wish that I were that ambitious.
      My Computers


  6. Posts : 15,062
    Windows 10 IoT
    Thread Starter
       #1646

    Having some issues with the weather station mockup. Not exactly sure what's going on? It's just freezing / locking up. I have to do a reset to get back in with Thonny. I think it might be my ICP10125 pressure sensor breakout. I remarked that code out and its been running for about 30 minutes without error. Before that I was lucky to get 10 minutes. I'll let it run for another hour or so and then put the code back in for that sensor and see what happens.

    Edit: Fixed it, code issue. That's a relief, would have sucked if the sensor was bad.
    Last edited by alphanumeric; 1 Week Ago at 03:19.
      My Computer


  7. Posts : 15,062
    Windows 10 IoT
    Thread Starter
       #1647

    The Raspberry Pi Thread [6]-capture.png
    Pictures not the best, my camera blooms a bit on light sources like LED's.
    The OLED display is showing
    Battery Status
    4.08V 92%
    Something like that, I'm typing in what it's displaying now. I added a Pimoroni Lipo Amigo Pro. It can recharge a Lipo etc.
    LiPo Amigo (LiPo/LiIon Battery Charger) - LiPo Amigo Pro

    With some creative wiring and a small modification, I can tell if it's USB powered, and if the battery is charging / fully charged. And get the voltage and % left if its running on Battery. Just wish I could get bigger text on the OLED. It's one Jack gave me, and I had to hunt around for a Micro Python Library. It's i2c so just for fun I plugged it in and set it up. The BME280 and ICP10125 are soldered together on a 5 pin header. Would also be nice to rotate the text 180 so I could plug it into the i2c HUB and orientate it the other way.
    This is my current Pico main.py

    Code:
    import time, math, os
    import network
    import pimoroni_bus
    import veml6075
    import breakout_icp10125
    import ssd1306
    
    from machine import ADC, Pin, PWM
    from pimoroni_i2c import PimoroniI2C
    from breakout_ltr559 import BreakoutLTR559
    from breakout_bme280 import BreakoutBME280
    from breakout_rtc import BreakoutRTC
    from machine import RTC
    from pimoroni import Analog
    
    i2c = PimoroniI2C(sda=(4), scl=(5))
    bme = BreakoutBME280(i2c)
    ltr = BreakoutLTR559(i2c)
    uv = veml6075.VEML6075(i2c)
    connected = uv.initUV()
    icp10125 = breakout_icp10125.BreakoutICP10125(i2c)
    #RV3028 = BreakoutRTC(i2c)
    display = ssd1306.SSD1306_I2C(128, 32, i2c)
    
    rtc = BreakoutRTC(i2c)
    
    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():
        # Pico W voltage read function by darconeous on reddit: 
        # https://www.reddit.com/r/raspberrypipico/comments/xalach/comment/ipigfzu/
        conversion_factor = 3 * 3.3 / 65535
        wlan = network.WLAN(network.STA_IF)
        wlan_active = wlan.active()
    
        try:
            # Don't use the WLAN chip for a moment.
            wlan.active(False)
    
            # Make sure pin 25 is high.
            Pin(25, mode=Pin.OUT, pull=Pin.PULL_DOWN).high()
            
            # Reconfigure pin 29 as an input.
            Pin(29, Pin.IN)
            
            vsys = ADC(29)
            return vsys.read_u16() * conversion_factor
    
        finally:
            # Restore the pin state and possibly reactivate WLAN
            Pin(29, Pin.ALT, pull=Pin.PULL_DOWN, alt=7)
            wlan.active(wlan_active)
    
    power = Pin('WL_GPIO2', Pin.IN)  # reading this pin tells us whether or not USB power is connected
    charging = Pin(22, mode=Pin.IN, pull=Pin.PULL_UP) #pin29 GP22
    
    full_battery = 4.2                  # these are our reference voltages for a full/empty battery, in volts
    empty_battery = 2.8                 # the values could vary by battery size/manufacturer so you might need to adjust them
    
    
    while True:
    
        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="")            
        
        temp, press, hum = bme.read()
        reading = bme.read()
            
        
        print('Temperature {:05.2f}*C'.format(temp))       
        print('Humididty {:05.2f}%'.format(hum))
        print('Pressure {:05.2f}hPa'.format(press))
    
        t, p, status = icp10125.measure(icp10125.NORMAL)
        if status == icp10125.STATUS_OK:
            icppressure = p / 100
            print('ICP Pressure {:05.2f}mb'.format(icppressure))
            #print(p)    
    
        reading = ltr.get_reading()
        if reading is not None:
            print("Light:", reading[BreakoutLTR559.LUX],"LUX")    
              
        #light = reading[BreakoutLTR559.LUX]
                
     
        UVI, UVIA, UVIB = uv.readUV()
                    
        #print('UV {:05.1f} UVA {:05.1f} UVB {:05.1f}'.format(UVI, UVIA, UVIB))
        print('UV {:05.1f} '.format(UVI))    
        print('UVA {:05.1f}'.format(UVIA))
        print('UVB {:05.1f}'.format(UVIB))
        
        percentage = 100 * ((get_vsys() - empty_battery) / (full_battery - empty_battery))
        if percentage > 100:
            percentage = 100.00
            
        if power.value() == True:# if it's plugged into USB power...
            
            if charging.value() == 0:
                print ("Charging!")
                display.fill(0)
                display.show()      
                display.text('Charging!', 0, 0, 1)
                display.show()
            else:
                print ("USB Powered")
                display.fill(0)
                display.show()      
                display.text('USB Powered', 0, 0, 1)
                display.show()
        else:# if not, display the battery stats
            print('{:.2f}V'.format(get_vsys()))
            print('{:.0f}%'.format(percentage))
            display.fill(0)
            display.show()
            display.text('Battery Status', 0, 0, 1)
            display.text('{:.2f}V'.format(get_vsys()), 0, 10, 1)
            display.text('{:.0f}%'.format(percentage), 50, 10, 1)
            display.show()
        #print(reading)
            
            
        time.sleep(5.0)
    and this is the oled file

    Code:
    # MicroPython SSD1306 OLED driver, I2C and SPI interfaces
    
    from micropython import const
    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)
    
    # Subclassing FrameBuffer provides support for graphics primitives
    # http://docs.micropython.org/en/latest/pyboard/library/framebuf.html
    class SSD1306(framebuf.FrameBuffer):
        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)
            super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB)
            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.width > 2 * self.height 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 poweron(self):
            self.write_cmd(SET_DISP | 0x01)
    
        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)
    
    
    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)
            self.write_list = [b"\x40", None]  # Co=0, D/C#=1
            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.write_list[1] = buf
            self.i2c.writevto(self.addr, self.write_list)
    
    
    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
            import time
    
            self.res(1)
            time.sleep_ms(1)
            self.res(0)
            time.sleep_ms(10)
            self.res(1)
            super().__init__(width, height, external_vcc)
    
        def write_cmd(self, cmd):
            self.spi.init(baudrate=self.rate, polarity=0, phase=0)
            self.cs(1)
            self.dc(0)
            self.cs(0)
            self.spi.write(bytearray([cmd]))
            self.cs(1)
    
        def write_data(self, buf):
            self.spi.init(baudrate=self.rate, polarity=0, phase=0)
            self.cs(1)
            self.dc(1)
            self.cs(0)
            self.spi.write(buf)
            self.cs(1)
      My Computer


  8. Posts : 15,062
    Windows 10 IoT
    Thread Starter
       #1648

    I'm having fun with the weather station mock up. I've got it cycling through each of the sensor readings on the OLED. Basically anytime it does a print text, it also does a display text. No having to connect via IDE and watch the console output. I can take it outside on battery and check the LUX and UV.
    I'm going to order up one of these,
    1.12" Mono OLED (128x128, white/black) Breakout - I2C
    and solder on a i2c pigtail.
    JST-SH Cable (Qwiic, STEMMA QT, QW/ST) - Male to male (200mm)
    i2c via QWICC is so much easier when testing code. It's as close to plug and play as your going to get on a Pico. And I'm fine with black and white for mock up testing. Hooking up an SPI display is a lot of work when all you want is a quick and easy text display.
      My Computer


  9. Posts : 5,715
    insider build 10586.3 win10 pro 64
       #1649

    neat stuff ! swoosh, way over my head
      My Computer


  10. Posts : 15,062
    Windows 10 IoT
    Thread Starter
       #1650

    caperjack said:
    neat stuff ! swoosh, way over my head
    I was in the mood to do some coding, and it wasn't all that hard coding. Mostly clip, past, edit, wash rinse and repeat, lol. I like having some kind of visual indication said device is actually (working) doing something.
      My Computer


 

  Related Discussions
Our Sites
Site Links
About Us
Windows 10 Forums is an independent web site and has not been authorized, sponsored, or otherwise approved by Microsoft Corporation. "Windows 10" and related materials are trademarks of Microsoft Corp.

© Designer Media Ltd
All times are GMT -5. The time now is 14:38.
Find Us




Windows 10 Forums