I’m pleased with the progress made with this project. I think, looking at the first entry on this blog and going to the latter entries, it shows a clear progression in understanding and knowledge with using an Arduino and it’s components. Whilst I still have much to learn on the subject, I would happily continue to learn more about Arduino and what it can do. I would even consider buy one for my son when he’s old enough. I believe it a good way of introducing coding to a person because it provides a visual representation, via the components, of what you have made.
Whilst I’m happy with The Passive-aggressive Hat as a concept, it probably hasn’t reached its full potential. The main problem I have with it are the GSR sensor and particularly the pulse sensor. Both are too unreliable and erratic in taking readings. I spent quite some time fine-tuning both to make sure they gave accurate readings, but it seems liked every time I turned the Arduino back on, the sensors were acting differently. I’m confident this isn't a code issue and is most likely a hardware problem. This could possibly be resolved by using more expensive sensors to see if they improve anything and worth pursuing in the future.
Another area I’d like to try and improve is the actual design and layout of the hat. I tried to think of a way to hide most of the Arduino components, but it wasn't possible. At least, I couldn't think of a way without destroying the hat! Maybe a version 2 of The Passive-aggressive Hat would only have one sensor taking readings? This would mean a breadboard wouldn't be needed, reducing the amount of components needs to get the hat running and therefore fewer wires. Alternatively, perhaps a different hat could be used? Maybe a top hat that hides all the components inside? A bigger hat could also mean using a different component to a servo, one that is larger with more torque, for example like a motor.
All of these suggestions could be experimented with if anyone decided to take this project further.
Servo myServo;
// The LED on the Arduino board
const int LED13 = 13;
// 'S' signal pin connected to A0
const int PulseWire = 0;
// signal pin connected to A2
const int GSR = A2;
// Determine which Signal to "count as a beat" and which to ignore
int Threshold = 500;
// Servo position
int pos = 0;
// GSR sensor values
int sensorValue = 0;
int gsrAverage = 0;
PulseSensorPlayground pulseSensor;
/*
DIN connects to pin 12
CLK connects to pin 11
CS connects to pin 10
*/
LedControl lc = LedControl(12,11,10,1);
// delay between faces
unsigned long delaytime = 1000;
// happy face
byte hf[8]= {B00000000,B01100110,B01100110,B00000000,B01000010,B00111100,B00000000,B00000000};
// neutral face
byte nf[8]= {B00000000, B00000000,B01100110,B00000000,B00000000,B01111110,B00000000,B00000000};
// sad face
byte sf[8]= {B00000000,B00100100,B01000010,B00000000,B00000000,B00111100,B01000010,B00000000};
void setup() {
lc.shutdown(0,false);
// Set the brightness to a medium values
lc.setIntensity(0,8);
// and clear the display
lc.clearDisplay(0);
// attaches the servo on pin 3 to the servo object
myServo.attach(3);
// Configures the PulseSensor and GSR by assigning our variables to them
Serial.begin(9600);
pulseSensor.analogInput(PulseWire);
pulseSensor.blinkOnPulse(LED13);
// Blink onboard LED with heartbeat
pulseSensor.setThreshold(Threshold);
// Check the "pulseSensor" object was created and began seeing a signal
if (pulseSensor.begin()) {
Serial.println("PulseSensor object created!");
}
}
void drawFaces(uint8_t mood) {
// Display sad face
if (mood == SAD) {
lc.setRow(0,0,sf[0]);
lc.setRow(0,1,sf[1]);
lc.setRow(0,2,sf[2]);
lc.setRow(0,3,sf[3]);
lc.setRow(0,4,sf[4]);
lc.setRow(0,5,sf[5]);
lc.setRow(0,6,sf[6]);
lc.setRow(0,7,sf[7]);
}
// Display neutral face
if (mood == RESTING) {
lc.setRow(0,0,nf[0]);
lc.setRow(0,1,nf[1]);
lc.setRow(0,2,nf[2]);
lc.setRow(0,3,nf[3]);
lc.setRow(0,4,nf[4]);
lc.setRow(0,5,nf[5]);
lc.setRow(0,6,nf[6]);
lc.setRow(0,7,nf[7]);
}
// Display happy face
if (mood == HAPPY) {
lc.setRow(0,0,hf[0]);
lc.setRow(0,1,hf[1]);
lc.setRow(0,2,hf[2]);
lc.setRow(0,3,hf[3]);
lc.setRow(0,4,hf[4]);
lc.setRow(0,5,hf[5]);
lc.setRow(0,6,hf[6]);
lc.setRow(0,7,hf[7]);
}
}
int pulseReading() {
int myBPM = pulseSensor.getBeatsPerMinute();
// Calculates BPM
if(pulseSensor.sawStartOfBeat()) {
// Constantly test to see if a beat happened
Serial.println("♥ A HeartBeat Happened ! ");
// If true, print a message
Serial.print("BPM: ");
Serial.println(myBPM); // Print the BPM value
}
delay(20);
return myBPM;
}
long gsrReading() {
long sum = 0;
//Average the 10 measurements to remove the glitch
for (int i = 0; i < 10; i++)
{
sensorValue = analogRead(GSR);
sum += sensorValue;
delay(5);
}
gsrAverage = sum / 10;
Serial.print("GSR: ");
Serial.println(gsrAverage);
return gsrAverage;
}
uint8_t currentMood() {
int pulse = pulseReading();
long gsr = gsrReading();
//Readings that work work me wearing the GSR and pulse sensor
if((gsr >= 301) && (gsr <= 425) && (pulse >= 90) && (pulse < 200)) return SAD;
void servoControl() {
// goes from 0 degrees to 180 degrees
for (pos = 0; pos <= 180; pos += 1) {
// in steps of 1 degree
myServo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
myServo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
}
I added an extra circle of garden wire to increase the strength of the hat and allow components to hang off of it.
After doing this, the Arduino and Dot matrix display were attached to it with string. The breadboard was attached by wrapping more wire around it.
The servo on the top of the hat seemed stable enough, so was left as is. The next step was to wire the thing up!
The GSR and Pulse Sensor were pushed through a small hole in the hat, normally used for the drawstring. The first image shows the GSR sensor.
The below images shows the pulse sensor.
Finally, everything was together. Now just to test it all still works! The image shows me wearing the hat, without the sensors attached to myself. As it should have done, the resting face is displaying.
I decided to build a frame, of which the Arduino and some components could be attached to. My guess was that this would make the project stronger and allow for easier transportation. The frame is built out of gardening wire as shown below.
The loops on the top are for the power supply to sit in, as shown here. Without the frame, the power supply wouldn't stay attached.
The initial plan was for the Arduino to sit on the brim at the back. However, this caused a problem, it was too heavy and caused it to sag.
The dot matrix display and the servo were stuck to the hat directly using gorilla double-sided sticky tape.
The design I decided to go with on the servo was someone giving the middle finger. It felt appropriately passive-aggressive. Most importantly, it is small, is light and doesn’t take up too much space on the hat. So now, if your heartbeat and skin resistance increases, the finger waves.
Finally, I attached a clear plastic circuit to the front of the dot matrix display. This was given to me as an idea to make it look more like a face. Personally I’m not sure how this looks yet but will give it a go. Worst case scenario, I remove it and just have the dot matrix display.
However, before attaching the breadboard, it was apparent that the weight of the components was a problem. It was too delicate and components were only just staying on the hat. This required a rethink of the design.
Servo myservo;
// The LED on the Arduino board
const int LED13 = 13;
// 'S' signal pin connected to A0
const int PulseWire = 0;
// signal pin connected to A2
const int GSR = A2;
// Determine which Signal to "count as a beat" and which to ignore
int Threshold = 500;
// Servo position
int pos = 0;
// GSR sensor values
int sensorValue = 0;
int gsr_average = 0;
PulseSensorPlayground pulseSensor;
/*
DIN connects to pin 12
CLK connects to pin 11
CS connects to pin 10
*/
LedControl lc = LedControl(12,11,10,1);
/* delay between faces */
unsigned long delaytime = 1000;
// happy face
byte hf[8]= {B00000000,B01100110,B01100110,B00000000,B01000010,B00111100,B00000000,B00000000};
// neutral face
byte nf[8]= {B00000000, B00000000,B01100110,B00000000,B00000000,B01111110,B00000000,B00000000};
// sad face
byte sf[8]= {B00000000,B00100100,B01000010,B00000000,B00000000,B00111100,B01000010,B00000000};
void setup() {
lc.shutdown(0,false);
/* Set the brightness to a medium values */
lc.setIntensity(0,8);
/* and clear the display */
lc.clearDisplay(0);
// attaches the servo on pin 3 to the servo object
myservo.attach(3);
// Configures the PulseSensor and GSR by assigning our variables to them
Serial.begin(9600);
pulseSensor.analogInput(PulseWire);
pulseSensor.blinkOnPulse(LED13);
// Blink on-board LED with heartbeat
pulseSensor.setThreshold(Threshold);
// Check the "pulseSensor" object was created and began seeing a signal
if (pulseSensor.begin()) {
Serial.println("PulseSensor object created!");
}
}
void drawFaces(uint8_t mood) {
// Display sad face
if (mood == SAD) {
lc.setRow(0,0,sf[0]);
lc.setRow(0,1,sf[1]);
lc.setRow(0,2,sf[2]);
lc.setRow(0,3,sf[3]);
lc.setRow(0,4,sf[4]);
lc.setRow(0,5,sf[5]);
lc.setRow(0,6,sf[6]);
lc.setRow(0,7,sf[7]);
}
// Display neutral face
if (mood == RESTING) {
lc.setRow(0,0,nf[0]);
lc.setRow(0,1,nf[1]);
lc.setRow(0,2,nf[2]);
lc.setRow(0,3,nf[3]);
lc.setRow(0,4,nf[4]);
lc.setRow(0,5,nf[5]);
lc.setRow(0,6,nf[6]);
lc.setRow(0,7,nf[7]);
}
// Display happy face
if (mood == HAPPY) {
lc.setRow(0,0,hf[0]);
lc.setRow(0,1,hf[1]);
lc.setRow(0,2,hf[2]);
lc.setRow(0,3,hf[3]);
lc.setRow(0,4,hf[4]);
lc.setRow(0,5,hf[5]);
lc.setRow(0,6,hf[6]);
lc.setRow(0,7,hf[7]);
}
}
int pulseReading() {
int myBPM = pulseSensor.getBeatsPerMinute();
// Calculates BPM
if(pulseSensor.sawStartOfBeat()) {
// Constantly test to see if a beat happened
Serial.println("♥ A HeartBeat Happened ! ");
// If true, print a message
Serial.print("BPM: ");
Serial.println(myBPM);
// Print the BPM value
}
delay(20);
return myBPM;
}
long gsrReading() {
long sum = 0;
for (int i = 0; i < 10; i++) // Average the 10 measurements to remove the glitch
{
sensorValue = analogRead(GSR);
sum += sensorValue;
delay(5);
}
gsr_average = sum / 10;
Serial.println(gsr_average);
return gsr_average;
}
void servoControl() {
for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
// in steps of 1 degree
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(15); // waits 15ms for the servo to reach the position
}
}
I have taken the Dot matrix display, a servo, the GSR and Pulse Sensor and attacked them all to the Arduino board. The first test was to see if the power pack would power everything, which I’m pleased to say it will. Then, I took code from previous experiments to try and produce code for the hat. A quick note on the face. You will notice it is different from the face I used in my preliminary tests of the Dot matrix display. This was because the original faces were not that clear.
A note regarding the sensor readings. I have spent a large amount of time, about two hours, trying to make the readings as accurate as possible. This involves adjusting the ‘threshold’ variable in the code for the pulse sensor, which tells the sensor which signal to count as a beat and which ones to ignore. Basically, it tries to reduce any interference in the readings. For the GSR, I had to adjust the resistor until the serial output as 512 (see post below for more details). The problem is that even after configuring these sensors for me wearing them, the readings are still erratic. I’ve been able to get the faces in a resting state, but the readings are all over the place, particularly for the Pulse Sensor. This fits with my findings about the pulse sensor, where the consensus is not to use it to take readings in important situations (see post below for more details). The GSR seems to be more reliable than the pulse sensors, but harder to test a change in readings, purely because it is hard to make yourself more stressed on the stop to see if the readings change.
I have been able to produce something that will work for the hat!
The first image shows a ‘resting’ face. This face is displayed when the GSR and Pulse Sensor are not attached to anything
The second image shows a ‘happy’ face. This face is displayed when the GSR and Pulse Sensor are attached to a person and get readings within a certain range. In this case, these readings have been decided upon based on me wearing each sensor.
Finally, the last image shows a ‘sad’ face. Similar to the happy face, this is displayed when the GSR and Pulse Sensor are attached to a person and get readings within a certain range. Again, these have been decided upon based on me wearing each sensor. The servo will also start to move if on the sad face.
This is a refined version of ‘The Hat of Ignorance’. After doing various tests with Arduino and the attachable components, I have decided to create ‘The Passive-Aggressive Hat’! Ignore the original name, ‘The Hat of Stress’.
The basic idea is that this hat measures the heartbeat, via the pulse sensor, and a personas stress levels, via the GSR. If one gets high, the Dot matrix display with show a sad face. If both get high, the servo will start to spin, drawing attention to the passive-aggressive message attached.
/*
DIN connects to pin 12
CLK connects to pin 11
CS connects to pin 10
*/
LedControl lc=LedControl(12,11,10,1);
/* delay between faces */
unsigned long delaytime=1000;
// happy face
byte hf[8]= {B00111100,B01000010,B10100101,B10000001,B10100101,B10011001,B01000010,B00111100};
// neutral face
byte nf[8]= {B00111100, B01000010,B10100101,B10000001,B10111101,B10000001,B01000010,B00111100};
// sad face
byte sf[8]= {B00111100,B01000010,B10100101,B10000001,B10011001,B10100101,B01000010,B00111100};
void setup() {
lc.shutdown(0,false);
/* Set the brightness to a medium values */
lc.setIntensity(0,8);
/* and clear the display */
lc.clearDisplay(0);
}
If I’m measuring emotions or how someone is feeling with the hat idea, it might be good to display these emotions.
I’ve put together some code that displays a happy, neutral and sad face on the matrix. Currently, it just loops through, but I should be able to link it up to a pulse sensor or GSR and displays the correct face depending on the readings from those sensors.
//We always have to include the library
#include "LedControl.h"
/* Now we need a LedControl to work with.
pin 12 is connected to the DataIn
pin 11 is connected to the CLK
pin 10 is connected to LOAD
We have only a single MAX72XX.
*/
LedControl lc=LedControl(12,11,10,1);
/* we always wait a bit between updates of the display */
unsigned long delaytime=500;
void setup() {
/*
The MAX72XX is in power-saving mode on startup,
we have to do a wakeup call
*/
lc.shutdown(0,false);
/* Set the brightness to a medium values */
lc.setIntensity(0,8);
/* and clear the display */
lc.clearDisplay(0);}
/*
This method will display the characters for the
word "Arduino" one after the other on the matrix.
(you need at least 5x7 leds to see the whole chars)
*/
void writeArduinoOnMatrix() {
/* here is the data for the characters */
byte a[5]={B01111110,B10001000,B10001000,B10001000,B01111110};
byte r[5]={B00010000,B00010000,B00100000,B00100000,B00111110};
byte d[5]={B11111110,B00100010,B00100010,B00010010,B00011100};
byte u[5]={B00111110,B00000100,B00000010,B00000010,B00111100};
byte i[5]={B00000000,B00000010,B10111110,B00100010,B00000000};
byte n[5]={B00111110,B00100000,B00100000,B00010000,B00111110};
byte o[5]={B00011100,B00100010,B00100010,B00100010,B00011100};
/* now display them one by one with a small delay */
lc.setRow(0,0,a[0]);
lc.setRow(0,1,a[1]);
lc.setRow(0,2,a[2]);
lc.setRow(0,3,a[3]);
lc.setRow(0,4,a[4]);
delay(delaytime);
lc.setRow(0,0,r[0]);
lc.setRow(0,1,r[1]);
lc.setRow(0,2,r[2]);
lc.setRow(0,3,r[3]);
lc.setRow(0,4,r[4]);
delay(delaytime);
lc.setRow(0,0,d[0]);
lc.setRow(0,1,d[1]);
lc.setRow(0,2,d[2]);
lc.setRow(0,3,d[3]);
lc.setRow(0,4,d[4]);
delay(delaytime);
lc.setRow(0,0,u[0]);
lc.setRow(0,1,u[1]);
lc.setRow(0,2,u[2]);
lc.setRow(0,3,u[3]);
lc.setRow(0,4,u[4]);
delay(delaytime);
lc.setRow(0,0,i[0]);
lc.setRow(0,1,i[1]);
lc.setRow(0,2,i[2]);
lc.setRow(0,3,i[3]);
lc.setRow(0,4,i[4]);
delay(delaytime);
lc.setRow(0,0,n[0]);
lc.setRow(0,1,n[1]);
lc.setRow(0,2,n[2]);
lc.setRow(0,3,n[3]);
lc.setRow(0,4,n[4]);
delay(delaytime);
lc.setRow(0,0,o[0]);
lc.setRow(0,1,o[1]);
lc.setRow(0,2,o[2]);
lc.setRow(0,3,o[3]);
lc.setRow(0,4,o[4]);
delay(delaytime);
lc.setRow(0,0,0);
lc.setRow(0,1,0);
lc.setRow(0,2,0);
lc.setRow(0,3,0);
lc.setRow(0,4,0);
delay(delaytime);
}
This is a simple 8x8 display, meaning it has 8 rows and 8 columns, with a total of 64 LEDs. Each column and row is indexed from 0 to 7. The pins on the matrix should be facing the left, as shown in the diagram above. This ensures it is orientated correctly, making items of the display appear correctly.
To display something on the matrix, you need to either turn on or off the LEDs. This is done using binary, so 0 represents the LEDs turned off and 1 represents them turned on.
For example, on the image below, Row 0 has 8 LEDs. To turn off the first two and last two, leaving the rest are on, the binary code used would be 00111100.
0 notes
Statistics
We looked inside some of the posts by
alanfranchi
and here's what we found interesting.
Average Info
Notes Per Post
0
Likes Per Post
0
Reblog Per Post
0
Reply Per Post
0
Time Between Posts
9 hours
Number of Posts By Type
Text
14
Video
3
Explore Tagged Posts
Fun Fact
When “GIF” was named word of the year in 2012, Oxford Dictionaries U.S.A. credited Tumblr for pushing the word.