element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      • Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Vietnam
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Wearable Technology
  • Technologies
  • More
Wearable Technology
Blog Christmas Hat: The Final Code
  • Blog
  • Forum
  • Documents
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Wearable Technology to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: brenyc13
  • Date Created: 19 Dec 2014 1:54 AM Date Created
  • Views 1111 views
  • Likes 3 likes
  • Comments 2 comments
  • flora
  • wearable_technology
  • code
  • christmas_hat
  • Wearables
  • adafruit
  • arduino
  • haturday
  • hat
Related
Recommended

Christmas Hat: The Final Code

brenyc13
brenyc13
19 Dec 2014

A post with the program.

 

image

 

Here it is, folks. The program for my Christmas Hat! I just want to give a big thank you to my Hunky Assistant, Pierre-Marc, for doing fancy code interpolations and humoring me during the lighting design process. I'm not yet good at enough at coding to have written all of this myself.

 

One of my favorite late-stage additions to the code is in line 134 below: "return get_tempF_serial();" which I un-comment and use to in order to tell the hat a specific temperature via the serial port. This was especially helpful when working out how it would look at what temp.

Let me know what you think!

 

//final version of the Xmas Hat code


#include <math.h>
#include <Adafruit_NeoPixel.h>


// change these to adjust the range of temperatures you want to measure
// (these are in Fahrenheit, multiplied by 10 to account for a decimal point)
#define COLDTEMP 400
#define TRANSITION_TEMP 700
#define HOTTEMP  800


#define INSTALLED_PIXELS 73


//The long Neopixel Strip is called "strip1"
Adafruit_NeoPixel strip1 = Adafruit_NeoPixel(INSTALLED_PIXELS, 6, NEO_GRB + NEO_KHZ800);
//The two 5mm Neopixels and three 8mm Neopixels are called "strip2"
Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(5, 9, NEO_RGB + NEO_KHZ800);


//TMP36 Pin Variables
int sensorPin = 10; //the analog pin the TMP36's data-out (middle) pin is connected to


//defining colors for cold state
uint8_t myColors[][3] = {{170, 170, 255},   // dim white
                         {170, 85, 255},   // white
                         {51, 102, 255},   // blue
                          };
                             
// don't edit the line below
#define COLDCOLORS sizeof(myColors) / 3


#define COLD_MODE_COLD_BACKGROUND
const uint8_t cold_mode_cold_background[] = { 0, 0, 11 };
const uint8_t cold_mode_hot_background[] = { 1, 2, 1 };


const uint8_t cold_mode_cold_interval = 2;
const uint8_t cold_mode_hot_interval = 200;


const uint8_t hot_mode_hot_frame_sleep = 2;
const uint8_t hot_mode_cold_frame_sleep = 30;


const uint8_t hot_mode_hot_interphase_sleep = 700;
const uint8_t hot_mode_cold_interphase_sleep = 60000;




#define HOT_FRONT_WIDTH 5
#define FRAMES_PER_PIXEL 10


uint8_t lut[256];
#define K  1.02189714865 // 256^(1/256)


// The current temperature
float temp;


void initialize_lut(void)
{
  short T;
  double TPh;
  for(lut[0] = 0, TPh = K, T = 1; T < 256; TPh *= K, T++) {
    lut[T] = (uint8_t) lrint(TPh);
    //Serial.print(TPh); Serial.print(" "); Serial.println(lut[T]);
  }
}


/*
* the setup() function runs once when you turn on the Flora
* Initialize the serial connection with the computer
* Initialize strip1 and strip2
*/
void setup()
{
   Serial.begin(9600);  //Start the serial connection with the computer
                       //to view the result open the serial monitor
                     
   pinMode(6, INPUT_PULLUP); //initializes strip1
   pinMode(9, INPUT_PULLUP); //initializes strip2
   strip1.begin();
   strip2.begin();
   strip1.show(); // Initializes strip1 to 'off'
   strip2.show(); // Initializes strip2 to 'off'

   initialize_lut();
    
   temp = get_tempF();
}


int get_tempF_serial()
{
  static char buf[10];
  static char *ptr = buf;
  static int serial_temp = get_tempF_sensor();

  while(Serial.available()) {
    Serial.readBytes(ptr, 1);
    if (ptr - buf == 10) {
      ptr = buf;
    }
  
    if (*ptr == '\n') {
      *ptr = '\0';
      serial_temp = atoi(buf);
      ptr = buf;


    } else {
      ptr++;
    }
  }
  Serial.print(serial_temp); Serial.println(" degrees F (serial)");

  return serial_temp;
}


int get_tempF()
{
  // to use serial temp, uncomment
  // return get_tempF_serial();
  return get_tempF_sensor();
}

/*
*this next bit is the Flora getting the temp from the sensor
* and also converting it into fahrenheit
*/
int get_tempF_sensor()  // gets the temp
{

//getting the voltage reading from the temperature sensor
int reading = analogRead(sensorPin);

// converting that reading to voltage, for 3.3v arduino use 3.3
float voltage = reading * 3.3;
voltage /= 1024.0;

// print out the voltage
//Serial.print(voltage); Serial.println(" volts");

// now print out the temperature
float temperatureC = (voltage - 0.5) * 100 ;  //converting from 10 mv per degree wit 500 mV offset
                                               //to degrees ((voltage - 500mV) times 100)
//Serial.print(temperatureC); Serial.println(" degrees C");

// now convert to Fahrenheit
float tempF = (temperatureC * 9.0 / 5.0) + 32.0;
Serial.print(tempF); Serial.println(" degrees F");

return tempF * 10;
}


void interpolate_detailed(uint8_t components, int frame, int total_frames, const uint8_t *initial, const uint8_t *next, uint8_t *vals)
{
  int i;

  //Serial.print("frame ");  Serial.print(frame);  Serial.print("/");  Serial.println(total_frames);

  for (i = 0; i < components; i++) {
    int16_t attrib_prev_val;
    int16_t attrib_next_val;

    attrib_prev_val = initial[i];
    attrib_next_val = next[i];
    int32_t tmp = (attrib_next_val - attrib_prev_val);
    tmp = tmp * frame / total_frames;
    vals[i] = attrib_prev_val + tmp;
  }
}


void set_background_color(uint8_t *col)
{
  int i;
  for (i=0; i<INSTALLED_PIXELS; i++) {
    strip1.setPixelColor(i, Adafruit_NeoPixel::Color(col[0], col[1], col[2]));
  }
}


uint16_t current_frame = 0;
uint16_t cold_frame = 0;
uint16_t cold_phase = 0;
uint8_t hot_phase = 0;
/* Here's the meat of the program -- the loop
*/
void loop()
{
  uint8_t white1, white2, blue1, blue2, green1, green2, red1, red2;


  if (temp < COLDTEMP) {
     temp = COLDTEMP;
  }

  if (temp > HOTTEMP) {
    temp = HOTTEMP;
  }

  if (temp < TRANSITION_TEMP) {
    uint8_t background[3];
    interpolate_detailed(3, temp - COLDTEMP, TRANSITION_TEMP - COLDTEMP, cold_mode_cold_background, cold_mode_hot_background, background);
    //set_background_color(background);
    uint32_t base_color = Adafruit_NeoPixel::Color(background[0], background[1], background[2]);
  
    uint8_t interval;
    interpolate_detailed(1, temp - COLDTEMP, TRANSITION_TEMP - COLDTEMP, &cold_mode_cold_interval, &cold_mode_hot_interval, &interval);
  
    flashRandom(strip1, 0, INSTALLED_PIXELS, interval, 1, base_color);  // first number is 'wait' delay, shorter num == shorter twinkle, third number is base color

    white1 = map(temp, TRANSITION_TEMP, COLDTEMP, 0, 255);
    blue1 = map(temp, TRANSITION_TEMP, COLDTEMP, 50, 255);
  
    strip2.setPixelColor(0, white1, white1, blue1); // strip.setPixelColor(pixel number in strip, R,G,B)
    strip2.setPixelColor(1, white1, white1, blue1); // "behind" LEDs get brighter the colder it gets
    strip2.setPixelColor(3, 0, 0, 4);
  
    strip2.show();
  
    temp = get_tempF();

  } else {
    uint16_t total_frames = (INSTALLED_PIXELS + 1) * FRAMES_PER_PIXEL;
  
    int i;
    for (i = 0; i < HOT_FRONT_WIDTH; i++) {
      if (current_frame / 10 < i) {
        break;
      }


      green1 = map(temp, TRANSITION_TEMP, HOTTEMP, 0, 250);
      green2 = map(temp, TRANSITION_TEMP, HOTTEMP, 0, 50);
      red1 = map(temp, TRANSITION_TEMP, HOTTEMP, 100, 250);
      red2 = map(temp, TRANSITION_TEMP, HOTTEMP, 0, 50);
    
      uint8_t green1_triplet[3] = {0, green1, 0};
      uint8_t green2_triplet[3] = {0, green2, 0};
      uint8_t red1_triplet[3] = {red1, 0, 0};
      uint8_t red2_triplet[3] = {red2, 0, 0};
    
      uint8_t this_pixel = current_frame / 10 - i;
      uint8_t val = 128*(i*FRAMES_PER_PIXEL+current_frame%FRAMES_PER_PIXEL)/(HOT_FRONT_WIDTH*FRAMES_PER_PIXEL);
    
    
    
      if (hot_phase < 1) {
        uint8_t color1_triplet[3] = {0, green1, 0};
        uint8_t color2_triplet[3] = {0, green2, 0};
              
        if (current_frame < 256) {
          interpolate_detailed(3, lut[current_frame], 255, red1_triplet, green1_triplet, color1_triplet);
          interpolate_detailed(3, lut[current_frame], 255, red2_triplet, green2_triplet, color2_triplet);
        }
    
        strip1.setPixelColor(this_pixel, strip1.Color(lut[val], 0, 0));
        strip2.setPixelColor(0, color1_triplet[0], color1_triplet[1], color1_triplet[2]); // strip.setPixelColor(pixel number in strip, R,G,B)
        strip2.setPixelColor(1, color1_triplet[0], color1_triplet[1], color1_triplet[2]); // "behind" LEDs get brighter the warmer it gets
        strip2.setPixelColor(3, color2_triplet[0], color2_triplet[1], color2_triplet[2]);
      } else {
        uint8_t color1_triplet[3] = {red1, 0, 0};
        uint8_t color2_triplet[3] = {red2, 0, 0};
              
        if (current_frame < 256) {
          interpolate_detailed(3, lut[current_frame], 255, green1_triplet, red1_triplet, color1_triplet);
          interpolate_detailed(3, lut[current_frame], 255, green2_triplet, red2_triplet, color2_triplet);
        }
    
        strip1.setPixelColor(this_pixel, strip1.Color(0, lut[val], 0));
        strip2.setPixelColor(0, color1_triplet[0], color1_triplet[1], color1_triplet[2]); // strip.setPixelColor(pixel number in strip, R,G,B)
        strip2.setPixelColor(1, color1_triplet[0], color1_triplet[1], color1_triplet[2]); // "behind" LEDs get brighter the warmer it gets
        strip2.setPixelColor(3, color2_triplet[0], color2_triplet[1], color2_triplet[2]);


      }


    }


  
    strip1.show();
    strip2.show();
    current_frame += 1;
  
    if (current_frame >= total_frames) {
      current_frame = 0;
      hot_phase++;
    
      uint8_t sleep_ms;
      interpolate_detailed(1, temp - TRANSITION_TEMP, HOTTEMP - TRANSITION_TEMP, &hot_mode_cold_interphase_sleep, &hot_mode_hot_interphase_sleep, &sleep_ms);
      delay(sleep_ms);
    
      delay(15000);
      hot_phase %= 2;
    
      temp = get_tempF();
    }
  
    uint8_t sleep_ms;
    interpolate_detailed(1, temp - TRANSITION_TEMP, HOTTEMP - TRANSITION_TEMP, &hot_mode_cold_frame_sleep, &hot_mode_hot_frame_sleep, &sleep_ms);
    delay(sleep_ms);
  }



}


void flashRandom(Adafruit_NeoPixel &strip, uint8_t range_start, uint8_t range_end, int wait, uint8_t howmany, uint32_t base_color)
{
    // pick a random favorite color!
    int c = random(COLDCOLORS);
    int red = myColors[c][0];
    int green = myColors[c][1];
    int blue = myColors[c][2];

    // get a random pixel from the list
    int chosen_pixels[howmany];
    for(uint16_t i=0; i<howmany; i++) {
      chosen_pixels[i] = random(range_end - range_start) + range_start;
    }
  
    int dim = 32;
  
    // now we will 'fade' it in 5 steps
    for(uint16_t i=0; i<howmany; i++) {
      strip.setPixelColor(chosen_pixels[i], strip.Color(red*dim/255, green*dim/255, blue*dim/255));
    }
    strip.show();
    delay(wait);


    for(uint16_t i=0; i<howmany; i++) {
      strip.setPixelColor(chosen_pixels[i], base_color);
    }
    strip.show();
    delay(wait);
}


void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip1.numPixels(); i++) {
      strip1.setPixelColor(i, c);
      strip1.show();
      delay(wait);
  }
}

 

Final post coming soon!

  • Sign in to reply
  • brenyc13
    brenyc13 over 11 years ago in reply to mcb1

    Thanks, Mark. I have a mind like a sieve so I know that I won't be able to remember anything unless it's commented.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • mcb1
    mcb1 over 11 years ago

    Nice work.

    Good to see lots of comments in your code ...it helps when you revisit it later as well.

     

    Mark

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube