Project tutorial
deCart

deCart

a cart that drives you to give.

  • 1,590 views
  • 10 comments
  • 0 respects

Components and supplies

About this project

Description

deCart is an attachment to a shopping cart that uses social pressure to make the shopping a more productive, connected experience for society as a whole. 

Motto: I give, therefore I am. -deCart

Concept Video

List of Materials

Although the entire premise of the project is simple, the implementation, however, is not and requires a lot of patience and system building. 

  1. LCD Display. For us, we used Sparkfun's Basic 16x2 Character LCD - White on Black 5V. See  https://www.sparkfun.com/products/709.
  2. 11 x LED lights. One to indicate selfishness (we used red), the other ten to indicate progress bar (we used yellow; colors are up to your discretion). 
  3. Speaker circuitry and any 8-ohm speaker. Specifically, this breakout board https://www.sparkfun.com/products/11125 and amplifierhttps://www.sparkfun.com/products/11125
  4. Bluetooth Modem - BlueSMIRF module from Sparkfun - https://www.sparkfun.com/products/12582.
  5. Materials needed to construct the box. In our case, we used simple wood. 
  6. Arduino Mega 2560. 
  7. 1x Piezo drum sensor. 

Step by Step of our Build Process (Hardware)

Step 1: Familiarize yourself with the Circuitry!

Test each individual circuit and get a handle of the connections. For example, try turning on the LCD display, controlling the progress bar, flashing the selfish light, etc.

Step 2: Construct the Design!

See the roughDesign.DXF file. For us, we made our product by laser cutting wood.

Step 3: The Interface Components

Hot glue all the components that have slits for them! Example: the LCD display, speaker, and the LED lights. Make sure that they fit snugly in and they don't protrude outwards.

Step 4: Wire them!

Each LED light needs to be connected in series to a 200 ohm resistor and not to mention that all their grounds need to be shared. For the LCD display and speaker, I would recommend using a protoboard. For me, I created a makeshift shield for the Arduino Mega, soldered on the speaker circuitry, and had all wires eventually lead into this board.

Step 5: Wire, Wire, Wire.

Don't forget about the Piezo drum sensor and the bluetooth module!

Step 6: Wire.

Hey, when did the sun go up?

Step 7: Cry.

Helps you wire more afterwards.

Step 8: Final wiring and enclosure

After finally connecting all circuitry and ensuring there are no shorts, hot glue the pieces and you're done! Congratulations! :) Use a 9 volt battery to charge your deCart.

App Code

Features - Current and Future

Current

  • Ten LED lights that serves as a progress bar for two modes - one for collective goal towards a charity, the other for your personal contributions. 
  • Knocking on it to change modes.
  • A red LED light that marks the "selfishness" of a person. The faster it blinks, the more selfish and vice versa. To slow down the speed, users will have to donate items.
  • LCD display showing current contributions and comments. 
  • Sound effects for successful and the not so successful donations. 
  • Interfacing with an App that serves as a scanner. 

Future>

  • Implement snap-on feature and experiment more with design so that it can more easily rest on the handle bar of the shopping cart. 
  • Also add vibrate and hot/cold feedback. 
  • Have it smart enough to make shopping cart "smartly" gravitate towards item of interest.

Design

Box Design

Design

Building

The Arduino Code

decart2.ino
The Arduino Code

Warning: Embedding code files within the project story has been deprecated. To edit this file or add more files, go to the "Software" tab. To remove this file from the story, click on it to trigger the context menu, then click the trash can button (this won't delete it from the "Software" tab).

/*
 Decart Arduino Code
 Author: Felix Li
 */

#include <LiquidCrystal.h>
#include <Wtv020sd16p.h>
#include <SoftwareSerial.h>  

//---------LCD DISPLAY---------

//Pin Layout
#define RS 13
#define E 12

#define D4 6
#define D5 7
#define D6 9
#define D7 8

#define NUM_COLS 16
#define NUM_ROWS 2

LiquidCrystal lcd(RS, E, D4, D5, D6, D7);

//---------SOUND MODULE---------
#define resetPin 2  // The pin number of the reset pin.
#define clockPin 3   // The pin number of the clock pin.
#define dataPin 4   // The pin number of the data pin.
#define busyPin 5   // The pin number of the busy pin.
#define shutDownPin 23

Wtv020sd16p wtv020sd16p(resetPin,clockPin,dataPin,busyPin);


//---------PROGRESS BAR---------
#define LED10 24
#define LED9 26
#define LED8 28
#define LED7 30

#define LED6 40
#define LED5 42
#define LED4 44
#define LED3 46
#define LED2 48
#define LED1 50

//---------SELFISH LIGHT---------
#define SELF_LED 29
unsigned long lastTime = 0;
int TOGGLE = 200;
boolean SELFISH = true;

//---------BLUETOOTH MODULE---------
#define bluetoothTx 10
#define bluetoothRx 11

//---------PIEZO SENSOR---------
#define PIEZO A2
#define TIME_DELAY 1500
int THRESHOLD = 30;
unsigned long SOUND_NOISE = 0;
boolean NOISY = false;

SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);

//---------GLOBAL VARIABLES/STATES---------
#define PERSONAL 0
#define CHARITY 1
#define NUM_OF_MODES 2
int mode = PERSONAL;
int personal_donations = 0;

void setup() {
  //Initializes the module.
  Serial.begin(9600);

  bluetooth.begin(115200);  // The Bluetooth Mate defaults to 115200bps
  bluetooth.print("$");  // Print three times individually
  bluetooth.print("$");
  bluetooth.print("$");  // Enter command mode
  delay(100);  // Short delay, wait for the Mate to send back CMD
  bluetooth.println("U,9600,N");  // Temporarily Change the baudrate to 9600, no parity
  // 115200 can be too fast at times for NewSoftSerial to relay the data reliably
  bluetooth.begin(9600);  // Start bluetooth serial at 9600
 
  lcd.begin(NUM_COLS, NUM_ROWS);

  pinMode(shutDownPin, OUTPUT);
  digitalWrite(shutDownPin, LOW); 
  wtv020sd16p.reset();
 
  pinMode(LED1, OUTPUT); 
  pinMode(LED2, OUTPUT); 
  pinMode(LED3, OUTPUT); 
  pinMode(LED4, OUTPUT); 

  pinMode(LED5, OUTPUT); 
  pinMode(LED6, OUTPUT); 
  pinMode(LED7, OUTPUT); 
  pinMode(LED8, OUTPUT); 
  pinMode(LED9, OUTPUT); 
  pinMode(LED10, OUTPUT); 
  pinMode(SELF_LED, OUTPUT); 


  digitalWrite(LED1, HIGH);
  digitalWrite(LED2, HIGH);
  digitalWrite(LED3, HIGH);
  digitalWrite(LED4, HIGH);
  digitalWrite(LED5, HIGH);
  digitalWrite(LED6, HIGH);
  digitalWrite(LED7, HIGH);
  digitalWrite(LED8, HIGH);
  digitalWrite(LED9, HIGH);
  digitalWrite(LED10, HIGH);  
  
//  digitalWrite(LED1, LOW);
//  digitalWrite(LED2, LOW);
//  digitalWrite(LED3, LOW);
//  digitalWrite(LED4, LOW);
//  digitalWrite(LED5, LOW);
//  digitalWrite(LED6, LOW);
//  digitalWrite(LED7, LOW);
//  digitalWrite(LED8, LOW);
//  digitalWrite(LED9, LOW);
//  digitalWrite(LED10, LOW);   
  
  digitalWrite(SELF_LED, HIGH);


  //Default mode to charity
  toggle_mode();
}

void toggle_selfish() {
  digitalWrite(SELF_LED, digitalRead(SELF_LED) ^ 1);  
}

void write_led(int led, int intensity) {
  switch (led) {
   case 1:
     digitalWrite(LED1, intensity);
     break;
   case 2:
     digitalWrite(LED2, intensity);
     break;
   case 3:
     digitalWrite(LED3, intensity);
     break;
   case 4:
     digitalWrite(LED4, intensity);
     break;
   case 5:
     digitalWrite(LED5, intensity);
     break;
   case 6:
     digitalWrite(LED6, intensity);
     break;
   case 7:
     digitalWrite(LED7, intensity);
     break;
   case 8:
     digitalWrite(LED8, intensity);
     break;
   case 9:
     digitalWrite(LED9, intensity);
     break;
   case 10:
     digitalWrite(LED10, intensity);
     break; 
  }   
}

void donation_led() {
   for (int i = 1; i < personal_donations+1; i++) {
      write_led(i, HIGH);  
    }
    
    for (int i = personal_donations+1; i < 11; i++) {
      write_led(i, LOW);  
    }
 
}

void toggle_mode() {
  mode += 1;
  mode = mode%2;  
  switch(mode) {
    case PERSONAL:
      {
        
       lcd.clear();
       lcd.setCursor(0,0);
       lcd.print("Your Donations!");
       lcd.setCursor(0,1);
       lcd.print("Contribution: " + String(personal_donations));
        
       donation_led();       
        break; 
      }
      
    case CHARITY:
      {
        
       lcd.clear();
       lcd.setCursor(0,0);
       lcd.print("Charity Goal!");
       lcd.setCursor(0,1);
       lcd.print("Percentage: 30%");
        
        //hardcoded to always be 30%
        write_led(1, HIGH);
        write_led(2, HIGH);
        write_led(3, HIGH);
        write_led(4, LOW);
        write_led(5, LOW);
        write_led(6, LOW);
        write_led(7, LOW);
        write_led(8, LOW);
        write_led(9, LOW);
        write_led(10, LOW);
        break;
     }
    
    
  }
  
  delay(100);


}

void update_donations() {
  digitalWrite(shutDownPin, HIGH);
  if (personal_donations < 10) {
    personal_donations += 1;
    TOGGLE += 100;
    if (personal_donations == 10) {
      SELFISH = false;
      wtv020sd16p.asyncPlayVoice(2);
      digitalWrite(SELF_LED, LOW);
      //play sound for complete donations
      lcd.setCursor(0, 0);
      lcd.print("Selfless!");
      lcd.setCursor(0,1);
      lcd.print("Contribution: " + String(personal_donations));  
    } 
  }
  
    
  if (personal_donations != 10) {
    wtv020sd16p.asyncPlayVoice(0);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Donated!");
    lcd.setCursor(0,1);
    lcd.print("Contribution:" + String(personal_donations));  
  }
  
  donation_led();
  NOISY = true;  
  SOUND_NOISE = millis() + TIME_DELAY;
}

void loop() {
  // play sound file 0 
  int piezo_in = analogRead(PIEZO);
//  Serial.println("Current Time:" + String(millis()));
//  Serial.println("SOUND-NOISE:" + String(SOUND_NOISE));
//  Serial.println("NOISY " + String(NOISY));
// 
  if (NOISY) {
    if (millis() > SOUND_NOISE) {
      NOISY = false;
      digitalWrite(shutDownPin, LOW);      
    }    
  } else {
  
    if (piezo_in > THRESHOLD) {
      toggle_mode();
    }    
  }
  
  if (millis() > (lastTime + TOGGLE) && SELFISH) {
    toggle_selfish();
    lastTime = millis();
  }
 
  if(bluetooth.available())  // If the bluetooth sent any characters
  {
    // Send any characters the bluetooth prints to the serial monitor
    
    char received = (char) bluetooth.read();
    Serial.print(received);  
    
    if (received == '1') {
      update_donations();
    } else {
      digitalWrite(shutDownPin, HIGH);
      SOUND_NOISE = millis() + TIME_DELAY;
      NOISY = true;  
      wtv020sd16p.asyncPlayVoice(1);       
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Not a good");
      lcd.setCursor(0,1);
      lcd.print("charity item.");  

    }
  }
  
  
  
}

Code

decart2.inoC/C++
decart2.ino
/*
 Decart Arduino Code
 Author: Felix Li
 */

#include <LiquidCrystal.h>
#include <Wtv020sd16p.h>
#include <SoftwareSerial.h>  

//---------LCD DISPLAY---------

//Pin Layout
#define RS 13
#define E 12

#define D4 6
#define D5 7
#define D6 9
#define D7 8

#define NUM_COLS 16
#define NUM_ROWS 2

LiquidCrystal lcd(RS, E, D4, D5, D6, D7);

//---------SOUND MODULE---------
#define resetPin 2  // The pin number of the reset pin.
#define clockPin 3   // The pin number of the clock pin.
#define dataPin 4   // The pin number of the data pin.
#define busyPin 5   // The pin number of the busy pin.
#define shutDownPin 23

Wtv020sd16p wtv020sd16p(resetPin,clockPin,dataPin,busyPin);


//---------PROGRESS BAR---------
#define LED10 24
#define LED9 26
#define LED8 28
#define LED7 30

#define LED6 40
#define LED5 42
#define LED4 44
#define LED3 46
#define LED2 48
#define LED1 50

//---------SELFISH LIGHT---------
#define SELF_LED 29
unsigned long lastTime = 0;
int TOGGLE = 200;
boolean SELFISH = true;

//---------BLUETOOTH MODULE---------
#define bluetoothTx 10
#define bluetoothRx 11

//---------PIEZO SENSOR---------
#define PIEZO A2
#define TIME_DELAY 1500
int THRESHOLD = 30;
unsigned long SOUND_NOISE = 0;
boolean NOISY = false;

SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);

//---------GLOBAL VARIABLES/STATES---------
#define PERSONAL 0
#define CHARITY 1
#define NUM_OF_MODES 2
int mode = PERSONAL;
int personal_donations = 0;

void setup() {
  //Initializes the module.
  Serial.begin(9600);

  bluetooth.begin(115200);  // The Bluetooth Mate defaults to 115200bps
  bluetooth.print("$");  // Print three times individually
  bluetooth.print("$");
  bluetooth.print("$");  // Enter command mode
  delay(100);  // Short delay, wait for the Mate to send back CMD
  bluetooth.println("U,9600,N");  // Temporarily Change the baudrate to 9600, no parity
  // 115200 can be too fast at times for NewSoftSerial to relay the data reliably
  bluetooth.begin(9600);  // Start bluetooth serial at 9600
 
  lcd.begin(NUM_COLS, NUM_ROWS);

  pinMode(shutDownPin, OUTPUT);
  digitalWrite(shutDownPin, LOW); 
  wtv020sd16p.reset();
 
  pinMode(LED1, OUTPUT); 
  pinMode(LED2, OUTPUT); 
  pinMode(LED3, OUTPUT); 
  pinMode(LED4, OUTPUT); 

  pinMode(LED5, OUTPUT); 
  pinMode(LED6, OUTPUT); 
  pinMode(LED7, OUTPUT); 
  pinMode(LED8, OUTPUT); 
  pinMode(LED9, OUTPUT); 
  pinMode(LED10, OUTPUT); 
  pinMode(SELF_LED, OUTPUT); 


  digitalWrite(LED1, HIGH);
  digitalWrite(LED2, HIGH);
  digitalWrite(LED3, HIGH);
  digitalWrite(LED4, HIGH);
  digitalWrite(LED5, HIGH);
  digitalWrite(LED6, HIGH);
  digitalWrite(LED7, HIGH);
  digitalWrite(LED8, HIGH);
  digitalWrite(LED9, HIGH);
  digitalWrite(LED10, HIGH);  
  
//  digitalWrite(LED1, LOW);
//  digitalWrite(LED2, LOW);
//  digitalWrite(LED3, LOW);
//  digitalWrite(LED4, LOW);
//  digitalWrite(LED5, LOW);
//  digitalWrite(LED6, LOW);
//  digitalWrite(LED7, LOW);
//  digitalWrite(LED8, LOW);
//  digitalWrite(LED9, LOW);
//  digitalWrite(LED10, LOW);   
  
  digitalWrite(SELF_LED, HIGH);


  //Default mode to charity
  toggle_mode();
}

void toggle_selfish() {
  digitalWrite(SELF_LED, digitalRead(SELF_LED) ^ 1);  
}

void write_led(int led, int intensity) {
  switch (led) {
   case 1:
     digitalWrite(LED1, intensity);
     break;
   case 2:
     digitalWrite(LED2, intensity);
     break;
   case 3:
     digitalWrite(LED3, intensity);
     break;
   case 4:
     digitalWrite(LED4, intensity);
     break;
   case 5:
     digitalWrite(LED5, intensity);
     break;
   case 6:
     digitalWrite(LED6, intensity);
     break;
   case 7:
     digitalWrite(LED7, intensity);
     break;
   case 8:
     digitalWrite(LED8, intensity);
     break;
   case 9:
     digitalWrite(LED9, intensity);
     break;
   case 10:
     digitalWrite(LED10, intensity);
     break; 
  }   
}

void donation_led() {
   for (int i = 1; i < personal_donations+1; i++) {
      write_led(i, HIGH);  
    }
    
    for (int i = personal_donations+1; i < 11; i++) {
      write_led(i, LOW);  
    }
 
}

void toggle_mode() {
  mode += 1;
  mode = mode%2;  
  switch(mode) {
    case PERSONAL:
      {
        
       lcd.clear();
       lcd.setCursor(0,0);
       lcd.print("Your Donations!");
       lcd.setCursor(0,1);
       lcd.print("Contribution: " + String(personal_donations));
        
       donation_led();       
        break; 
      }
      
    case CHARITY:
      {
        
       lcd.clear();
       lcd.setCursor(0,0);
       lcd.print("Charity Goal!");
       lcd.setCursor(0,1);
       lcd.print("Percentage: 30%");
        
        //hardcoded to always be 30%
        write_led(1, HIGH);
        write_led(2, HIGH);
        write_led(3, HIGH);
        write_led(4, LOW);
        write_led(5, LOW);
        write_led(6, LOW);
        write_led(7, LOW);
        write_led(8, LOW);
        write_led(9, LOW);
        write_led(10, LOW);
        break;
     }
    
    
  }
  
  delay(100);


}

void update_donations() {
  digitalWrite(shutDownPin, HIGH);
  if (personal_donations < 10) {
    personal_donations += 1;
    TOGGLE += 100;
    if (personal_donations == 10) {
      SELFISH = false;
      wtv020sd16p.asyncPlayVoice(2);
      digitalWrite(SELF_LED, LOW);
      //play sound for complete donations
      lcd.setCursor(0, 0);
      lcd.print("Selfless!");
      lcd.setCursor(0,1);
      lcd.print("Contribution: " + String(personal_donations));  
    } 
  }
  
    
  if (personal_donations != 10) {
    wtv020sd16p.asyncPlayVoice(0);
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Donated!");
    lcd.setCursor(0,1);
    lcd.print("Contribution:" + String(personal_donations));  
  }
  
  donation_led();
  NOISY = true;  
  SOUND_NOISE = millis() + TIME_DELAY;
}

void loop() {
  // play sound file 0 
  int piezo_in = analogRead(PIEZO);
//  Serial.println("Current Time:" + String(millis()));
//  Serial.println("SOUND-NOISE:" + String(SOUND_NOISE));
//  Serial.println("NOISY " + String(NOISY));
// 
  if (NOISY) {
    if (millis() > SOUND_NOISE) {
      NOISY = false;
      digitalWrite(shutDownPin, LOW);      
    }    
  } else {
  
    if (piezo_in > THRESHOLD) {
      toggle_mode();
    }    
  }
  
  if (millis() > (lastTime + TOGGLE) && SELFISH) {
    toggle_selfish();
    lastTime = millis();
  }
 
  if(bluetooth.available())  // If the bluetooth sent any characters
  {
    // Send any characters the bluetooth prints to the serial monitor
    
    char received = (char) bluetooth.read();
    Serial.print(received);  
    
    if (received == '1') {
      update_donations();
    } else {
      digitalWrite(shutDownPin, HIGH);
      SOUND_NOISE = millis() + TIME_DELAY;
      NOISY = true;  
      wtv020sd16p.asyncPlayVoice(1);       
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Not a good");
      lcd.setCursor(0,1);
      lcd.print("charity item.");  

    }
  }
  
  
  
}

Custom parts and enclosures

futureDesign.stl

Sketchfab still processing.

Comments

Similar projects you might like

Integrated HOME Irrigation System

by Hernanduino

  • 4,671 views
  • 0 comments
  • 17 respects

Local and Remote Programmable Robotic Arm

Project tutorial by MJRoBot

  • 22,389 views
  • 7 comments
  • 61 respects

How to Build a DIY Arduino-Based Smart Home Hub with 1Sheeld

Project tutorial by amrmostaafaa

  • 14,310 views
  • 1 comment
  • 41 respects

IoT Aquarium Light Controller

Project in progress by Neto Carrer

  • 10,094 views
  • 2 comments
  • 27 respects

My Motion Activated SMS sender

Project tutorial by Christiaan Neil Burger

  • 2,172 views
  • 0 comments
  • 5 respects

Control Music Volume and Ledbar Using Slider of 1Sheeld

Project tutorial by ahmed ismail

  • 1,952 views
  • 2 comments
  • 14 respects
Add projectSign up / Login