What The Tech

Hand Gesture

Control your project with touchless hand gestures

Johann Wyss

Issue 32, March 2020

This article includes additional downloadable resources.
Please log in to access.

Log in

We take a look at the hand gesture sensor from Jaycar & see how effective they are.

An early notion of hand-gesture technology appeared in a Sci-Fi movie in 2002, where we saw Tom Cruise in Minority Report scroll through images onscreen by simply moving his hands in the air. More recently, we’ve seen Tony Stark in his Iron Man outfit control his head-up display with hand gestures.

The use of hand gestures became a reality in many households in 2010, thanks to the Kinect input device for the Xbox gaming console, and now we’ve seen the technology incorporated into the Google Pixel 4 for gesture control without having to touch the screen.

We can only imagine the possibilities for this technology, like giving people with reduced mobility the ability to perform complex tasks that they lack the dexterity for.

Fortunately, for us makers, we can now add gesture control to our projects thanks to affordable sensors available to the hobbyist market. To test out what is available, we grabbed the latest gesture module from Jaycar Electronics and put it through its paces.

Shopping List:

Hand Gesture Sensor available at Jaycar Electronics: www.jaycar.com.au

  • Hand Sensor Gesture Module XC3742 $19.95

WHAT IS IT?

The XC3742 module from Jaycar sells for under $20 and is fairly tiny, measuring just 15mm x 20mm. It comes with a set of headers which will need to be soldered if you’re using the sensor on a breadboard or in a PCB. If you’re wanting to mount the sensor remotely, you can just solder wires directly to it, but you will need to implement some strain relief.

Objects and gestures are detected by the onboard infrared LEDs, and processed by the integrated PAJ7620 chip, which has the ability to detect 9 different hand gestures including:

  • Left
  • Right
  • Up
  • Down
  • Forward
  • Backward
  • Clockwise
  • Counter-clockwise
  • Wave

Each one of these gestures can, in turn, be used to trigger a specific gestures. However, with a little coding voodoo, you could link series of functions with a specific function. For example, you could use a series of four movements that, if performed in the correct sequence, actuated a lock working as a sudo secret knock.

CURRENT DRAW

We measured the current of the sensor in one of our practical examples, using our Digitech QM1323 digital multimeter.

In normal operation with a 5V supply from the Arduino 5V regulator, the device consumes 6mA, however, if the sensor does not detect any movement for 3 seconds it enters a standby mode, drawing 2.5mA. If the device does not detect movement for an additional 7 seconds (10 seconds in total) the sensor enters a sleep mode and drops to 2.13mA current. In either of the two reduced power states, the sensor rapidly wakes and reacts to movement. This low to medium current requirement makes the sensor suitable for battery operated projects.

The sensor appears to have an external interrupt pin that may be able to be used to wake a microcontroller from a sleep mode. This makes the module a fantastic candidate for battery operated projects as you can also put the microcontroller to sleep, which in the case of an ATmega328P with a 16MHz external oscillator and powered via a 5V supply, can drop the current for the microcontroller from 16.5mA to less than 100μA.

GETTING IT RUNNING

Jaycar have made a datasheet and manual available on their website to get you started. The first step is to download and install the library from the Seed studio GitHub page found here: https://github.com/Seeed-Studio/Gesture_PAJ7620

The Jaycar manual has some sample code, which we copied over into the Arduino IDE and attempted to run. In our case, we were met with compiler errors in the Arduino IDE (version 1.8.10) and the code would not run or upload to the Arduino Nano we were using.

After a little investigating, we figured out that the lines:

short error = paj7620Init();
short data = 0;

must be changed to:

uint8_t error = paj7620Init();
uint8_t data = 0;

The Short datatype is a 16-bit datatype, whereas, uint8_t and or byte are both 8-bit. This must be changed in order for the code to compile. Also, the line:

break; 

had to be removed, as this code does not contain any “do”, “for” or “while” loops. Nor does it contain any switch statements. Thus, leaving this line in caused the compiler to throw up errors and refuse to upload to the Arduino.

With these code changes, we were able to upload code to the Arduino and test its functionality.

We’ll now run you through two practical experiments to demonstrate the sensor in action. We have included the parts lists and code if you want to make these for yourself.

Practical Example 1:

Serial Output

To try the sensor out for yourself, we have put together an easy to build prototype with code and made it available on our website. This example uses the Serial Monitor to show you the sensor in action.

Wire up your circuit following the Fritzing diagram or by using the following wiring instructions:

Take care to ensure that VCC and GND are correctly wired on the sensor because it doesn’t have reverse polarity protection.

Incorrect wiring may damage the sensor.

Parts Required:JaycarAltronicsCore Electronics
1 x Hand Gesture Sensor ModuleXC3742-SEN0285
1 x Arduino Nano or CompatibleXC4414Z6372CE05101
1 × 28 Pin or 40 Pin Male Header - StraightHM3211P5430FIT0084

Parts Required:

Note: A breadboard and prototyping hardware are also required. † May require alternate libraries and wiring.

THE CODE

We have made the following code available on our website for you to download. This code enables you to move your hand across the sensor left or right and clockwise, and see the results on the serial monitor.

#include<Wire.h>
#include<paj7620.h>
void setup() {
  Serial.begin(9600);
  uint8_t error = paj7620Init();
  if (error) {
    Serial.print("sensor error 0x");
    Serial.println(error, HEX);
    for (;;);
  }
  Serial.println("Go");
}
void loop() {
  //see the examples for more complete code
  uint8_t data = 0;
  paj7620ReadReg(0x43, 1, &data); 
  // Read Bank_0_Reg_0x43/0x44 for gesture result
  if (data == GES_LEFT_FLAG) {
    Serial.println("LEFT");
  }
  else if (data == GES_RIGHT_FLAG)
  {
    Serial.println("RIGHT");
  }
  else if (data == GES_CLOCKWISE_FLAG)
  {
    Serial.println("CLOCKWISE");
  }

Here’s a screenshot of the serial monitor log from our own testing.

Note: Your hand needs to be no more than 50mm from the sensor to reliably read left and right, up and down or forward and backward. It must be even closer to correctly detect the more subtle clockwise, counter-clockwise or wave motions. You need to keep that in mind when designing your projects.

Practical Example 2:

Servo Control

To test the gesture sensor in a real world application, we decided to actuate a servo with hand movements. This would be a good starting point for creative projects where the user wanted to move objects, say, steer a robot, flick a mechanical switch, open a lock or many other simple tasks.

We have provided a Fritzing diagram for you here to create it on a breadboard.

The connections between the microcontroller and the gesture sensor are the same as Practical Example 1, but we are now adding a servo and a 220μF electrolytic capacitor to smooth out the voltage when the servo is actuating.

Parts Required:JaycarAltronicsCore Electronics
1 x Hand Gesture Sensor ModuleXC3742-SEN0285
1 x Arduino Nano or CompatibleXC4414Z6372CE05101
1 × SG90 ServoYM2758Z6392SER0043
1 × 220uF 16V Electrolytic CapacitorRE6158R4847CE05149
1 × 28 Pin or 40 Pin Male Header - StraightHM3211P5430FIT0084

Parts Required:

OPTIONAL: JaycarAltronicsCore Electronics
1 × 50 × 70mm PerfboardHP9550H0714ADA2670

OPTIONAL:

Note: A breadboard and prototyping hardware are also required. † May require alternate libraries and wiring.

Prototype Tests

In our prototype tests, we had some intermittent results, which we suspected were communication issues between the sensor and the Nano board via the breadboard.

The sensor uses a 400kbit/s I²C two-wire communication protocol. If the I²C connection is unreliable, the sensor will fail to work correctly. The higher speed of this sensor is likely to be more prone to crosstalk and is more susceptible to stray capacitance of the breadboard. This could have also been a contributing factor to the communication issues we were having. We could have possibly had an intermittent connection in the breadboard too.

This is why we quickly soldered the prototype to a perfboard that you can see here. If you want to make something more permanent than a breadboard you can follow this approach. All of our communication issues were solved when switching to a PCB, therefore, if you’re having such issues you may want to consider this.

Wiring guide:

The capacitor needs to go as close to the servo VCC and GND pins as possible. Pay attention to the markings and leads on the capacitor. The long lead is VCC and the short lead is GND. The GND lead should also have a marking on the case denoting that it is the GND connection.

After reading the library file paj7620.h, we were able to ascertain each of the individual flags for each of the nine possible gestures, which are as follows:

You can substitute any of these flags into the code we have provided on our website to change the program to react to the appropriate action. For example, if you wanted to change the code from running the function when you swipe left, to running the function when you move your hand up, you need to change only one line from:

if (data == GES_LEFT_FLAG) {
    Serial.println("LEFT");
    newPos = 180;
    moveServo();
  } </div>

To:

if (data == GES_UP_FLAG) {
    Serial.println("UP");
    newPos = 180;
    moveServo();
  } </div>

Note: The serial print function is simply there for debug purposes and has no impact on the servo functionality.

You may note that we are calling the same function for both cases. This makes the code a little more streamlined, as both cases actually require the same task. In each case, we simply change a variable to a desired state. In our case, a left swipe makes the servo more all the way to the left. If you would like more control, instead of changing the value of newPos to 180, you could use the line:

newPos = (newPos + 10); 

This would make the servo move only 10° toward the left for each detection of a left swipe. This would give you much more fine control of the servo movement, albeit take longer to reach the full 90° range of motion. This would also require an additional 'if' statement on each range of motion to make sure that the maximum and minimum values sent to the servo is not less than 0° and did not exceed 180°.

In our servo code, we called a function which we named moveServo(), which as its name suggests, tells the servo to move to the required location.

void moveServo() {
  while (newPos > pos) {
    pos ++;
    myservo.write(pos);
    delay(2);
  }
  while (newPos < pos) {
    pos --;
    myservo.write(pos);
    delay(2);
  }

It is simply two while statements that compare the current values of 'pos' against the desired value of newPos, and makes the servo move one degree every 2ms. If you don’t want to make a servo move but would rather illuminate an LED or actuate a relay, you can either create a function using the same structure as above or you can just add simple commands inside the corresponding if statement.

This means you can easily adapt the code to work with multiple servos or more importantly a vast array of different other devices. You could use a MOSFET and turn on large loads using a function and or digitalWrite() or you could control the speed of a motor or brightness of a LED using analogWrite() / PWM, etc.

This code and project is a great place to get started using gesture control with an Arduino microcontroller development board.

To make things easy we will include a sample code on the website that will allow you to detect all nine hand gestures and apply your own code for when each gesture is detected.

PERFORMANCE

All in all, the sensor is extremely simple to get going and is quite a lot of fun to experiment with.

We did notice that in bright sunlight, the sensor was more prone to detection errors and sometimes not detecting gestures at all, however, we had minimal issues when using the sensor indoors.

The datasheet recommends that for best results, this sensor should be used in conjunction with a protective cover made from less than 0.7mm thick sheet of glass or polycarbonate placed with a tiny airgap less than 0.2mm between it and the sensor itself. This sheet is not included in the hobby level sensors, but should be added to help absorb external infrared radiation, and thus reduce interference.

If you are noticing significant incorrect readings or the sensor is not detecting readings at all, consider the level of infrared light in the area that you’re operating the sensor in. Reducing the ambient light may have a positive effect.

WHERE TO FROM HERE?

By completing the two prototypes we describe here, you should be able to apply the sensor to suit your project’s needs. Build a touchless power switch, control your robotic arm or vehicle project, activate a door solenoid, trigger a desk lamp, all with a wave of your hand.

Johann Wyss

Johann Wyss

Staff Technical Writer