#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.
Comments