So, I revisited reading distance measurements with an IR LED and a phototransistor. It became immediately evident that I had not taken the time to fully understand what I was working with. This write-up is an attempt to more clearly analyze and explain the hardware and circuit wiring.
Experiment & Results:
Here in the United States, we have an electronics shop called Radio Shack. They sell a pair of components: an IR LED and a phototransistor. The LED has a forward voltage of 1.3-1.7V. I used the lowest value for safety. The forward current is 150mA. So, at 5V, the LED only needs a 16 Ohm resistor. At 3.3, it needs less than 5 Ohms. The lowest value I had on hand was 33 Ohms, so that is what I used for these experiments. The phototransistor is what I really messed up on. The schematic on the package clearly indicates that the transistor is an NPN by the arrow on the emitter pointing out. This is consistent with web searches I've done. They indicate that all phototransistors since the 1960's are NPN. The pin diagram shows that the collector is on the flat side of the LED casing. Here's the problem, wired up with the collector (flat side) to positive just doesn't work!
If I put the resistor to ground and the analog sense pin on what I thought was the emitter (non-flat side), the reading didn't change. If I put the resistor to Vcc and the sense pin on what I thought was the collector (flat side), I got inconsistent readings. If I treat the flat-side as the emitter, things change drastically.
With the flat side ( now calling it the emitter ) hooked to ground and the non-flat side ( now calling the collector ) hooked through a 47k resistor to Vcc, the sense pin on the collector behaved consistently. The values were large ( 800 - 990 ) and got smaller as the distance to the object decreased. With the resistor and sense pin moved to the flat side ( emitter ), the values were also consistent. They were low (20-200) and increased as the object grew closer.
The values were measured with a 10 bit A/D pin on a Pic16F88. Everything was kept the same other than the variations of the positive and negative connections, the resistor, and the location of the sensor pin wire on the phototransistor.
Analysis:
So, from all of this, either the Radio Shack phototransistor is a PNP transistor, or the pin diagram mis-labels the collector and emitter. That, or I totally screwed up how things should be wired. Electronics forums on the web since certain that all phototransistors since the mid-60s have been NPN. I don't think Radio Shacks transistors are that old, so I discard the possibility that they are PNP. I based my wiring off of the line sensor from Pololu. Those guys graduated from MIT. I believe they know what they are doing. That leaves the fact that Radio Shack labelled the pins incorrectly on the package.
Conclusion:
Go with what works. In this case, treat the flat side of the phototransistor as the emitter of an NPN phototransistor. For my purposes, putting the resistor and sensor pin on the emitter works best. The values jump quite a bit when the object detected is withing 6 cm. This makes it easy to set an "danger perimeter alarm" for distance sensing robots.
Update:
I tested this with another phototransistor. This one is a standard QRD1114, typically used for line sensing. It has a very short range. Pin one is the collector and pin two the emitter. With the collector hooked to Vcc via the 47k resistor and the emitter to ground, the sensor pin on the collector side read values that increased as the distance grew against white paper. Against a black line at any distance, they read their maximum value of 50. This, and all the above experiments, were done at 5V. The values and the range were vastly smaller, from 15-50. It seems to confirm what I theorized above. Results were consistent with all four arrangements above. Treated as a PNP, the values were inconsistent or unchanging.
Search This Blog
Sunday, January 20, 2013
Monday, December 31, 2012
THE Framework - Iterative Elements FAIL
Iterative elements are not going well. Here are notes on this:
31 Dec., 2012
------------------
Worked on the iterative problem. I tried creating a custom foreach Directive for Velocity. First, the Parser will not accept an underscore in the directive name. I had wanted to use the_foreach, but that's no good. Second, the Parser will only allow the argument syntax ( $item in $list ) in the foreach Directive. It's a hard coded literal in the Parser.
So, I tried creating a subclass and/or a wrapper for the foreach Directive. The name can't be anything but foreach. The next effort was a subclass that copied the foreach Directive code entirely and modifying from there. This required creating a ForeachScope wrapper class as well to allow access to the private members of the scope class. The class uses the foreach name and is found before the Foreach class by the Parser. This is fragile. It does allow additional arguments to be passed in. It accepts an optional boolean argument to indicate whether to perform the nesting constructions. All of this could break with changes to Velocity.
The idea was to have a variable called currentLabel and a stack of currentLabels in the Velocimacro library. On the call of a nested foreach, the currentLabel would be pushed on the scope stack. The currentLabel would have the value of the list argument appended to it. As the loop ended, the currentLabel would be replaced by popping the top value off the stack. This allows nested scoping.
Inside the body of the foreach loop, tags that needed to use the currentLabel would call a VelociMacro called nestedBindTo. This would prepend the currentLabel to the property name and place it in the bindTo attribute.
Here's the problem I'm trying to solve. The controller's model has a List of something, say of Object Group. Each Group wants to be a Panel or Accordion or table row. Each Group has a List of Items. These want to be in a table or ordered/unorder list. They want to be able to subscribTo or reRenderOn events, so they need to be bound back to the controller's Model by the JavaScript engine. The end rendered result would look like this:
<ul id="groups" subscribeTo="save" bindTo="groups">
<ul subscribeTo="save" bindTo="groups.0">
<li><input type="text" subscribeTo="save" bindTo="groups.0.item.0" value="Exciting Item One"></li>
<li><input type="text" subscribeTo="save" bindTo="groups.0.item.1" value="Boring Item Two"></li>
</ul>
<ul subscribeTo="save" bindTo="groups.1">
<li><input type="text" subscribeTo="save" bindTo="groups.1.item.0" value="Group 2 Item One"></li>
<li><input type="text" subscribeTo="save" bindTo="groups.1.item.1" value="Group 2 Item Two"></li>
</ul>
</ul>
I could finish my class hack on the foreach Directive, but this is a terrible hack and very fragile. Another option would be to dump the responsibility for nesting on Devlopers. This puts a load of tedious mapping on the Developer and is error prone. I would still provide the currentLabel, scope stack, and nestedBindTo VelociMacro as well as push and popAndSetCurrentLabel methods for the stack. Coding would have to look like this:
#set( $currentLabel = 'groups' )
<ul id="groups" subscribeTo="save" data="#bindTo( 'groups' )">
#foreach( $group in $page.groups )
#push( $currentLabel )
#set( $currentLabel = $currentLabel'.'$foreach.index )
<ul subscribeTo="save" data="#nestedBindTo( $currentLabel )">
#foreach( $item in $group )
#push( $currentLabel )
#set( $currentLabel = $currentLabel'.'$foreach.index )
<li><input type="text" subscribeTo="save" value="#nestedBindTo( $currentLabel )"></li>
#popAndSetCurrentLabel()
#end
#popAndSetCurrentLabel()
#end
This points out a number of flaws in the design. It does not handle non-form elements having a binding where the value gets displayed. As an example, what if the list items above want to have their values displayed as simple text?
<li data="#nestedBindTo( $currentLabel )"> --- How to get and show the value here? How will it be reRendered? --</li>
This wants a completely different solution.
31 Dec., 2012
------------------
Worked on the iterative problem. I tried creating a custom foreach Directive for Velocity. First, the Parser will not accept an underscore in the directive name. I had wanted to use the_foreach, but that's no good. Second, the Parser will only allow the argument syntax ( $item in $list ) in the foreach Directive. It's a hard coded literal in the Parser.
So, I tried creating a subclass and/or a wrapper for the foreach Directive. The name can't be anything but foreach. The next effort was a subclass that copied the foreach Directive code entirely and modifying from there. This required creating a ForeachScope wrapper class as well to allow access to the private members of the scope class. The class uses the foreach name and is found before the Foreach class by the Parser. This is fragile. It does allow additional arguments to be passed in. It accepts an optional boolean argument to indicate whether to perform the nesting constructions. All of this could break with changes to Velocity.
The idea was to have a variable called currentLabel and a stack of currentLabels in the Velocimacro library. On the call of a nested foreach, the currentLabel would be pushed on the scope stack. The currentLabel would have the value of the list argument appended to it. As the loop ended, the currentLabel would be replaced by popping the top value off the stack. This allows nested scoping.
Inside the body of the foreach loop, tags that needed to use the currentLabel would call a VelociMacro called nestedBindTo. This would prepend the currentLabel to the property name and place it in the bindTo attribute.
Here's the problem I'm trying to solve. The controller's model has a List of something, say of Object Group. Each Group wants to be a Panel or Accordion or table row. Each Group has a List of Items. These want to be in a table or ordered/unorder list. They want to be able to subscribTo or reRenderOn events, so they need to be bound back to the controller's Model by the JavaScript engine. The end rendered result would look like this:
<ul id="groups" subscribeTo="save" bindTo="groups">
<ul subscribeTo="save" bindTo="groups.0">
<li><input type="text" subscribeTo="save" bindTo="groups.0.item.0" value="Exciting Item One"></li>
<li><input type="text" subscribeTo="save" bindTo="groups.0.item.1" value="Boring Item Two"></li>
</ul>
<ul subscribeTo="save" bindTo="groups.1">
<li><input type="text" subscribeTo="save" bindTo="groups.1.item.0" value="Group 2 Item One"></li>
<li><input type="text" subscribeTo="save" bindTo="groups.1.item.1" value="Group 2 Item Two"></li>
</ul>
</ul>
I could finish my class hack on the foreach Directive, but this is a terrible hack and very fragile. Another option would be to dump the responsibility for nesting on Devlopers. This puts a load of tedious mapping on the Developer and is error prone. I would still provide the currentLabel, scope stack, and nestedBindTo VelociMacro as well as push and popAndSetCurrentLabel methods for the stack. Coding would have to look like this:
#set( $currentLabel = 'groups' )
<ul id="groups" subscribeTo="save" data="#bindTo( 'groups' )">
#foreach( $group in $page.groups )
#push( $currentLabel )
#set( $currentLabel = $currentLabel'.'$foreach.index )
<ul subscribeTo="save" data="#nestedBindTo( $currentLabel )">
#foreach( $item in $group )
#push( $currentLabel )
#set( $currentLabel = $currentLabel'.'$foreach.index )
<li><input type="text" subscribeTo="save" value="#nestedBindTo( $currentLabel )"></li>
#popAndSetCurrentLabel()
#end
#popAndSetCurrentLabel()
#end
This points out a number of flaws in the design. It does not handle non-form elements having a binding where the value gets displayed. As an example, what if the list items above want to have their values displayed as simple text?
<li data="#nestedBindTo( $currentLabel )"> --- How to get and show the value here? How will it be reRendered? --</li>
This wants a completely different solution.
Sunday, December 30, 2012
Something Different - THE Framework
So I find myself with a little time off here at the end of the year. I'd been wanting to try out a few of the many Java web frameworks out there. I'm always looking for "the one". You know, the one that does everything you want effortlessly with no configuration and no glitches. The one that will handle all those outside cases that other frameworks make you really hack the heck out of them to get it work. Yeah, that impossible framework. I checked out the latest Tapestry, tried Wicket, looked at Grails. They all frustrated me fairly quickly. I was looking for immediate solutions to problems I've faced with JSF, facelets, RichFaces, IceFaces, ADF, and Struts. With lots of free time, I started thinking about what that ideal framework would look like.
I started with the usual principles: simplicity and flexibility. I assume that the developer using the framework is like me: intelligent and intelligently lazy. This developer doesn't want to have his hand held or be tied down into one style of solution. This developer also doesn't want to have to think to much about the framework or its configuration. He wants it to allow rapid prototyping that can be quickly adopted as working code.
Oh yeah, and AJAX, lots of AJAX. I mean, really tight AJAX requests and responses. Each submit should send exactly and ONLY what it needs to send. The responses should have just the stuff needed, too. Any tag should be able to register itself as a listener for either or both the send and response to any event.
The events should be able to register themselves, including their name, and what phases they want to use. The phases would be: gather submit data, send a request, and reRender. The event could even skip the AJAX send if it wants to and just be a gather data and reRender. This would be useful especially in development.
The listeners would register themselves just by adding attributes to their tags. To register to be sent to the server, it would add a subscribeTo attribute with the names of the events it wants to be a part of ( of which it wants to be a part, for the grammar nazis ). To register for the reRendering, it would add a reRenderOn attribute with the names of the events of which it wants to be a part.
Now, here's the cool part. In the value attribute for form fields, or the data attribute of ANY tag, it would simply put something like 'value="page.person.address.lineOne"'. If the page defined a model Object for person.address.lineOne with a value like '227 Main St.', the engine would alter that on the server side to be 'value="227 Main St." bindTo="person.address.lineOne"'. This would help the client side JavaScript engine to take the value or data attribute's value and map it to a JavaScript Object graph of person.address.lineOne. The AJAX request would send this as a JSON string to the server. The server would automagically transform this to the page's Object graph.
Once it had processed the request, the server would send an (optional) JSON response. The client side JavaScript engine would receive this and map the response back to the tags that had registered for reRendering.
A templating engine would allow page composition and fragment reuse. Requests for a new page (navigation) would use a POST/Redirect/GET(POST) paradigm.
Above all, the framework would allow maximum flexibility. Provide a means to register and de-register listeners on the fly. It would intercept true submits and turn them into AJAX requests with all values from all bound tags with subscribeTos, but this would be a convenience. Developers would have to include a few key things in their controllers to make things work. A PageMaker would handle the necessary alterations to the templates to add the bindTo attribute.
One sticky part was the amount of raw configuration that would be required. A Maven archetype could set up most of the necessary boilerplate, saving the developer a lot of time. The rest is down to documentation.
Could this really work? I decided to play around. The results aren't fantastic yet, and they have already led to a number of less than ideal solutions. On the whole, it looks pretty cool, and it has been a lot of fun to do. Here's what I came up with.
My name is Thomas Edward Hunt. My monogram, like the kind you get from your aunt on a set of hankies or an ugly sweater, is THE. I decided to create THE framework. It's really more of a stack with some glue code. For the client side, I went with jQuery and jQuery-UI. It has all the selector and AJAX functionality I was looking for, along with all the cool UI stuff. For the templating engine, Velocity seems to have everything required. It allows page composition. It can do the necessary attribute instrumentation ( I think ). I still have a nagging problem with iterative elements. See my notes below for more. For the servlet piece, Jersey has proven very flexible. With JaxB, it can take JSON as an argument and render JSON from an Object graph with little or no effort. Just a little effort gets you the POST/Redirect/Get paradigm. Spring adds the necessary glue for almost everything. Spring Acegi will do the security. Add in the ORM of your choice. I haven't even begun to look at validation or submission value scrubbing/security. One thing at a time.
Here are my working notes to date. These are REALLY rough, but I like to capture my evolving thoughts.
*********************************************************************************
NOTES:
*********************************************************************************
18, Dec., 2012
---------------
Premise:
Build a web application in Jersey and jQuery. The majority of requests will be Ajax calls that will return a JSON object. The HTML will be mostly plain markup. A special attribute on tags will mark what events it will subscribe as a listener for refresh. Whole swaths of HTML may be rewritten in this way while still allowing prototype placeholder text to be put in the HTML. Gotta figure out how to do this.
Jersey will allow composition of HTML by recursively scanning the page templates for composed sub-pages.
On Ajax response, jQuery should allow to find all elements whose subscribe attribute is set to the event at hand.
This wants to be converted to a JSON object. Ajax wants to send a POST of the JSON to Jersey. Jersey will convert that to an expected POJO and process.
Server side tasks:
1. Receive request for page. Get master template. Recurse sub templates and compose page. Parse EL and fill with markup. Blech! (Antlr?)
2. Receive JSON with a request as a POST. Convert JSON and process request. Return JSON or FORWARD to new Resource.
Client Side tasks:
1. build Subscription lists. Probably 2 lists: one for "I'm a part of submits for" and one for "I'm a part of reRenders".
2. Build Ajax framework to get all sendSubscribed elements from an Ajax submit and build JSON object. Submit Ajax request as a POST.
3. Ajax framework to receive all responses. Parse JSON response. Need a way to know where each element of JSON goes in the DOM without encumbering the server with knowing about the page's needs.
4. Intercept full page submits and still perform the mappings needed.
5. Need a way for each page to intercept all requests and responses for pre- and post- processing. Ya just need it.
#####################################################################
FORWARDS IN JERSEY
#####################################################################
Step 1. Get access to HttpServletResponse. To do it declare in your service something like:
@Context
HttpServletResponse _currentResponse;
Step 2. make redirect
...
_currentResponse.sendRedirect(redirect2Url);
EDIT
Well, to call forward method you need get to ServletContext. It is can be resolved the same way as response:
@javax.ws.rs.core.Context
ServletContext _context;
Now _context.forward is available
20 Dec., 2012
------------------
Okay, Here is the stack idea: javascript: jQuery and Bootstrap.js; View: Velocity; Servlet Engine: Jersey ( need to marry with VelocityViewServlet in some way. Custom: event registration for send and reRender, using jQuery. This will need the rewrite in velocity to add attributes of subscribe and reRender as well a tag
that will indicate to what part of the model a tag belongs ( eg, person.address.firstLine ). In other words,
it will need to extend the basic Velocity engine to include adding in the modelRef attribute to point to the
model path ( eg, person.address.firstLine ).
Engine: Jersey: will take in a JSON and put out a JSON ( figure out how to accept and auto-translate JSON
to Java ). Figure out page transitions with Post-Redirect-Get. Figure out how to return Velocity templates.
Wire to Spring, Acegi, Hibernate, etc. and make an archetype. Figure out a Submit intercept to follow regular AJAX course.
Velocity looks like it is extensible. It definitely supports includes, so that' good.
Need to figure out the VelocityViewServlet and Jersey integration. It wants this to be seamless yet extensible. Not sure how to do this. Also, needs a security measure to ensure against cross-site scripting, SQL injection, etc.
26 Dec., 2012
------------------
First, Jersey will take a JSON as input and parse it to the Models it knows.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
GENERAL APPROACH GUIDELINE
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This wants ANY tag to be a part of the conversation with the server. To do this, the general approach will be that the value bound will be the the value attribute if the element involved is an form element such as an input, a select, or a textarea. If the element is not one of these, it should look to a data attribute for the
value.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Now, the tags want two attributes: subscribeTo and reRenderOn. These will have a comma separated list of events in them.
On render of the page, the event handler will somehow magically insert an additional attribute for any element that has one or both of these tags. This extra attribute is the bindTo. It will have the path to the model field such as person.address.lineOne.
This will need to be modified to accomodate iterative things like lists, table rows, dropdown menus, etc. They may look like category.0, category.1, etc.
In the jQuery onload process, there wants to be a method to register all listeners. The idea is to get a list of all elements that have a bindTo attribute. Simple to do with a selector: $('[bindTo]').
Each Ajax event wants to have an event name. This could either be an attribute on the calling element ( button, link, etc ) or a string passed in as a parameter. The latter seems to offer more flexibility. Each event
will have several phases. There should be a means to indicate which phases the event requires. The phases will be
1. Gather data from registered elements with a subscribeTo that contains the event and form an Object from it.
2. Transmit an Ajax request ( possibly with a JSON Object from step 1 ) to the server.
3. Handle reRendering, based on registered elements with the event in their reRenderOn attribute.
Really, it would be cool and very flexible if the event could specify any combination of these three phases. Additionally, the event should be able to pass in an arbitrary Object to use in place of the model. This can be added later.
The call first wants to get a list of all registered elements that have the event name in their subscribeTo attribute. It wants to retrieve the value of each element. The value will be the value attribute if the element is a form element. Otherwise, the value will be in the data attribute. The function will use the element's bindTo in order to add the value to the JSON object that will be passed to the server.
Once the JSON Object has been formed and stringified, a jQuery.post() is made. The callback will handle the response and reRender.
The callback wants to get a list of all registered elements that have the event name in their reRenderOn attribute. It wants to retrieve the value from the JSON Object in the Ajax.data, being mindful of iterative indexes in the bindTo value. It wants to set the new value in the element. It needs to figure out how to make sure that the visible page changes when this value is changed.
Notably, dropdown lists have been problematic.
Runtime gives EventCartridge gives Iterator over ReferenceInsertionEventHandlers gives events I want to mess with ( I think ).
27 Dec., 2012
------------------
Decided to not use Bootstrap.js. It is just not usable at this point. Documentation is lacking and it doesn't
work with IE 7-8. Reality is, a good number of users still use these sub-standard browsers.
Decided to go with jQuery UI.
Odd issue with Accordion under a tab nav. Height of accoridions is zero. Google, please...
StackOverflow tells us: you must initialize the accordion before the tabs!!! Gack! How crude, but it works...
Best practice with jQuery MAY BE ( don't know ) to load all inner widgets before the outer ones.
Got the initial project set up with Spring, Jersey, Velocity, MyBatis. Very primitive but working. Next, need
to add velocity template composition, get sources, and figure out event handling...
29 Dec., 2012
-----------------
Okay, Got jQuery, jQuery-UI, Jersey, Velocity, and Spring set up. Need to bind Velocity into Spring eventually.
Wrote the PageMaker class to handle rendering page templates for all Pages. They just need to extend PageMaker.
May want to change this, so it doesn't consume a Page's only super class... Maybe an injected utility?
It really doesn't want to be a static class.
Dropped the EventHandler solution. The event didn't have enough context. Velocity's parser is an actual language parser from JavaCC. It lexes a stream into tokens, parses the token stream into an AST, and then walks the AST to generate the page from the template and values.
Instead, THE provides a Velocimacro in the library. This macro is available to all templates. Developers will need to use the macro on anything they want mapped to the server's model. For form fields, this will be the value attribute. Any other tag can be bound with the data attribute. For a form field that wants to bind to, for example, HomePage's person.address.lineOne, the developer would put this in the vm file:
<input id="lineOne" type="text" value="#bindTo( 'page.person.address.lineOne' )" />
Note, that the value passed in is a string literal. It has NO Velocity
variable indicator. The macro will turn this into a variable reference and also
use the value for its bindTo value. Likewise, you only need to ever specify
'page' for the page and not the page's actual name. This is handled by the
PageMaker class. The macro actually strips out the "page." part of the string.
That's why PageMaker provides the universal "page" root.
The rendered result would be:
<input id="lineOne" type="text" value="227 Foo St." bindto="person.address.lineOne"/>
30 Dec., 2012
------------------
Moved PageMaker to be an injected class ala Spring. Developers will have to inject this into their pages or just new it up as needed. It has no dependencies as yet, so either way will work. The framework archetype injects it for now in case it adds dependencies later.
Next Steps:
1. Work on page navigation and loading. Looks like Post/Redirect/Get might be the right strategy here.
The client side probably wants to intercept full submits, grab everything registered for any subscribeTo event and push it's current value into the javascript Object that will then be turned into JSON. The default submit will be suppressed, and an AJAX POST will be made instead. The server will receive and process as needed, then send a redirect. This **SHOULD** result in a second GET request for the new page.
The redirect will need to have any needed attributes loaded into the query string.
For later consideration: Should this be a Post/Redirect/POST? Developers could put sensitive stuff in the request...
2. Client Side: Lots of good javascript to write here. Baby steps here.
A. get the registration of event listeners done. This is a list of any elements with a bindTo attribute set with either a subscribeTo or reRenderOn attribute.
NOTE: THE VELOCIMACRO SOLUTION PRESENTS A SERIOUS PROBLEM FOR ITERATIVE ELEMENTS! Sorry to shout, but this needs attention. A separate macro will hopefully solve for this. The whole solution is looking a little shaky.
The development experience is getting a little too involved in the engine. This really wants to be abstracted from the developer.
B. Figure out event registration, including phases required and callbacks. Populate the Object for transmission.
C. Handle the reRender callback.
D. Add methods for registering and un-registering listeners on the fly.
*********************************************************************************
*********************************************************************************
A good portion of the JavaScript in the last TODOs has already been worked out in a proof of concept. I'm now working on getting it to a more robust and true solution. The biggest sticking point is the iterative components. I'm not quite sure whether to figure that out first or just move on the JavaScript solution.
I'd appreciate any feedback. Again, this was just a thought experiment that turned into a bit of code as an exercise. As long as it keeps feeling worth it, I'll keep pursuing it. If someone has already solved a part of this well, let me know. I'd be glad to save a few hours on something that's already solved. I'm already leveraging a huge stack of code to solve well defined problems.
Thanks for reading!
Tom
So I find myself with a little time off here at the end of the year. I'd been wanting to try out a few of the many Java web frameworks out there. I'm always looking for "the one". You know, the one that does everything you want effortlessly with no configuration and no glitches. The one that will handle all those outside cases that other frameworks make you really hack the heck out of them to get it work. Yeah, that impossible framework. I checked out the latest Tapestry, tried Wicket, looked at Grails. They all frustrated me fairly quickly. I was looking for immediate solutions to problems I've faced with JSF, facelets, RichFaces, IceFaces, ADF, and Struts. With lots of free time, I started thinking about what that ideal framework would look like.
I started with the usual principles: simplicity and flexibility. I assume that the developer using the framework is like me: intelligent and intelligently lazy. This developer doesn't want to have his hand held or be tied down into one style of solution. This developer also doesn't want to have to think to much about the framework or its configuration. He wants it to allow rapid prototyping that can be quickly adopted as working code.
Oh yeah, and AJAX, lots of AJAX. I mean, really tight AJAX requests and responses. Each submit should send exactly and ONLY what it needs to send. The responses should have just the stuff needed, too. Any tag should be able to register itself as a listener for either or both the send and response to any event.
The events should be able to register themselves, including their name, and what phases they want to use. The phases would be: gather submit data, send a request, and reRender. The event could even skip the AJAX send if it wants to and just be a gather data and reRender. This would be useful especially in development.
The listeners would register themselves just by adding attributes to their tags. To register to be sent to the server, it would add a subscribeTo attribute with the names of the events it wants to be a part of ( of which it wants to be a part, for the grammar nazis ). To register for the reRendering, it would add a reRenderOn attribute with the names of the events of which it wants to be a part.
Now, here's the cool part. In the value attribute for form fields, or the data attribute of ANY tag, it would simply put something like 'value="page.person.address.lineOne"'. If the page defined a model Object for person.address.lineOne with a value like '227 Main St.', the engine would alter that on the server side to be 'value="227 Main St." bindTo="person.address.lineOne"'. This would help the client side JavaScript engine to take the value or data attribute's value and map it to a JavaScript Object graph of person.address.lineOne. The AJAX request would send this as a JSON string to the server. The server would automagically transform this to the page's Object graph.
Once it had processed the request, the server would send an (optional) JSON response. The client side JavaScript engine would receive this and map the response back to the tags that had registered for reRendering.
A templating engine would allow page composition and fragment reuse. Requests for a new page (navigation) would use a POST/Redirect/GET(POST) paradigm.
Above all, the framework would allow maximum flexibility. Provide a means to register and de-register listeners on the fly. It would intercept true submits and turn them into AJAX requests with all values from all bound tags with subscribeTos, but this would be a convenience. Developers would have to include a few key things in their controllers to make things work. A PageMaker would handle the necessary alterations to the templates to add the bindTo attribute.
One sticky part was the amount of raw configuration that would be required. A Maven archetype could set up most of the necessary boilerplate, saving the developer a lot of time. The rest is down to documentation.
Could this really work? I decided to play around. The results aren't fantastic yet, and they have already led to a number of less than ideal solutions. On the whole, it looks pretty cool, and it has been a lot of fun to do. Here's what I came up with.
My name is Thomas Edward Hunt. My monogram, like the kind you get from your aunt on a set of hankies or an ugly sweater, is THE. I decided to create THE framework. It's really more of a stack with some glue code. For the client side, I went with jQuery and jQuery-UI. It has all the selector and AJAX functionality I was looking for, along with all the cool UI stuff. For the templating engine, Velocity seems to have everything required. It allows page composition. It can do the necessary attribute instrumentation ( I think ). I still have a nagging problem with iterative elements. See my notes below for more. For the servlet piece, Jersey has proven very flexible. With JaxB, it can take JSON as an argument and render JSON from an Object graph with little or no effort. Just a little effort gets you the POST/Redirect/Get paradigm. Spring adds the necessary glue for almost everything. Spring Acegi will do the security. Add in the ORM of your choice. I haven't even begun to look at validation or submission value scrubbing/security. One thing at a time.
Here are my working notes to date. These are REALLY rough, but I like to capture my evolving thoughts.
*********************************************************************************
NOTES:
*********************************************************************************
18, Dec., 2012
---------------
Premise:
Build a web application in Jersey and jQuery. The majority of requests will be Ajax calls that will return a JSON object. The HTML will be mostly plain markup. A special attribute on tags will mark what events it will subscribe as a listener for refresh. Whole swaths of HTML may be rewritten in this way while still allowing prototype placeholder text to be put in the HTML. Gotta figure out how to do this.
Jersey will allow composition of HTML by recursively scanning the page templates for composed sub-pages.
On Ajax response, jQuery should allow to find all elements whose subscribe attribute is set to the event at hand.
This wants to be converted to a JSON object. Ajax wants to send a POST of the JSON to Jersey. Jersey will convert that to an expected POJO and process.
Server side tasks:
1. Receive request for page. Get master template. Recurse sub templates and compose page. Parse EL and fill with markup. Blech! (Antlr?)
2. Receive JSON with a request as a POST. Convert JSON and process request. Return JSON or FORWARD to new Resource.
Client Side tasks:
1. build Subscription lists. Probably 2 lists: one for "I'm a part of submits for" and one for "I'm a part of reRenders".
2. Build Ajax framework to get all sendSubscribed elements from an Ajax submit and build JSON object. Submit Ajax request as a POST.
3. Ajax framework to receive all responses. Parse JSON response. Need a way to know where each element of JSON goes in the DOM without encumbering the server with knowing about the page's needs.
4. Intercept full page submits and still perform the mappings needed.
5. Need a way for each page to intercept all requests and responses for pre- and post- processing. Ya just need it.
#####################################################################
FORWARDS IN JERSEY
#####################################################################
Step 1. Get access to HttpServletResponse. To do it declare in your service something like:
@Context
HttpServletResponse _currentResponse;
Step 2. make redirect
...
_currentResponse.sendRedirect(redirect2Url);
EDIT
Well, to call forward method you need get to ServletContext. It is can be resolved the same way as response:
@javax.ws.rs.core.Context
ServletContext _context;
Now _context.forward is available
20 Dec., 2012
------------------
Okay, Here is the stack idea: javascript: jQuery and Bootstrap.js; View: Velocity; Servlet Engine: Jersey ( need to marry with VelocityViewServlet in some way. Custom: event registration for send and reRender, using jQuery. This will need the rewrite in velocity to add attributes of subscribe and reRender as well a tag
that will indicate to what part of the model a tag belongs ( eg, person.address.firstLine ). In other words,
it will need to extend the basic Velocity engine to include adding in the modelRef attribute to point to the
model path ( eg, person.address.firstLine ).
Engine: Jersey: will take in a JSON and put out a JSON ( figure out how to accept and auto-translate JSON
to Java ). Figure out page transitions with Post-Redirect-Get. Figure out how to return Velocity templates.
Wire to Spring, Acegi, Hibernate, etc. and make an archetype. Figure out a Submit intercept to follow regular AJAX course.
Velocity looks like it is extensible. It definitely supports includes, so that' good.
Need to figure out the VelocityViewServlet and Jersey integration. It wants this to be seamless yet extensible. Not sure how to do this. Also, needs a security measure to ensure against cross-site scripting, SQL injection, etc.
26 Dec., 2012
------------------
First, Jersey will take a JSON as input and parse it to the Models it knows.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
GENERAL APPROACH GUIDELINE
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This wants ANY tag to be a part of the conversation with the server. To do this, the general approach will be that the value bound will be the the value attribute if the element involved is an form element such as an input, a select, or a textarea. If the element is not one of these, it should look to a data attribute for the
value.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Now, the tags want two attributes: subscribeTo and reRenderOn. These will have a comma separated list of events in them.
On render of the page, the event handler will somehow magically insert an additional attribute for any element that has one or both of these tags. This extra attribute is the bindTo. It will have the path to the model field such as person.address.lineOne.
This will need to be modified to accomodate iterative things like lists, table rows, dropdown menus, etc. They may look like category.0, category.1, etc.
In the jQuery onload process, there wants to be a method to register all listeners. The idea is to get a list of all elements that have a bindTo attribute. Simple to do with a selector: $('[bindTo]').
Each Ajax event wants to have an event name. This could either be an attribute on the calling element ( button, link, etc ) or a string passed in as a parameter. The latter seems to offer more flexibility. Each event
will have several phases. There should be a means to indicate which phases the event requires. The phases will be
1. Gather data from registered elements with a subscribeTo that contains the event and form an Object from it.
2. Transmit an Ajax request ( possibly with a JSON Object from step 1 ) to the server.
3. Handle reRendering, based on registered elements with the event in their reRenderOn attribute.
Really, it would be cool and very flexible if the event could specify any combination of these three phases. Additionally, the event should be able to pass in an arbitrary Object to use in place of the model. This can be added later.
The call first wants to get a list of all registered elements that have the event name in their subscribeTo attribute. It wants to retrieve the value of each element. The value will be the value attribute if the element is a form element. Otherwise, the value will be in the data attribute. The function will use the element's bindTo in order to add the value to the JSON object that will be passed to the server.
Once the JSON Object has been formed and stringified, a jQuery.post() is made. The callback will handle the response and reRender.
The callback wants to get a list of all registered elements that have the event name in their reRenderOn attribute. It wants to retrieve the value from the JSON Object in the Ajax.data, being mindful of iterative indexes in the bindTo value. It wants to set the new value in the element. It needs to figure out how to make sure that the visible page changes when this value is changed.
Notably, dropdown lists have been problematic.
Runtime gives EventCartridge gives Iterator over ReferenceInsertionEventHandlers gives events I want to mess with ( I think ).
27 Dec., 2012
------------------
Decided to not use Bootstrap.js. It is just not usable at this point. Documentation is lacking and it doesn't
work with IE 7-8. Reality is, a good number of users still use these sub-standard browsers.
Decided to go with jQuery UI.
Odd issue with Accordion under a tab nav. Height of accoridions is zero. Google, please...
StackOverflow tells us: you must initialize the accordion before the tabs!!! Gack! How crude, but it works...
Best practice with jQuery MAY BE ( don't know ) to load all inner widgets before the outer ones.
Got the initial project set up with Spring, Jersey, Velocity, MyBatis. Very primitive but working. Next, need
to add velocity template composition, get sources, and figure out event handling...
29 Dec., 2012
-----------------
Okay, Got jQuery, jQuery-UI, Jersey, Velocity, and Spring set up. Need to bind Velocity into Spring eventually.
Wrote the PageMaker class to handle rendering page templates for all Pages. They just need to extend PageMaker.
May want to change this, so it doesn't consume a Page's only super class... Maybe an injected utility?
It really doesn't want to be a static class.
Dropped the EventHandler solution. The event didn't have enough context. Velocity's parser is an actual language parser from JavaCC. It lexes a stream into tokens, parses the token stream into an AST, and then walks the AST to generate the page from the template and values.
Instead, THE provides a Velocimacro in the library. This macro is available to all templates. Developers will need to use the macro on anything they want mapped to the server's model. For form fields, this will be the value attribute. Any other tag can be bound with the data attribute. For a form field that wants to bind to, for example, HomePage's person.address.lineOne, the developer would put this in the vm file:
<input id="lineOne" type="text" value="#bindTo( 'page.person.address.lineOne' )" />
Note, that the value passed in is a string literal. It has NO Velocity
variable indicator. The macro will turn this into a variable reference and also
use the value for its bindTo value. Likewise, you only need to ever specify
'page' for the page and not the page's actual name. This is handled by the
PageMaker class. The macro actually strips out the "page." part of the string.
That's why PageMaker provides the universal "page" root.
The rendered result would be:
<input id="lineOne" type="text" value="227 Foo St." bindto="person.address.lineOne"/>
30 Dec., 2012
------------------
Moved PageMaker to be an injected class ala Spring. Developers will have to inject this into their pages or just new it up as needed. It has no dependencies as yet, so either way will work. The framework archetype injects it for now in case it adds dependencies later.
Next Steps:
1. Work on page navigation and loading. Looks like Post/Redirect/Get might be the right strategy here.
The client side probably wants to intercept full submits, grab everything registered for any subscribeTo event and push it's current value into the javascript Object that will then be turned into JSON. The default submit will be suppressed, and an AJAX POST will be made instead. The server will receive and process as needed, then send a redirect. This **SHOULD** result in a second GET request for the new page.
The redirect will need to have any needed attributes loaded into the query string.
For later consideration: Should this be a Post/Redirect/POST? Developers could put sensitive stuff in the request...
2. Client Side: Lots of good javascript to write here. Baby steps here.
A. get the registration of event listeners done. This is a list of any elements with a bindTo attribute set with either a subscribeTo or reRenderOn attribute.
NOTE: THE VELOCIMACRO SOLUTION PRESENTS A SERIOUS PROBLEM FOR ITERATIVE ELEMENTS! Sorry to shout, but this needs attention. A separate macro will hopefully solve for this. The whole solution is looking a little shaky.
The development experience is getting a little too involved in the engine. This really wants to be abstracted from the developer.
B. Figure out event registration, including phases required and callbacks. Populate the Object for transmission.
C. Handle the reRender callback.
D. Add methods for registering and un-registering listeners on the fly.
*********************************************************************************
*********************************************************************************
A good portion of the JavaScript in the last TODOs has already been worked out in a proof of concept. I'm now working on getting it to a more robust and true solution. The biggest sticking point is the iterative components. I'm not quite sure whether to figure that out first or just move on the JavaScript solution.
I'd appreciate any feedback. Again, this was just a thought experiment that turned into a bit of code as an exercise. As long as it keeps feeling worth it, I'll keep pursuing it. If someone has already solved a part of this well, let me know. I'd be glad to save a few hours on something that's already solved. I'm already leveraging a huge stack of code to solve well defined problems.
Thanks for reading!
Tom
Sunday, July 29, 2012
Programming PIC 18F in C
I've been playing around with MPLAB X lately. It's still quite buggy, but I love the convenience of an IDE that manages my code, lets me version the software, program the devices, step debug, etc. It's a shame they chose NetBeans instead of Eclipse. Regardless, some new learnings were in the offing. I wrote some programs in C with Microchips C18 compiler. I learned how to program the chips for In Circuit Debugging (ICD ) with the PicKit2. Wow! It is definitely cool to be able to step debug on the actual circuit.
Not much to show for this first foray. I redid an old routine that reads from the ADC on AN0 and pushes the value onto an LCD screen. The set up and whatnot is the same as posted in earlier blogs. The difference was porting the whole thing to C. The config fuses are set in an include file to get them out of the way. Here it is:
configFuses.h
The source code is fairly compact:
adc_lcd.c
Next up is a hybrid C and assembly program that I've been wanting to do. It reads an analog value from AN0. I took advantage of C to divide the value by 6 and add one. This result is fed to a servo value. The servo is driven by chained interrupts on timers 0 and 1. Timer 0 acts as the controller and interrupts on the period ( 50 Hz or 20ms ). On interrupt, it resets itself and starts timer 1 for the first .65 ms of the duty cycle. It turns on all servos ( in this case only one ). The timer 1 interrupt handles the remaining 1.35 ms of the duty cycle. It sets itself to interrupt every 7.4 us for 180 times. This means that the servos will have a resolution of 180 degrees.
The interrupts are all written in assembly. While they could have been done in C for one servo, this code wants to evolve to control 16 or 17 servos at a time. Each will have an independent value. To control the 18 or more servos for a hexapod, the timings will have to adjust to a PLL driven clock at 48 MHz. That buys 160 instructions per "degree" of resolution to work with ( as opposed to the 40 instructions available at 20 MHz ).
The assembly portion is rammed into the code inline. This led to some interesting knowledge. The program employs a lot of #define statements to make the code more readable and adjustable. All of the delays and interrupt timings are done by define. It should be a simple matter to adjust them to 48 MHz. For the assembly, the pins needed to be defined as well. They could not use the definitions from the chip's include file. As a part of changing the timings for 48 MHz, the assembly will be placed in its own .asm file and linked in. That should simplify things.
The same configFuses.h file was used as above. One thing to note: The MCLR is ON in this file. This allows debugging the program in circuit. It also means a 10k resistor needs to be connected to RE3.
Here is the code for the servo tester as it stands now: adc_servo.c
That's all for now!
Not much to show for this first foray. I redid an old routine that reads from the ADC on AN0 and pushes the value onto an LCD screen. The set up and whatnot is the same as posted in earlier blogs. The difference was porting the whole thing to C. The config fuses are set in an include file to get them out of the way. Here it is:
configFuses.h
The source code is fairly compact:
adc_lcd.c
Next up is a hybrid C and assembly program that I've been wanting to do. It reads an analog value from AN0. I took advantage of C to divide the value by 6 and add one. This result is fed to a servo value. The servo is driven by chained interrupts on timers 0 and 1. Timer 0 acts as the controller and interrupts on the period ( 50 Hz or 20ms ). On interrupt, it resets itself and starts timer 1 for the first .65 ms of the duty cycle. It turns on all servos ( in this case only one ). The timer 1 interrupt handles the remaining 1.35 ms of the duty cycle. It sets itself to interrupt every 7.4 us for 180 times. This means that the servos will have a resolution of 180 degrees.
The interrupts are all written in assembly. While they could have been done in C for one servo, this code wants to evolve to control 16 or 17 servos at a time. Each will have an independent value. To control the 18 or more servos for a hexapod, the timings will have to adjust to a PLL driven clock at 48 MHz. That buys 160 instructions per "degree" of resolution to work with ( as opposed to the 40 instructions available at 20 MHz ).
The assembly portion is rammed into the code inline. This led to some interesting knowledge. The program employs a lot of #define statements to make the code more readable and adjustable. All of the delays and interrupt timings are done by define. It should be a simple matter to adjust them to 48 MHz. For the assembly, the pins needed to be defined as well. They could not use the definitions from the chip's include file. As a part of changing the timings for 48 MHz, the assembly will be placed in its own .asm file and linked in. That should simplify things.
The same configFuses.h file was used as above. One thing to note: The MCLR is ON in this file. This allows debugging the program in circuit. It also means a 10k resistor needs to be connected to RE3.
Here is the code for the servo tester as it stands now: adc_servo.c
That's all for now!
Thursday, May 17, 2012
NTSC Composite Video
As usual, one thing distracts another. The hardware is set up for the first VGA test, but the code has not come out yet. In the meantime, I found an old LCD screen that I wanted to examine. It comes from an old DVD player for the car. The main unit has a DVD player and 7" LCD screen. It also comes with a second 7" LCD that attaches to the main unit via a three prong RCA cable. The signal should be composite video. The screen on the main player is broken, but the second one works. It is small, thin, and portable.
It is ripe for hacking, so VGA will now have to wait. This screen is just waiting for a game of Pong or just a cool, big, text terminal! The NTSC and PAL standards are quite taxing to implement in software. Questions to the Google revealed a few possible shortcuts. Here then are my notes thus far. The project will attempt to write black and white ( and maybe some gray ), using my new Pic18F4550, clocked with PLL at 48MHz. This gives a Pic a working speed of 12 MIPS. The links below provide some of the shortcuts that should make the vertical synching less of a hassle.
==========================
Composite Video
==========================
-------------
17 May, 2012
-------------
References
----------
Rikard Gunee's Pong and Tetris on a Pic
The Post That Gave Me Inspiration
Uzebox
The Shortcuts from AVRFreaks
Going to try the simplest method. This will not try to do interlaced lines. Instead, it will only do the even line field over and over.
Frame = 2 fields of both even lines.
Timings
--------
Line = 63.5 us
262 lines per field
Time per Field = 262 x 63.5 = 16.637 ms
Line Parts
----------
Name Voltage Time Instructions @ 12 Mips
_______________________________________________________
Front Porch .3V 1.4us 17 ( actual 16.8 )
HSynch 0V 4.4us 53 ( actual 52.8 )
Back Porch .3V 4.4us 53 ( actual 52.8 )
Active .3-1.2V 53.3us 639 ( actual 639.6 )
Total Instructions = 762
Freq = 8.333 x 10^-8
Total Time = 762 x 8.333x10^-8 = 63.5us
Vertical Synch
---------------
Try just setting the line to 0V for the whole 63.5us on the 3 VSynch lines.
Field Layout
------------
Lines Function
------------------------------------
3 Dummy H lines
3 VSynch lines
14 Dummy H lines
242 Visible lines
Dummy H line:
Front Porch, HSynch, Back Porch, .3V for active 53.3us
During the active time of the dummy lines, 639 free instructions are available per line.
Use this time to set up the line arrays.
Pin Setup
----------
Pin 1 has a 470 Ohm resistor
Pin 0 has a 1k resistor
Pins Result
---------------
00 0V (synch)
01 .3V (black)
10 .6V (gray)
11 1V (white)
Interrupts
-----------
Use Timer 0 in 16 bit mode. Interrupt every 63.5us ( every 762 instructions at 48MHz ).
65536 - 762 = 64774
In binary = 0b1111110100000110
The High byte is 253
The Low byte is 6
High = 0xFD
Low = 0x06
Need to keep track of line numbers. At start of interrupt, immediately set output to 01 ( black ).
If it is a vertical synch, set output port to 00 ( 0V ) and return to process data.
Else, waste time and do the horizontal synch ( porches and synch ).
If it's a dummy line, return to main for processing.
If it's an active line, process the line.
Need to figure out the line and array housekeeping, too.
Need to look for a way to use the 106 instructions of porch and Hsynch time effectively.
It is ripe for hacking, so VGA will now have to wait. This screen is just waiting for a game of Pong or just a cool, big, text terminal! The NTSC and PAL standards are quite taxing to implement in software. Questions to the Google revealed a few possible shortcuts. Here then are my notes thus far. The project will attempt to write black and white ( and maybe some gray ), using my new Pic18F4550, clocked with PLL at 48MHz. This gives a Pic a working speed of 12 MIPS. The links below provide some of the shortcuts that should make the vertical synching less of a hassle.
==========================
Composite Video
==========================
-------------
17 May, 2012
-------------
References
----------
Rikard Gunee's Pong and Tetris on a Pic
The Post That Gave Me Inspiration
Uzebox
The Shortcuts from AVRFreaks
Going to try the simplest method. This will not try to do interlaced lines. Instead, it will only do the even line field over and over.
Frame = 2 fields of both even lines.
Timings
--------
Line = 63.5 us
262 lines per field
Time per Field = 262 x 63.5 = 16.637 ms
Line Parts
----------
Name Voltage Time Instructions @ 12 Mips
_______________________________________________________
Front Porch .3V 1.4us 17 ( actual 16.8 )
HSynch 0V 4.4us 53 ( actual 52.8 )
Back Porch .3V 4.4us 53 ( actual 52.8 )
Active .3-1.2V 53.3us 639 ( actual 639.6 )
Total Instructions = 762
Freq = 8.333 x 10^-8
Total Time = 762 x 8.333x10^-8 = 63.5us
Vertical Synch
---------------
Try just setting the line to 0V for the whole 63.5us on the 3 VSynch lines.
Field Layout
------------
Lines Function
------------------------------------
3 Dummy H lines
3 VSynch lines
14 Dummy H lines
242 Visible lines
Dummy H line:
Front Porch, HSynch, Back Porch, .3V for active 53.3us
During the active time of the dummy lines, 639 free instructions are available per line.
Use this time to set up the line arrays.
Pin Setup
----------
Pin 1 has a 470 Ohm resistor
Pin 0 has a 1k resistor
Pins Result
---------------
00 0V (synch)
01 .3V (black)
10 .6V (gray)
11 1V (white)
Interrupts
-----------
Use Timer 0 in 16 bit mode. Interrupt every 63.5us ( every 762 instructions at 48MHz ).
65536 - 762 = 64774
In binary = 0b1111110100000110
The High byte is 253
The Low byte is 6
High = 0xFD
Low = 0x06
Need to keep track of line numbers. At start of interrupt, immediately set output to 01 ( black ).
If it is a vertical synch, set output port to 00 ( 0V ) and return to process data.
Else, waste time and do the horizontal synch ( porches and synch ).
If it's a dummy line, return to main for processing.
If it's an active line, process the line.
Need to figure out the line and array housekeeping, too.
Need to look for a way to use the 106 instructions of porch and Hsynch time effectively.
Sunday, May 6, 2012
VGA Wiring, Fast 16 Bit Counters
Here are a few brief notes/findings.
Cheap Wire
Home Depot in the States sells Cat 5e riser network cable. This is 24 AWG solid core wire. There are 8 wires in the cable. These work fairly well as jumper wires for breadboard. Left in the insulator, they make really good connection wires. There are eight of them, so that's a parallel byte or a full register. In the case of the line follower I want, that's the six input lines and the power and ground. One short of what is needed ( the LED on/off line ). Here's the cool part: THE PRICE! A 20 foot roll of a single wire at 22 AWG at Radio Shack is a bit over $8.00 USD. The Cat 5e Riser ( not Plenum ) cable is $0.18 per foot. And that's for eight wires. The stuff can be used like Kleenex at that price. Plenum cable is not much more expensive at about $0.59 per foot. This stuff is going on almost everything project from now on.
VGA
A VGA driver is the next experiment on the docket. Lucid Science has a great tutorial. It's written for an Atmel AVR in assembly. With a datasheet and maybe a tutorial, it's pretty easy to adapt to a PIC. The main problem with the PIC is speed. Even with an 18F microcontroller running at 96 MHz with PLL, the processor gets 48 MHz from that. Each instruction takes four clocks, so the effective MIPS is 12. This is slow and it makes conversion a bit tricky. It should be possible to get a test display of Lucid Science's RRGGBBII palette to work. Even with SRAM, the operable resolution for graphics will be pretty low, though. Still, it should be fun to try.
To that end, I wired up a VGA female cable, using some newly purchased Cat 5e cable. As a reminder to myself:
Fast 16 Bit Counter
Now for some cool news. The 18F series has made some big improvements. First, you can avoid the Read-Modify-Write problem by writing directly to the Latch registers for the ports. Next, they include a new SFR, WREG. This shadows the W register. Unlike the W register, it allows direct math and manipulation. Mathematical operations on the WREG can be interchanged with W reserved operations like movlw and addwf.
Tonight proved two other operations unknown to me. First, it is possible to maintain a 16 Bit increment ( an increment over 2 bytes ) in only 2 instructions. The W register must be zero for this to work. The lower byte is incremented as usual with incf:
movlw 0x000
incf myRegLow,F
Then, the magical addwfc is invoked. This adds the W register ( value zero ) to the higher byte as well as the Carry bit from the last operation ( the incf ). This effectively increments the higher byte only when the lower byte overflows to 256 ( ie, back to zero ).
addwfc myRegHigh,F
Wait, wait. Don't order yet! Now how much would you pay? If you act now, we'll throw in the fact that you can do mathematical operations directly on the Latch registers! This means that if the SRAM address for VGA output needs to be incremented very quickly through 16 bits worth of addresses ( and it does ), it is possible. If LATB holds the lower address byte and LATD holds the higher byte:
movlw 0x000
beginAddressLoop:
incf LATB,F
addwfc LATD,F
bra beginAddressLoop
This, of course, is nothing like what will be used. It does illustrate the point. These little discoveries will drastically reduce the cycles needed for the various operations needed for VGA output.
Cheap Wire
Home Depot in the States sells Cat 5e riser network cable. This is 24 AWG solid core wire. There are 8 wires in the cable. These work fairly well as jumper wires for breadboard. Left in the insulator, they make really good connection wires. There are eight of them, so that's a parallel byte or a full register. In the case of the line follower I want, that's the six input lines and the power and ground. One short of what is needed ( the LED on/off line ). Here's the cool part: THE PRICE! A 20 foot roll of a single wire at 22 AWG at Radio Shack is a bit over $8.00 USD. The Cat 5e Riser ( not Plenum ) cable is $0.18 per foot. And that's for eight wires. The stuff can be used like Kleenex at that price. Plenum cable is not much more expensive at about $0.59 per foot. This stuff is going on almost everything project from now on.
VGA
A VGA driver is the next experiment on the docket. Lucid Science has a great tutorial. It's written for an Atmel AVR in assembly. With a datasheet and maybe a tutorial, it's pretty easy to adapt to a PIC. The main problem with the PIC is speed. Even with an 18F microcontroller running at 96 MHz with PLL, the processor gets 48 MHz from that. Each instruction takes four clocks, so the effective MIPS is 12. This is slow and it makes conversion a bit tricky. It should be possible to get a test display of Lucid Science's RRGGBBII palette to work. Even with SRAM, the operable resolution for graphics will be pretty low, though. Still, it should be fun to try.
To that end, I wired up a VGA female cable, using some newly purchased Cat 5e cable. As a reminder to myself:
| Pin | Wire Color(s) | Value |
|---|---|---|
| 1 | Orange | Red |
| 2 | Green | Green |
| 3 | Blue | Blue |
| 5,6,7,8,10 | White/Green White/Blue White/Orange |
Ground |
| 13 | Brown | Hz Synch |
| 14 | White/Brown | Vt Synch |
Fast 16 Bit Counter
Now for some cool news. The 18F series has made some big improvements. First, you can avoid the Read-Modify-Write problem by writing directly to the Latch registers for the ports. Next, they include a new SFR, WREG. This shadows the W register. Unlike the W register, it allows direct math and manipulation. Mathematical operations on the WREG can be interchanged with W reserved operations like movlw and addwf.
Tonight proved two other operations unknown to me. First, it is possible to maintain a 16 Bit increment ( an increment over 2 bytes ) in only 2 instructions. The W register must be zero for this to work. The lower byte is incremented as usual with incf:
movlw 0x000
incf myRegLow,F
Then, the magical addwfc is invoked. This adds the W register ( value zero ) to the higher byte as well as the Carry bit from the last operation ( the incf ). This effectively increments the higher byte only when the lower byte overflows to 256 ( ie, back to zero ).
addwfc myRegHigh,F
Wait, wait. Don't order yet! Now how much would you pay? If you act now, we'll throw in the fact that you can do mathematical operations directly on the Latch registers! This means that if the SRAM address for VGA output needs to be incremented very quickly through 16 bits worth of addresses ( and it does ), it is possible. If LATB holds the lower address byte and LATD holds the higher byte:
movlw 0x000
beginAddressLoop:
incf LATB,F
addwfc LATD,F
bra beginAddressLoop
This, of course, is nothing like what will be used. It does illustrate the point. These little discoveries will drastically reduce the cycles needed for the various operations needed for VGA output.
Friday, May 4, 2012
Hand Made Board - Finished!
The Dremel drill bits from Amazon arrived. They come in a packet of 4 and are 1/32". Man, are they small! They fit in the Dremel chuck nicely, but it took a bit of fiddling to get them in straight. The problem with the Dremel is that the hold button needs to be depressed as you tighten. The whole operation would be a lot easier with three hands. I used my trusty Dremel drill press and banged out the holes. It was very easy. I took my time. The copper around the holes actually nudge the bit where it needs to go. The Dremel was set to 15,000 RPMs. The bit dwells a bit at the top of the cut, then a smooth plunge finishes off each hole. Here's the result:
Soldering was very different from either a proto-board or a professional PCB. The solder and heat want to go everywhere. The ground plane was particularly a problem. I have to admit, I rushed the soldering. I was so excited that everything looked good. I just wanted to see the board done. Here's the top with the pins and sockets added:
Here's a picture of the bottom solder that's as bad as the soldering job:
I printed out a pin "cheat sheet" for the microcontroller in lieu of a stencil:
Now, to test it out with a hello world style blinking LED!
Soldering was very different from either a proto-board or a professional PCB. The solder and heat want to go everywhere. The ground plane was particularly a problem. I have to admit, I rushed the soldering. I was so excited that everything looked good. I just wanted to see the board done. Here's the top with the pins and sockets added:
Here's a picture of the bottom solder that's as bad as the soldering job:
I printed out a pin "cheat sheet" for the microcontroller in lieu of a stencil:
Now, to test it out with a hello world style blinking LED!
Subscribe to:
Posts (Atom)



