logo-mobile

ROHM

ROHM
Menu
  • Arduino –
  • Raspberry Pi –
  • Trending –
  • Others –
  • About –
  • Contact –

Arduino

UCLA “AirMouse” using ROHM Sensor Evaluation Kit – Part 2

Rahul Iyer
Published by Rahul Iyer at May 16, 2017
Categories
  • Arduino
Tags
  • 3d
  • 3d airmouse
  • airmouse
  • Arduino
  • diy
  • sensor evaluation kit
3d airmouse

Click here to read Part 1 of this article >

3d airmouse

 

We left off last time in UCLA “AirMouse” using ROHM Sensor Evaluation Kit – Part 1 having finished the hardware portion of the project.  The transmitter portion involved assembling a shield with the AirMouse’s buttons and the interface between the Uno’s GPIO pins and the RF module.  We chose to use the ROHM SensorShield with the accelerometer module because of its convenience in prototyping and DIY projects such as this.  As you’ll see in this tutorial, the ROHM shield packages the I2C communications between the Arduino and its peripherals nicely so that with some simple code, the user can receive accelerometer data without having to write any of the underlying I2C functions to send and receive data from device addresses.  The receiver portion of the project involved assembling similar breakout board for a Teensy microcontroller to interface it with an RF module as well.  

The code we’ll introduce and describe in this tutorial will help you complete the project by connecting the two modules to each other.  We’ll show you our basic code to send data between the two modules and process the accelerometer data to move a cursor on the computer monitor, and hopefully you’ll be able to come up with some cool additions and improvements of your own!

 

Quick AirMouse Overview

We’ve all used computer mice before, but they are limited to only working on top of flat surfaces like tables.  We’ve made 3D AirMouse, a computer mouse that functions in 3D space.  The user can tilt the mouse to move the cursor on the screen, allowing for a wide range of customizable motions. We’ve already covered the basics of building the AirMouse in Part 1. There are two main pieces that make up the AirMouse: the handheld mouse transmitter, and the receiver connected to the user’s computer.  The transmitter gathers information about the mouse’s orientation and the states of its buttons, while the receiver translates this information to perform corresponding actions on the computer screen. The AirMouse was built using Arduino Uno and nRF24L01 RF  modules, combined with an accelerometer on the ROHM sensor shield.

 

Hardware from Part 1:

Transmitter:

  • 1 x Arduino Uno microcontroller
  • 1 x ROHM Sensor Evaluation Kit
  • 1 x ROHM Accelerometer (KX022-1020)
  • 1 x nRF24L01+ RF module
  • Female header pins
  • Slide switch
  • 1 x Solderable perfboard large enough to fit the microcontroller and accompanying electronics
  • 2 x Push-buttons
  • 1 x 1s LiPo Battery
  • 1 x 1kΩ resistor
  • 1 x 3.3kΩ resistor

Receiver:

  • 1 x Teensy 3.2 microcontroller
  • 1 x NRF24L01+ RF module
  • Female header pins
  • 1 x Solderable perfboard large enough to fit the microcontroller and accompanying electronics
  • 1 x Red, Yellow, and Green LEDs
  • 1 x 150Ω resistor

Once you have the hardware wired up as specified in Part 1, you can use the following program to run the transmitter and receiver.

 

Transmitter:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include <SPI.h>
#include "RF24.h"
 
#define byte uint8_t
#include <Wire.h>
#include <KX022.h>
 
KX022 accelerometer(KX022_DEVICE_ADDRESS_1E);
 
RF24 radio(9,10);
 
uint64_t pipes[2] = {0xF0F0F0F0F0, 0xF0F1F1F1F1}; //reading, writing
 
void initRadio()
{
radio.setPALevel(RF24_PA_HIGH);
//payload size default 32...
radio.setChannel(10); //you can change the channel setting
radio.setCRCLength(RF24_CRC_16); //2-byte CRC
radio.setDataRate(RF24_1MBPS); //1Mbps data rate
 
radio.openReadingPipe(0, pipes[0]);
radio.openWritingPipe(pipes[1]);
}
 
#define buttonPinR 2 //change these accordingly
#define buttonPinL 3
 
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
while (!Serial);
 
pinMode(buttonPinR, INPUT);
pinMode(buttonPinL, INPUT);
 
radio.begin();
initRadio();
radio.stopListening();
 
Wire.begin();
accelerometer.init();
}
 
long lastDebounceTimeR = 0;  // the last time the output pin was toggled
long lastDebounceTimeL = 0;
long debounceDelay = 50;
int buttonStateR = LOW;             // the current reading from the input pin
int buttonStateL = LOW;
int lastReadingR = LOW;
int lastReadingL = LOW;
 
char readButtonR(){
int reading = digitalRead(buttonPinR);//get what state the button is
char out = 'a';//the value to return if nothing special happened
if (reading != lastReadingR) {//We're reading a new state for button
   // reset the debouncing timer
   lastDebounceTimeR = millis();
}
 
if ((millis() - lastDebounceTimeR) > debounceDelay) {//We finally have a stable value
   if (reading != buttonStateR)//Compared to our previous state, we have a flip
   {
     out = 'r';//prepare to toggle the Mini
   }
   buttonStateR = reading;//Make the buttonState the same
}
 
lastReadingR = reading;//make the last state the "current" state
return out;
}
 
char readButtonL(){
int reading = digitalRead(buttonPinL);
char out = 'a';
if (reading != lastReadingL) {
   // reset the debouncing timer
   lastDebounceTimeL = millis();
}
 
if ((millis() - lastDebounceTimeL) > debounceDelay) {
  
   if (reading != buttonStateL)
   {
     out = 'l';
   }
   buttonStateL = reading;
}
 
lastReadingL = reading;
return out;
}
 
struct data
{
boolean isPushedR = false;
boolean isPushedL = false;
int8_t acceleration[3] = {0, 0, 0};
};
 
data packet;
boolean rState = false;//these states are used to represent the current state of the buttons
boolean lState = false;
 
void loop() {    
  
   if(readButtonR() == 'r'){ //toggle button state when button state change is detected
     rState = !rState;
   }
  
   if(readButtonL() == 'l'){ //toggle button state when button state change is detected
     lState=!lState;
   }
 
   packet.isPushedR = rState;
   packet.isPushedL = lState;
 
   uint8_t rc;
   float acc[3];
   rc = accelerometer.get_val(acc);
  
   if (rc == 0)
   {
     //we cast to drop the decimal, we don't need that high precision
     packet.acceleration[0] = (int8_t)(acc[0]*100); //x
     //Serial.print(packet.acceleration[0]); Serial.print(" ");
     packet.acceleration[1] = (int8_t)(acc[1]*100); //y
     //Serial.print(packet.acceleration[1]); Serial.print(" ");
     packet.acceleration[2] = (int8_t)(acc[2]*100); //z
     //Serial.println(packet.acceleration[2]);
   }
   radio.write((char*) &packet, sizeof(packet));
}

Receiver:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include <SPI.h>
#include "RF24.h"
 
RF24 radio(9,10);
 
uint64_t pipes[2] = {0xF0F1F1F1F1, 0xF0F0F0F0F0}; //reading, writing
 
void initRadio()
{
radio.setPALevel(RF24_PA_HIGH);
//payload size default 32...
radio.setChannel(10);
radio.setCRCLength(RF24_CRC_16); //2-byte CRC
radio.setDataRate(RF24_1MBPS); //1Mbps data rate
radio.openReadingPipe(0, pipes[0]); //reading pipe
radio.openWritingPipe(pipes[1]);
 
radio.startListening();
 
}
#define R_PIN 6 //Red LED
#define G_PIN 7 //Green LED
#define Y_PIN 8 //Yellow LED
 
void setup() {
Serial.begin(9600);
while(!Serial); //wait until Serial is initialized...(we found that not including this line of code caused errors on the
                 //Teensy because it started executing code without ensuring that Serial communication with the laptop was
                 //properly initialized...
radio.begin();
initRadio();
 
Mouse.screenSize(1920, 1080);  // configure screen size
randomSeed(analogRead(0));
pinMode(R_PIN, OUTPUT);
pinMode(G_PIN, OUTPUT);
pinMode(Y_PIN, OUTPUT);
}
 
#define CALIX 6 //calibration for X
#define CALIY -1 //calibration for Y
 
#define scalingFactor 0.05
#define THRESHOLD 1
 
double moveVector[2] = {0, 0};
 
void tiltToVector(const int8_t* acceleration){
moveVector[0] = 0;
moveVector[1] = 0;
if(abs(acceleration[0] - CALIX) > THRESHOLD){ //calculate move
   moveVector[1] = (double)(acceleration[0] * scalingFactor);
}
if(abs(acceleration[1] - CALIY) > THRESHOLD) {
   moveVector[0] = (double)(acceleration[1] * scalingFactor);
}
}
 
struct data
{
boolean isPushedR = false;
boolean isPushedL = false;
int8_t acceleration[3] = {0, 0, 0};
};
 
data packet;
 
void loop() {
 
bool stillWaiting = true;
//Serial.println("About to read");
   while(stillWaiting){
     if(radio.available(0)){ //You've got mail!!!
       radio.read((char*) &packet, sizeof(packet));
       stillWaiting = false;
     }
   }
 
Mouse.move(moveVector[0], moveVector[1]);
Mouse.move(moveVector[0], moveVector[1]); //call it twice within the loop for smoothness :)
 
//prints for debugging purposes
Serial.println("Finished writing the pins");
if (packet.isPushedR) {
   Serial.println("The right button has been clicked!!! (Did you mean to right click?!?!)");
}
 
if (packet.isPushedL) {
   Serial.println("The left button has been clicked!!! (Did you mean to left click?!?!)");
   //Mouse.click();
}
Serial.print("X: ");
Serial.println(packet.acceleration[0]);
Serial.print("Y: ");
Serial.println(packet.acceleration[1]);
Serial.print("Z: ");
Serial.println(packet.acceleration[2]);
 
tiltToVector(packet.acceleration); //re-calculate move vector coordinates
 
//  Mouse.move(moveVector[0], moveVector[1]);
}

 

The process for uploading code to a Teensy is slightly different from the process for uploading to an Arduino Uno.  For the Uno, you can simply follow the usual compile and upload steps:

  1. Select Tools > Board > Arduino/Genuino Uno
  2. Select the Port
  3. Click the “Upload” button in the Arduino IDE

 

For the Teensy, follow these steps to upload the receiver code:

  1. Select Tools > Board > Teensy 3.2 / 3.1
  2. Select Tools > USB Type > Keyboard + Mouse + Joystick (we’ll be using the Teensy as a USB device)
  3. Click the “Upload” button in the Arduino IDE

 

For the purposes of this tutorial, we won’t go into too much detail about the different communication protocols involved and how communication with the RF module works at the software level.  You can check out our communications protocols and nRF24L01+ module tutorials for more information on these topics!  Instead, we’ll briefly explain the workings of the main control loop in the software.

In the AirMouse, the transmitter collects data, but most of the data processing is handled by the receiver module.  We designed the system this way so that the Arduino, a weaker processor than the Teensy, could spend fewer resources on decision-making and computations and instead run faster cycles just collecting data.  With this implementation, the only data being sent between the two devices is the raw accelerometer and button data.  The Teensy receives this raw data and processes it to perform actions on the computer screen.

To detect the orientation of the AirMouse, the system must translate the raw accelerometer data.  To accomplish this, one must first identify the “zero-values” of each of the coordinates.  This value is defined as the accelerometer’s output for each axis when the AirMouse is held flat (parallel to the ground).  With knowledge of the zero-values, the software is then able to translate accelerometer data into a direction and amount to move the cursor on-screen by analyzing the acceleration (due to gravity) in each axis and comparing it to the zero-value for that axis.

Now we’ll take a look at the interaction between the receiver module and the computer.  The Teensy is specified to act as a USB Human Interface Device (specifically, a USB Mouse).  After translating orientation data, the software makes calculations on what speed and direction to move the cursor.  In addition, the software also interprets the left-button clicks as left-clicks and the right-button clicks as right-clicks, calling appropriate methods to show left or right-clicks on the computer screen.  Here’s the cool part: you can modify or add to the mouse’s on-screen functionality fully through software!  Currently, the abilities and performance of the mouse is rudimentary, but you can easily add features such as scrolling, moving the cursor to a certain point on the screen, etc. with some simple additions to the software!  (Here’s the Teensy USB Mouse guide for reference)  Here are some cool hardware and software ideas you can implement:

  • Have different patterns of button clicks act as different controls (for example, double-click right button to close the window)
  • Add scrolling! (change to a “scroll mode” when both buttons are clicked)
  • Add other buttons to the mouse to do things like scrolling or to get more button patterns for different functions

We hope you enjoy building the AirMouse, and definitely look forward to modifications and improvements on both its design and its functionality!    

The original version of AirMouse was developed by Rahul Iyer, Aaron and Andrew Wilhelm, as part of UCLA IEEE’s Advanced Projects program. Find out more at http://ieeebruins.org

Device Plus is looking to collaborate with active student engineering organizations and labs. For more information about our Hardware Sponsorship Program, please contact us at info@deviceplus.com

 

Click here to read Part 1 of this article >

Rahul Iyer
Rahul Iyer
Studying Electrical Engineering at UCLA, Rahul loves to work on electronics and robotics projects as a hobby. He is especially enthusiastic about electric vehicle technology and assistive robotics.

Check us out on Social Media

  • Facebook
  • Twitter

Recommended Posts

  • UCLA “AirMouse” using ROHM Sensor Evaluation Kit – Part 1UCLA “AirMouse” using ROHM Sensor Evaluation Kit – Part 1
  • Arduino Sensors – ROHM Sensor Evaluation Kit OverviewArduino Sensors – ROHM Sensor Evaluation Kit Overview
  • Arduino-Based DIY Electric SkateboardArduino-Based DIY Electric Skateboard
  • 3D Cases for ROHM Sensor Evaluation Kit and RohmMultiSensor Library Update3D Cases for ROHM Sensor Evaluation Kit and RohmMultiSensor Library Update
  • Step By Step Guide To Your First Project With ArduinoStep By Step Guide To Your First Project With Arduino
  • DIY RepRap 3D Printer for Beginners – Part 1: BuildDIY RepRap 3D Printer for Beginners – Part 1: Build
Receive update on new postsPrivacy Policy

Recommended Tutorials

  • How to integrate an RFID module with Raspberry Pi How to integrate an RFID module with Raspberry Pi
  • How to Use the NRF24l01+ Module with Arduino How to Use the NRF24l01+ Module with Arduino
  • How to Run Arduino Sketches on Raspberry Pi How to Run Arduino Sketches on Raspberry Pi
  • Setting Up Raspberry Pi as a Home Media Server Setting Up Raspberry Pi as a Home Media Server

Recommended Trends

  • SewBot Is Revolutionizing the Clothing Manufacturing Industry SewBot Is Revolutionizing the Clothing Manufacturing Industry
  • All About The Sumo Robot Competition And Technology All About The Sumo Robot Competition And Technology
  • 5 Interesting Tips to Calculating the Forward Kinematics of a Robot 5 Interesting Tips to Calculating the Forward Kinematics of a Robot
  • Go Inside the Drones That Are Changing Food Delivery Go Inside the Drones That Are Changing Food Delivery
Menu
  • Arduino –
    Arduino Beginner’s Guide
  • Raspberry Pi –
    Raspberry Pi Beginner's Guide
  • Trending –
    Updates on New Technologies
  • Others –
    Interviews / Events / Others

Check us out on Social Media

  • Facebook
  • Twitter
  • About
  • Company
  • Privacy Policy
  • Terms of Service
  • Contact
  • Japanese
  • 简体中文
  • 繁體中文
Don’t Forget to Follow Us!
© Copyright 2016-2023. Device Plus - Powered by ROHM
© 2023 Device Plus. All Rights Reserved. Muffin group

istanbul escort istanbul escort istanbul escort