All prices in Canadian dollars. Free shipping on orders over $150!

News

June 12, 2017

Posted in neopixel, projects, store news


Clap on 👏👏, Clap off 👏👏

The offices next to Elmwood's must be wondering what we've been up to over the last couple of days. They would have heard sudden bursts of applause, then giggling, then more applause, and so on. There is, I can now reveal, a very good reason for this odd behaviour.

We've been testing Verbal Machines' Hand Clap Sensor VM-CLAP1. While it might look a bit like a cheap “noise detector” board, VM-CLAP1 has a bunch of clever signal processing built in so that almost all background noise is filtered out. Only handclaps or finger snaps will make the sensor trigger, and will do so over a range of a few metres.

We tried it with a speaker blaring right next to the microphone, and it could still pick out our handclaps over the noise. Really short percussive sounds like sharp snare hits might confuse the VM-CLAP1, but the board makes audio control of your electronic projects much simpler.

VM-Clap1 is really easy to set up, with only three connections:

  1. GND – to your system's ground
  2. PWR – anything from 2.5 – 5.5 V, so it will work with all common micro-controller project boards, including the Raspberry Pi. It draws only 1.7 mA at 3 V, too.
  3. OUT – this is an open collector output, which means the sensor sinks current when it is triggered. To use it with an Arduino, be sure to set INPUT_PULLUP for the VM-CLAP1 pin, or use an external pull-up resistor. Output is normally HIGH but is held LOW for 40 m/s when triggered.

I've written a couple of Arduino demos to show off what the VM-CLAP1 can do. The first is a very simple “clap twice for on, clap twice for off” script that switches the built-in LED on and off. Flashing LED_BUILTIN is no big deal, but choose a different pin, add a coffee maker and a Power Switch Tail II, and you've got a clappuccino machine!

Wiring is as follows:

  • OUT → Pin 2
  • PWR → 5 V or 3.3 V
  • GND → GND

And here's the code for Arduino:

/*
    Verbal Machines VM-CLAP1 sensor test
    clap twice within ¼ second to turn Arduino LED on or off

    by  scruss - 2017-06
    for Elmwood Electronics - https://elmwood.to/

    Sensor wiring:

      OUT   → Arduino Pin 2 (use INPUT_PULLUP)
      PWR   → 5V or 3.3V
      GND   → GND
*/

#define CLAPIN  2             // pin must be interrupt-capable
#define CLAP_DELAY   250      // max gap between claps to trigger

volatile boolean clap = false;                // clap detected state
boolean led_state = false;                    // LED on/off state
unsigned long clap_time, last_clap_time = 0;  // clap time records

void setup() {
  pinMode(CLAPIN, INPUT_PULLUP);
  pinMode(LED_BUILTIN, OUTPUT);     // control built-in LED by clapping
  Serial.begin(57600);
  Serial.println("# Clap sensor test ...");
  attachInterrupt(                  // register Interrupt Service Routine (ISR):
    digitalPinToInterrupt(CLAPIN),  //   pin to watch for interrupt
    heard_clap,                     //   void function to call on interrupt
    FALLING                         //   trigger interrupt on HIGH → LOW change
  );
}

void loop() {
  digitalWrite(LED_BUILTIN, led_state);  // set LED based on clap status
  if (clap) {                       // we heard a clap from ISR
    clap = false;                   // make sure we don't trigger again too soon
    last_clap_time = clap_time;     // store old clap time
    clap_time = millis();           // note current clap time
    if (clap_time - last_clap_time < CLAP_DELAY) {  // if two claps heard in ¼ s:
      Serial.println("clap clap!");                 //   notify
      led_state = !led_state;                       //   and switch LED state
    }
    else {
      Serial.println("clap!");                      // notify of only one clap
    }
  }
}

void heard_clap() {
  clap = true;      // just set clap state in ISR
}

 The next demo is a "clapometer", where we use an Adafruit NeoPixel Stick - 8 x WS2812 5050 RGB LED as the indicator. The faster you clap, the more LEDs light up - and in different colours, too!

Wiring is as follows:

  • VM-CLAP1 Sensor OUT → Pin 2
  • VM-CLAP1 PWR → 5 V or 3.3 V
  • VM-CLAP1 GND → GND
  • NeoPixel stick DATA IN → Pin 6
  • NeoPixel stick PWR → 5 V
  • NeoPixel stick GND → GND

You'll need to install the Adafruit NeoPixel Arduino Library to use the code:

/*
    Verbal Machines VM-CLAP1 sensor test
    clapometer with neopixel output

    by  scruss - 2017-06
    for Elmwood Electronics - https://elmwood.to/

    Sensor wiring ("open collector"):

      OUT   → Arduino Pin 2 
      PWR   → 5V
      GND   → GND

    8 Neoxpixel strip on Arduino pin 6
*/

#define CLAPIN          2     // pin must be interrupt-capable
#define CLAP_INTERVAL   600  // time over which claps are counted
#define MAX_COUNT       7    // max claps to count
#define NEOPIN          6     // 8 px strip on pin 6
#define NUMPIXELS       8     // 0 ..7

// this is a colour table of pleasing(ish) HSV hues:
unsigned long hues[] = {0x7F0000, // 0 degree hue
                        0x7F5F00, // 45 deg
                        0x407F00, // 90 ...
                        0x007F40, // 135
                        0x007F7F, // 180
                        0x00407F, // 225
                        0x40007F, // 270
                        0x7F005F  // 315
                       };
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif

volatile boolean clap = false;          // clap detected state
unsigned long clap_times[MAX_COUNT];   // clap time records
int array_pos = 0;                      // index of current time record
int clap_count = 0;                     // count of claps within CLAP_INTERVAL
unsigned long current_time = 0;
int i, j = 0;
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, NEOPIN,
                           NEO_GRB + NEO_KHZ800);

void setup() {
  pinMode(CLAPIN, INPUT_PULLUP);
  Serial.begin(57600);
  Serial.println("# Clapometer ...");
  pixels.begin();
  for (i = 0; i < NUMPIXELS; i++) {
    // turn all pixels off
    pixels.setPixelColor(i, 0);
  }
  pixels.show();
  attachInterrupt(                  // register Interrupt Service Routine (ISR):
    digitalPinToInterrupt(CLAPIN),  //   pin to watch for interrupt
    heard_clap,                     //   void function to call on interrupt
    FALLING                         //   trigger interrupt on HIGH → LOW change
  );
}

void loop() {
  if (clap) {                       // we heard a clap from ISR
    clap = false;                   // make sure we don't trigger again too soon
    clap_times[array_pos] = millis();
    array_pos++;
    if (array_pos == MAX_COUNT) {
      array_pos = 0;
    }
  }
  current_time = millis();
  clap_count = 0;
  for (i = 0; i < MAX_COUNT ; i++) {
    if (current_time - clap_times[i] <= CLAP_INTERVAL) {
      clap_count++;
    }
  }
  // set neopixels to clap count in right hue

  for (i = 0; i <= clap_count ; i++) {
    pixels.setPixelColor(i, hues[i]);
  }
  if (clap_count < NUMPIXELS) {
    // blank any unused pixels
    for (i = clap_count + 1; i < NUMPIXELS ; i++) {
      pixels.setPixelColor(i, 0);
    }
  }
  pixels.show();
  Serial.print("clap count: ");
  Serial.println(clap_count);
  delay(10);
}

void heard_clap() {
  clap = true;      // just set clap state in ISR
}

Have fun with your new 👏-enhanced projects!

 

Stewart  would like to thank/blame Brent Marshall and Anna Humphrey for the idea of the "clappuccino" machine.

September 16, 2016

Posted in neopixel, projects


NeoPixel Colour Picker

The lighting in my garage was pretty poor, and since we sell lots of NeoPixels, naturally I had a strip lying around!  So I figured NeoPixel LED's would be an efficient and bright way to light the garage!

The lighting in my garage was pretty poor, and since we sell lots of NeoPixels, naturally I had a strip lying around!  So I figured NeoPixel LED's would be an efficient and bright way to light the garage!

Of course I didn't want just an on / off switch, it would be way more fun to be able to pick colours.  So, I grabbed a set of round tactile buttons, and luckily there were red, green, blue, yellow, and gray.  I decided red, green and blue would control the colour, yellow would be "white", and gray would be off.

To control everything I used a Pro Trinket 5V, which is like an Arduino Mini with more pins and USB.  I  used 5 input pins for the switches and one output pin for the NeoPixel Strip.

The buttons are wired to ground, meaning, when you press the button the switch closes and sends a ground (LOW) signal to the Trinket.  I wrote the code so it constantly loops to see what buttons are pressed.  What's nice about this is that I was able to have it see if more than one button is pressed, so you can make more than just Red, Green and Blue!

Programming the Pro Trinket is easy via a microUSB cable.  More details on programming the Pro Trinket can be found in the Adafruit Learning System.

On my first prototype I used a basic solderless breadboard with some hookup wires, but to really finish it off i used an Adafruit Perma-Proto board.  This was a good choice because i could easily mount it to the wall and wire up all the connections.  

Adafruit has a great tutorial on how to use NeoPixels, so I will not get into much detail on how they work.  The important thing to know is that they need a good amount of power if you are using a bunch of them, so I used a hefty 10 amp 5V power supply to run 150 NeoPixels.  Also pay attention to the guide's suggestions regarding capacitors and resistors to avoid damaging your NeoPixels.

You'll want to make sure you install Adafruit's NeoPixel Library and also set your Arduino IDE up for the Pro Trinket.

See below for my Arduino code.  Basically I just took the Adafruit NeoPixel strandtest code and added some logic for the buttons.  Super simple!  

 

 

#include <Adafruit_NeoPixel.h>

#define PIN 4
#define HIGH 1
#define LOW 0

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(150, PIN, NEO_GRB + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel. Avoid connecting
// on a live circuit...if you must, connect GND first.

// constants won't change. They're used here to
// set pin numbers:
const int offPin = 10; // the number of the pushbutton pin
const int whitePin = 13;
const int greenPin = 6;
const int redPin = 8;
const int bluePin = 5;

// variables will change:
int offState = 0; // variable for reading the pushbutton status
int whiteState = 0;
int greenState = 0;
int redState = 0;
int blueState = 0;
int pixelSpeed = 10;

void setup() {
strip.begin();
strip.show(); // Initialize all pixels to 'off'
pinMode(offPin, INPUT_PULLUP);
pinMode(whitePin, INPUT_PULLUP);
pinMode(greenPin, INPUT_PULLUP);
pinMode(bluePin, INPUT_PULLUP);
pinMode(redPin, INPUT_PULLUP);
pinMode(13, OUTPUT);
}

void loop() {
// Some example procedures showing how to display to the pixels:
whiteState = digitalRead(whitePin);
offState = digitalRead(offPin);
greenState = digitalRead (greenPin);
blueState = digitalRead (bluePin);
redState = digitalRead (redPin);
if (greenState == LOW | redState == LOW | blueState == LOW) {
colorWipe(strip.Color(255 * (1-redState), 255 * (1-greenState), 255 * (1-blueState)), pixelSpeed); // RGB
}
else if (whiteState == LOW) {
colorWipe(strip.Color(255, 255, 255), pixelSpeed); // WHITE
}
else if (offState == LOW) {
colorWipe(strip.Color(0, 0, 0), pixelSpeed); // WHITE
}
}

// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
for(uint16_t i=0; i<strip.numPixels(); i++) {
strip.setPixelColor(i, c);
strip.show();
delay(wait);
}
}