Autonomous Smart Suitcase Pixy Camera!

About: Hi, this is Ali Shwaiheen. I`m here to share knowledge and experience gained in the field of Electrical Engineering and learning cool things you make. I`m enjoying being member of this community.
  • Definition

ASS is an autonomous smart suitcase that will follow the user wherever he goes. Apart from this it also has additional features such as lost mode, bag fall detection and an LCD to display the user information. The bag will mainly be used by commuters, handicapped people and others in indoor facilities.

We all know the hassle of pushing along our baggage in the airport. It is a tedious process that aggravates our tiredness and difficulty during the journey. The aim of our project “autonomous smart suitcase” is to eliminate the issue of pushing the suitcase around. Not only this I will also be adding additional functionality to the suitcase that will make my suitcase more easy to use and convenient.

  • Applications

ASS has applications in the following areas:

· Airports as luggage

· Universities

· Hospitals

· Offices

· Other indoor facilities

Step 1: Components Required

Step 2: Project Specification and Objectives

  • Specification

•Max weight of luggage: 7 Kg.

•Speed: 5 km/h.

•Operating Time on full charge: 3 Hours.

•Wireless: Bluetooth, GPRS, and GPS.

•Image recognition: 2 m Max distance, 20 cm stop

  • Objectives

1.Simulates the latest advanced technology of the actual autonomously following.

2.Reduces the need for the human control interference.

3.Acquires capability to develop the artificial intelligence systems.

4.Acquiring the ability to integrate theoretical knowledge and practical skills by designing a real-world application based on specification requirements

Step 3: Parts Description

Pixy2 CMUcam5 Smart Vision Sensor.

Pixy2 is smaller, faster and more capable than the original Pixy. Like its predecessor, Pixy2 can learn to detect objects that you teach it, just by pressing a button. Additionally, Pixy2 has new algorithms that detect and track lines for use with line-following robots. The new algorithms can detect intersections and “road signs” as well. The road signs can tell your robot what to do, such as turn left, turn right, slow down, etc. And Pixy2 does all of this at 60 frames-per-second, so your robot can be fast, too. Find More HERE|

L298N Motor Drive Controller.

L-298 has two enable input to control any device by enabling or disabling it. L 298 IC is most commonly used to make motor drivers or motor controllers. These motor controllers can be controlled by any micro controller e.g Arduino, PIC, Raspberry Pi etc. They receives input from micro controllers and operate the load attached to their output terminals correspondingly. L-298 motor driver (H-Bridge) is able to control two different DC motors simultaneously. While it can control a single stepper motor as well. L 298 has two Pulse Width Modulation (PWM) pins. PWM pins are used to control the speed of the motor. By changing the voltage signal’s polarity at its input we can rotate the motor in either clockwise or counter clockwise direction. Find more HERE!

GPS breakout board

The breakout is built around the MTK3339 chipset, a no-nonsense, high-quality GPS module that can track up to 22 satellites on 66 channels, has an excellent high-sensitivity receiver (-165 dB tracking!), and a built in antenna. It can do up to 10 location updates a second for high speed, high sensitivity logging or tracking. Power usage is incredibly low, only 20 mA during navigation. Find more HERE!

Ultrasonic Module.

The HC-SR04 ultrasonic sensor uses sonar to determine distance to an object like bats do. It offers excellent non-contact range detection with high accuracy and stable readings in an easy-to-use package.
From 2cm to 400 cm or 1” to 13 feet. Its operation is not affected by sunlight or black material like sharp rangefinders are (although acoustically soft materials like cloth can be difficult to detect). It comes complete with ultrasonic transmitter and receiver module. Find more HERE!

Arduino GSM Shield

The Arduino GSM Shield V2 connects your Arduino to the internet using the GPRS wireless network. Just plug this module onto your Arduino board, plug in a SIM card from an operator offering GPRS coverage and follow a few simple instructions to start controlling your world through the internet. You can also make/receive voice calls using the on-board audio/mic jack and send/receive SMS messages. Find more HERE!

Step 4: Architecture

Subsystem 1: Wireless communication

Main functions:

GPRS Communication between bag and the user

GPS signal reception for the bag

Bluetooth connection between user and the bag

Hardware used:

GSM chip

GPS chip

HC 06 Bluetooth chip

Android device

Subsystem 2: User following autonomous mode

Main functions:

Follow the user autonomously

Detect of the bag falls down and make a notification

Receive image data using the camera

Detect the users legs

Move the bag according to the position of the user

Stop if he is very close to the user

Hardware used:

DC motor

DC motor controller

Ping transmitter

ping receivers

Camera and processor

Subsystem 3: Sensory sub system

Main functions:

Detect the orientation of the bag using an accelerometer

Play the buzzer in case the bag is lost

Display message in case the bag is lost

Hardware used:




Step 5: Autonomous Mode Video

This video showing the ASS in the autonomous following mode

Step 6: Bluetooth Mode Video

This video showing the ASS in the Manual Mode

Step 7: Falling Detect Mode Video

This video showing the ASS in the Detect Mode

Step 8: The Android App

You Can download for the Google store HERE!

Step 9: Codes Sample!



SoftwareSerial GPRS(7, 8); //7 = TX, 8 = RX

unsigned char buffer[64]; port

int count=0;

int i = 1; //if i = 0, send SMS.

void setup(){


GPRS.begin(19200); // the GPRS baud rate

Serial.begin(19200); // the Serial port of Arduino baud rate.

Serial.print("I'm ready");



void loop(){

if (GPRS.available()){ // if date is comming from softwareserial port ==> data is comming from gprs shield

while(GPRS.available()){ // reading data into char array

buffer[count++]; // writing data into array

if(count == 64)break;


Serial.write(buffer,count); // if no data transmission ends, write buffer to hardware serial port

clearBufferArray(); // call clearBufferArray function to clear the storaged data from the array

count = 0; // set counter of while loop to zero


if (Serial.available()) // if data is available on hardwareserial port ==> data is comming from PC or notebook

GPRS.write(; // write it to the GPRS shield

if(i == 0){

GPRS.print("AT+CMGF=1\r"); //sending SMS in text mode



GPRS.print("AT+CMGS=\"+554988063979\"\r"); // phone number



GPRS.print("Test\r"); // message



GPRS.write(0x1A); //send a Ctrl+Z(end of the message)


Serial.println("SMS sent successfully");




void clearBufferArray(){ // function to clear buffer array

for (int i=0; i

buffer[i]=NULL; // clear all index of array with command NULL






Reads an Analog Devices ADXL3xx accelerometer and communicates the

acceleration to the computer. The pins used are designed to be easily

compatible with the breakout boards from SparkFun, available from:

The circuit:

- analog 0: accelerometer self test

- analog 1: z-axis

- analog 2: y-axis

- analog 3: x-axis

- analog 4: ground

- analog 5: vcc

created 2 Jul 2008

by David A. Mellis

modified 30 Aug 2011

by Tom Igoe

This example code is in the public domain.


// these constants describe the pins. They won't change:

const int groundpin = 18; // analog input pin 4 -- ground

const int powerpin = 19; // analog input pin 5 -- voltage

const int xpin = A3; // x-axis of the accelerometer

const int ypin = A2; // y-axis

const int zpin = A1; // z-axis (only on 3-axis models)

void setup() {

// initialize the serial communications:


// Provide ground and power by using the analog inputs as normal digital pins.

// This makes it possible to directly connect the breakout board to the

// Arduino. If you use the normal 5V and GND pins on the Arduino,

// you can remove these lines.

pinMode(groundpin, OUTPUT);

pinMode(powerpin, OUTPUT);

digitalWrite(groundpin, LOW);

digitalWrite(powerpin, HIGH);


void loop() {

// print the sensor values:


// print a tab between values:



// print a tab between values:




// delay before next reading:



1.2 Motor

const int pwm = 2 ; //initializing pin 2 as pwm

const int in_1 = 8 ;

const int in_2 = 9 ;

//For providing logic to L298 IC to choose the direction of the DC motor

void setup() {

pinMode(pwm,OUTPUT) ; //we have to set PWM pin as output

pinMode(in_1,OUTPUT) ; //Logic pins are also set as output

pinMode(in_2,OUTPUT) ;


void loop() {

//For Clock wise motion , in_1 = High , in_2 = Low

digitalWrite(in_1,HIGH) ;

digitalWrite(in_2,LOW) ;

analogWrite(pwm,255) ;

/* setting pwm of the motor to 255 we can change the speed of rotation

by changing pwm input but we are only using arduino so we are using highest

value to driver the motor */

//Clockwise for 3 secs

delay(3000) ;

//For brake

digitalWrite(in_1,HIGH) ;

digitalWrite(in_2,HIGH) ;

delay(1000) ;

//For Anti Clock-wise motion - IN_1 = LOW , IN_2 = HIGH

digitalWrite(in_1,LOW) ;

digitalWrite(in_2,HIGH) ;

delay(3000) ;

//For brake

digitalWrite(in_1,HIGH) ;

digitalWrite(in_2,HIGH) ;

delay(1000) ;




* Bluetooh Basic: LED ON OFF - Avishkar

* Coder - Mayoogh Girish

* Website -

* Download the App :

* This program lets you to control a LED on pin 13 of arduino using a bluetooth module


char data = 0; //Variable for storing received data

void setup()


Serial.begin(9600); //Sets the baud for serial data transmission

pinMode(13, OUTPUT); //Sets digital pin 13 as output pin


void loop()


if(Serial.available() > 0) // Send data only when you receive data:


data =; //Read the incoming data & store into data

Serial.print(data); //Print Value inside data in Serial monitor


if(data == '1') // Checks whether value of data is equal to 1

digitalWrite(13, HIGH); //If value is 1 then LED turns ON

else if(data == '0') // Checks whether value of data is equal to 0

digitalWrite(13, LOW); //If value is 0 then LED turns OFF



Step 10: Codes for the GPS Tracker

/******************************************************************** * AltSoftSerial always uses these pins for Serial communication: * * * * Board Transmit Receive PWM Unusable * * ----- -------- ------- ------------ * * Teensy 3.0 & 3.1 21 20 22 * * Teensy 2.0 9 10 (none) * * Teensy++ 2.0 25 4 26, 27 * * Arduino Uno 9 8 10 * * Arduino Leonardo 5 13 (none) * * Arduino Mega 46 48 44, 45 * * Wiring-S 5 6 4 * * Sanguino 13 14 12 * *********************************************************************/ #include #include #include SoftwareSerial GPRS(2, 3); // RX, TX TinyGPSPlus gps; // The TinyGPS++ object for interfacing with the GPS AltSoftSerial ss; char c; void setup() { pinMode(12,OUTPUT); pinMode(7, OUTPUT); Power_gsm(); ss.begin(9600); // begin the GPS serial connection GPRS.begin(9600); // Start software serial delay(2000); GPRS.println("AT+CMGF=1"); // AT+CMGF Select SMS Massage Format delay(100); GPRS.println("AT+CNMI=1,2,0,0,0"); // AT+CNMI New SMS Massage INdication delay(100); GPRS.println("AT+CMGD=1,4"); // AT+CMGD=1,4 Range of SMS on SIM card Can be deleted delay(1000); //SMSsend("SYSTEM IS ON:)");//2 GPRS.flush(); // deleting all massages at the first boot delay(100); } void loop() { while (ss.available() > 0) if (gps.encode( while (GPRS.available()) { delay(3); c =; if (c == 'D') { if (GPRS.available()) { delay(3); c =; if (c == 'o') { digitalWrite(12,HIGH); Senddata(); } else if (c == 'c') { digitalWrite(12, LOW); } } } } GPRS.flush(); } void Power_gsm() { digitalWrite(7, HIGH); delay(3000); digitalWrite(7, LOW); } void Senddata() { GPRS.print("AT+CMGF=1\r"); // Carriage return delay(100); GPRS.println("AT+CMGS=\"+966569634067\""); // replace x by your number ("AT+CMGS=\"+966xxxxxxxxx\""); to yours delay(100); // (+966) is the country code replace it with yours GPRS.print(""); GPRS.print(, 6); GPRS.print(","); GPRS.print(gps.location.lng(), 6); GPRS.println((char)26); GPRS.println(); delay(100); GPRS.println("AT+CMGD=1,4"); // some AT Commands delay(100); GPRS.println("AT+CMGF=1"); delay(100); GPRS.println("AT+CNMI=1,2,0,0,0"); delay(200); }

Step 11: The Hole Program

#include #include #include #include #include #include // SparkFun ADXL345 Library Pixy pixy; ADXL345 adxl = ADXL345(); // USE FOR I2C COMMUNICATION int buzzer = 8; int fstop = 0; int x_c; char serialchar = ' '; int h_c; int enA = 2;//black to blue int in1 = 3;//white int in2 = 4;//orange // motor two int dist1 = 0; int dist2 = 0; int dist3 = 0; int dist0 = 0; int s1 = 14; int s2 = 15; int enB = 9;//blue int in3 = 5;//yellow int in4 = 6;//green int bstop = 0; char recv; #define SONAR_NUM 1// Number or sensors.XXXXXCHANGED #define MAX_DISTANCE 500 // Max distance in cm. #define PING_INTERVAL 200 // Milliseconds between pings char recvc = 'x'; //int front = 5; //int back = 6; //int left =2; //int right = 3; //unsigned long pingTimer[SONAR_NUM]; // When each pings. //unsigned int cm[SONAR_NUM]; // Store ping distances. int cm[SONAR_NUM]; // Store ping distances. uint8_t currentSensor = 0; // Which sensor is active. const int buttonPin = 40; const int button2Pin = 44; int buttonState = 0; int button2State = 0; int units = US_ROUNDTRIP_CM; char* unitText[] = {"cm", "in"}; int diffU; int diffD; int diffL; int diffR; //SoftwareSerial bluetooth(2,3); NewPing sonar[SONAR_NUM] = { // Sensor object array. NewPing(46, 45, MAX_DISTANCE), }; void calc_dist() { delay(50); // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings. unsigned int uS0 = sonar[0].ping(); // Send ping, get ping time in microseconds (uS). dist0 = uS0 / US_ROUNDTRIP_CM; Serial.print(dist0); // Convert ping time to distance in cm and print result (0 = outside set distance range) Serial.println("cm0"); //delay(250); } void ADXL_ISR() { // getInterruptSource clears all triggered actions after returning value // Do not call again until you need to recheck for triggered actions byte interrupts = adxl.getInterruptSource(); // Free Fall Detection if (adxl.triggered(interrupts, ADXL345_FREE_FALL)) { Serial.println("*** FREE FALL ***"); //add code here to do when free fall is sensed } // Inactivity if (adxl.triggered(interrupts, ADXL345_INACTIVITY)) { Serial.println("*** INACTIVITY ***"); //add code here to do when inactivity is sensed } // Activity if (adxl.triggered(interrupts, ADXL345_ACTIVITY)) { Serial.println("*** ACTIVITY ***"); //add code here to do when activity is sensed } // Double Tap Detection if (adxl.triggered(interrupts, ADXL345_DOUBLE_TAP)) { Serial.println("*** DOUBLE TAP ***"); //add code here to do when a 2X tap is sensed } // Tap Detection if (adxl.triggered(interrupts, ADXL345_SINGLE_TAP)) { Serial.println("*** TAP ***"); //add code here to do when a tap is sensed } } void seeAcc() { int x, y, z; adxl.readAccel(&x, &y, &z); // Read the accelerometer values and store them in variables declared above x,y,z // Output Results to Serial /* UNCOMMENT TO VIEW X Y Z ACCELEROMETER VALUES */ Serial.print(x); Serial.print(", "); Serial.print(y); Serial.print(", "); Serial.println(z); if ((y < -5) || (y > 15) || (x < -35) || (x > -3)) { digitalWrite(buzzer, HIGH); } else { digitalWrite(buzzer, LOW); } ADXL_ISR(); } void stops() { // now turn off motors digitalWrite(in1, LOW); digitalWrite(in2, LOW); digitalWrite(in3, LOW); digitalWrite(in4, LOW); } void left() { analogWrite(enA, 200); analogWrite(enB, 200); digitalWrite(in1, HIGH); digitalWrite(in2, LOW); digitalWrite(in3, LOW); digitalWrite(in4, HIGH); } void right() { analogWrite(enA, 255); analogWrite(enB, 240); stops(); digitalWrite(in3, HIGH); digitalWrite(in4, LOW); digitalWrite(in1, LOW); digitalWrite(in2, HIGH); } void forward() { analogWrite(enA, 255); analogWrite(enB, 255); digitalWrite(in3, HIGH); digitalWrite(in4, LOW); digitalWrite(in1, HIGH); digitalWrite(in2, LOW); } void back() { digitalWrite(in1, LOW); digitalWrite(in2, HIGH); digitalWrite(in3, LOW); digitalWrite(in4, HIGH); } void setup() { pixy.init(); adxl.powerOn(); // Power on the ADXL345 adxl.setRangeSetting(16); // Give the range settings // Accepted values are 2g, 4g, 8g or 16g // Higher Values = Wider Measurement Range // Lower Values = Greater Sensitivity adxl.setSpiBit(0); // Configure the device to be in 4 wire SPI mode when set to '0' or 3 wire SPI mode when set to 1 // Default: Set to 1 // SPI pins on the ATMega328: 11, 12 and 13 as reference in SPI Library adxl.setActivityXYZ(1, 0, 0); // Set to activate movement detection in the axes "adxl.setActivityXYZ(X, Y, Z);" (1 == ON, 0 == OFF) adxl.setActivityThreshold(75); // 62.5mg per increment // Set activity // Inactivity thresholds (0-255) adxl.setInactivityXYZ(1, 0, 0); // Set to detect inactivity in all the axes "adxl.setInactivityXYZ(X, Y, Z);" (1 == ON, 0 == OFF) adxl.setInactivityThreshold(75); // 62.5mg per increment // Set inactivity // Inactivity thresholds (0-255) adxl.setTimeInactivity(10); // How many seconds of no activity is inactive? adxl.setTapDetectionOnXYZ(0, 0, 1); // Detect taps in the directions turned ON "adxl.setTapDetectionOnX(X, Y, Z);" (1 == ON, 0 == OFF) // Set values for what is considered a TAP and what is a DOUBLE TAP (0-255) adxl.setTapThreshold(50); // 62.5 mg per increment adxl.setTapDuration(15); // 625 μs per increment adxl.setDoubleTapLatency(80); // 1.25 ms per increment adxl.setDoubleTapWindow(200); // 1.25 ms per increment // Set values for what is considered FREE FALL (0-255) adxl.setFreeFallThreshold(7); // (5 - 9) recommended - 62.5mg per increment adxl.setFreeFallDuration(30); // (20 - 70) recommended - 5ms per increment // Setting all interupts to take place on INT1 pin //adxl.setImportantInterruptMapping(1, 1, 1, 1, 1); // Sets "adxl.setEveryInterruptMapping(single tap, double tap, free fall, activity, inactivity);" // Accepts only 1 or 2 values for pins INT1 and INT2. This chooses the pin on the ADXL345 to use for Interrupts. // This library may have a problem using INT2 pin. Default to INT1 pin. // Turn on Interrupts for each mode (1 == ON, 0 == OFF) adxl.InactivityINT(1); adxl.ActivityINT(1); adxl.FreeFallINT(1); adxl.doubleTapINT(1); adxl.singleTapINT(1); //attachInterrupt(digitalPinToInterrupt(interruptPin), ADXL_ISR, RISING); // Attach Interrupt pinMode(enB, OUTPUT); pinMode(s1, INPUT); pinMode(s2, INPUT); pinMode(buzzer, OUTPUT); pinMode(in1, OUTPUT); pinMode(in2, OUTPUT); pinMode(in3, OUTPUT); pinMode(in4, OUTPUT); analogWrite(enA, 255); analogWrite(enB, 255); Serial.begin(9600); Serial3.begin(9600); } void loop() { //forward(); calc_dist(); { seeAcc(); detect(); //BLUETOOTH char a =; if (a > 0) Serial.println(a); analogWrite(enA, 180); analogWrite(enB, 180); if (a == 'a') { forward(); delay(500); } else if (a == 'e') { back(); delay(200); } else if (a == 'd') { right(); delay(350); } else if (a == 'b') { left(); delay(350); } if (a == 'c') { stops(); } } } void detect() { static int i = 0; int j; uint16_t blocks; char buf[32]; // grab blocks! blocks = pixy.getBlocks(); // If there are detect blocks, print them! if (blocks) { i++; // do this (print) every 50 frames because printing every // frame would bog down the Arduino if (i % 5 == 0) { sprintf(buf, "Detected %d:\n", blocks); // Serial.println(buf); for (j = 0; j < blocks; j++) { sprintf(buf, " block %d: ", j); // Serial.println(buf); if (x_c > 225) { stops(); Serial.println("right"); right(); delay(200); stops(); } if (x_c < 115) { stops(); Serial.println("left"); left(); delay(200); stops(); } if (x_c > 115 && x_c < 225) { stops(); Serial.println("front"); forward(); delay(300); stops(); } else { Serial.println("stop"); stops(); } } } } }

Step 12: Thank You



    • PCB Contest

      PCB Contest
    • Warm and Fuzzy Contest

      Warm and Fuzzy Contest
    • Comfort Food Challenge

      Comfort Food Challenge