Rhys' EE Adventures

Don't let the smoke out

  • Home

Persistence Of Vision Fan (Prototype/incomplete)

Posted by Rhys on 25 February 2015
Posted in: Personal Projects.

5.Action_ShotWarning: Incomplete write-up.
Server Side:
Image –> Resize to 16px height –> Determine Pixel Red, Green and Blue components –> Compensate, arrange and bit-shift values to a byte string of 12 bit PWM (Pulse Width Modulation) values.

Micro-controller:
Use hall effect sensor for positioning –> Display RGB PWM image using internal microcontroller timers and serial communication.

Potential next steps:

  • Add phase locked loop (PLL) clock multiplier to GSCLK line for faster display timing (4096 clock cycles)
  • Modify library for multiplied GSCLK signal, allow “frames” to be imported on the fly via serial (or possibly parallel)
  • Use an ESP8266 ESP-07 to get frames over TCP and relay those frames to the Arduino on the fly.
  • Update PHP to have the fan automatically display new images
  • Build transformer for power transmission from fan housing to fan blade.

4.Mounted_LEDs 3.Power_Pass+Regulation

 

 

2.LED_Board_Back 1.LED_Board_Front

Custom circuit boards, diodes on Red LEDs due to lower forward voltage.

PHP code adapted from Alex Leone’s original greyscale JAVA code:

[code language=”php”]
<?php
$source_file = "latest.png";

//$im = ImageCreateFromPng($source_file); //For later use
//$im = ImageCreateFromJpeg($source_file); //For later use

function imageCreateFromAny($filepath) {
    $type = exif_imagetype($filepath); // [] if you don’t have exif you could use getImageSize()
    $allowedTypes = array(
        1,  // [] gif
        2,  // [] jpg
        3,  // [] png
        6   // [] bmp
    );
    if (!in_array($type, $allowedTypes)) {
        return false;
    }
    switch ($type) {
        case 1 :
            $im = imageCreateFromGif($filepath);
        break;
        case 2 :
            $im = imageCreateFromJpeg($filepath);
        break;
        case 3 :
            $im = imageCreateFromPng($filepath);
        break;
        case 6 :
            $im = imageCreateFromBmp($filepath);
        break;
    }   
    return $im;
}

$im = ImageCreateFromAny($source_file);

$imgw = imagesx($im);
$imgh = imagesy($im);

$line = "#define    ANIRGB_FRAMES    ".($imgw).PHP_EOL;// "\r\n"; // PHP_EOL;
//echo $line;
$data = $line;
$line = "uint8_t aniRGB[NUM_TLCS * 24 * ANIRGB_FRAMES] PROGMEM = {".PHP_EOL;
//echo $line;
$data .= $line;

for ($i=$imgw; $i>0; $i–)
{

        for ($j=0; $j <= ($imgh – 1); $j+=2)
        {

                // get the rgb value for current pixel

                $rgb = ImageColorAt($im, $i, $j);
                $rgb2 = ImageColorAt($im, $i, ($j + 1));

                // extract each value for r, g, b
                /*
                $r = ($rgb >> 16) & 0xFF;
                $g = ($rgb >> 8) & 0xFF;
                $b = $rgb & 0xFF;
                */
                
                $a = (int)round(0.4 * (($rgb >> 16) & 0xFF));
                $b = (int)round(0.8 * (($rgb >> 8) & 0xFF));
                $c = (int)($rgb & 0xFF);
                $d = (int)round(0.4 * (($rgb2 >> 16) & 0xFF));
                $e = (int)round(0.8 * (($rgb2 >> 8) & 0xFF));
                $f = (int)($rgb2 & 0xFF);
                
                // echo $a.",".$b.",".$c.",".$d.",".$e.",".$f.",,"; //DEBUG
                
                $line = ((((int)$a >> 4) & 0xFF).",".((((int)$a << 4) | ((int)$b >> 8)) & 0xFF).",".((int)$b & 0xFF).",".(((int)$c >> 4) & 0xFF).",".(((int)($c << 4) | ((int)$d >> 8)) & 0xFF).",".((int)$d & 0xFF).",".(((int)$e >> 4) & 0xFF).",".((((int)$e << 4) | ((int)$f >> 8)) & 0xFF).",".((int)$f & 0xFF).",");//.PHP_EOL;
                //echo $line;
                $data .= $line;

        }
        $line = PHP_EOL;
        //echo $line;
        $data .= $line;
}

$line = "};".PHP_EOL;
//echo $line;
$data .= $line;
//echo $data;

$myFile = "aniRGB.h";
$fh = fopen($myFile, ‘w’) or die("can’t open file");
fwrite($fh, $data);
fclose($fh);
?>
[/code]

Arduino Code based on TLC5940 Library animation sketch and customised accordingly

[code]
/*
    Writes "Ardunio" with Persistance of Vision (POV) with 16 LEDs (output 0
    is on bottom, output 15 is top).  The animation below doesn’t work with
    more than 1 TLC.

    I generated the animation with the included java code:
    <arduino folder>/hardware/libraries/Tlc5940/examples/BasicAnimations

    To use the code, run
        java AnimationCreator
    in the folder above and it will parse all images in the folder to
    .h files.  For best results use images that are 16 pixels high.

    See the BasicUse example for hardware setup.

    Alex Leone <acleone ~AT~ gmail.com>, 2009-02-03 */

#include "Tlc5940.h"
#include "tlc_animations.h"
#include "aniRGB.h"
const int hallPin =  7;

void setup()
{
  Tlc.init();
  delay(5000);
}

void loop()
{
  if (digitalRead(hallPin) == HIGH) {
    
  }
 else if (!tlc_onUpdateFinished) { // checks to see if the animation is finished playing

    /*
      void tlc_playAnimation(prog_uint8_t *animation, uint16_t frames,
                             uint16_t periodsPerFrame);
      periods per frame is PWM periods, 1.024ms per frame (0 is valid – this
      will play the animation as fast as possible).

      Plays an animation in the "background".
      Don’t call Tlc.update() while this is running.
      You can check if this is done with !tlc_onUpdateFinished */
    tlc_playAnimation(aniRGB, ANIRGB_FRAMES, 0);

    // If you don’t want to do anything until it’s finished, use:
    // while (!tlc_onUpdateFinished);

  }
  else {
    //wait
  }

}

[/code]

Posts navigation

← Benchtop ATX Power Supply (updated)
Basic “PLC” Road/Rail Intersection Controller →
  • Recent Posts

    • Pineapple Cam
    • Toastmasters Speech Timing System
    • A very expensive Etch-A-Sketch (+Extensions)
    • Driving a multiplexed 512 LED panel from the stack
    • PicAXE based Motor Driver
  • Recent Comments

    • Archives

      • July 2017
      • January 2016
      • December 2015
      • November 2015
      • October 2015
      • August 2015
      • June 2015
      • May 2015
      • February 2015
    • Categories

      • Personal Projects
      • Uni Projects
    • Meta

      • Log in
      • Entries feed
      • Comments feed
      • WordPress.org
    • Recent Posts

      • Pineapple Cam
      • Toastmasters Speech Timing System
      • A very expensive Etch-A-Sketch (+Extensions)
      • Driving a multiplexed 512 LED panel from the stack
      • PicAXE based Motor Driver
    • Recent Comments

      • Archives

        • July 2017
        • January 2016
        • December 2015
        • November 2015
        • October 2015
        • August 2015
        • June 2015
        • May 2015
        • February 2015
      • Categories

        • Personal Projects
        • Uni Projects
      • Meta

        • Log in
        • Entries feed
        • Comments feed
        • WordPress.org
      Proudly powered by WordPress Theme: Parament by Automattic.