Bluetooth Low Energy (BLE)

ble-graphic2

WARNING THIS BLOG IS VERY INFORMATIC IN ITS NATURE, YOU HAVE BEEN WARNED.

In this blog post, I will be covering what I’ve researched and learned about the new Bluetooth protocol called “Bluetooth Low Energy” “(BLE)” also known as “Bluetooth Smart”.

In 2009 Bluetooth SIG announced a new version of Bluetooth noted as V4.0 that included a new protocol called BLE. Originally BLE was made by Nokia in 2006 under the name Wibree, however, Wibree was merged into the main Bluetooth standard in 2010 with the release of Bluetooth V4.0.

So what makes Bluetooth V4.0 so special? Well Bluetooth V4.0 operates two different protocols. Number 1 being Bluetooth classic, and number 2 being Bluetooth Low Energy, both protocols operate under the 2.4 GHz ISM band, however, both protocols are not compatible. BLE uses a 40 2MHz-wide channels while Classic uses the 89 1MHz-whide Channels, but one thing both protocols have in common is the ability to use frequency hopping to spread their RF energy.

Bluetooth Low energy, however, is unique in comparison to Bluetooth Classic, not only in the sense of the 40 2MHz-wide Channels but also in how it operates and how its operation allows for low power consumption. With BLE communications two types of communication’s come into play “GAP” and “GATT”, both operate differently, however, comes with its beneficial applications.

 

Generic Acess Profile (GAP)

GAP defines how BLE devices can make them selfs available to each other and how two devices can communicate with each other. GAP plays four different roles that allow for communication to take place:

  1. Broadcaster
  2. Observer
  3. Peripheral
  4. Central

 

Broadcaster – Broadcasts public advertising data packets, an example of this would be as if a button was pressed every 20 – 40ms to show that a signal is taking place within a system however in terms of Bluetooth Low Energy application, these advertising data packets may come as a local thermometer presenting its latest temperature update, or for a business to advertise its latest sales.

Observer – An observer device listens to the data in the advertising packets that is being sent by the broadcaster, an observer can be a range of different devices that is programmed to take in this information, such as a smartphone that is take in that temperate update or present the sales deals.

Note: Overserver and Broadcaster roles do not need to connect in order to transfer data. These two roles are typically used in Bluetooth beacon technology.

Peripheral – Peripheral devices make its presence known through advertising a data packet to allow for a central device to establish a connection. After a connection has been made by a central device the peripheral device stops broadcasting to other central devices and stays connected with the device that has accepted the connection request.

Central – Central devices initiate the connection between its self and a peripheral by the first listening to the advertised data made by a peripheral device. When a central device wants to connect it sends a request connection data packet to a peripheral device. If the peripheral device accepts the request from the central device, a connection is therefore made. Another note about central devices is its ability to connect to many other peripheral devices. Central device can also update the connection parameters between the two devices, the peripheral device cannot, however, the peripheral device can ask permission to the central device to update the connection parameters.

Note: Central or Peripheral devices can terminate the connection made, both devices can terminate connections intentionally, other reasons why the connection may break is due to power issues (such as the device’s batteries dying out) or out of signal range.

Do take a quick few minutes to process that information before moving onto GATT

Generic Attribute Profile (GATT)

GATT defines the roles how two BLE devices send back and forth data using concepts called “services” and “characteristics”. However similar to GAP, GATT is very different as the connection is exclusive to the two connected devices. A GATT connection is only made after a central and peripheral device has gone through the GAP process and updated its communication parameters.

A GATT connection requires two devices whose roles are followed:

 Client – Sends a request to the GATT server, the client can either read and/or write attributes found in the server

Server – the role of the server is to store the attributes, once the client makes the request, the server must make the attributes available.

Client-Server Relationships

An example of a client-server relationship would be. If my accelerometer test device were fully operational and is experiencing movement, and I want to know what type of movement is being experienced by my test device in the form of updated graphs or data through my phone. The test device acts as the server and provides the information, while the phone acts as the client reading the information.

But one interesting point about Client and Server relationships is the fact the roles can be swapped depending on how information is flowing, for example, if the phone needed to send an update for the test device, now the phone would act as the server while the test device acts as the client. Another interesting point would be the fact that central and peripheral devices can act as either a client or server as silently hinted from the previous sentence, but in terms of GAP and GATT communications, both are independently different from one another.

 

Conclusion

In the world of IoT (Internet of things) many new ideas for devices have been under development, mediums such as BLE or NFC have already quickly changed how many of us on earth operate for example contactless payments via card was a NFC “thing” that came out 3 to 5 years ago, now many countries are slowly moving to using their phones via NFC for contactless payments. In nursing homes, Fitbit-like BLE enabled devices are now potentially becoming both a tracker and heart monitor for residents or even patients in a hospital.

Many of these “things” are still the research and development stage however with active devices using BLE, more devices can be interconnected to one another, especially with Bluetooth 5 and their upcoming feature called “Bluetooth Mesh” what will create a whole network of different BLE devices together.

Bluetooth V4.0 – V4.2, and Bluetooth 5 are setting the scene for future and new IoT applications in almost every and any sector.

Resources:

EDN-Europe: http://www.edn-europe.com/blog/bluetooth-low-energy-ble-short-history-ble-standard-and-gatt

Bluetooth SIG: https://www.bluetooth.com/what-is-bluetooth-technology/how-it-works

Adafruit: https://learn.adafruit.com/introduction-to-bluetooth-low-energy/introduction

Punch Through Designs: https://punchthrough.com/bean/docs/guides/everything-else/how-gap-and-gatt-work/

 

Advertisements

My Cordova Environment

For this blog post, I will be covering the do’s and didn’t do’s for my Cordova Environment which was operating on a Ubuntu 16.01 on a virtual machine.

Minor Details:

Originally I had intended on using my windows laptop to build my app however from all the junk that had been downloaded, installed, accumulated over previous projects, I have decided to us a Virtual Machine running Ubuntu on it to use as my App development Environment, however, due to hardware issues (my computer being not simply powerful enough) I had to return to my old web developing friend my MacBook Pro. Thankfully it is powerful enough run a fast Ubuntu build. Moving on.

Apache Cordova is a Mobile Application Framework that allows software programmers to build mobile applications using a web stack (HTML5, CSS3, JS) instead of using platform-specific APIs for Android, IOS, or Windows which would be three or more different software. It reduces it to one framework that allows you to build apps towards the platform of choice with plugins eg. IOS or Android.

This creates a hybrid application that neither native mobile (due to rendering done via web views) nor is purely web-based (they are not viewed on a browser though packed as standard mobile apps via installing platform e.g. IOS App Store or Google Play Store).

Environment Build (WARNING!! This may get tedious and boring)

Just to warn anyone who is following this example of mine, I had originally started with 15Gb for my Ubuntu OS running on my virtual machine, now this was expanded first to 20Gb and then 100Gb. This was done by using the following command on the terminal (note: my operating system is OSx).  Also before typing the code below make sure to be in the directory of the file. If anyone is wondering what is using most of this disk space, it is the Android SDK. And for anyone who is curious, the total amount of disk space that was the Ubuntu environment used about 23GB.

 


               Mac Terminal: VBoxManage modifyhd “<vdi_file_full_path_and_name>” –resize 40000

A list of Things to Install:

  • NodeJS
  • NPM
  • GIT
  • Cordova
  • Java
  • JavaC
  • Ant
  • Android SDK Tools

NodeJS

Type the following in the Terminal:


               sudo apt-get install nodejs

To see if nodejs works type this into the terminal:


nodejs --version

If Nodejs is installed, the latest version should show up in the terminal.

Next, in order for Cordova to work, Nodejs needs to have an alias “node”.


               sudo ln -s /usr/bin/nodejs /usr/bin/node

 

NPM

Type this in the Terminal:


               sudo apt-get install npm

To see if NPM is installed:


               npm --version

GIT

To install GIT on Ubuntu type the following:


               Sudo apt-get install git

Bored yet? Don’t worry were almost done…


 

Cordova

Cordova yay! type this into the terminal:


               Sudo npm install -g cordova

And lastly to see if Cordova was installed properly do type the following in the terminal:


               cordova --version

Now Apache Cordova is fully installed however in order to start building apps another few pieces needs to be installed and set to PATH in order for the web stack to be converted into an App. and if you don’t believe me do type:


               cordova requirements

into your terminal. This should return a list with the following:

  • Java
  • Javac
  • Ant
  • Android SDK

So let’s keep at it.


 

Java

In order for the Android SDK to be installed, the Java Development Kit (JDK) needs to be installed.  To check if the JDK is already installed type the following into the terminal:


java -version

javac -version

If a version does pop up, that means Java is already installed, however, that Java is an OpenJDK rather than the Oracle JDK which is needed for signing Android apps.

The following steps show the process in installing the Oracle JDK.

First: We need to remove the OpenJDK by typing the following commands into the terminal:


sudo apt-get purge openjdk-\*

sudo apt-get autoremove

 

Next, we need to install a 32-bit library since were using a 64-bit Linux machine by typing the following:

Note some examples may say install the “ia32-libs” however that library isn’t available anymore, and running that command will direct you to lib32z1 unless it has been updated again.


               sudo apt-get lib32z1

 

Next the JDK “Java SE Development Kit” needs to be downloaded from the oracle website.

 

 

If using a 32 Bit system, make sure to download the Linux x86 and for 64 bit systems do make sure to download Linux x64. Also, make sure to download the “.tar.gz”.

Note: please do know whatEverYourFileNameIs.tar.gz will be replaced by whatever the real name of your downloaded file is.

 

 


mkdir -p ~/java 

cd ~/Downloads 

mv whatEverYourFileNameIs.tar.gz ~/java 

cd ~/java 

tar xvzf whatEverYourFileNameIs.tar.gz

rm whatEverYourFileNameIs.tar.gz

 

Now we must check the name of the JDK install directory with:


ls

 

The path to the JDK will be displayed in the terminal, and will look something like “~/java/jdk1.8.0_11”. Copy whatever directory the terminal has produced.

 

Now to add the JDK to bath we ned to edit the .bashrc in our home directory. To do this you can either use “nano” or “gedit”, I used gedit as I’m used to that method, however both work accordingly.

 


nano ~/.bashrc

or:

gedit ~/.bashrc

 

Add the following lines to the end of the code, which you might have copied in the last step.

 

 

 

 

 


JAVA_HOME=~/java/”FolderName”     PATH=$PATH:~/java/”FolderName”/bin 

               export JAVA_HOME

               export PATH

 

Now we must edit the .bash_profile in the terminal(make sure it’s in the home directory).

 

Simply type again I prefer the gedit.

 


nano ~/.bash_profile

or:

gedit ~/.bash_profile

 

 

Once gedit is opened paste the following in the file and save it.

 


               if [ -f ~/.bashrc ]; then   

                               source ~/.bashrc

               fi

 

now that should be everything. To see if its working type the following in the terminal


               javac -version 

               java -version

If version info has displayed you are done with the JDK install!

 

 

 

 

Ant

 

Apache Ant is a build system for Java, which is used by both Cordova and the Android SDK. Click here to get to the link and download the stable version. Be sure to downlaod the “apache-ant-whateverVersion-bin.zip” file


mkdir -p ~/ant 

cd ~/ant 

unzip apache-ant-1.9.4-bin.zip 

rm apache-ant-1.9.4-bin.zip 

 

now a familiar process will take place, we need to add Ant to PATH we do this again by editing the .bashrc file by first typing. Again I use the gedit method.

 


nano ~/.bash_profile

or:

gedit ~/.bash_profile

 

and just underneath your Java export and before “export PATH” and the bottom of the file add the following

 

</strong>

ANT_HOME=~/ant/apache-ant-1.9.4 PATH=$PATH:~/ant/apache-ant-1.9.4/bin

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; export ANT_HOME

<strong>

 

 

 

 

The code should look like this:

 


JAVA_HOME=~/java/jdk1.8.0_11 PATH=$PATH:~/java/jdk1.8.0_11/bin

export JAVA_HOME 

ANT_HOME=~/ant/apache-ant-1.9.4 

PATH=$PATH:~/ant/apache-ant-1.9.4/bin 

export ANT_HOME 

export PATH

 

Now to test to see if the install worked simply type in the terminal

 


ant –version

 

If a version number shows up, that shows Ant has been installed successfully.

 

 

 

Lastly the android SDK Tools

Android SDK Tools are used by Cordova to build Android apps.

 

First you need to download the SDK tools which will be located at the bottom of their downloads page. Downlaod the zip file.

Now follow the next set of steps:

 


mkdir –p ~/android-sdk

cd mv ~/Downloads/android-sdk_whatEverVersion-linux.zip

unzip android-sdk_r23.0.2-linux.zip

rm android-sdk_r23.0.2-linux.zip

 

now that the files are inplace we have to add this to PATH.

 

Add the following two lines to the .bashrc that can be accessed in the terminal by typing :


nano ~/.bash_profile

or:

gedit ~/.bash_profile

 

 

 

 

 

 

Again I like to use gedit, now add this code before the “export PATH” and after the export “ANT_HOME”.

 


PATH=$PATH:~/android-sdk-linux/platform-tools 

PATH=$PATH:~/android-sdk-linux/tools

 

Now your .bashrc should look a lot more like this.

 


JAVA_HOME=~/java/jdk1.8.0_11 PATH=$PATH:~/java/jdk1.8.0_11/bin 

export JAVA_HOME

ANT_HOME=~/ant/apache-ant-1.9.4 

PATH=$PATH:~/ant/apache-ant-1.9.4/bin 

export ANT_HOME 

PATH=$PATH:~/android-sdk-linux/platform-tools 

PATH=$PATH:~/android-sdk-linux/tools

export PATH

 

Note: the Android-SDK tools may not come with the platform-tools component, if the “Platform-tools” are not seen in your “Android-SDK” after you have unzipped the Android-SDK, the platform-tools component is available here. And to add the platform-tools component to path follow the steps above on how the Android SDK was installed.
Final Steps
Now that everything is almost fully installed we just need to use the Android-SDK-manager to download the necessary API in order to make Android apps build correctly. To open the Android-SDK-manager simply type the following into the terminal:


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Android

 

Now the software should pop up and give you a list of Android-API’s that is installed. As stated in the Apache Cordova website link, the version of Cordova you should have installed is 6. Version 6 requires API levels between 14 – 23. So it’s safe to select API 23 in the SDK-Manager, however for future references if something is not working correctly within your app build it maybe safe to assume that if you fall back on to a previous API build eg. API 14 – 22, it may fix the problem. Just to warn you the API’s were the everything that filled up my hard disk space within my virtual machine.

 

Now just to see if everything installed properly. Let’s open up the terminal and type:


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adb version

 

Which will display the version of the Android debug bridge.

 

 

 

Now type in the terminal after everything has finally been installed and updated. Just to be sure the “PATH”ed files are working which should both display two directories.

 


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo $JAVA_HOME

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; echo $ANT_HOME

 

 

 

Updated 25/5/17

 

With the latest Cordova updated a few small changes have to be made

 

First, lets update Cordova


Sudo npm –g cordova

Ok

Next Gradle has to be installed separately.

Download the latest build here: https://gradle.org/releases

Download the zip file, and create a folder called “gradle” in “home” directory

Move the zip file into the gradle filder, and then unzip it, then remove it

Open up gedit ~/.bashrc and add a new file to %PATH by typing the following

 


GRADLE_HOME=~/gradle/gradle.ver

PATH=$PATH:~/gralde/gradle.ver/bin

EXPORT GRADL
<pre>

RoboSlam goes to the Philippines

This Workshop took place on 24th January 2017.

The RoboSlam project is a DIT School of Electrical and Electronic Engineering STEM education outreach initiative in which many primary and secondary schools in Ireland have participated. It aims to inspire a new generation of engineers. I myself am an engineering student in DIT, currently studying Electrical Engineering (DT009). I recently traveled to my other home country the Philippines for a short holiday. As part of my trip, I got in touch with an old classmate (Charis Go)  who is now the president of the school I attended for the first two years of secondary school. We talked over Facebook about programming and robotics in education, which I have some experience of from my college programme, including modules on RoboSumo and Robotics and volunteering as a facilitator at RoboSlam workshops.

After getting in touch with Ted Burke and Damon Berry who coordinate the RoboSlam Project, I secured two RoboSlam kits*. I then organized a day with Charis at Berkeley School in Baguio City.

Each RoboSlam Kit has a cost price of €15 – €20, which is roughly equivalent of 800-100o Philippine Pesos (depending on the currency rate).

Berkeley School Baguio

Berkeley is a relatively young private school that has recently launched a new educational program for Grade 11 & 12 students (which only was installed into the Filipino Education system in the last few years). The STEM (Science Technology Engineering Mathematics) program aims to help students have a better understanding of STEM-related courses before entering third level education. There are other streams of education that students can choose to enter into, but in this blog I will focus on the STEM programme.

As an engineering student, I tend to reflect on certain things I wished I had learned earlier or technologies I wished I had been exposed to at a younger age, such as coding, electronics, and robotics. By bringing the kits to Charis in Berkeley, I’m hoping it might inspire teenagers who are interested in one day doing STEM-related courses that they should consider engineering. Of course, I don’t know whether RoboSumo will be implemented in this programme, but I just wanted to show the school’s president how simple and affordable it can be to build a robot.

3559016970_2f66a15f46

Boring Part

After meeting Charis for the first time in 8 years,  we did some catching up and toured some of the new facilities of the school which had not been completed at the time. I found out that not much had changed, but it was nice to see the full school being closer to completion and experiencing large student growth numbers. It felt good to be in a creatively shaped building once again.

The Fun Part (Building The Robot)

Thanks to the online resources found on the RoboSlam website that Ted Burke, Damon Berry, Shannon Chance and Frank Duigan have developed, Charis just simply followed the instructions (which are available here). Most of the time, I supervised Charis with building her robot, while giving her advice and assistance whenever she found anything difficult or unclear.

This slideshow requires JavaScript.

We named the robot “Berkeley 01”.  Unfortunately, the rubber bands we tried to put onto the wheels did not stay on, which meant that the plastic wheels were prone to slipping while rotating. We therefore used some double sided tape that was on hand to increase wheel traction. However, as you will see in the video below, it tended to move the paper which was the only white surface available to us. At least it helped us think about the design of future bots.

Hopefully, I’ll be back again soon to do this little workshop with a larger group of students and a bit of RoboSumo!

* Special thanks to the RoboSlam Project at DIT School of Electrical & Electronic Engineering for providing these kits.

Stepper Motor

In this blog post, I will talking about a stepper motor and will be interfacing it with the DSPIC30F4011.

A stepper motor is a brushless DC motor that divides a full rotation into a number of steps. The stepper motor we will be using for this module is the 28BYJ-48 which we will be operating at 5V. Each “Step” is basically a magnetic coil within the motor turning on, as the coil turns on the within the stator, the magnetic field created by the stator turns the rotor, as the rotor turns the next step is made by simply turning off another coil within the stator and off the previous coil. In this circuit diagram and image below show a perfect example of how the coils are wired and how the rotor turns within the motor. The circuit diagram below shows a total of four coils, however, these four coils are only there to represent the circuit electrically, the stator its self is made of many of these “single coils”, the GIF image below shows these coils magnetic field rotating.

This allows for great control as small degree’s of movement can be made with this motor

Typically due to the fact, the dspic cannot feed a high enough level for current to move motors, the SN754410NE driver chip will be used once again to drive the stepper motor, very similar to how the DC motor works.

stepper-motor_schem

Operational Code


// Written by Kevin T
// Code Written on the 16/12/16
// Based on the code written from Ted Burke
// @batchloaf.wordpress.com or @roboted.wordpress.com

#include &lt;xc.h&gt;
#include 			&lt;libpic30.h&gt;
#include &lt;time.h&gt;

//definitions
#define STEP_DELAY 65000

// Configuration settings
_FOSC(CSW_FSCM_OFF &amp; FRC_PLL16); // Fosc=16x7.5MHz, i.e. 30 MIPS
_FWDT(WDT_OFF); // Watchdog timer off
_FBORPOR(MCLR_DIS); // Disable reset pin

//functions must FUNCTION
void full_step_forward();
void full_step_backward();
void half_step_forward();
void half_step_backward();
void steps();

int main()
{
int n = 0;

//configure digital I/O
TRISD = 0b0000; // one digital output for each winding
LATD = 0b0001; // all windings off to start with

while(1)
{
n = n + 1;
if      (n &lt;= 1 ) full_step_forward(); else if (n &gt;= 1 ) full_step_backward();
else if (n &lt;= 2 ) half_step_forward(); else if (n &gt;= 2 ) half_step_backward();
else n = 0;
}

return 0;

}

void half_step_forward()
{
if      (LATD == 0b0001) LATD = 0b1001;
else if (LATD == 0b1001) LATD = 0b1000;
else if (LATD == 0b1000) LATD = 0b1100;
else if (LATD == 0b1100) LATD = 0b0100;
else if (LATD == 0b0100) LATD = 0b0110;
else if (LATD == 0b0110) LATD = 0b0010;
else if (LATD == 0b0010) LATD = 0b0011;
else                     LATD = 0b0001;

__delay32(STEP_DELAY);
}

void full_step_forward()
{
if      (LATD == 0b0001) LATD = 0b1000;
else if (LATD == 0b1000) LATD = 0b0100;
else if (LATD == 0b0100) LATD = 0b0010;
else                     LATD = 0b0001;

__delay32(STEP_DELAY);
}

void half_step_backward()
{
if      (LATD == 0b0001) LATD = 0b0011;
else if (LATD == 0b0011) LATD = 0b0010;
else if (LATD == 0b0010) LATD = 0b0110;
else if (LATD == 0b0110) LATD = 0b0100;
else if (LATD == 0b0100) LATD = 0b1100;
else if (LATD == 0b1100) LATD = 0b1000;
else if (LATD == 0b1000) LATD = 0b1001;
else                     LATD = 0b0001;

__delay32(STEP_DELAY);
}

void full_step_backward()
{
if      (LATD == 0b0001) LATD = 0b0010;
else if (LATD == 0b0010) LATD = 0b0100;
else if (LATD == 0b0100) LATD = 0b1000;
else                     LATD = 0b0001;

__delay32(STEP_DELAY);
}

Unfortunately, my code does not transition between direction very quickly this video has been brought up to twice the original speed of the video recorded, so please do skip to 0:35, 1:10, 1:45, and 2:20 to see the direction change. And yes I did record that video for 5 minutes I would of speed up the video a bit more, however, my phone only allows me to speed it up to twice the speed max, hopefully, the background music. enjoy!

Body Guard Bot (Build)

For my mini-project, I have decided to create a simple bodyguard robot. Its main functions are protect something in a certain place area and if someone were to come close to that area the robot will try to prevent you from entering that area.

All my previous codes were built and designed to work with the final mini-project.

The construction of the robot uses two pan and tilt servo motor kits which were purchased from the robotshot.com and a few other parts to keep the whole system together.

Movement of the arms (servo motors) are controlled by the output compare [OC1 – OC4] module within the DSPIC main reason why I swapped from the PWM channels to the output compare was I had 4 servo motors to be used and only 3 PWM channels, also I had two motors that needed to be used for PWM to vary the speed at which they turn. So the best and efficent way of controlling the servo motors was with the output compare module located on all 4 RD pins, the motors, and the LED are controlled by RB pins configured in digital output mode [RB5 – RB9], while the IR range sensors the ADC [AN1 – AN2].

This slideshow requires JavaScript.

Circuit Diagram

servo-motor_schem

Although the circuit diagram above shows that there is an IR colour sensor, in the end, I wasn’t able to add it to follow or detect white lines on the ground, this was due to time constraints however in the future I plan to continue to upgrade this robot with more features.

Power Issue

After the robot was constructed both mechanically and electrically one noticeable problem after uploading the code onto the DSpic was that the robot was restarting very frequently. After setting up an oscilloscope and applying it across the voltage rail, it was noted that voltage was not stable due to power consumption from all the motors (a total of 6). So quick fix to allow for the voltage not to drop below 5volts and resetting the DSpic was to add another battery pack, in parallel (so that voltage doesn’t double but the current). With more current carrying capacity from the voltage source, the voltage rail was stable and the robot functioned without resetting.

img_3793

 

 

 

 

 

Possible States

In this code, I did not use a state machine as I felt there wasn’t a need to however, there are 4 possible actions coming from the bodyguard robot I have listed them down below.

 State  Action  Actuators State Transition
 1 Move Forward

Arms down

Left & Right Motor Forward

Left & Right Arms Down

 If Right & Left Range Finder Are within Threshold move to state 2

If Right Range Finder is within Threshold move to state 3

If Left Range Finder is within Threshold move to state 4

 2 Full Stop

Both Arms Up

Left & Right Motor Fully Stop

Left & Right Arms up

If Right Range Finder is within Threshold move to state 3

If Left Range Finder is within Threshold move to state 4

If Left & Right Range Finder are not within Threshold move to state 1

3 Turn Right

Right Arm Up

Right Motor Forward Left Motor Stop

Right Arm up       Left Arm Down

  If Right & Left Range Finder Are within Threshold move to state 2

If Left Range Finder is within Threshold move to state 4

If Left & Right Range Finder are not within Threshold move to state 1

 4  Turn Left

Left Arm Up

Left Motor Forward Right Motor Stop

Left Arm up             Right Arm Down

If Right & Left Range Finder Are within Threshold move to state 2

If Right Range Finder is within Threshold move to state 3

If Left & Right Range Finder are not within Threshold move to state 1

Code that runs this contraption


// Final Code that makes the body move forward, turn left or right
// depending on what the two range finder sensors see individually
// last updated 11-1-2017
// Written by Kevin Tighe
// code based on Batchloaf/Roboted.wordpress.com by Ted Burke

//important stuff
#include &lt;xc.h&gt;
#include &lt;libpic30.h&gt;

//Hash_define
#define Second 30000000

//More important stuff
_FOSC(CSW_FSCM_OFF &amp; FRC_PLL16); // Clock speed = 7.5MHz x 16, i.e. 30 MIPS
_FWDT(WDT_OFF);                  // Watchdog timer off
_FBORPOR(MCLR_DIS);              // Disable reset pin

//Functions
unsigned int read_analog_channel(int channel);
void SetArmPositionLeft();
void SetArmPositionRight();
void Backward();
void Left();
void Right();
void Stop();

int main(void)
{
     // Configure RB pins to be digital and Analogue
    ADPCFG = 0b11111000;

    // Configure AN0as analog inputs
    ADCON3bits.ADCS = 15;  // Tad = 266ns, conversion time is 12*Tad
    ADCON1bits.ADON = 1;   // Turn ADC ON

    // Make RB4 and RD8 digital outputs;
    LATB = 0;
    TRISB = 0b000001111;

    // Configure Timer 2 (default timer for output compare)
    T2CONbits.TCKPS = 0b10; // Timer 2 prescaler 1:64
    PR2 = 9375;             // Timer 2 period (20ms)
    T2CONbits.TON = 1;      // Enable Timer 2

    // Configure Output Compare channels
    OC1CONbits.OCM = 0b101; // continuous pulse mode
    OC1R = 0;               // pulse start time
    OC1RS = 703;            // pulse stop time
    OC2CONbits.OCM = 0b101;
    OC2R = 0;
    OC2RS = 703;
    OC3CONbits.OCM = 0b101;
    OC3R = 0;
    OC3RS = 703;
    OC4CONbits.OCM = 0b101;
    OC4R = 0;
    OC4RS = 703; 

    // Configure PWM
    // PWM period = PTPER * prescale * Tcy = 9470 * 64 * 33.33ns = 20ms
    _PMOD1 = 0; // PWM channel 3 mode: 0 for complementary, 1 for independent
    _PEN1H = 1; // PWM1H pin enable: 1 to enable, 0 to disable
    _PTCKPS = 3; // PWM prescaler setting: 0=1:1, 1=1:4, 2=1:16, 3=1:64
    PTPER = 9470; // Set PWM time base period to 20ms (15-bit value)
    PDC1 = 0; // 0% duty cycle on channel 1 (16-bit value)
    _PTEN = 1; // Enable PWM time base to start generating pulses

    int r;
    for(r=0 ; r&lt;10 ; ++r)
    {
        _LATB4 = 1;
        __delay32(1500000);
        _LATB4 = 0;
        __delay32(1500000);
    }

    // Configure max and min OC1RS values
    int min = 260;  // OC1RS value for 0 degrees
    int max = 1070; // OC1RS value for 180 degrees

    // An Array of angles for arm movement.
    //                            0      1      2      3      4      5      6      7      8     9     10     11     12     13     14     15     16     17     18
    float LeftShoulder  [] = {  0.0,  10.0,  20.0,  30.0,  40.0,  50.0,  60.0,  70.0,  80.0, 90.0, 100.0, 110.0, 120.0, 130.0, 140.0, 150.0, 160.0, 170.0, 180.0};
    float LeftElbow     [] = {  0.0,  10.0,  20.0,  30.0,  40.0,  50.0,  60.0,  70.0,  80.0, 90.0, 100.0, 110.0, 120.0, 130.0, 140.0, 150.0, 160.0, 170.0, 180.0};
    float RightShoulder [] = {180.0, 170.0, 160.0, 150.0, 140.0, 130.0, 120.0, 110.0, 100.0, 90.0,  80.0,  70.0,  60.0,  50.0,  40.0,  30.0,  20.0,  10.0,   0.0};
    float RightElbow    [] = {180.0, 170.0, 160.0, 150.0, 140.0, 130.0, 120.0, 110.0, 100.0, 90.0,  80.0,  70.0,  60.0,  50.0,  40.0,  30.0,  20.0,  10.0,   0.0};

    int threshold  = 256;
    //int threshold2 = 256

    while(1)
    {
        if      (read_analog_channel(1) &lt; threshold &amp;&amp; read_analog_channel(2) &lt; threshold)
        {
        Right();
        Left();
        SetArmPositionRight(RightShoulder[0], RightElbow[7]);
        SetArmPositionLeft(LeftShoulder[0], LeftElbow[7]);
        __delay32(Second/10);
        }
        else if (read_analog_channel(1) &gt; threshold &amp;&amp; read_analog_channel(2) &gt; threshold)
        {
            _LATB4 = 1;
            SetArmPositionRight(RightShoulder[12], RightElbow[10]);     //Right Arm up
            SetArmPositionLeft(LeftShoulder[12], LeftElbow[10]);        //Left Arm up
            Stop();                                                     //Stop Both Motors
            __delay32(Second/10);                                       //Delay to keep servo motors steady in position
        }

        else if (read_analog_channel(1) &gt; threshold)                    //Right Sensor has detected something
        {
            SetArmPositionRight(RightShoulder[12], RightElbow[7]);      //Raise Right arm
            SetArmPositionLeft(LeftShoulder[0], LeftElbow[7]);
            Stop();
            Right();                                                    //Turn rightmotor to follow person
            __delay32(Second/10);
        }

        else if (read_analog_channel(2) &gt; threshold)                    //Left Sensor has detected something
        {
            SetArmPositionRight(RightShoulder[0], RightElbow[7]);
            SetArmPositionLeft(LeftShoulder[12], LeftElbow[7]);         //Riase Left arm
            Stop();
            Left();                                                     //Turn leftmotor to follow person
            __delay32(Second/10);
        }
    }
}

//Arm Functions
void SetArmPositionLeft(double shoulder, double elbow)
{
    // Configure max and min OC1RS values
    int min = 260;  // OC1RS value for 0 degrees
    int max = 1070; // OC1RS value for 180 degrees

    OC1RS = min + (shoulder/180.0)*(max-min); // Left Arm
    OC4RS = min + (elbow/180.0)*(max-min);
}
void SetArmPositionRight(double shoulder, double elbow)
{
     // Configure max and min OC1RS values
    int min = 260;  // OC1RS value for 0 degrees
    int max = 1070; // OC1RS value for 180 degrees

    OC2RS = min + (shoulder/180.0)*(max-min);// Right Arm
    OC3RS = min + (elbow/180)*(max-min);
}

//Motor Functions
void Stop()
{
    _LATB5 = 0;
    _LATB6 = 0;
    _LATB7 = 0;
    _LATB8 = 0;
}

void Right()
{
    _LATB5 = 1;
    _LATB6 = 0;
    PDC1 = 0.9 * 2 * PTPER;     // 90% duty cycle
}

void Left()
{
    _LATB7 = 1;
    _LATB8 = 0;
    PDC1 = 0.9 * 2 * PTPER;     // 90% duty cycle
}

// This function reads a single sample from the specified
// analog input. It should take less than 5us when the
// microcontroller is running at 30 MIPS.
// The dsPIC30F4011 has a 10-bit ADC, so the value
// returned is between 0 and 1023 inclusive.
unsigned int read_analog_channel(int channel)
{
    ADCHS = channel;          // Select the requested channel
    ADCON1bits.SAMP = 1;      // Start sampling
    __delay32(30);            // 1us delay @ 30 MIPS
    ADCON1bits.SAMP = 0;      // Start Converting
    while (!ADCON1bits.DONE); // Should take 12 * Tad = 3.2us
    return ADCBUF0;
}

A selection of videos of the robot operational to the build Enjoy!

 

Tools

Microcontroller

As part of Robotics 3.1 Module, I have been given the task of operating a few actuators with the DSPIC30F4011. The DSPIC30F series is a 16-bit signal controller that allows for both Pulse Width Modulation (PWM) for motor control and analog and digital inputs that can be used for control mechanisms or some really awesome robotic projects. A pickit2 is the medium device used to connect to the DSpic30 to the PC to program it. The pickit2 can power up the DSPIC however due to safety mechanisms or maximum current output from the pickit there will be moments where the I will have to use the battery pack provided to power up the system, an example of this would be when motors are used due to the level of current that is needed to produce torque.

Text Editor

It was recommended to use Notepad ++ which is installed in most of the computers in college however, due to my experience in web development I’ve decided to stick with using Subline Text as I found it a great text editor to use, theoretically it does not matter what type of text editor you use to write any computer code language, however with its simplicity and features I personally have found it handy in helpful when debug code.

Compiler

The compiler used to convert the c-code into machine code was the xc compiler which is downloadable for free.