PDA

View Full Version : hush pc vfd display serial plugin



mhwlng
April 7th, 2007, 01:48 PM
I just got a brand new hush pc that has a built-in 140x32 pixel vfd display

I made a serial plugin for the vfd display (the hush supplied software only works with MCE, which I don't use)

note that I haven't got any protocol documentation. I figured out part of it, by looking at the serial data from the existing application, so there might be more functionality available !

The display is quite slow and has no handshaking. A 4ms(!) delay between bytes is needed.
So it takes 3 seconds to fill the screen with graphical data (IMG6 below). But displaying text using the built-in fonts is quick enough (IMG2 below)...

the code looks like :



HushLCD:InitLCD();
local now = os.date("*t",os.time());
HushLCD: DrawRectangle(19,1,120,20,HushLCD.FillStyle.outlin e)
HushLCD: DrawText(23,18,HushLCD.FontSize.large,string.forma t("%02d:%02d:%02d",now.hour,now.min,now.sec))
HushLCD: DrawRectangle(0,23,139,31,HushLCD.FillStyle.black)
HushLCD: DrawText(20,29,HushLCD.FontSize.small,os.date( "%d %B %Y" ))


or



HushLCD:InitLCD();
local im = gd.createTrueColor(144,32)
local white = im:colorAllocate(255,255,255)
local black = im:colorAllocate(0,0,0)
im:filledRectangle(0, 0, 144, 32, black)
im:rectangle(0, 0, 139, 31, white)
im:stringFT(white, win.GetDirectory ("WINDOWS").."\\fonts\\arial.ttf (file://fonts//arial.ttf)", 18, 0, 2,25, "hello Girder")
local data = im:wbmpStr(black);
HushLCD: DrawGraphic(0,0,139,31,string.sub(data,6))



If anyone wants the serial plugin, let me know and I'll publish it..

Marcel

Ron
April 8th, 2007, 12:28 PM
Awesome stuff!

mhwlng
April 8th, 2007, 02:16 PM
Ron, while I've got your attention ;) , I've got a strange problem getting this to work reliably:

The serial plugin is quite simple, no handshaking, no receive, 4 ms sleeps between serial sends

so something like :



local device = serial.Classes.Base:New({
Name = "HushLCD Display",
Description = "HushLCD Display",
BaudRate = 115200,
Parity = 0,
StopBits = 0,
DataBits = 8,
FlowControl = 'N',
GlobalName = 'HushLCD',
LogLevel = false,
...
...
DrawText = function (self,x,y,fontsize,text)
self.Serial:Write(math.hextobyte("0FF2")..string.char(fontsize))
win.Sleep(4);
self.Serial:Write(math.hextobyte("0FF232"))
win.Sleep(4);
self.Serial:Write(math.hextobyte("0FF0")..string.char(x)..string.char(y))
win.Sleep(4);
for i=1,string.len(text) do
self.Serial:Write(string.char(string.byte(text,i)) )
win.Sleep(4);
end
end,
....
....
Initialize = function (self)
....
return true;
end,
}
)
serial.AddDevice (device)


Then, I start a scripting action with the F5 button that updates the screen every 1 second :



local function clock()
local now = os.date("*t",os.time());
...
HushLCD: DrawText(23,18,HushLCD.FontSize.large,string.forma t("%02d:%02d:%02d",now.hour,now.min,now.sec))
...
end
local AutoUpdateTimer = gir.CreateTimer (nil,
function (...) return clock () end,nil,1,true)
AutoUpdateTimer:Arm (1000)


After about 20-30 min., the timer simply stops, no errors, no crash...
girder doesn't hang when I stop it.

It doesn't matter if the CreateTimer childstate parameter is true or false
and it doesn't matter if I use the base or queued serial classes...

This is the only code running in girder 5, on a fast dual core machine (XP Pro).

any ideas ?

Marcel

Ron
April 8th, 2007, 02:41 PM
That is very odd. I'll have to prepare a debug version of the timer for you.

mhwlng
April 22nd, 2007, 10:29 AM
I've got the same problem in G5 build 517

Marcel

Ron
April 22nd, 2007, 01:18 PM
I'll see what I can do this week.

mhwlng
April 22nd, 2007, 01:57 PM
I'll see what I can do this week.


the serial plugin is configured not to use handshaking and only data is sent to the serial port, not received.

so it shouldn't matter if the device is actually connected...

I pointed the plugin at COM1 (that has nothing connected) and now the timer doesn't stop.

so could it be a handshaking issue ? (even though it's disabled)

note that the display is a USB device (virtual com port), so I can't make up a serial cable with just the tx and gnd connected !

attached the plugin and a test gml file...

I did notice that the G5 serial library only supports rts/cts handshaking
and not DTR/DSR handshaking. could this be the problem ?

Marcel

Promixis
April 22nd, 2007, 02:48 PM
you could use the gir.OutputDebugString to monitor if the timer is in fact dieing or not.

mhwlng
April 22nd, 2007, 02:56 PM
I pointed the plugin at COM1 (that has nothing connected) and now the timer doesn't stop.


ok, that was wrong...
it just stopped after 40 minutes, so you should be able to test this yourself as well, without a display..



you could use the gir.OutputDebugString to monitor if the timer is in fact dieing or not.


I used print statements at the beginning and end



local function clock()
local now = os.date("*t",os.time());
print (now.sec);
print ("in")
HushLCD:DrawText(23,18,HushLCD.FontSize.large,stri ng.format("%02d:%02d:%02d",now.hour,now.min,now.sec))
HushLCD:DrawText(20,29,HushLCD.FontSize.small,os.d ate( "%d %B %Y" ).." ")
print ("out")
end
local AutoUpdateTimer = gir.CreateTimer (nil,
function (...) return clock () end,nil,1,true)
AutoUpdateTimer:Arm (1000)




and the last thing I see on the console is :

44
in
out

so the function was exited and it didn't 'hang' in the DrawText call....

hoox
April 22nd, 2007, 04:32 PM
Marcel,

Did you try to assign the timer to a global variable instead of a local?

AutoUpdateTimer = gir.CreateTimer (nil,
function (...) return clock () end,nil,1,true)IIRC, it's also good practice to destroy timers on ScriptDisable, it should be easier like that.

Promixis
April 22nd, 2007, 07:23 PM
Ah, you are right! Its a local variable going out of scope and getting collected :D

Promixis
April 22nd, 2007, 07:25 PM
Ah, you are right! Its a local variable going out of scope and getting collected :D

To fix that, you can ref. the local in your anonymous function that you are passing to the timer.

hoox
April 23rd, 2007, 02:31 AM
Thanks for the tip Mike!

Marcel,
I'm not sure about ScriptDisable, but it's better to check that a timer does not already exist before creating it (see Examples/demo.GML).
Otherwise you could get funny results, and may not be able to stop all namesake timers.

mhwlng
April 23rd, 2007, 03:20 AM
Did you try to assign the timer to a global variable instead of a local?




Ah, you are right! Its a local variable going out of scope and getting collected


yep... that fixed it.

thanks guys.

Marcel

Promixis
April 23rd, 2007, 07:01 AM
yep... that fixed it.

thanks guys.

Marcel


timers do get collected in a script reset.

Promixis
April 23rd, 2007, 07:02 AM
Marcel, if you wrapped all this inside a component it would save you a lot of work

mhwlng
April 23rd, 2007, 07:05 AM
Marcel, if you wrapped all this inside a component it would save you a lot of work

as soon as you provide some documentation on that, I will....
(and I don't mean : use the source code for another component as an example)

;)

Marcel