Visualizing My Personal Space (Part 2)
Read part 1 here.
Getting Sensors on My Body
I made the visualization program, now it was time to getting the actual data (i.e. placing sensors on my body).
I already had some IR distance sensors from my theremin project, but I decided to buy ultrasonic sensors instead since they: (1) have a range from 2-400cm, and (2) give a value that can be readily converted into cm's.
The sensors had to be on my body so my dear roommate sewed a pouch/necklace thing to hold my sensors and Arduino.


Cute!
Recording My Personal Space
Danny recommended using EEProm to record my data, so I wrote 2 programs to use with the Arduino + distance sensors: (1) to read input from sensor and record it into EEProm, and (2) output the data from EEProm via serial communication.
Recording the input form sensor to EEProm was hard to figure out, because each address could only save a byte, whereas the sensors gave int values for the distance. I had to sacrifice distance resolution and mapped the distance values into byte.
void loop() {
if (digitalRead(switchPin) == HIGH) { isStarting = true; }
if (isStarting) { //Record Front Distance SonarSensor(trigPin1, echoPin1); frontVal = constrain(distance, 2, 400); frontVal = map(frontVal, 2, 400, 1 , 255); FrontSensor = (byte) frontVal; writeEEPROM(disk1, counter, FrontSensor);
//Record Back Distance SonarSensor(trigPin2, echoPin2); backVal = constrain(distance, 2, 400); backVal = map(backVal, 2, 400, 0 , 255); BackSensor = (byte) backVal; writeEEPROM(disk1, counter + 1, BackSensor); counter += 2; delay(waitDuration); } }
void writeEEPROM(int deviceaddress, unsigned int eeaddress, byte data ) { Wire.beginTransmission(deviceaddress); Wire.write((int)(eeaddress >> 8)); // MSB Wire.write((int)(eeaddress & 0xFF)); // LSB Wire.write(data); Wire.endTransmission();
delay(5); }
byte readEEPROM(int deviceaddress, unsigned int eeaddress ) { byte rdata = 0xFF;
Wire.beginTransmission(deviceaddress); Wire.write((int)(eeaddress >> 8)); // MSB Wire.write((int)(eeaddress & 0xFF)); // LSB Wire.endTransmission();
Wire.requestFrom(deviceaddress, 1);
if (Wire.available()) rdata = Wire.read();
return rdata; }
//FUNCTION TO READ DISTANCE void SonarSensor(int trigPin, int echoPin) { digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); duration = pulseIn(echoPin, HIGH); distance = (duration / 2) / 29.1; }
Sending Data to P5
I spent the most time trying to figure this out. The sequence of data is important in this project, so the program should only start drawing when all of the data are properly recorded and indexed.
My first attempt was draw the data as soon as P5 received data from serial, but I had different asynchronous functions running at the same time and the data just got all jumbled up and sometimes the program would try to draw an instance that had not been initialized yet.
So I tried using the "handshake" method I found in the lab, and store the values into an array first.
function serialEvent() { // read a string from the serial port // until you get carriage return and newline: var stringFromSerial= serial.readLine(); //check to see that there's actually a string there: if (stringFromSerial.length>0){ if(stringFromSerial!== 'hello'){ // if you get hello, ignore it var trimmedString = trim(stringFromSerial); fromSerial=split(trimmedString, ','); if (fromSerial.length > 2){ inputDataIndex = fromSerial[0]; frontVal[inputDataIndex/2] = fromSerial[1]; backVal[inputDataIndex/2] = fromSerial[2]; //console.log(fromSerial[1]); //inputDataIndex++; } } console.log(inputDataIndex/2); serial.write('x'); // send a byte requesting more serial data } }
And this is the Arduino code for data output
#include <Wire.h>
#define disk1 0x50 //Address of 24LC256 eeprom chip
int counter = 0; int waitDuration = 50; //Speed of sending data to P5 int maximum = 600; //define end of data address from EEProm
boolean isStarting = false;
void setup(void) { Serial.begin(9600); Wire.begin(); while (Serial.available() <= 0) { Serial.println("hello"); // send a starting message delay(300); // wait 1/3 second } counter = 0; }
void loop() {
if (Serial.available() > 0) { if (counter < maximum) { Serial.print(counter); Serial.print(","); Serial.print(readEEPROM(disk1, counter), DEC); Serial.print(","); Serial.println(readEEPROM(disk1, counter + 1), DEC); counter += 2; delay(waitDuration); } } }
void writeEEPROM(int deviceaddress, unsigned int eeaddress, byte data ) { Wire.beginTransmission(deviceaddress); Wire.write((int)(eeaddress >> 8)); // MSB Wire.write((int)(eeaddress & 0xFF)); // LSB Wire.write(data); Wire.endTransmission();
delay(5); }
byte readEEPROM(int deviceaddress, unsigned int eeaddress ) { byte rdata = 0xFF;
Wire.beginTransmission(deviceaddress); Wire.write((int)(eeaddress >> 8)); // MSB Wire.write((int)(eeaddress & 0xFF)); // LSB Wire.endTransmission();
Wire.requestFrom(deviceaddress, 1);
if (Wire.available()) rdata = Wire.read();
delay(50); return rdata; }
Few hundred trials later, I got the program to work. The source code for the visualization in P5 can be found here.


#PComp #ICM #PhysicalComputing #Arduino #p5js #DataVisualization