iOS Accelerometer Control with Javascript

This project allows you to control your Dojo Derby Vehicle by tilting your iOS device. Speed is controlled by Forward/ Back tilting, and direction is side to side.

We use Javascript to to pull the X,Y and Z coordinate values from the iOS devices, and then create if/else statements to send commands to the vehicle using XMLHttpRequest with GET.

Current Project Confidence Level: Proof of Concept

This project works well for moving the vehicle. The quirk is that for iOS the webpage has to be presented using SSL for iOS to allow permission to the Accelerometer. You can install a local SSL certificate easily, but I have not yet figured out how to get the camera to work with SSL.

Setup Self Signed SSL Certificate

For this project we need the encryption capability of SSL, but actual security is not the highest concern so we can simply create our own SSL certificate.

First install openssl

sudo apt-get install openssl
Code language: JavaScript (javascript)

Then we create a directory for the certificates

sudo mkdir -p /etc/ssl/mycerts

Create SSL Certificate

sudo openssl req -new -x509 -days 365 -nodes -out /etc/ssl/mycerts/apache.pem -keyout /etc/ssl/mycerts/apache.key
Code language: JavaScript (javascript)

Set permission for mycerts folder

sudo chmod 600 /etc/ssl/mycerts/apache*

Enable Apache2 SSL Module

sudo a2enmod ssl

Configure Apache2 to use SSL Certificates

sudo nano /etc/apache2/sites-available/default-ssl.conf
Code language: JavaScript (javascript)

Add certificate location under SSL Engine Switch

SSLCertificateFile /etc/ssl/mycerts/apache.pem SSLCertificateKeyFile /etc/ssl/mycerts/apache.key

Then enable SSL Configuration

sudo a2ensite default-ssl
Code language: JavaScript (javascript)

Finally Restart Apache2

sudo service apache2 reload

index-accel.php Code

First, at this point this isn’t an actual PHP file, but since we use PHP to build the dashboards and panels I have named this with .php to make it easier for add-ons in the future.

Currently this is a single file that contains the CSS, Javascript and HTML. I have done it this way to make it simpler to understand what the full program looks like, but the CSS and Javascript could be put in their own files.

To send commands to the vehicle we use XMLHttpRequest to send values to the controls.php and speed.php scripts on the vehicle. When he device is tilted based on the value a commend is sent using the direction or speed variable.

Note: The controls.php and speed.php scripts take the values received, and write them to text files. The vehicle has a python script in infinite loop constantly reading from those text files and then modifying the status of the GPIO pins.

For diagnostic purposes we have a DIV that shows the current X,Y and Z Axis readings, and another DIV that shows the commands being sent to the vehicle.

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Dojo Derby Accelerometer Control</title> <style> .coordinateDisplay{ width: 600px; height: 125px; background-color:blanchedalmond; } .commandDisplay{ width: 600px; height: 100px; background-color:lightblue; } </style> <script> function getAccel(){ DeviceMotionEvent.requestPermission().then(response => { if (response == 'granted') { // Add a listener to get smartphone orientation // in the alpha-beta-gamma axes (units in degrees) window.addEventListener('deviceorientation',(event) => { // Expose each orientation angle in a more readable way rotation_degrees = event.alpha; frontToBack_degrees = event.beta; leftToRight_degrees = event.gamma; //Print out Coordinates document.getElementById("coordinates").innerHTML = "Y Axis: " +frontToBack_degrees+"<br>X Axis: "+leftToRight_degrees+"<br>Z Axis: "+rotation_degrees; //Controls Vehicle Speed if(frontToBack_degrees > 80){ speed = " "; var xmlhttp = new XMLHttpRequest(); xmlhttp.open("GET", "./speed.php?speed=" + speed); xmlhttp.send(); } else if (frontToBack_degrees < 80 && frontToBack_degrees > 50){ speed = "slow"; var xmlhttp = new XMLHttpRequest(); xmlhttp.open("GET", "./speed.php?speed=" + speed); xmlhttp.send(); } else if (frontToBack_degrees < 50 && frontToBack_degrees > 30){ speed = "medium"; var xmlhttp = new XMLHttpRequest(); xmlhttp.open("GET", "./speed.php?speed=" + speed); xmlhttp.send(); } else if (frontToBack_degrees < 30 && frontToBack_degrees > 10){ speed = "fast"; var xmlhttp = new XMLHttpRequest(); xmlhttp.open("GET", "./speed.php?speed=" + speed); xmlhttp.send(); } else if (frontToBack_degrees < 10){ speed = " "; var xmlhttp = new XMLHttpRequest(); xmlhttp.open("GET", "./speed.php?speed=" + speed); xmlhttp.send(); } //Controls Vehicle Direction if(leftToRight_degrees > -20 && leftToRight_degrees < 20){ direction = "forward"; var xmlhttp = new XMLHttpRequest(); xmlhttp.open("GET", "./controls.php?command=" + direction); xmlhttp.send(); } else if (leftToRight_degrees > -50 && leftToRight_degrees < -20){ direction = "forwardLeft"; var xmlhttp = new XMLHttpRequest(); xmlhttp.open("GET", "./controls.php?command=" + direction); xmlhttp.send(); } else if ( leftToRight_degrees < -50){ direction = "left"; var xmlhttp = new XMLHttpRequest(); xmlhttp.open("GET", "./controls.php?command=" + direction); xmlhttp.send(); } else if ( leftToRight_degrees < 50 && leftToRight_degrees > 20){ direction = "forwardRight"; var xmlhttp = new XMLHttpRequest(); xmlhttp.open("GET", "./controls.php?command=" + direction); xmlhttp.send(); } else if ( leftToRight_degrees > 50){ direction = "right"; var xmlhttp = new XMLHttpRequest(); xmlhttp.open("GET", "./controls.php?command=" + direction); xmlhttp.send(); } //Prints Speed and Direction to Page document.getElementById("speed").innerHTML = speed; document.getElementById("direction").innerHTML = direction; }); } }); } </script> </head> <body> <h1>iOS Accelerometer Car App Javascript</h1> <button id="accelPermsButton" style="height:50px;" onclick="getAccel()"><h1>Get Accelerometer Permissions</h1></button> <div class="coordinateDisplay"> <p id="coordinates" style="font-size: 30px;">Axis Coordinates</p> </div> <div class="commandDisplay"> <p id="direction" style="font-size: 30px;"></p> <p id="speed" style="font-size: 30px;"></p> </div> </body> </html>
Code language: HTML, XML (xml)