Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
r Linte
Published © MIT

Cyberpunk Mask

I was wondering if I could make a futuristic and comfortable mask in this legendary punk cyber in 2020.

BeginnerProtip1 hour4,332
Cyberpunk Mask

Things used in this project

Hardware components

Seeeduino XIAO
I have to mention the xiao development board seen here. It is awesome. Its size has been reduced to the extreme, saving me a lot of space to install these electronic components in the mask.
×1
WS2813B Digital RGB LED Flexi-Strip 60 LED - 1 Meter
×1
Servo
×1
Grove - Air quality sensor v1.3
Seeed Studio Grove - Air quality sensor v1.3
×1
Grove - Relay
Seeed Studio Grove - Relay
×1
small fan
×1
Battery
×1
Dupont Line
×1
3M Mask
×1
Heat shrink tube
×1

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Hot glue gun
Electrical soldering iron
Laser cutter (generic)
Laser cutter (generic)

Story

Read more

Custom parts and enclosures

week2_gdEA4RREYP.dxf

Code

s_timer.h

C Header File
#ifndef STIMER_h
#define STIMER_h

#include "Adafruit_ZeroTimer.h"

namespace s_timer {

    void set(void (*f)(void));
    void start();
    void stop();
    void _overflow();

};
#endif

CyberpuckMaskXiao.ino

C/C++
#include <Arduino.h>

#include <Servo.h>

#include "s_timer.h"

#include "Adafruit_NeoPixel.h"

#include "Air_Quality_Sensor.h"
#define PIN 6
#define NUMPIXELS      11
#define BRIGHTNESS 255

AirQualitySensor sensor(A0);
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);
Servo servo_2;
int delayval = 500; // delay for half a second
int stateflag = 0;
int Secondcount = 0;
void setup() {
  // put your setup code here, to run once:
  servo_2.attach(5);

  servo_2.write(90);

  // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
#if defined (__AVR_ATtiny85__)
  if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
  // End of trinket special code

  strip.setBrightness(BRIGHTNESS);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  colorWipe(strip.Color(255, 255, 255), 50); // Green

  pinMode(4, OUTPUT);

  Serial.begin(115200);
//  while (!Serial);

  Serial.println("Waiting sensor to init...");
  delay(5000);

  if (sensor.init()) {
    Serial.println("Sensor ready.");
  }
  else {
    Serial.println("Sensor ERROR!");
  }
  
  colorWipe(strip.Color(0, 255, 0), 50); // Green
  s_timer::set(Timer4Callback0);
  s_timer::start();

}

void loop() {
  // put your main code here, to run repeatedly:
  if (stateflag == 1) {
    air_test();
    stateflag = 0;
  }
}
void air_test() {
  Serial.print("Sensor value: ");
  servo_2.detach();
  int data=sensor.getValue();
  Serial.println(data);
  int quality = sensor.slope();
  
  if (quality == AirQualitySensor::FORCE_SIGNAL) {
    Serial.println("High pollution! Force signal active.");
    colorWipe(strip.Color(255, 0, 0), 50); // Red
    digitalWrite(4, HIGH);
    servo_2.attach(5);
    servo_2.write(0);
    delay(2000);
  } else if (quality == AirQualitySensor::HIGH_POLLUTION) {
    Serial.println("High pollution!");
    colorWipe(strip.Color(255, 0, 0), 50); // Red
    digitalWrite(4, HIGH);//fan
    servo_2.attach(5);
    servo_2.write(0);
    delay(2000);
  } else if (quality == AirQualitySensor::LOW_POLLUTION) {
    Serial.println("Low pollution!");
    colorWipe(strip.Color(255, 255, 0), 50); // yellow
    digitalWrite(4, HIGH);
    servo_2.attach(5);
    servo_2.write(90);
    delay(2000);
  } else if (quality == AirQualitySensor::FRESH_AIR) {
    Serial.println("Fresh air.");
    colorWipe(strip.Color(0, 255, 0), 50); // Green
    digitalWrite(4, LOW);
    servo_2.attach(5);
    servo_2.write(90);
  }
}
volatile uint16_t dacout = 0;
void Timer4Callback0()
{
  stateflag = 1;
}
void colorWipe(uint32_t c, uint8_t wait) {
  for (uint16_t i = 0; i < strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    //  delay(wait);
  }
}

s_timer.cpp

C/C++
#include <Arduino.h>

#include <Servo.h>

#include "s_timer.h"

#include "Adafruit_NeoPixel.h"

#include "Air_Quality_Sensor.h"
#define PIN 6
#define NUMPIXELS      11
#define BRIGHTNESS 255

AirQualitySensor sensor(A0);
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);
Servo servo_2;
int delayval = 500; // delay for half a second
int stateflag = 0;
int Secondcount = 0;
void setup() {
  // put your setup code here, to run once:
  servo_2.attach(5);

  servo_2.write(90);

  // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
#if defined (__AVR_ATtiny85__)
  if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
#endif
  // End of trinket special code

  strip.setBrightness(BRIGHTNESS);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  colorWipe(strip.Color(255, 255, 255), 50); // Green

  pinMode(4, OUTPUT);

  Serial.begin(115200);
//  while (!Serial);

  Serial.println("Waiting sensor to init...");
  delay(5000);

  if (sensor.init()) {
    Serial.println("Sensor ready.");
  }
  else {
    Serial.println("Sensor ERROR!");
  }
  
  colorWipe(strip.Color(0, 255, 0), 50); // Green
  s_timer::set(Timer4Callback0);
  s_timer::start();

}

void loop() {
  // put your main code here, to run repeatedly:
  if (stateflag == 1) {
    air_test();
    stateflag = 0;
  }
}
void air_test() {
  Serial.print("Sensor value: ");
  servo_2.detach();
  int data=sensor.getValue();
  Serial.println(data);
  int quality = sensor.slope();
  
  if (quality == AirQualitySensor::FORCE_SIGNAL) {
    Serial.println("High pollution! Force signal active.");
    colorWipe(strip.Color(255, 0, 0), 50); // Red
    digitalWrite(4, HIGH);
    servo_2.attach(5);
    servo_2.write(0);
    delay(2000);
  } else if (quality == AirQualitySensor::HIGH_POLLUTION) {
    Serial.println("High pollution!");
    colorWipe(strip.Color(255, 0, 0), 50); // Red
    digitalWrite(4, HIGH);//fan
    servo_2.attach(5);
    servo_2.write(0);
    delay(2000);
  } else if (quality == AirQualitySensor::LOW_POLLUTION) {
    Serial.println("Low pollution!");
    colorWipe(strip.Color(255, 255, 0), 50); // yellow
    digitalWrite(4, HIGH);
    servo_2.attach(5);
    servo_2.write(90);
    delay(2000);
  } else if (quality == AirQualitySensor::FRESH_AIR) {
    Serial.println("Fresh air.");
    colorWipe(strip.Color(0, 255, 0), 50); // Green
    digitalWrite(4, LOW);
    servo_2.attach(5);
    servo_2.write(90);
  }
}
volatile uint16_t dacout = 0;
void Timer4Callback0()
{
  stateflag = 1;
}
void colorWipe(uint32_t c, uint8_t wait) {
  for (uint16_t i = 0; i < strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    //  delay(wait);
  }
}

Credits

r Linte

r Linte

3 projects • 9 followers

Comments