Provocation 3: Urban Encounters

Urban 5x5x5x5x15

Work in progress769
Provocation 3: Urban Encounters

Things used in this project

Hardware components

Arduino UNO & Genuino UNO
Arduino UNO & Genuino UNO
×2
LCD screen 16x2
×1
Resistors
×1
Green Acrylic
×1
XBee series 1
×2
XBee adapter
×2
SoftPot Membrane Potentiometer
×1
Tin foil
×1
Photo-resistor
×1
9V battery (generic)
9V battery (generic)
×2
iPad
Apple iPad
×1
Stretchy Fabric
×1
Elastic
×1

Story

Read more

Code

Casual_Encounters.ino

C/C++
Casual_Encounters.ino
#include <QueueArray.h>

#include <CapacitiveSensor.h>

#include <SoftwareSerial.h>

#include <LiquidCrystal.h>



// Initialize the library with the pins we're using.

// (Note that you can use different pins if needed.)

// See http://arduino.cc/en/Reference/LiquidCrystal

// for more information:



LiquidCrystal lcd(12,11,5,4,3,2);



const int SENSOR_PIN = 0;

CapacitiveSensor cs_8_9 = CapacitiveSensor(8,9);

SoftwareSerial xbeeSerial(6,7);



char previousXbeeByte = '1';

boolean previousTouchActivated = false;



const int SELECT_MODE = 0;

const int INPUT_SEX_MODE = 1;

const int INPUT_OPP_SEX_MODE = 2;

const int INPUT_AGE_MODE = 3;

const int INPUT_INTEREST_MODE = 4;

const int INPUT_NUMBER_MODE = 5;

const int INPUT_END_MODE = 69;

const int DISPLAY_MODE = 100;

const int DISPLAY_OFF_MODE = 101;



int menu_state = SELECT_MODE;

int current_selection_value = 0;



char phone_number[] = {'0','0','0','0','0','0','0','0','0','0'};

int phone_index = 0;



long displayStartTime;



struct CasualEncounter {

  boolean viewed;

  int sex_selection_value;

  int opp_sex_selection_value;

  int age_selection_value;

  int interest_selection_value;

  char phone_number[13];

};

CasualEncounter encounters [10]= { { false, 0, 1, 0, 0, "408-921-0322" }, { false, 1, 1, 1, 2, "408-215-1055" }, { false, 0, 0, 0, 1, "405-837-2910" }, { false, 1, 0, 1, 4, "384-924-0391" } };

int displayIndex;

int numEncounters = 4;

     

String mode_options [] = { "Input", "Display" };

String sex_options [] = { "Male", "Female", "Trans" };

String opp_sex_options [] = { "Male", "Female", "Either" };

String age_options [] = { "10-19", "20-29", "30-39", "40-49", "50-59", "60-69", "70-79", "80-89", "90-99", "100-109" };

String interest_options [] = { "Friendship", "Date", "Sex", "Chat", "Games", "Sports", "Event"};

String number_options [] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };     



void setup()

{

  // Tells Library this display has 2 lines of 16 characters

  lcd.begin(16, 2);



  // Data sent to the display will stay there until it's

  // overwritten or power is removed. This clears the LCD.

  lcd.clear();

  

  // Set up inputs

  cs_8_9.set_CS_AutocaL_Millis(0xFFFFFFFF);

  Serial.begin(9600);

  xbeeSerial.begin(9600);

  delay(1000);

  screen_mode(menu_state, current_selection_value);

  delay(200);

  Serial.println("setup");

}



void loop()

{

  // Read input values: xbee, capacitive sensor, potentiometer (pressure)

  boolean crosswalk_changed_to_stop = false;

  boolean crosswalk_changed_to_go = false;

  if (xbeeSerial.available()) { 

    char incomingXbeeByte = xbeeSerial.read();

    

    if (incomingXbeeByte != previousXbeeByte) {

      if (incomingXbeeByte == '1') {

        crosswalk_changed_to_stop = true;

      } else if (incomingXbeeByte == '0') {

        crosswalk_changed_to_go = true;

      }

    }



    // update previous value

    previousXbeeByte = incomingXbeeByte;

  }

  

  long capSenseTotal = cs_8_9.capacitiveSensor(30);

  boolean tappedCapacitiveSensor = previousTouchActivated && !touchActivated(capSenseTotal); // detects release

  // update previous value

  previousTouchActivated = touchActivated(capSenseTotal);

  

  int potentiometerValue = analogRead(SENSOR_PIN);

  Serial.println(potentiometerValue);



  if (100 < potentiometerValue && potentiometerValue < 450) {

    current_selection_value = (current_selection_value - 1 + selection_value_modulus(menu_state)) % selection_value_modulus(menu_state);

    screen_mode(menu_state, current_selection_value);

  }

 

  if (500 < potentiometerValue && potentiometerValue < 1000) {

    current_selection_value = (current_selection_value + 1) % selection_value_modulus(menu_state);

    screen_mode(menu_state, current_selection_value);

  }



  // State based behavior



  switch (menu_state) {

    case SELECT_MODE:

      if (tappedCapacitiveSensor) {

        if (current_selection_value == 0) {

          menu_state = INPUT_SEX_MODE;

        } else {

          menu_state = DISPLAY_MODE;

        }

        current_selection_value = 0;

        screen_mode(menu_state, current_selection_value);

      }

    break;

    

    case INPUT_SEX_MODE:

      if (tappedCapacitiveSensor) {

        encounters[numEncounters].sex_selection_value = current_selection_value;



        menu_state = INPUT_OPP_SEX_MODE;

        current_selection_value = 0;

        screen_mode(menu_state, current_selection_value);

      }

    break;



    case INPUT_OPP_SEX_MODE:

      if (tappedCapacitiveSensor) {

        encounters[numEncounters].opp_sex_selection_value = current_selection_value;



        menu_state = INPUT_AGE_MODE;

        current_selection_value = 0;

        screen_mode(menu_state, current_selection_value);

      }

    break;

    

    case INPUT_AGE_MODE:

      if (tappedCapacitiveSensor) {

        encounters[numEncounters].age_selection_value = current_selection_value;



        menu_state = INPUT_INTEREST_MODE;

        current_selection_value = 0;

        screen_mode(menu_state, current_selection_value);

      }

    break;

    

    case INPUT_INTEREST_MODE:

      if (tappedCapacitiveSensor) {

        encounters[numEncounters].interest_selection_value = current_selection_value;



        menu_state = INPUT_NUMBER_MODE;

        current_selection_value = 0;

        screen_mode(menu_state, current_selection_value);

      }

    break;

    

    case INPUT_NUMBER_MODE:

      if (tappedCapacitiveSensor) {

        phone_number[phone_index] = (char)(((int)'0')+current_selection_value);

        phone_index = phone_index + 1;



        if (phone_index == 10) {

          phone_index = 0;

          int phone_number_string_index = 0;

          for (int i = 0; i < 10; i++) {

            if (i==3) {

              encounters[numEncounters].phone_number[phone_number_string_index++] = '-';

            }

            if (i==6) {

              encounters[numEncounters].phone_number[phone_number_string_index++] = '-';

            }

            encounters[numEncounters].phone_number[phone_number_string_index++] = phone_number[i];

            Serial.print(phone_number[i]);

            phone_number[i] = '0';

          }

          encounters[numEncounters].phone_number[phone_number_string_index++] = 0;

          encounters[numEncounters].viewed = false;

          numEncounters++;



          menu_state = INPUT_END_MODE;

        }



        current_selection_value = 0;

        screen_mode(menu_state, current_selection_value);

      }

      lcd.setCursor(correctPhoneNumberCharIndex(phone_index), 1);

      lcd.cursor();

    break;

    

    case INPUT_END_MODE:

      lcd.noCursor();

      delay(2000);

      menu_state = DISPLAY_MODE;

      current_selection_value = 0;

      screen_mode(menu_state, current_selection_value);

    break;

    

    case DISPLAY_MODE:

     

      if (tappedCapacitiveSensor)

      {

        if (displayIndex == numEncounters) {

          menu_state = INPUT_SEX_MODE;

          current_selection_value = 0;

          screen_mode(menu_state, current_selection_value);

        } else {

          encounters[displayIndex].viewed = true;

          

          lcd.clear();

          lcd.setCursor(0,0);

          lcd.print(encounters[displayIndex].phone_number);

          delay(4000);

        }

      }



      if (millis() - displayStartTime > 2000) {

        do {

          displayIndex = (displayIndex + 1) % (numEncounters + 1);

        } while (encounters[displayIndex].viewed && displayIndex != numEncounters);

        if (displayIndex == numEncounters) {

          lcd.clear();

          lcd.setCursor(0,0);

          lcd.print("Tap to create");

          lcd.setCursor(0,1);

          lcd.print("New Encounter!");

        } else {

          displayEncounter(displayIndex);

        }

        displayStartTime = millis();

      }



      if (crosswalk_changed_to_go) {

        menu_state = DISPLAY_OFF_MODE;

        current_selection_value = 0;

        screen_mode(menu_state, current_selection_value);

      }



    break;



    case DISPLAY_OFF_MODE:

      if (crosswalk_changed_to_stop) {

        menu_state = DISPLAY_MODE;

        current_selection_value = 0;

        screen_mode(menu_state, current_selection_value);  

      }

    break;

  }

  

  // Need to delay, otherwise Arduino loop will add too quickly.

  delay(200);

  

  // TIP: Since the numeric data we're sending is always growing

  // in length, new values will always overwrite the previous ones.

  // However, if you want to display varying or decreasing numbers

  // like a countdown, you'll find that the display will leave

  // "orphan" characters when the new value is shorter than the

  // old one.



  // To prevent this, you'll need to erase the old number before

  // writing the new one. You can do this by overwriting the

  // last number with spaces. If you erase the old number and

  // immediately write the new one, the momentary erase won't 

  // be noticeable. Here's a typical sequence of code:



  // lcd.setCursor(0,1);   // Set the cursor to the position

  // lcd.print("       "); // Erase the largest possible number

  // lcd.setCursor(0,1);   // Reset the cursor to the original position

  // lcd.print(millis()/1000); // Print our value



  // Arduino also comes with a number of built-in examples

  // showing off the features of the LiquidCrystal library.

  // These are locted in the file/examples/LiquidCrystal menu.

}



void screen_mode(int stage, int selection_value)

{

  

  // Clear screen and set cursor to top left corner

  lcd.clear();

  lcd.setCursor(0,0);

  

  switch(stage)

  {

    case SELECT_MODE:

    {

      lcd.print("Select Mode");

      lcd.setCursor(0,1);

      lcd.print(mode_options[selection_value]);

      draw_arrows();

      break;

    }

    case INPUT_SEX_MODE:

    {

      lcd.print("Select your sex.");

      lcd.setCursor(0,1);

      lcd.print(sex_options[selection_value]); 

      draw_arrows();

      break;

    }

    case INPUT_OPP_SEX_MODE:

    {

      lcd.print("Looking for?");

      lcd.setCursor(0,1);

      lcd.print(opp_sex_options[selection_value]); 

      draw_arrows();

      break;

    }

    case INPUT_AGE_MODE:

    {

      lcd.print("Your age.");

      lcd.setCursor(0,1);      

      lcd.print(age_options[selection_value]);      

      draw_arrows();      

      break;

    }

    case INPUT_INTEREST_MODE:

    {

      lcd.print("Interested in?");

      lcd.setCursor(0,1);

      lcd.print(interest_options[selection_value]);

      draw_arrows();

      break;

    }

    case INPUT_NUMBER_MODE:

    {

      lcd.print("Phone Number");

      lcd.setCursor(0,1);

      for (int n = 0; n < 10; n++)

      {

        if (n==3) {

          lcd.setCursor(3, 1);

          lcd.write('-');

        }

       

        if (n==7) {

          lcd.setCursor(7,1);

          lcd.write('-');

        }

       

        lcd.setCursor(correctPhoneNumberCharIndex(n), 1);

        lcd.write(phone_number[n]);

      }

      lcd.setCursor(correctPhoneNumberCharIndex(phone_index), 1);

      lcd.print(number_options[selection_value]);

      draw_arrows();

      break;

    }

    case INPUT_END_MODE:

    {

      lcd.clear();

      lcd.setCursor(0,0);

      lcd.print("Thank you for");

      lcd.setCursor(0,1);

      lcd.print("Participating");

      break;

    }

    case DISPLAY_MODE:

    {

      displayIndex = 0;

      while (encounters[displayIndex].viewed && displayIndex != numEncounters) {

        displayIndex = (displayIndex + 1) % (numEncounters + 1);

      }

      displayEncounter(displayIndex);

      displayStartTime = millis();

      break;

    }

    case DISPLAY_OFF_MODE:

    {

      // lcd clear called at the beginning

      break;

    }

  }

}



int selection_value_modulus(int mode) {

  if (mode == SELECT_MODE) {

    return 2;

  } else if (mode == INPUT_SEX_MODE) {

    return 3;

  } else if (mode == INPUT_OPP_SEX_MODE) {

    return 3;

  } else if (mode == INPUT_AGE_MODE) {

    return 10;

  } else if (mode == INPUT_INTEREST_MODE) {

    return 7;

  } else if (mode == INPUT_NUMBER_MODE) {

    return 10;

  } else {

    return 1;

  }

}



//Draws arrows at the end of the second row.

void draw_arrows() {

  byte arrows[8] = { // set up arrow frame 3, look at the 0's and the 1's

      B00000, // 

      B00000, // 

      B01010, // 

      B11011, // 

      B01010, // 

      B00000, // 

      B00000, // 

      B00000  // 

      };



  lcd.createChar(0, arrows);

  lcd.setCursor(15, 1);

  lcd.write((byte) 0);

}



int touchActivated(long capSenseTotal) 

{

  if (capSenseTotal > 100) {

    return 1;

  } else {

    return 0;

  }

}



int correctPhoneNumberCharIndex(int index) 

{

  int correctIndex = index;



  if (index >= 3) {

    correctIndex = correctIndex + 1;

    if (index >= 6) {

      correctIndex = correctIndex + 1;

    }

  }

  

  return correctIndex;

}



void displayEncounter(int index) {

  CasualEncounter ce = encounters[index];

  char firstLine [17];

  int charIndex = 0;

  switch (ce.sex_selection_value) {

    case 0:

      firstLine[charIndex++] = 'M';

    break;

    case 1:

      firstLine[charIndex++] = 'F';

    break;

    case 2:

      firstLine[charIndex++] = 'T';

    break;

  }

  firstLine[charIndex++] = '4';

  switch (ce.opp_sex_selection_value) {

    case 0:

      firstLine[charIndex++] = 'M';

    break;

    case 1:

      firstLine[charIndex++] = 'F';

    break;

    case 2:

      firstLine[charIndex++] = 'M';

      firstLine[charIndex++] = '/';

      firstLine[charIndex++] = 'F';

    break;

  }

  firstLine[charIndex++] = ' ';

  switch (ce.age_selection_value) {

    case 0:

      firstLine[charIndex++] = '1';

      firstLine[charIndex++] = '0';

      firstLine[charIndex++] = '-';

      firstLine[charIndex++] = '1';

      firstLine[charIndex++] = '9';

    break;

    case 1:

      firstLine[charIndex++] = '2';

      firstLine[charIndex++] = '0';

      firstLine[charIndex++] = '-';

      firstLine[charIndex++] = '2';

      firstLine[charIndex++] = '9';

    break;

    case 2:

      firstLine[charIndex++] = '3';

      firstLine[charIndex++] = '0';

      firstLine[charIndex++] = '-';

      firstLine[charIndex++] = '3';

      firstLine[charIndex++] = '9';

    break;

    case 3:

      firstLine[charIndex++] = '4';

      firstLine[charIndex++] = '0';

...

This file has been truncated, please download it to see its full contents.

photodiode_prov4.ino

C/C++
photodiode_prov4.ino
#include <SoftwareSerial.h>



const int sensorPin = 1;

int lightLevel, high = 0, low = 1023, time = 0, time2 = 0, darkLevel = 50;



SoftwareSerial mySerial = SoftwareSerial(2,3);

  

void setup() 

{

  Serial.begin(9600);

  mySerial.begin(9600);

}





void loop()

{

  time = millis();

  

  lightLevel = analogRead(sensorPin);

  // Serial.print(lightLevel);

  // Serial.print("\n");

  

  // dark for more than 2 seconds means "Walk" sign is on

  if ((lightLevel <= darkLevel) && ((time - time2) > 2000)) { 

    time2 = time;

    Serial.print("off \n");

    mySerial.print('0');

  } else if ((lightLevel > darkLevel) && ((time - time2) > 2000)) {

    time2 = time;

    Serial.print("on \n");

    mySerial.print('1');

  } else {

  }





}

Credits

Moeka Takagi

Moeka Takagi

4 projects • 1 follower
Kelsey Brennan

Kelsey Brennan

3 projects • 0 followers
Dennis Rong

Dennis Rong

4 projects • 1 follower
Alvin Yuan

Alvin Yuan

5 projects • 3 followers

Comments