How to drive APA102 FastLED through Pa.HUB port extender?



  • Hello all together,
    I’m new with the M5 ecosystem and very inspired from this devices.

    Now I’m working on a project to control an APA102 digital LED stripe by two TOF distance sensors by Arduino. The APA102 and the two TOF sensors are connected by a PaHUB to a M5stickC Grove port. I’s no problem to read the distances from this sensors through the port extender.

    But how I can tell to the FastLED library to use the two I/O pins of the PaHUB Ch.0 to drive the LED stripe?

    Thank you very much for any hints.

    Greetings from Berlin in Germany
    Vaiolux

    My code:

    // the setup routine runs once when M5Stack starts up
    #include <M5StickC.h>
    #include <Wire.h>
    #include <FastLED.h>
    
    // Defines for VL53L0X TOF sensor
    #define VL53L0X_REG_IDENTIFICATION_MODEL_ID         0xc0
    #define VL53L0X_REG_IDENTIFICATION_REVISION_ID      0xc2
    #define VL53L0X_REG_PRE_RANGE_CONFIG_VCSEL_PERIOD   0x50
    #define VL53L0X_REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD 0x70
    #define VL53L0X_REG_SYSRANGE_START                  0x00
    #define VL53L0X_REG_RESULT_INTERRUPT_STATUS         0x13
    #define VL53L0X_REG_RESULT_RANGE_STATUS             0x14
    #define address 0x29                                         //the iic address of tof
    byte gbuf[16];
    uint16_t distance1 = 0;
    uint16_t distance2 = 0;
    
    // Defines for Pa.HUB
    #define PaHub_I2C_ADDRESS 0X77
    
    // Defines for FastLED
    // Use if you want to force the software SPI subsystem to be used for some reason (generally, you don't)
    #define FASTLED_FORCE_SOFTWARE_SPI
    // Use if you want to force non-accelerated pin access (hint: you really don't, it breaks lots of things)
    // #define FASTLED_FORCE_SOFTWARE_SPI
    // #define FASTLED_FORCE_SOFTWARE_PINS
    
    // Defines for APA102 LED strip
    #define NUM_LEDS 10    // How many leds are in the strip?
    #define DATA_PIN 32    // Data pin that led data will be written out over
    #define CLOCK_PIN 33   // Clock pin only needed for SPI based chipsets when not using hardware SPI
    CRGB leds[NUM_LEDS];   // This is an array of leds.  One item for each led in your strip.
    
    void setup() {
    
     M5.begin();          // Initialize the M5Stack object
     Wire.begin();        // join i2c bus (address optional for master)    
    
     // Uncomment one of the following lines for your leds arrangement.
     FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN, BGR>(leds, NUM_LEDS);
     //FastLED.addLeds<APA102, DATA_PIN, CLOCK_PIN, BGR, DATA_RATE_MHZ(12)>(leds, NUM_LEDS);
    
     // LCD display
     M5.Lcd.setRotation(1);
     M5.Lcd.setTextSize(2);
     M5.Lcd.setTextColor(BLACK);
    }
    
    void portselectall(uint8_t ports) {  
     Wire.beginTransmission(PaHub_I2C_ADDRESS);
     Wire.write(ports&0x3f);
     Wire.endTransmission(); 
    }
    void portselect(uint8_t i) {
     if (i > 7) return;
     Wire.beginTransmission(PaHub_I2C_ADDRESS);
     Wire.write(1 << i);
     Wire.endTransmission(); 
    }
    
    void led_strip() {
      // Move a single  led 
      for(int LedPix = 0; LedPix < NUM_LEDS; LedPix = LedPix + 1) {
     
         leds[LedPix] = CRGB::HotPink;
         FastLED.setBrightness(50);
       
         // Show the leds (only one)
         FastLED.show();
         // Wait a little bit
         delay(50);
         // Turn our current led back to black for the next loop around
         leds[LedPix] = CRGB::Black;
      }
    }
    
    void loop() {
     portselect(1);        //Hub range is 0 to 5
     delay(10);
     distance1 = tof_reed();
     portselect(2);        //Hub range is 0 to 5
     delay(10);
     distance2 = tof_reed();
        
     M5.Lcd.fillScreen(0xFF8000);
     M5.Lcd.setCursor(0, 0, 1);
     M5.Lcd.printf("D1:%d ",distance1);
     M5.Lcd.setCursor(0, 15, 1);
     M5.Lcd.printf("D2:%d ",distance2);
    
     portselect(0);        //Hub range is 0 to 5
     delay(10);  
     led_strip();
    
    }