Don't wanna be here? Send us removal request.
Text
The Passive-aggressive Hat final thoughts
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.
0 notes
Video
youtube
The Passive-aggressive Hat!
This video perfectly sums up what this project is about.
0 notes
Text
The Passive_aggressive Hat final code
The final project code. A few minor tweets to improve sensor readings and clean up code where possible.
#define HAPPY 1 #define SAD 2 #define RESTING 3 // Set-up low level interrupts for most accurate BPM maths #define USE_ARDUINO_INTERRUPTS true
#include <LedControl.h> #include <binary.h> #include <Servo.h> #include <PulseSensorPlayground.h>
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;
if((gsr >= 100) && ( gsr <= 299) && (pulse <= 61)) return HAPPY;
if((gsr >= 450 ) && (pulse <=500) && (pulse <=550)) return RESTING; }
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 } }
void loop() { uint8_t mood = currentMood(); drawFaces(mood); if (mood == SAD) servoControl(); }
0 notes
Text
The Passive-Aggressive Hat construction, part 2
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.

0 notes
Text
The Passive-Aggressive Hat construction, part 1
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.
0 notes
Text
The Passive-aggressive Hat diagram
The following explains how the hardware is connected together.

Arduino V5 to breadboard + row Arduino GND to breadboard - row
Matrix pin GND to Breadboard GND Matrix pin VCC to Breadboard V5 Matrix pin DIN to Arduino Pin 12 Matrix pin CS to Arduino Pin 10 Matrix pin CLK to Arduino Pin 11
Servo pin GND to Breadboard - row Servo pin V5 to Breadboard + row Servo pin SIGNAL to Arduino pin 3
Pulse Sensor GND to Breadboard - row Pulse Sensor V5 to Breadboard + row Pulse Sensor SIGNAL to Arduino A0
GSR GND to Breadboard - row GSR V5 to Breadboard + row GSR SIGNAL to Arduino A2
This photo shows everything together as described above.

0 notes
Text
The Passive-Aggressive Hat initial code
This is the code I used in the initial tests. This may or may not change for the final product.
#define HAPPY 1 #define SAD 2 #define RESTING 3 // Set-up low-level interrupts for most accurate BPM maths #define USE_ARDUINO_INTERRUPTS true
#include <LedControl.h> #include <binary.h> #include <Servo.h> #include <PulseSensorPlayground.h>
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; }
uint8_t currentMood() { int pulse = pulseReading(); long gsr = gsrReading(); // if((pulse >= 90) && (pulse < 200)) return SAD; // if(pulse <= 61 ) return HAPPY; // if ((pulse <=500) && (pulse <=550)) return RESTING
// Readings that work work me wearing the GSR and pulse sensor if((gsr >= 301) && (gsr <= 499) && (pulse >= 90) && (pulse < 200)) return SAD;
if((gsr >= 200) && ( gsr <= 300) && (pulse <= 61)) return HAPPY;
if((gsr >= 500 ) && (pulse <=500) && (pulse <=550)) return RESTING; }
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 } }
void loop() { uint8_t mood = currentMood(); drawFaces(mood); if (mood == SAD) servoControl(); }
0 notes
Text
The Passive-Aggressive Hat initial tests
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.

0 notes
Text
The Passive-Aggressive Hat concept drawing
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.
0 notes
Text
Matrix face code
#include "LedControl.h" #include "binary.h"
/* 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); }
void drawFaces() { // Display sad face 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]); delay(delaytime); // Display neutral face 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]); delay(delaytime); // Display happy face 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]); delay(delaytime); }
void loop() { drawFaces(); }
0 notes
Text
Arduino matrix for hat idea
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.

0 notes
Text
Display ‘Arduino’ code
//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); }
void loop() { writeArduinoOnMatrix(); }
0 notes
Video
tumblr
The video shows the word ‘Arduino’ being displayed on the matrix
0 notes
Text
Arduino matrix example
This shows the matrix running off the Arduino and being powered by the power bank.

This example displays the character for the word ‘Arduino’ one after the other on the matrix.
0 notes
Text
Arduino matrix circuit diagram
Here is the circuit diagram for the matrix board.
The pin wiring is as follows:
Matrix pin GND to Arduino Pin GND Matrix pin VCC to Arduino Pin V5 Matrix pin DIN to Arduino Pin 12 Matrix pin CS to Arduino Pin 10 Matrix pin CLK to Arduino Pin 11
0 notes
Text
Arduino Dot Matrix MAX7219 display
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