0

I am trying to link WS2812 with the HC-SR04 sensor. My aim is to change the color of the leds depending on the distance the sensor measures. I am using the Adafruit Neopixel library for controlling the leds. My problem is as soon as a function linked to the Adafruit library is used in the while loop the readings get very slow. Is there a way to speed the code process time up?

My code:

import RPi.GPIO as GPIO
import time
import signal
import sys
from neopixel import *
import neopixel

LED_COUNT = 124  # Number of LED pixels.
LED_PIN = 18  # GPIO pin connected to the pixels 
LED_FREQ_HZ = 800000  
LED_DMA = 10  
LED_BRIGHTNESS = 255 
LED_INVERT = False  # True to invert the signal (when using NPN transistor 
level shift)
LED_CHANNEL = 0  # set to '1' for GPIOs 13, 19, 41, 45 or 53

GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)

# set GPIO Pins
pinTrigger = 16
pinEcho = 12

def TurnOn(strip, color):
    for i in range(strip.numPixels()):
       strip.setPixelColor(i, color)
       strip.show()
    time.sleep(.5)

def close(signal, frame):
    print("\nTurning off ultrasonic distance detection...\n")
    GPIO.cleanup()
    sys.exit(0)

signal.signal(signal.SIGINT, close)

# set GPIO input and output channels
GPIO.setup(pinTrigger, GPIO.OUT)
GPIO.setup(pinEcho, GPIO.IN)

strip = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, 
LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL)
strip.begin()


while True:
    # set Trigger to HIGH
    GPIO.output(pinTrigger, True)
    # set Trigger after 0.01ms to LOW
    time.sleep(0.00001)
    GPIO.output(pinTrigger, False)

    startTime = time.time()
    stopTime = time.time()

    # save start time
    while 0 == GPIO.input(pinEcho):
        startTime = time.time()

    # save time of arrival
    while 1 == GPIO.input(pinEcho):
        stopTime = time.time()

    # time difference between start and arrival
    TimeElapsed = stopTime - startTime
    distance = (TimeElapsed * 34300) / 2

    print ("Distance: %.1f cm" % distance)

    if distance < 8:
        TurnOn(strip, Color(127, 0, 0))
    else:
        TurnOn(strip, Color(0, 127, 0))

    time.sleep(0.02)
  • 2
    Why sleep() in TurnOn? If you removed that then it would surely run faster... – Rob Bricheno Feb 27 '19 at 14:19
  • overlooked that. of course its faster now, thanks! – Atomic94 Feb 27 '19 at 14:38
  • WS2812 LEDs require a lot of realtime processing that can slow down other CPU tasks. While it looks like you've found the real reason (I hate it when time.sleep() happens!), sometimes it's better to hand off the blinkies to a dedicated microcontroller. – scruss Feb 27 '19 at 15:14
  • @scruss thanks for the reply! even though the readings got faster it is still not as fast as without using the TurnOn function. which microcontroller would you recommend for such a task? – Atomic94 Feb 27 '19 at 16:04
  • Almost any will do. There are dedicated boards like the FadeCandy for controlling LEDs, but then the problem becomes managing the protocol for the external controller board. If you don't want to do that, maybe look at gpiozero's DistanceSensor - it handles polling for you. Also, unless it's a feature you like, TurnOn is calling strip.show() 124 times in very quick succession. strip.fill() would do the job of TurnOn in one command. – scruss Feb 27 '19 at 19:16
0

Question

Trying to link WS2812 with the HC-SR04 sensor.

Aim is to change LED color depending on sensor distance.

Using Adafruit Neopixel library for controlling the leds.

A while loop SR04 read function linked to the Adafruit library get very slow.

How to speed up?

Answer

Introduction

I read that AdaFruit NeoPixel library supports Arduino and Circuit Python. And CircuitPython library is NOT 100% compatible to Rpi python. So you might need to do some modifications to you Rpi python code to make it compatible to AdaFruit arduino/circuit library.

Now let me start from the very beginning, using the following tutorial:

Using Using Neopixels with the Raspberry Pi - Pi Hut

I am using a WS2812B 8 LED stick shown below.

neopixel stick

Pi Hut Tutorial is Good

I found Pi Hut's tutorial is very good, except that it uses AdaFruit's Ciccuit Library and need to make changes in library and code, as summarized below:

Changes to make AdaFruit Library Rpi Compatible

pip3 install --force-reinstall adafruit-blinka

sudo pip3 install rpi_ws281x

Make some changes to AdaFruit code

Comment out this line pixel_pin = board.NEOPIXEL

Remove the comment on this line pixel_pin = board.D18

Change the number of Neopixels num_pixels = 10

Pi Hut's tutorial notes on power consideration and hardware setup is also good, as summarized below:

Power Consideration

The Raspberry Pi can only power a few Neopixels.

Need to power them separately.

Don’t risk putting too many Neopixels onto a pi.

They will pull more current than it can provide

Hardware Setup

Convert jumper cable end with ring terminal

Neopixels can pull up to 60mA, 20mA if not fully bright

Separate 5V, 4A power supply strips of 60 lights

Remember to connect Rpi ground to LED power ground

Update 2019apr24hkt2016

I googled a couple of WS2812B tutorial and youTubes and found the following video the best so far. The guy is a LED expert, does not use any Arduino/AdaFruit library or code, every function by himself, and how he does sub microsecond write seems fantastic (but I have no yet understood what he says), ...

Easy Addressable LEDs with Arduino! WS2812B Tutorial - Kevin Darrah 2016mar01 296,084 views

/ to continue, ...

References

Using Using Neopixels with the Raspberry Pi

WS2812B-V4 Intelligent control LED Integrated Light Source

AdaFrui NixoPixel Tutorial - Lada Ada

AdaFruit NeoPixel Stick 8 x 5050 RGB LED with Integrated Drivers $5.95

Description

Eight tiny 5050 (5mm x 5mm) smart RGB LEDs

Use only one microcontroller pin to control as many as you can chain together

Each LED is addressable as the driver chip is inside the LED.

Each one has ~18mA constant current drive so the color will be very consistent even if the voltage varies

No external choke resistors are required

Power whole thing with 5VDC (4 - 7V works)

The LEDs are 'chainable' by connecting the output of one stick into the input of another

A single data line with a very timing-specific protocol, requires a real-time microconroller such as an AVR, Arduino, PIC, mbed, etc.

It cannot be used with a Linux-based microcomputer or interpreted microcontroller such as the netduino or Basic Stamp.

Our wonderfully-written Neopixel library for Arduino supports these pixels!

As it requires hand-tuned assembly it is only for AVR cores

Others may have ported this chip driver code so please google around.

An 8MHz or faster processor is required.

Our detailed NeoPixel Uberguide has everything you need to use NeoPixels in any shape and size. Including ready-to-go library & example code for the Arduino UNO/Duemilanove/Diecimila, Flora/Micro/Leonardo, Trinket/Gemma, Arduino Due & Arduino Mega/ADK (all versions)

Technical Details

WS2812B or SK6812-based LEDs. They are the same brightness, color and protocol.

Update 2019apr24hkt2015

Easy Addressable LEDs with Arduino! WS2812B Tutorial - Kevin Darrah 2016mar01 296,084 views

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.