Mohamed Fadiga
Published © LGPL

Foton - The Connected Lightsaber

Foton is a special lightsaber, which can monitor temperature and humidity of a room, detect movements, and send those data to a smartphone.

IntermediateFull instructions provided2 days1,438

Things used in this project

Hardware components

Photon
Particle Photon
×1
Android device
Android device
×1
PIR Motion Sensor
×1
Seeed Studio RGB LED Flexi-Strip 30 LED
×1
Catalex MP3 Board (YX5300 Chip)
×1
Seeed Studio Grove - Temperature&Humidity Sensor Pro
×1
Plexiglass pipe - Ø 30 - 26 MM
×1
microSD card
×1

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)

Story

Read more

Schematics

Foton

Foton.fzz

Code

foton.ino

C/C++
Spark Firmware
#include "application.h"
#include "neopixel/neopixel.h"
#include "PietteTech_DHT.h"

#define DHTTYPE  DHT22              
#define DHTPIN   D4       	    
#define PIRPIN   D0 

#define PIXEL_PIN D2
#define PIXEL_COUNT 28
#define PIXEL_TYPE WS2812B

#define CMD_PLAY_W_VOL 0X22
#define CMD_SEL_DEV 0X09
#define DEV_TF 0X02

static int8_t Send_buf[8] = {0} ;


void dht_wrapper(); 


PietteTech_DHT DHT(DHTPIN, DHTTYPE, dht_wrapper);
bool dht_acquiring = false;
int dht_sample_time = 0;
double temp = 0.00;
double humid = 0.00;
bool old_pir_val = LOW;
unsigned long pir_cooldown = 30000;
unsigned long last_pir_time = 0;
unsigned long dht22_sample_time = 30000;
unsigned long last_dht22_sample = 0;
bool dht22_acquiring = false;
bool movement = false;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);

void setup()
{
    Serial1.begin(9600);
    delay(500);//Wait chip initialization is complete
    sendCommand(CMD_SEL_DEV, DEV_TF);//select the TF card  
    delay(200);//wait for 200ms
    strip.begin();
    strip.show(); //turn off all the leds
    lightSaber(); //aniamte the lightsaber
    Particle.variable("temp", temp);
    Particle.variable("humid", humid);
    pinMode(PIRPIN, INPUT);
}


void rainbow(uint8_t wait) 
{
  uint16_t i, j;

  for(j=0; j<256; j++) 
  {
    for(i=0; i<strip.numPixels(); i++) 
    {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) 
{
  if(WheelPos < 85) {
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}

void lightSaber()
{
    strip.clear();
    sendCommand(CMD_PLAY_W_VOL, 0X1E01); //play sound 
    for(int i =0;i<28;++i)
    {
        strip.setPixelColor(i, 0, 0, 255);
        strip.show();
        delay(30);
    }
    rainbow(5);
    
}

void dht_wrapper() 
{
    DHT.isrCallback();
}

void loop()
{
    if(!dht22_acquiring && movement) //if there is a movement, but dht22 is not acquiring data
    {
        lightSaber();
        movement = false;
    }
    
    bool pir_val = digitalRead(PIRPIN);
    if(pir_val)
    {
        if(!old_pir_val)
        {
             if(millis() - last_pir_time >= pir_cooldown) //motion datected
             {
                movement = true;
                last_pir_time = millis();
                Particle.publish("Motion detected", NULL, 60, PRIVATE); //publish motion event to the cloud
             }
             old_pir_val = true;
        }
    }
    else old_pir_val = false;
    

    if(millis() - last_dht22_sample >= dht22_sample_time)
    {
        if (!dht22_acquiring) 
      	{
      	    Particle.publish("acquiring");
            DHT.acquire();
	        dht22_acquiring = true;
	    }
    	if (!DHT.acquiring()) //if dht22 finished acquiring data
    	{	

            temp = DHT.getCelsius();
            humid =  DHT.getHumidity();
            dht22_acquiring = false;  
            last_dht22_sample = millis();  
        }   
    }
}



//used to send serial command to mp3 module
void sendCommand(int8_t command, int16_t dat)
{
  delay(20);
  Send_buf[0] = 0x7e; //starting byte
  Send_buf[1] = 0xff; //version
  Send_buf[2] = 0x06; //the number of bytes of the command without starting byte and ending byte
  Send_buf[3] = command; //
  Send_buf[4] = 0x00;//0x00 = no feedback, 0x01 = feedback
  Send_buf[5] = (int8_t)(dat >> 8);//datah
  Send_buf[6] = (int8_t)(dat); //datal
  Send_buf[7] = 0xef; //ending byte
  for(uint8_t i=0; i<8; i++)//
  {
    Serial1.write(Send_buf[i]) ;
  }
}

Foton

Credits

Mohamed Fadiga

Mohamed Fadiga

8 projects • 36 followers
Teaher/ Maker / developer / IoT addicted / Sprinter 📚💡🤓💻. Passionate about anime, manga and pop-punk music. 🍥📖🎬🎸

Comments