Vinayak Shantaram Joshi
Published © MIT

DevDuino LCD Image Generator

Did you just happen to buy a DevDuino, and don't know how to generate an image for its LCD? If yes, then this is the blog for you.

BeginnerFull instructions provided12 minutes994
DevDuino LCD Image Generator

Things used in this project

Hardware components

DevDuino
×1

Story

Read more

Code

Arduino Code.

C/C++
I got this code as an example for the Devduino. This code has to be tweaked with the converted image, if you want to display the image on the lcd
#include <devduino.h>
#include <devduinoSprite.h>


#include "DevduinoSprite.h"

/*Replace the converted image here*/
static const uint8_t devduinoLogoBuffer[8][128] PROGMEM = {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x3c,0x1f,0x1f,0x0f,0x06,0x07,0x03,0x03,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x03,0x07,0x07,0x0e,0x0f,0x1f,0x1e,0x38,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},\
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xe0,0xff,0x3f,0x07,0x80,0x80,0x80,0xc0,0xe1,0xe0,0x70,0x30,0x38,0x18,0x1c,0x0e,0x0e,0x07,0x07,0x03,0x03,0x03,0x07,0x07,0x06,0x0e,0x0e,0x0c,0x0c,0x1c,0x1c,0x1c,0x18,0x18,0x18,0x1c,0x1c,0x1c,0x0c,0x0e,0x0e,0x0e,0x06,0x07,0x03,0x03,0x03,0x03,0x07,0x0e,0x0e,0x1c,0x1c,0x39,0x38,0x70,0x60,0xe0,0xc0,0xc0,0x80,0x80,0x01,0x1f,0xff,0xf8,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},\
{0x00,0x00,0x00,0x00,0x0c,0x17,0x31,0x20,0x40,0x80,0x86,0x0f,0x1f,0x0f,0x87,0xc1,0x60,0x30,0x18,0x0e,0x07,0x05,0x04,0x04,0x04,0x07,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0xfc,0xfc,0x1c,0x07,0x03,0x3c,0xc0,0xf0,0x3e,0x07,0x00,0x00,0x07,0x04,0x04,0x04,0x04,0x84,0x84,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x07,0x00,0x0f,0x00,0x1f,0x10,0x1f,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x03,0x04,0x04,0x84,0x85,0x07,0x07,0x06,0x01,0x0f,0x78,0xc0,0x3c,0x07,0x00,0x01,0x07,0x04,0x04,0x04,0xfc,0xfc,0xc4,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x0f,0x13,0x20,0x20,0x40,0x80,0x86,0x0f,0x1f,0x0f,0x87,0x41,0x20,0x10,0x0c,0x06,0x01,0x00,0x00},\
{0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x03,0x80,0xc0,0xf0,0xf8,0xbc,0x7f,0x3f,0x7f,0xfe,0xfc,0xf8,0x1e,0x01,0x00,0x80,0xf0,0xfe,0x7f,0x0c,0x30,0x60,0x38,0x1e,0x0e,0x38,0xc0,0x00,0x01,0x0f,0x7f,0xf8,0x80,0x00,0x01,0x00,0x00,0xe0,0x7c,0x0f,0xff,0x0f,0x1f,0x1e,0x1c,0x1f,0x00,0x00,0x00,0x1f,0x1f,0x1c,0x0e,0x0f,0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x07,0x01,0x06,0x0c,0x30,0x60,0x81,0x07,0x0e,0x38,0x70,0xe0,0x80,0x83,0x1e,0xe0,0x00,0x00,0x01,0x00,0x80,0x70,0xff,0xff,0x07,0x0f,0x1c,0x1f,0x1f,0x00,0x00,0x00,0x00,0x1f,0x1e,0x1f,0x0f,0x07,0xfe,0xfc,0xff,0x7f,0x1f,0x07,0x03,0x80,0xe0,0xf0,0xf8,0xfe,0x73,0x30,0x60,0xc0,0x80,0x00,0x00},\
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x11,0x0f,0x06,0x00,0x80,0xc0,0xe0,0x79,0x1f,0x0f,0xc7,0x3d,0x03,0x00,0x00,0x00,0x01,0x0f,0x1f,0x03,0x00,0x00,0x00,0x03,0x3f,0xfe,0xf0,0x00,0x00,0x03,0x3f,0xff,0xfe,0x0e,0x01,0x00,0xc0,0xf8,0x9f,0x03,0x00,0x00,0xff,0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00,0x80,0x80,0x00,0x01,0xc0,0x07,0xf0,0xff,0xff,0x00,0x00,0x20,0xfe,0xc1,0x80,0x00,0x00,0x00,0x07,0x38,0xc0,0x00,0x01,0x0f,0x77,0xfe,0x7f,0x07,0x00,0x00,0xe0,0x9c,0x03,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0xc0,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0xc0,0xe0,0xf8,0xfc,0xfe,0x7f,0x1f,0x0f,0x06,0x00,0x80,0x40,0x30,0x19,0x0e,0x00},\
{0x00,0x02,0x07,0x07,0x07,0x0f,0x0f,0x17,0x17,0x27,0x27,0x4f,0x8f,0x1f,0x1e,0x1e,0x3e,0x3c,0x7c,0xf8,0xf8,0xf0,0xe0,0xc0,0xc0,0x80,0x78,0x07,0x7f,0xff,0xff,0xf8,0xc0,0x78,0x0e,0x7f,0xfb,0xc3,0x03,0x03,0x07,0x7f,0xff,0xfc,0xc0,0x00,0x00,0xe0,0x3c,0x03,0x03,0x83,0xf3,0x7f,0x3f,0xff,0x03,0x03,0x03,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x00,0xff,0xc0,0xf8,0x1f,0x03,0x03,0x83,0x7b,0x07,0x0f,0x73,0x83,0x03,0x03,0x1c,0xe0,0xc0,0x00,0x00,0xe0,0xfc,0xff,0x1f,0x03,0x03,0xc3,0x7b,0xff,0xff,0x03,0x03,0x03,0x03,0x07,0x03,0x03,0x07,0x07,0x07,0x0f,0x0f,0x17,0x16,0x26,0x64,0x4c,0x8c,0x18,0x18,0x10,0x20,0x60,0x40,0x80,0x00,0x00,0x00},\
{0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x1e,0x10,0x17,0x9c,0x0e,0x14,0x1e,0x14,0x10,0x00,0x8b,0x9c,0x9e,0x8a,0x84,0x8c,0x82,0x0e,0x19,0x12,0x0c,0x13,0x1c,0x16,0x8a,0x90,0x86,0x84,0x8c,0x82,0x8e,0x80,0xc2,0xe0,0xf0,0x38,0x1c,0x0f,0x07,0x03,0x01,0xf0,0x00,0xfe,0x00,0xf0,0x01,0x03,0x0f,0x9e,0xbc,0xf8,0xf0,0xc2,0xcd,0x92,0x8e,0x8a,0x93,0x0d,0x1e,0x02,0x0e,0x00,0x04,0x0c,0x86,0x8a,0x99,0x92,0x8e,0x8f,0x9c,0x9e,0x82,0x8e,0x88,0x1a,0x80,0x9c,0x86,0x1e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},\
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xc0,0xe0,0xf0,0x78,0x3c,0x78,0xe0,0xc0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x03,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x00}};
DevduinoSprite devduinoLogo((uint8_t*) devduinoLogoBuffer, 128, 8);


void setup() {
  // put your setup code here, to run once:
  devduino.begin();
  display.drawSprite(devduinoLogo, 0, 0);
  display.flush();
}

void loop() {
}

Image convertor.

JavaScript
This javascript gives you an easy interface to convert any jpg or png image to hex code, which you can upload to the devduino. This hex code can be used to display the image on the devduino.
The javascript creates and interface where you can select the height and width of the converted image, and what threshold (Black and White) to use incase you have supplied a color image.
You can even invert the image using the checkbox. The interface also provides a preview of what the image will look like on the board.
<html>
<body>
<script type='text/javascript'>

var image_loaded=false;
var output_created=false;

function removeElement(elementId){
    document.getElementById(elementId).parentNode.removeChild(document.getElementById(elementId))
}

function inputFileSelected(){
    if(document.getElementById("inputFileToLoad").files.length>0){
    if(output_created==true){
        output_created=false;
        removeElement('output_data')
        removeElement('main_data')
    }
    if(image_loaded==true){
        removeElement('my-image')
        removeElement('loadFile')
        removeElement('divider')
        removeElement('divider1')
        image_loaded=false;
    }
}
}

function main()
{
    var inputFileToLoad = document.createElement("input");
    inputFileToLoad.type = "file";
    inputFileToLoad.id = "inputFileToLoad";
    inputFileToLoad.onchange=inputFileSelected;
    document.body.appendChild(inputFileToLoad);

    var buttonLoadFile = document.createElement("button");
    buttonLoadFile.onclick = loadImageFileAsURL;
    buttonLoadFile.textContent = "Load Selected File";
    document.body.appendChild(buttonLoadFile);
    document.body.appendChild(document.createElement("br"));

    var Table = document.createElement("table");
    var Row =document.createElement("tr");
    var Lables=document.createElement("th");
    Lables.innerHTML="Width";
    Row.appendChild(Lables);
    Lables=document.createElement("th");
    Lables.innerHTML="Height";
    Row.appendChild(Lables);
    Lables=document.createElement("th");
    Lables.innerHTML="Threshold";
    Row.appendChild(Lables);
    Lables=document.createElement("th");
    Lables.innerHTML="Inverse";
    Row.appendChild(Lables);
    Table.appendChild(Row);
    Row =document.createElement("tr");
    var inputWidth = document.createElement("input");
    Lables=document.createElement("th");
    inputWidth.type = "number";
    inputWidth.id= "input_width";
    inputWidth.value="128";
    Lables.appendChild(inputWidth);
    Row.appendChild(Lables);
    // document.body.appendChild(inputWidth);
    var inputHeight = document.createElement("input");
    Lables=document.createElement("th");
    inputHeight.type = "number";
    inputHeight.id= "input_height";
    inputHeight.value="64";
    Lables.appendChild(inputHeight);
    Row.appendChild(Lables);
    // document.body.appendChild(inputHeight);
    var inputHeight = document.createElement("input");
    Lables=document.createElement("th");
    inputHeight.type = "number";
    inputHeight.id= "threshold";
    inputHeight.value="128";
    Lables.appendChild(inputHeight);
    Row.appendChild(Lables);
    // document.body.appendChild(inputHeight);
    var inputHeight = document.createElement("input");
    Lables=document.createElement("th");
    inputHeight.type = "checkbox";
    // inputHeight.onclick=toggleInvertSelection
    inputHeight.id= "inverse";
    // document.body.appendChild(inputHeight);
    Lables.appendChild(inputHeight);
    Row.appendChild(Lables);
    Table.appendChild(Row);
    document.body.appendChild(Table);

}

function loadImageFileAsURL()
{
    var filesSelected = document.getElementById("inputFileToLoad").files;
    if (filesSelected.length > 0)
    {
        var fileToLoad = filesSelected[0];

        if (fileToLoad.type.match("image.*"))
        {
            var fileReader = new FileReader();
            fileReader.onload = function(fileLoadedEvent) 
            {
                var imageLoaded;
                if(image_loaded==false){
                    document.body.appendChild(document.createElement("br"))
                    imageLoaded = document.createElement("img");
                    imageLoaded.src = fileLoadedEvent.target.result;
                    imageLoaded.id = 'my-image'
                    document.body.appendChild(imageLoaded);
                    var divider=document.createElement("br");
                    divider.id="divider1"
                    document.body.appendChild(divider);
                    divider=document.createElement("br");
                    divider.id="divider"
                    document.body.appendChild(divider);
                    var buttonLoadFile = document.createElement("button");
                    buttonLoadFile.onclick = convertImageFile;
                    buttonLoadFile.textContent = "Convert Loaded File";
                    buttonLoadFile.id="loadFile"
                    document.body.appendChild(buttonLoadFile);
                    image_loaded=true;
                }else{
                    imageLoaded=document.getElementById("my-image")
                    imageLoaded.src=fileLoadedEvent.target.result;
                }
                imageLoaded.height=parseInt(document.getElementById("input_height").value);
                imageLoaded.width=parseInt(document.getElementById("input_width").value);
            };
            fileReader.readAsDataURL(fileToLoad);if(output_created==true){
                output_created=false;
                removeElement('output_data')
                removeElement('main_data')
            }
        }
    }
}

function convertImageFile(){
    var img = document.getElementById('my-image');
    var canvas,temp_canvas;
    var output_width=parseInt(document.getElementById("input_width").value);
    var output_height=parseInt(document.getElementById("input_height").value);
    var threshold=parseInt(document.getElementById("threshold").value);
    var above_count=0;
    var below_count=0;
    var invert=document.getElementById("inverse").checked;
    temp_canvas=document.createElement('canvas')
    temp_canvas.width=img.width
    temp_canvas.height=img.height
    temp_canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);
    if(output_created==false)
    {
        canvas= document.createElement('canvas');
        canvas.id='output_data'
        output_created=true;
    }else{
        canvas=document.getElementById('output_data');
    }
    canvas.width = img.width;
    canvas.height = img.height;
    canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);
    var main_data;
    main_data=document.getElementById('main_data')
    if(main_data==null){
        main_data=document.createElement("div")
        main_data.id="main_data"
    }
    var output_text=""
    var x_inc=canvas.width/output_width;
    var y_inc=canvas.height/output_height;
    var x_pixel=0,y_pixel=0,z_pixel=0;
    var pixelData = canvas.getContext('2d').getImageData(x_inc, y_inc, 1, 1).data;
    output_text+="{"
    var context_2d_output=canvas.getContext('2d');
    var context_2d=temp_canvas.getContext('2d');
    for(var i=0;i<output_height/8;i++){
        if(i!=0){
            output_text+=",\\<br />";
        }
        output_text+="{"
        x_pixel=0
        for (var j=0;j<output_width;j++){
            var data=0
            z_pixel=y_pixel;
            for(var k=7;k>=0;k--){
                image_data=context_2d.getImageData(x_pixel, z_pixel, 1, 1);
                pixelData = image_data.data;
                z_pixel+=y_inc;
                 average=((21.25 * pixelData[0]) + (71.54 * pixelData[1]) + (7.21 * pixelData[2]))/100;
                // average=pixelData[3];
                if(((average>threshold)&&(invert==false))||((average<=threshold)&&(invert==true))){
                    data+=(1<<k)
                    pixelData[0]=255;
                    pixelData[1]=255;
                    pixelData[2]=255;
                    pixelData[3]=0;
                    above_count++;
                }else{
                    pixelData[0]=0;
                    pixelData[1]=0;
                    pixelData[2]=0;
                    pixelData[3]=255;
                    below_count++
                }
                image_data.data=pixelData
                context_2d_output.putImageData(image_data,x_pixel,z_pixel);
            }
            if(j!=0){
                output_text+=","
            }
                output_text+="0x"
            if(data<16){
                output_text+="0"
            }
            output_text+=data.toString(16);
            x_pixel+=x_inc
        }
        output_text+="}"
        y_pixel=z_pixel;
    }
    output_text+="};"
    main_data.innerHTML=output_text
    // document.body.insertBefore(main_data,document.getElementById('loadFile'))
    document.body.appendChild(main_data)
    document.body.insertBefore(canvas,document.getElementById('divider'))
}

main();

</script>

</body>
</html>

Credits

Vinayak Shantaram Joshi

Vinayak Shantaram Joshi

11 projects • 63 followers

Comments