Custom character generator for 16x Freetronics LCD+keypad

Download: https://dl.dropboxusercontent.com/u/85621331/custom%20char.zip

I wanted to add some custom characters, and it was fiddly designing them by hand. I also wanted to see what the text lines looked like without constantly counting characters in strings.

So I wrote a little utility to help. I am curious if anyone would be interested in the app - it's Windows only, sorry.

It looks like this:

If there's any interest, I just need somewhere to upload it. If there's something better already in existence, great, please let me know :smiley:

I'm probably going to write some other utilities as I get into Arduino development, so it would be good to know if there's any interest in sharing them with the community.

They're written in Delphi and use custom VCL components, so releasing source is not really an option, but am happy to release them as freeware.

Also: please let me know if there is a better place to post these sorts of messages.

Neat little program. You could upload it to somewhere like sourceforge or github. Is it stand-alone or do you have an installer? You could technically zip it up and upload to any file sharing site.

If you give a link to the download, I would use it..

That's quite nice, which way does the data entry work, I assume clicking on the "dots" in the graphic changes the code snippet.

Also can it generate a 2-dimensional array for X number of chars?

Doesn't matter what you do, people always want more eh :slight_smile:


Rob

Graynomad:
That's quite nice, which way does the data entry work, I assume clicking on the "dots" in the graphic changes the code snippet.

Also can it generate a 2-dimensional array for X number of chars?

Doesn't matter what you do, people always want more eh :slight_smile:


Rob

Yeah that's right. Click a dot and the code is updated. The 16x2 only allows 8 custom characters so doing them individually seemed good enough. I had lots of other ideas to enhance it but KISS is working as I focus on the Arduino programming :slight_smile:

If / when I upload it I will post a link.

Have struggled with the Arduino IDE :-/ I am designing a replacement for that in my head. Eesh!

aarondc:
Have struggled with the Arduino IDE :-/ I am designing a replacement for that in my head. Eesh!

Might want to consider the Arduino Enhanced Release 1.0.4 - http://arduino.cc/forum/index.php/topic,118440.0.html

And also using Notepad++ for the editor - http://arduino.cc/forum/index.php/topic,160456.0.html

Have struggled with the Arduino IDE :-/ I am designing a replacement for that in my head. Eesh!

There are 3-4 nice alternatives already so don't knock yourself out doing another one.

focus on the Arduino programming

Yes it's easy to get distracted making tools and get nothing done on the original project.


Rob

codlink:

aarondc:
Have struggled with the Arduino IDE :-/ I am designing a replacement for that in my head. Eesh!

Might want to consider the Arduino Enhanced Release 1.0.4 - http://arduino.cc/forum/index.php/topic,118440.0.html

And also using Notepad++ for the editor - http://arduino.cc/forum/index.php/topic,160456.0.html

Yeah was just perusing the Arduino enhanced thread. Still ugly as sin :wink:

I use Notepad++ for my web programming, so yes, a good suggestion.

Graynomad:

Have struggled with the Arduino IDE :-/ I am designing a replacement for that in my head. Eesh!

There are 3-4 nice alternatives already so don't knock yourself out doing another one.

focus on the Arduino programming

Yes it's easy to get distracted making tools and get nothing done on the original project.


Rob

Can you suggest any more IDEs?

Also: the serial monitor is kinda bare minimum. I downloaded RealTerm and that's interesting.

Any suggestions for serial comms app?

ETA: I stalked you over to ozelecforum, see you mentioned netbeans. Also learnt you can embed assembler! weeeee!! My first ever project out of uni was a serial port IVT accessible circular buffer data capture TSR for a POS system, all written in assembler. Good to know.

Am keen on getting into some solar / wind energy stuff, so will be joining ozelec at some stage to get the lowdown there too.

Found an online generator. http://mikeyancey.com/hamcalc/lcd_characters.php

aarondc:
I wanted to add some custom characters, and it was fiddly designing them by hand. I also wanted to see what the text lines looked like without constantly counting characters in strings.

So I wrote a little utility to help. I am curious if anyone would be interested in the app - it's Windows only, sorry.

It looks like this:

If there's any interest, I just need somewhere to upload it. If there's something better already in existence, great, please let me know :smiley:

Hi Aaron

That looks like a great app, we'd be happy to host that for you if you like. Email john at freetronics dot com.

Great app, no doubt about it, but can you se the build character in the lines?
If you could that would be an amazing app!

Looks quite nice. My only perceived draw-back is it's non-portability.

I played with something similar a few weeks back. First for designing custom characters for 1602 lcds, then later for either 1bit or 16bit images for 16bit tft screens. I can post them if anybody has a use for them.

Here's something I threw-together over something to eat for lunch. Tested under Win7, Raspian, Linux Mint - Chrome or Chromium in all cases.

lcdHelper.html

<!DOCTYPE html>
<html>
<head>
<script>
function byId(e){return document.getElementById(e);}
function newEl(tag){return document.createElement(tag);}
function newTxt(txt){return document.createTextNode(txt);}
function toggleClass(element, newStr)
{
	index=element.className.indexOf(newStr);
	if ( index == -1)
		element.className += ' '+newStr;
	else
	{
		if (index != 0)
			newStr = ' '+newStr;
		element.className = element.className.replace(newStr, '');
	}
}
function forEachNode(nodeList, func)
{
	var i, n = nodeList.length;
	for (i=0; i<n; i++)
	{
		func(nodeList[i], i, nodeList);
	}
}

function hasClass(el, classStr)
{
	if ( (el.className.indexof(classStr) == 0) || (el.className.indexof(" "+classStr) != -1) )
		return true;
	return false;
}

function addClass(el, classStr)
{
	el.className += " " + classStr;
}

function removeClass(el, classStr)
{
	var index = el.className.indexOf(classStr);
	if (index != -1)
	{
		if (index != 0)
			classStr = " " + classStr;
		el.className = el.className.replace(classStr, '');
	}
}

window.addEventListener('load', mInit, false);
var btnState = 0;

function mInit()
{
	var tdList = document.querySelectorAll('td');
	var i, n;
	forEachNode(tdList, function(el){el.addEventListener('mousedown', function(){toggleClass(this, 'active');})});

	n = tdList.length;
	for (i=0; i<n; i++)
		tdList[i].addEventListener('mouseover', onCellEnter);

	window.addEventListener('mousedown', onMouseDown, false);
	window.addEventListener('mouseup', onMouseUp, false);
}

function onCellEnter(evt)
{
	if (btnState == 1)
		toggleClass(this, "active");
	console.log(evt);
}

function onMouseDown(evt)
{
	btnState = 1;
}
function onMouseUp(evt)
{
	btnState = 0;
}

function computeOutput()
{
	var curByte=0, tbl, curRow, curCell, nRows, nCells;
	var curStr = "byte character[8] = {\n\t";
	
	tbl = byId('char');
	nRows = tbl.rows.length;
	for (curRow=0; curRow<nRows; curRow++)
	{
		curByte = 0;
		nCells = tbl.rows[curRow].cells.length;
		for (curCell = 0; curCell<nCells; curCell++)
		{
			curByte <<= 1;
			if (tbl.rows[curRow].cells[curCell].className.indexOf('active') != -1)
				curByte |= 1;
		}
		if (curRow != 0)
			curStr += ",\n\t";
		curStr += curByte;
	}
	curStr += "\n};"
	byId('result').value = curStr;
}

function computeOutput2()
{
	var curByte=0, tbl, curRow, curCell, nRows, nCells;
	var curStr = "";
	
	tbl = byId('char');
	nRows = tbl.rows.length;
	for (curRow=0; curRow<nRows; curRow++)
	{
		curByte = 0;
		nCells = tbl.rows[curRow].cells.length;
		for (curCell = 0; curCell<nCells; curCell++)
		{
			curByte <<= 1;
			if (tbl.rows[curRow].cells[curCell].className.indexOf('active') != -1)
				curStr += "x";
			else
				curStr += ".";
		}
		curStr += "\n";
	}
	byId('result').value = curStr;
}

function clearCells()
{
	var cells = document.getElementsByTagName('td');
	var i, n=cells.length;
	for (i=0;i<n;i++)
		cells[i].className = cells[i].className.replace(" active", "");
}
function fillCells()
{
	var cells = document.getElementsByTagName('td');
	var i, n=cells.length;
	for (i=0;i<n;i++)
		cells[i].className = " active";
}

function toggleCells()
{
	var cells = document.getElementsByTagName('td');
	var i, n=cells.length;
	for (i=0;i<n;i++)
		toggleClass(cells[i], 'active');
}
</script>
<style>
#lcdCharArea
{
	background: #3719ec;
	display: inline-block;
	padding: 1em;
}

#char td
{
	height: 2em;
	width: 2em;
	background: #1c0d79;
}
#char td.active
{
	background: #e3e1ee;
}
#ouputArea
{
	border: solid 1px black;
	display: inline-block;
}
</style>
</head>
<body>
<div id='lcdCharArea'>
	<table id='char'>
		<tbody>
			<tr><td></td><td></td><td></td><td></td><td></td></tr>
			<tr><td></td><td></td><td></td><td></td><td></td></tr>
			<tr><td></td><td></td><td></td><td></td><td></td></tr>
			<tr><td></td><td></td><td></td><td></td><td></td></tr>
			<tr><td></td><td></td><td></td><td></td><td></td></tr>
			<tr><td></td><td></td><td></td><td></td><td></td></tr>
			<tr><td></td><td></td><td></td><td></td><td></td></tr>
			<tr><td></td><td></td><td></td><td></td><td></td></tr>
		</tbody>
	</table>
	<hr>
	<div style='display: inline-block'>
		<input type='button' value='clear' onclick='clearCells();'/>
		<input type='button' value='fill' onclick='fillCells();'/>
		<input type='button' value='toggle' onclick='toggleCells();'/>
	</div>
</div>
<div style='display:inline-block;'>
	<input type='button' value='compute Hex code' onclick='computeOutput();'/>
	

	<input type='button' value='compute text img' onclick='computeOutput2();'/>
</div>
<div id = 'ouputArea'><textarea id='result' rows='18' cols='80'></textarea></div>
</body>
</html>

Non-portability is only a draw back if you have to develop on more than one OS platform. Never seen someone in that predicament, and expect it's one I will never be in myself.

aarondc:
Non-portability is only a draw back if you have to develop on more than one OS platform. Never seen someone in that predicament.

Bzzz. Not quite. What if you only develop on a single one - i.e linux.... What's your email address? I'll send you my photo.. :stuck_out_tongue:

If you don't feel the love for the Arduino IDE like I don't, you may consider and prefer Code::Blocks Arduino Edition. It blows the socks off the official IDE and anything else I've seen to date, to be honest. Eclipse is like using King Kong to catch a mosquito - big, slow and total overkill for such a project. Never mind the fact that C::B is written in C++ - a claim that neither Arduino or Eclipse can make (both Java piggies)

Bzzt. Wrong.

I wrote this app for myself. And offered it, for free, to anyone who wants it.

Non-portability is not a drawback. At all. I couldn't care less if it doesn't work for you or anyone else, I didn't write it for you or anyone else. I wrote it for me.

Ah haha hah hah hah hah.

Arduino kicks ass because it's portable. Inkscape, Gimp, LibreOffice, Steam, MS Office, Blender are but a few other portable apps.
If Arduino was only for linux or macos or windows it would have a much smaller following than it does.

Now get back in your box and stop acting like a petulant child. You made a program and offered it with the hope it would be useful to others. It is and people are happy to have it. I merely pointed out what I perceived as a potential draw-back. Go back and read the words.

You've become snooty and started contradicting yourself. Mate, it's your bat and ball. Why don't ya take em both and go home! And to think, you call yourself a fellow Aussie. Grow up!

We'll see what IDA Pro & DeDe has to say about source...

Great app :slight_smile: Working on OS X via Wine. However, is it possible to see the custom character in the lines below?

Doesn't seem likely to be possible. (The application makes use of Raize Components - a $399 add-on with a bunch of custom controls.)
Getting sick of clicking each cell individually yet? XD

If you have a close look at the text-preview window, you can see that there are only 7 vertical pixels. A 1602 of course uses character matrices that are 5x8. They also have a 1 cell gap between each row and between each letter within a row.

It seems that the help for the components are only available if you buy/try them. Only thing is, I haven't programmed in Pascal since the late 90s - but more importantly, it's a 70MB download that wont work with my (ancient) copy of TPW 1.5 - I'm not downloading a 70mb trial just in the hope I'll get the docs.

I've spent a few hours at night over the past week making a couple of native solutions. Both in win32 c (windows or wine only) and wxWidgets c++ (linux, mac, win). If it gives me enough of a kick, I'll crank out a version using MASM too.

Which brings me back to the whole reason I used html5 + javascript in the first place. It's immediately portable - requiring only a html5-capable browser. It's perfectly fine to distribute a single file that constitutes both the application and the source-code. It also means I don't have to go near the horror-show that is Java in order to run it on an Android phone.

The funny thing is, the html version may well end-up being the smallest. Ha! It's 4.7kb, with a dependancy of the browser. The ASM version will be next, likely weighing in at under 10kb without compression - with zero dependancies. Following that is the win32 C version, that is currently running at about 22kb with 1 or 2 small (sub 100kb) deps. Coming in lucky last are the wxWidgets versions - about 60kb on the Raspberry Pi, 70kb on Linux Mint x64 (dependencies installed in each by default, I think) and a whopping 1.88MB using the static-build of wx under windows. I really should get around to building a dll version of that library..

I'd vaguely considered adding the ability to define an entire font, which would come in far more useful when using a 128x160 lcd.
But currently, learning my way around wxWidgets enough to handle text-input operations in the output preview window. I'm vaguely considering making the lcd control itself editable - i.e you can click a cell to position a cursor there - editing with the keyboard in situ, rather than by a seperate edit window. But then again, I've also considered making the lcdPanel have the same member functions that the LiquidCrystal class does for positioning, custom char definition and text output. That would make a simple 'call' to lcd.print(0) --> lcd.print(7) show any of the custom chars.
Hmm. Actually, as I write this, I may have an idea.

This project is a perfect example of the 80/20 rule in play. You get 80% of the benefit for 20% of the effort. The html one isn't so nice looking, but like I said earlier - I smashed it together during the course of a lunch hour.

I've said it before offline and I'll say it again - the idea to include a preview window was really clever, and one that really dresses up the application.
I wouldv'e left my project gathering dust had it not been for the idea of a preview screen.

Anyway, I'm rambling. I only answer (instead of Aaron) since it looks like he may not be particularly keen to revisit this thread. He or someone else certainly deleted his last post, which was quite an er... ah, 'entertaining' read. :zipper_mouth_face:

Dessimat0r:
Great app :slight_smile: Working on OS X via Wine. However, is it possible to see the custom character in the lines below?

Thanks. I wanted to display the custom characters in the lines below, but access to individual pixels is not provided, so it is not possible.

I have been working on lots of other things since. Given LCD screens are roughly the same price as a HC06 BT module and 99% of Android phones have BT built in, I'm unlikely to ever need LCD screens or LCD custom characters again.