Revolving Games

RGPressPhotoResize

This crafty measuring device is meant to draw attention to the daily usage of revolving doors at Carnegie Mellon’s University Center building. It logs the time, proximity, and rpm data, but also incites a little competitive spirit on its free voltage.

This project revisited our previous class assignment that utilized seven segment displays to capture an interesting measurement. In my original idea, I wanted to choose a unique and fun way to portray numbers, and what better way to do that than with rankings? The reason I chose revolving doors as my subject matter was more or less because I was interested in the calculations involved with an accelerometer.

But as I developed my idea in this assignment, I wanted to convey more useful information about my subjects, the revolving doors. The research changed its direction from “interesting calculations” to bringing attention to those mundane doors that we pass through without a second thought. And I have to thank Maddy Varner and Golan Levin for reminding me that an extra seven segment display and data logging shield were just the things I needed to accomplish this.

That said, the actual wiring of all these new devices, as well as figuring out their libraries were the most technical aspect of the project. Through this process, I came to understand JUST HOW INVALUABLE neat soldering can be. But in the end, the effort was definitely worth it. (See below for fritzing and code). I had some technical difficulties along the way (I seem to have jynxed technology a lot this semester), but I find the data that came from my 7 hours of installation really valuable. The animated GIF below shows the plotted data from the data logging shield, and there are clear patterns of usage for these doors. (Click the image.)

SMALLGIF

Facts and Figures:
124 people used the door in those 7 hours
The highest score was 40 rpm
There were 4 notable mishaps

Of course, I won’t forget to address the most exciting–and hazardous–part of this project: the participants. I may have underestimated the competitive spirit of college students, because I felt fear watching some of them. My project installation time was cut short because the UC staff asked me not to display the high score portion, and I personally thought the goings could get worse since it is finals week. On a side note, I was extremely happy with how the magic arm stabilized the box. The whole contraption was incredibly sturdy.

In conclusion, I am very satisfied with this project. Although video editing is not my strong point, I did enjoy watching over my project and seeing people have fun and expressing a genuine interest.

Supported in part by a microgrant from the Frank-Ratchye Fund For Art at the Frontier
URL: bit.ly/revolving-games

Parts:

Sparkfun Arduino Uno
Adafruit ADXL345 Triple Axis Accelerometer
Adafruit Assembled Data Logging Shield
Adafruit IR Distance Sensor (10-80 cm)
Adafruit 4 Digit 7 Segment Displays (0.56″)
9V Batteries

Fritzing Diagram:

Revolving Games_bb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
//Revolving Games by Michelle Ma
//note the code may have been altered due to
//the Wordpress syntax
 
#include <wire .h>
#include <sd .h>
#include "RTClib.h"
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"
#include <adafruit_sensor .h>
#include <adafruit_adxl345 .h>
 
Adafruit_7segment matrix1 = Adafruit_7segment();
Adafruit_7segment matrix2 = Adafruit_7segment();
Adafruit_ADXL345 accel = Adafruit_ADXL345(12345);
 
RTC_DS1307 RTC; // Real Time Clock
 
const int chipSelect = 10; //for data logging
const int distancePin = 0; //A0 for IR sensor
 
const int threshold = 100; //collect data when someone near
const float radius = 0.65; //radius of door in meters
const float pi = 3.1415926;
 
File logfile;
 
int highScore;
 
void setup() {
  Serial.begin(9600);
  SD.begin(chipSelect);
  createFile();
  accel.begin();
  matrix1.begin(0x70);
  matrix2.begin(0x71);
 
  if (!RTC.isrunning()) {
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
 
  accel.setRange(ADXL345_RANGE_16_G);
 
  highScore = 0;
}
 
void createFile() {
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i=0; i<100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (!SD.exists(filename)) {
      logfile = SD.open(filename, FILE_WRITE);
      break;
    }
  }
 
  if (!logfile) {
    Serial.print("Couldn't create file");
    Serial.println();
    while(true);
  }
  Serial.print("Logging to: ");
  Serial.println(filename);
 
  Wire.begin();
 
  if (!RTC.begin()) {
    Serial.println("RTC error");
  }
  logfile.println("TimeStamp,IR Distance,Accel (m/s^2),RPM");
}
 
void loop() {
 
  DateTime now = RTC.now();
  sensors_event_t event; 
  accel.getEvent(&event);
 
  float distance = analogRead(distancePin);
  float acceleration = event.acceleration.z;
  float rpm;
 
  if (distance > threshold) {
    rpm = computeRpm();
  } else {
    rpm = 0; //I chose not to display the scores
  }          //of people in other booths
 
  if (rpm > highScore) {
    highScore = rpm;
  }
 
  logData(now, distance, acceleration, rpm);
  serialData(now, distance, acceleration, rpm);
  writeMatrices(int(rpm), int(highScore));
 
  Serial.println("Saved...");
  logfile.flush(); // Write data to SD
}
 
float computeRpm() {
  float velocity = computeVelocity();
  float result = abs(60.0*velocity)/(2.0*pi*radius);
  return result;
}
 
float computeVelocity() {
  float acceleration;
  float sum = 0;
  int samples = 100;
  int dt = 10; //millis
  for (int i=0; i<samples ; i++) {
    sensors_event_t event; 
    accel.getEvent(&event);
    acceleration = event.acceleration.z;
    if ((i==0)||(i==(samples-1))) {
      sum += acceleration;
    } else {
      sum += 2.0*acceleration;
    }
    delay(dt);
  }
  float result = ((dt/1000.0)/2.0)*sum;
  Serial.print("Velocity: "); Serial.println(result);
  return result;
 
}
 
void logData(DateTime x, float dist, float acc, float rpm) {
  logfile.print('"'); //TimeStamp
  logfile.print(x.year(), DEC);
  logfile.print("/");
  logfile.print(x.month(), DEC);
  logfile.print("/");
  logfile.print(x.day(), DEC);
  logfile.print(" ");
  logfile.print(x.hour(), DEC);
  logfile.print(":");
  logfile.print(x.minute(), DEC);
  logfile.print(":");
  logfile.print(x.second(), DEC);
  logfile.print('"');
  logfile.print(", ");
 
  logfile.print(dist);
  logfile.print(", ");
  logfile.print(acc);
  logfile.print(", ");
  logfile.print(rpm);
  logfile.println();
}
 
void serialData(DateTime x, float dist, float acc, float rpm) {
  Serial.print('"'); //TimeStamp
  Serial.print(x.year(), DEC);
  Serial.print("/");
  Serial.print(x.month(), DEC);
  Serial.print("/");
  Serial.print(x.day(), DEC);
  Serial.print(" ");
  Serial.print(x.hour(), DEC);
  Serial.print(":");
  Serial.print(x.minute(), DEC);
  Serial.print(":");
  Serial.print(x.second(), DEC);
  Serial.print('"');
  Serial.print(", ");
 
  Serial.print(dist);
  Serial.print(", ");
  Serial.print(acc);
  Serial.print(", ");
  Serial.print(rpm);
  Serial.println();
}
 
void writeMatrices(int m1, int m2) {
  if (m1==0) {
    matrix1.writeDigitNum(4, 0);
  } else {
    matrix1.println(m1); //Participant's rpm
  }
  if (m2==0) {
    matrix2.writeDigitNum(4, 0);
  } else {
    matrix2.println(m2); //High score
  }
  matrix1.writeDisplay();
  matrix2.writeDisplay();
}

Comments are closed.