Close
0%
0%

2D Heat Conduction Solver

A real-time solver for 2D transient heat conduction with isothermal boundary conditions in less than 1 Kb, visualized on an LED board.

Similar projects worth following
A real-time solver for 2D transient heat conduction with isothermal boundary conditions in less than 1 Kb, visualized on an LED board.

Despite all of your friends who like to say that "heat goes up", heat actual moves according to this equation,

If you're wondering what on earth that means, you have two options: study differential equations for a few years or watch the colors change on our LED board. This LED board displays our solution to the 2D heat equation, written in less than 1Kb of program space. If you were to heat up a 14.5 x 10.9 inch sheet of copper, the heat would move through it exactly as our board displays. The same temperatures would be at the same locations at the same time. Don't believe it? Grab your thermocouple and come along!


The Setup

We built a 32x24 RGB LED matrix and attached six thermistors to the border. The temperature readings from the thermistors serve as the real-time boundary conditions to the solver, while the solution is displayed by the LEDs. In the video below we're heating the thermistors with a heatgun.

Solution

In order to solve this differential equation, you first need to approximate it as an algebraic equation. We chose to use a first order, forward difference in time and a second order central difference in space. The equation to solve then becomes,

Since the distance between the LEDs in the x-direction is the same as the y-direction on our display board, we can simplify a bit.

Much better. Now we use Euler's Explicit method to solve for the temperature.

And there you have it, the temperature at each node as a function of time. Assign boundary conditions, the appropriate distance between LEDs, use a thermal diffusivity associated with a material of your liking (we chose copper), and take a time step that doesn't violate the Courant Limit.

Code

We coded the solution in five main steps.

  1. Read the thermistors
  2. Update the boundary conditions
  3. Solve the conduction equation
  4. Update the LED color
  5. Wait for the appropriate amount of real time to pass before continuing


To see the code in all its glory head over to Github:

https://github.com/VectorSpaceHQ/2d_conduction


Code Size

The following output generated by running make in the avr/src directory shows that when compiled with avr-gcc version 4.9.2 the binary size of the program falls less than or equal to 1kB. 1024 bytes exactly

avr-gcc --version
avr-gcc (GCC) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

avr-gcc -mmcu=atmega328p -std=gnu99 -Os -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,-Map=conduction.map -flto -mrelax -lm -nostartfiles -g3 -DNO_VECTORS -DF_CPU=16000000 -I startup/common main.c spi.c adc.c rgb_matrix.c colormap.c conduction.c timer.c interpolate.c startup/crt1/gcrt1.S -o conduction
avr-size conduction
   text    data     bss     dec     hex filename
   1024        0    1600    2624     a40 conduction
avr-objcopy -O ihex -R .eeprom conduction conduction.hex


Size Reduction Techniques

We are using the AVR flavor of GCC as our compiler, and have made a few tweaks to help with the 1kB size constraint

  • Used fixed point math instead of floating point
  • Ask GCC to perform its usual optimizations for size
    -Os	
  • Create separate function and data sections in the executable and instruct the linker to garbage collect any unused sections:

    -ffunction-sections -fdata-sections -Wl,--gc-sections	
  • Allow for standard link-time optimization by asking GCC to save some of its internal representations to the object file of each compilation unit
    -flto	
  • Disable the standard system startup files when linking the final executable. We've created our own in src/startup and modified crt1/gcrt1.S to remove the code for the interrupt vectors since we won't be needing them for our project.
    -nostartfiles	

  • 1 × Arduino Uno
  • 6 × 10K NTC Thermistor
  • 6 × 10K Resistor
  • 12 × RGB Matrix PCBs
  • 768 × SK9822 RGB LEDs

View all 6 components

  • Shrink this stuff down!

    Jordan Goulder01/05/2017 at 02:49 0 comments

    (Forgive the Walking Dead homage)

    I applied some supernatural ways to shrink the final size of our binary down, plan to add a separate section on the hackaday page describing some of the techniques.

  • Thermistors soldered up

    Jordan Goulder01/05/2017 at 02:46 0 comments

    We repurposed some old phone cable and soldered up six 10K thermocouples to the LED board. We drilled through the back of the board so the thermistors could sense heat from the front, either from a heat gun or even just touching it with your finger.

    A little too late too get much further tonight, but hopefully our board will be glowing soon

  • Battle of the LED Painting Algorithms

    Jordan Goulder01/05/2017 at 02:43 0 comments

    The LED matrix is actually made up of 12 smaller (8x8) boards that are connected together. This requires an interesting (painful) algorithm for getting our color map to display correctly.

    As Adam stated in 242560:

    Because Jordan soldered the LED matrix without care and respect for the
    rest of us, a significant amount of mapping has to be done from the
    temperature array to the LED layout.

    Adam made a decent attempt, but didn't quite get it right. It also took him a fair amount of convincing that his algorithm was junk, but a few tests and a final working solution put us all back on track.

  • Uh-oh 32x24x2 too big!

    Jordan Goulder01/05/2017 at 02:27 0 comments

    Our J-Goulder manufactured LED board has 32x24 LEDs and we definitely want to light the whole thing up with just our spare Arduino Uno. This would normally be no problem, but our transient conduction algorithm requires two arrays at a time (one for the current time step, one for the previous). This kind of pushes our RAM requirements too the limit.

    brewlius-cesar thought of a quick way to trim down the fat of our algorithm by keeping only a single row of "previous" values and swapping out the values as we do our radial sweeps for each time step.

  • Created a Github Repositiory

    Jordan Goulder01/05/2017 at 02:19 0 comments
  • Initial Idea

    Jordan Goulder01/05/2017 at 02:16 0 comments

    Adam has an idea:

    We add a few temperature sensors to each edge of Jordan's led screen. You hold it, and the led colors reflect the temperature around the edge, which is the initial condition. You hit a button, and it acts like a box full of water, showing natural convection driven by the initial edge temperature that you gave it

View all 6 project logs

Enjoy this project?

Share

Discussions

Ted Yapo wrote 01/05/2017 at 19:47 point

This is a great interactive visualization!  It's like some kind of thermal augmented reality.  I could see this becoming a science museum exhibit.

I remember having to implement this algorithm in FORTRAN as an undergrad in 1988.  We were the last engineering class they taught FORTRAN.  They started using C after that.

  Are you sure? yes | no

Adam Spontarelli wrote 01/07/2017 at 19:45 point

Thanks! Just think, kids today are probably using Matlab or Scratch.

  Are you sure? yes | no

Ted Yapo wrote 01/07/2017 at 20:45 point

As long as they stay off my lawn :-)

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates