john_dillenburg
Published © GPL3+

Light Up Dice Skull using Arduino Nano

If your dice go everywhere when you are playing games, then this dice skull may be what you need to make next.

BeginnerFull instructions provided1,370
Light Up Dice Skull using Arduino Nano

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
×1
RGB Diffused Common Cathode
RGB Diffused Common Cathode
×1
Resistor 220 ohm
Resistor 220 ohm
×3
Resistor 10k ohm
Resistor 10k ohm
×1
Photo resistor
Photo resistor
×1
9V battery (generic)
9V battery (generic)
×1
Slide Switch
Slide Switch
×1
Battery Holder, 9V
Battery Holder, 9V
or 3D print this 9V battery holder
×1

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)
Soldering iron (generic)
Soldering iron (generic)
Solder Wire, Lead Free
Solder Wire, Lead Free
Hot glue gun (generic)
Hot glue gun (generic)

Story

Read more

Custom parts and enclosures

Fritzing

Code

Main code file

Skull 3D Print File

9V Battery Holder 3D Print File

Schematics

Circuit Diagram

Code

Skull Code

C/C++
Upload this to Nano
// Light up skull code for Arduino Nano
// (C) Copyright 2021 John Dillenburg
// john _at_ dillenburg.org
//
double avgWhenOn;
double avgWhenOff; 
long last = 0;
int lightOnLevel = 4;
long lastTrigger = 0;
long triggerCooldown = 500; // milliseconds
int detectThreshold = 10;
long recalibrateInterval = 300000; // milliseconds
long lastRecalibrate = 0;

void setup() {
  Serial.begin(115200);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(A0, INPUT);
  calibrate();
  if (Serial) {
    Serial.print("lightOnLevel = ");
    Serial.print(lightOnLevel);
    Serial.print("   avgWhenOn = ");
    Serial.print(avgWhenOn);
    Serial.print("   avgWhenOff = ");
    Serial.println(avgWhenOff);
  }
  detectMode();
}

void calibrate() {
  lightOnLevel = 20;
  avgWhenOn = average(500, lightOnLevel);
  avgWhenOff = average(500, 0);
  while (avgWhenOff - avgWhenOn < detectThreshold && lightOnLevel < 255) {
    lightOnLevel += 16;
    avgWhenOn = average(500, lightOnLevel);
  }
  if (lightOnLevel > 255) lightOnLevel = 255;
  lastRecalibrate = millis();
}

void rgb(int r, int g, int b) {
  analogWrite(9, 255 - r);
  analogWrite(10, 255 - g);
  analogWrite(11, 255 - b);
}

void movementDetected() {
  rgb(255, 0, 0);
  delay(3000);  
}

void detectMode() {
  rgb(lightOnLevel, lightOnLevel, lightOnLevel);
}

double average(int duration, int level) {
  rgb(level, level, level);
  long start = millis();
  long count = 0;
  double sum = 0.0;
  while (millis() < start + duration) {
    sum += analogRead(A0);
    count++;
  }
  return sum / count;
}

void loop() {
  int detector = analogRead(A0);
  avgWhenOn = avgWhenOn * 0.999 + detector * 0.001;
  if (Serial && millis() > last + 1000) {
    Serial.print("detector = ");
    Serial.print(detector);
    Serial.print("  avg = ");
    Serial.println(avgWhenOn);
    last = millis();
  }
  if (detector > avgWhenOn + detectThreshold && millis() > lastTrigger + triggerCooldown) {
    if (Serial) {
      Serial.print("triggered ");
      Serial.println(detector);
    }
    movementDetected();
    lastTrigger = millis();
    detectMode();
  }
  if (millis() > lastRecalibrate + recalibrateInterval) {
    calibrate();
  }
}

Credits

john_dillenburg
2 projects • 3 followers

Comments