Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 6 of 6

Thread: Teensy 3.2 + PropShield + WS2811 LED Issue

  1. #1
    Junior Member
    Join Date
    Jun 2018
    Posts
    4

    Teensy 3.2 + PropShield + WS2811 LED Issue

    Hello all, I have connected WS2811 LED (60 pixels) to the teensy 3.2 board using level shifter 74AHTC125 and I can run the BasicTest available in OctoWS2811 library without any problems.

    Now I want to make the LEDs interactive using the prop shield and seems I have run into an issue. I've mounted the teensy on the prop shield and used four pins on the prop shield to communicate with the LED: 5v, GND, CLK and Data. I ignored the clock pin (because WS2811 has no relevant pin) and connected the data pin to the level shifter (the same configuration as I used earlier to connect the teensy board to the LED). I wrote a basic code to couple the movement to the light. For unknown reasons the LED does not light up. I checked the data pin value on the prop shield and it produces zero.

    By accident I touched the bottom right corner (in the set up you see in the photo attached) of the Teensy board and it lit up the LED with a random colour but no further interaction.

    Any thoughts?


    Click image for larger version. 

Name:	20180614_122050.jpg 
Views:	18 
Size:	179.3 KB 
ID:	14011

  2. #2
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    2,785

    Cool

    When you are using the propshield to do level conversions, you need to set pin 9 high to enable the level converter, and set it low to disable the converter.

    If you aren't using flash memory or any SPI device, you can set the pin high in the setup function:

    Code:
    const int PROP_SHIELD_LED_ENABLE = 9;
    
    void setup ()
    {
        // enable the prop shield level converter
        pinMode (PROP_SHIELD_LED_ENABLE, OUTPUT);
        digitalWrite (PROP_SHIELD_LED_ENABLE, HIGH);
        // ...
    }
    If you use other SPI devices, you would need to enable/disable the level converter when you do the leds. Note, the OctoWS2811 library is not really appropriate for using the prop shield as it uses different pins. You should use the Adafruit_Neopixel library for this.

    Code:
    const int PROP_SHIELD_LED_ENABLE = 9;
    
    void setup ()
    {
        // disable prop shield LED initially
        pinMode (PROP_SHIELD_LED_ENABLE, OUTPUT);
        digitalWrite (PROP_SHIELD_LED_ENABLE, LOW);
        // ...
    }
    
    void loop ()
    {
        // ...
        // Enable prop shield level converter
        digitalWrite (PROP_SHIELD_LED_ENABLE, HIGH);
    
        // print it
        pixels.show ();
    
        // Disable prop shield level converter
        digitalWrite (PROP_SHIELD_LED_ENABLE, LOW);
    }
    If you use an advanced library like FastLed that does DMA, you may need to wait until the DMA is finished before turning off the voltage shifter. If you use any other SPI device, you may/may not need to use SPI transactions to signal that you are using the SPI bus for doing the LEDs.

    If you are using WS2812Serial which does DMA, in addition to the DMA stuff, you would need to attach the serial output pin (typically 1, 8, or 10) to pin 11 to allow the use of the serial pin, but directing it to the prop shield.

    <edit>
    Here is some simple code that I wrote to play music from the flash memory on the prop shield and light up a 16 LED neopixel ring:

    Code:
    // Converted from the WavFilePlay from the Teensy release:
    // hardware/teensy/avr/libraries/Audio/examples/WavFilePlayer/WavFilePlayer.ino
    //
    // Simple RAW file player example for the prop shield to use the Analog DAC
    // and prop shield amplifier to play mono sounds.
    //         http://www.pjrc.com/teensy/gui/?info=AudioOutputAnalog
    //
    // On the prop shield, pin 6 selects the serial flash memory controller,
    // and pin 5 enables the amplifier.
    //
    // This example code is in the public domain.
    // After the sound plays do a round of neopixels
    
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    #include <Adafruit_NeoPixel.h>
    
    // GUItool: begin automatically generated code
    AudioPlaySerialflashRaw  playFlashRaw1;  //xy=149,388
    AudioMixer4              mixer1;         //xy=445,386
    AudioOutputAnalog        dac1;           //xy=591,379
    AudioConnection          patchCord1(playFlashRaw1, 0, mixer1, 0);
    AudioConnection          patchCord2(mixer1, dac1);
    // GUItool: end automatically generated code
    
    #define PROP_AMP_ENABLE		 5
    #define FLASH_CHIP_SELECT	 6
    #define PIN_PROP_LED_ENABLE	 7			// Pin to enable 11/13 as outputs
    #define PIN_PROP_LED_DATA	11			// Pin #1 for 5v LEDs (data for APA102/dotstar leds) 
    #define PIN_PROP_LED_CLK	13			// Pin #2 for 5v LEDs (clock for APA102/dotstar leds) 
    
    #define PIN_NEOPIXEL		PIN_PROP_LED_DATA	// PIN_PROP_LED_DATA to use prop shield level shifter
    
    Adafruit_NeoPixel strip = Adafruit_NeoPixel(16, PIN_PROP_LED_DATA, NEO_GRB + NEO_KHZ800);
    int cur_color;
    SPISettings neopixel_spi (20000000, MSBFIRST, SPI_MODE0);
    
    void do_ring ()
    {
      int red, green, blue;
    
      red   = (cur_color & 0x4) ? 5 : 0;
      green = (cur_color & 0x2) ? 5 : 0;
      blue  = (cur_color & 0x1) ? 5 : 0;
      Serial.printf ("Neopixel, red = %d, green = %d, blue = %d\n", red, green, blue);
    
      // Enable LEDs and put the pin back into digital mode
      if (PIN_NEOPIXEL == PIN_PROP_LED_DATA || PIN_NEOPIXEL == PIN_PROP_LED_CLK)
        {
          SPI.beginTransaction (neopixel_spi);
          digitalWrite (PIN_PROP_LED_ENABLE, HIGH);
          pinMode (PIN_NEOPIXEL, OUTPUT);
        }
    
      // Set the ring to a given color
      for (int i = 0; i < 16; i++)
        strip.setPixelColor (i, red, green, blue);
    
      strip.show ();
      Serial.println ("Sleep 5 seconds");
      delay (5000);
      Serial.println ("Done sleep");
    
      cur_color = (cur_color == 0x4) ? 0x1 : cur_color<<1;
    
      // Return pins 11/13 to be in SPI mode and disable the LEDs
      if (PIN_NEOPIXEL == PIN_PROP_LED_DATA || PIN_NEOPIXEL == PIN_PROP_LED_CLK)
        {
          volatile uint32_t *reg;
          SPI.endTransaction ();
          digitalWrite (PIN_PROP_LED_ENABLE, LOW);
    
          reg = portConfigRegister (PIN_NEOPIXEL);
          *reg = PORT_PCR_MUX (2);
        }
    }
    
    void setup()
    {
      Serial.begin (9600);
    
      // wait up to 3 seconds for the Serial device to become available
      long unsigned debug_start = millis ();
      while (!Serial && ((millis () - debug_start) <= 3000))
        ;
    
      Serial.println ("Start");
    
      // Enable the neopixels
      if (PIN_NEOPIXEL == PIN_PROP_LED_DATA || PIN_NEOPIXEL == PIN_PROP_LED_CLK)
        {
          SPI.begin ();
          pinMode (PIN_PROP_LED_ENABLE, OUTPUT);
          digitalWrite (PIN_PROP_LED_ENABLE, LOW);
        }
    
      strip.begin ();
      cur_color = 0x1;
    
          // Enable the amplifier on the prop shield
      pinMode (PROP_AMP_ENABLE, OUTPUT);
      digitalWrite (PROP_AMP_ENABLE, HIGH);
    
      // Do all color variations of the ring before enabling the sound
      for (int i = 0; i < 3; i++)
        do_ring ();
    
      // Audio connections require memory to work.  For more
      // detailed information, see the MemoryAndCpuUsage example
      AudioMemory (8);
    
      // Set initial volume
      mixer1.gain (0, 0.5f);
    
      // Start SerialFlash
      if (!SerialFlash.begin(FLASH_CHIP_SELECT)) {
        while (1)
          {
    	Serial.println ("Cannot access SPI Flash chip");
    	delay (1000);
          }
      }
    }
    
    void playFile(const char *filename)
    {
      // Start playing the file.  This sketch continues to
      // run while the file plays.
      playFlashRaw1.play(filename);
    
      // A brief delay for the library read RAW info
      delay(5);
    
      // Simply wait for the file to finish playing.
      while (playFlashRaw1.isPlaying()) {
        ;
      }
    
      Serial.println ("Done playing");
    }
    
    
    void loop()
    {
      char filename[12];
      uint32_t filesize;
    
      SerialFlash.opendir ();
      while (SerialFlash.readdir (filename, sizeof (filename), filesize))
        {
          const char *dot	= strchr (filename, '.');
          bool raw_p	= (dot && strcmp (dot, ".RAW") == 0);
    
          Serial.printf ("%s %-12s%7lu bytes\n",
    		     (raw_p ? "Playing " : "Skipping"),
    		     filename,
    		     (unsigned long) filesize);
    
          if (raw_p)
    	{
    	  playFile (filename);
    	  do_ring ();
    	}
        }
    
      Serial.println ("Sleep for 30 seconds");
      delay (30000);
    }

  3. #3
    Junior Member
    Join Date
    Jun 2018
    Posts
    4
    Thank you for the quick reply!

    Quote Originally Posted by MichaelMeissner View Post
    When you are using the propshield to do level conversions, you need to set pin 9 high to enable the level converter, and set it low to disable the converter.
    I am using the 74AHTC125 to do the level conversion. Is this OK?

    I am not using any flash memory or SPI devices either.


    QUOTE=MichaelMeissner;181560] If you use other SPI devices, you would need to enable/disable the level converter when you do the leds. Note, the OctoWS2811 library is not really appropriate for using the prop shield as it uses different pins. You should use the Adafruit_Neopixel library for this. [/QUOTE]

    Thank you for pointing this out. For some reasons Adafruit_Neopixel library does not work with the WS2811 LED. I have not found out where the problem is.

    It is also a real pain to connect WS2811 LED strip to the teensy or the propshield. The propshield and teensy are connected to each other through male and female header connectors and this does cause problems for feeding the data connector to the teensy board.

    Thank you so much for the code. If I can figure out how to use the Adafruit_Neopixel library, I can eventually use your code.

  4. #4
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    2,785
    If you are using the 74AHTC125 to do the conversion, you don't need the prop shield. The prop shield just combines several parts into one simple shield (i.e. the prop shield has a mono amplifier, 2 voltage level converters, some flash memory, and the regular version has motion sensors). So like it name says, it is useful for things like making a light saber in a small compact package.

    If you aren't using the prop shield to do the voltage level conversion, you don't need to worry about the SPI stuff. I have adapted code that writes two eyes to two separate 128x128 displays, and I added the neopixel/prop shield to the mix, and I had to dig down into the various SPI issues so that both displays and the neopixel could use pins 11 and 13.

  5. #5
    Junior Member
    Join Date
    Jun 2018
    Posts
    4
    Quote Originally Posted by MichaelMeissner View Post

    If you aren't using the prop shield to do the voltage level conversion, you don't need to worry about the SPI stuff. I have adapted code that writes two eyes to two separate 128x128 displays, and I added the neopixel/prop shield to the mix, and I had to dig down into the various SPI issues so that both displays and the neopixel could use pins 11 and 13.

    I like to use the prop shield to create interactive light i.e. change the brightness or move a series of lights from left to right and vice versa. I thought if I have 74AHTC125 at least I can do the level conversation separate from the prop shield and then use the motion sensors to control LEDs.

  6. #6
    Junior Member
    Join Date
    Jun 2018
    Posts
    4
    Connecting WS2811 LED strip to teensy + prop shield has been successful. I do not recommend this connection for multiple LED strips though. I de-soldered a wire to the data pin on Teensy 3.2 (picture attached) and fed it to 74AHTC125 to shift the voltage level to 5v which is enough for this LED strip. I placed teensy 3.2 on prop shield using male and female connectors. I used GND and +5V LED pins on the prop shield to connect to the LED strip.

    Click image for larger version. 

Name:	20180616_153415.jpg 
Views:	9 
Size:	181.2 KB 
ID:	14017Click image for larger version. 

Name:	20180616_153612.jpg 
Views:	10 
Size:	107.5 KB 
ID:	14018Click image for larger version. 

Name:	20180616_153432_001.jpg 
Views:	7 
Size:	97.4 KB 
ID:	14019

    Code to do some interaction with the LED is :

    Code:
    #include <NXPMotionSense.h>
    #include <Wire.h>
    #include "FastLED.h"
    FASTLED_USING_NAMESPACE
    
    NXPMotionSense imu;
    NXPSensorFusion filter;
    
    #define DATA_PIN      2
    
    #define LED_TYPE      WS2811
    #define COLOR_ORDER   BGR
    #define NUM_LEDS      60
    
    CRGB leds[NUM_LEDS];
    #define BRIGHTNESS    255
    #define FRAMES_PER_SECOND  200
    #define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
    uint8_t gHue = 20; // rotating "base color" used by many of the patterns
    uint8_t gSat = 255;
    uint8_t pos = 72;
    
    void setup() {
      imu.begin();
      filter.begin(100);
    
      FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);
    
      // set master brightness control
      FastLED.setBrightness(BRIGHTNESS);
    }
    
    void loop() {
      float ax, ay, az;
      float gx, gy, gz;
      float mx, my, mz;
     
      if (imu.available()) {
        // Read the motion sensors
        imu.readMotionSensor(ax, ay, az, gx, gy, gz, mx, my, mz);
    
        // Update the SensorFusion filter
        filter.update(gx, gy, gz, ax, ay, az, mx, my, mz);
    
       gHue = abs(2*filter.getYaw()*255/360);
       gSat = 255-abs(filter.getRoll()*255/360);
       pos = abs((filter.getPitch() * NUM_LEDS / 180) - (NUM_LEDS/2)); 
       fadeToBlackBy( leds, NUM_LEDS, 8);
       leds[pos] += CHSV( gHue, gSat, 255);
       
       FastLED.show();
      }
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •