Pages: [1] 2   Go Down
Author Topic: Text-based User Interface library new release  (Read 5132 times)
0 Members and 1 Guest are viewing this topic.
Central MN, USA
Offline Offline
Tesla Member
***
Karma: 72
Posts: 7171
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Text area with scroll bar to the right, up/down buttons scroll the text:


Top menu with current/total item indicator on top right (you can put it anywhere) and arrow/dot indicator or highlighted item. Indicator is customizable:


Top menu with 12345 index and the arrow is the indicator of the highlighted item


A sub menu:


    I'm happy to release a new version of the phi_prompt Text-based User Interface (TUI) library, which I have been working on lately.

    This new release has the following features that helps an Arduino project developer quickly whip up a professional-looking user interface, that otherwise would take at least weeks to get if starting from scratch. Using the library, you essentially decouple coding your project's functions and coding the user interface. Like when you program in Java, you wouldn't be making buttons and lists but using buttons classes and list classes instead. You can have phi_prompt handle the user interface with lots of customizable features anytime you want it and handle it your own way at other times if you want. Here are what phi_prompt offers:

  •    Supports multiple-level menu. See the menu example code how to construct a menu from a list of menu items. Use my template to save you time.
  •    Supports display of lists with a variety of customizable features.
This is the option byte:

[/list]
Code:
Scrolling bar Center choice Flashing cursor Auto scroll Current /total Index list 1 thru 0 Arrow/dot item indicator
  •    Supports text areas to display long messages. You don’t have to clip your messages in small chunks to display on 16X2 or 20X4 displays. Text areas do that for you. The user can use up/down keys to scroll up and down to read the entire message. This version has text_area_P(), which directly displays message from PROGMEM to LCD, saving tons of RAM.
  •    Scrolling texts horizontally if you want to display long messages on one line or if you have a long item on a list that won’t fit on one line.
  •    Function to display texts automatically center-aligned. No need to count characters.
  •    Supports integer entry, floating point number entry, and text entry. Easy to construct a password panel or ask user to enter a file name. Use my template to save time.
  •    Lists are stored in PROGMEM, saving RAM for variables. Long messages can also be printed from PROGMEM.
  •    Displays a vertical scroll bar anywhere you want.
  •    Displays yes/no and ok dialog that automatically scales to the size of your screen.
  •    Collect user button presses with wait_on_escape(). You don’t have to write your own code anymore. The return value tells you which button was pressed.
  •    Showing off your project with professional-looking interfaces!

Here is a video showing off most of its functions. The 20X4 display is definitely nice: I'll add annotations soon.
More clear video from today:


Somewhat unclear video a few days ago:


This is a more complete video:


I've uploaded the library to my blog but yet need time for complete documentation.
http://liudr.wordpress.com/libraries/phi_prompt/
« Last Edit: May 25, 2011, 07:43:41 pm by liudr » Logged


France
Offline Offline
Jr. Member
**
Karma: 3
Posts: 72
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Really nice, love it!
This is going to save me a lot of time!

But does this work on graphic LCDs too?
Logged

My projects :
- Interfacing with Minitel : http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1271350467
- Arduino PIC programmer : http://ardu

Netherlands
Offline Offline
Newbie
*
Karma: 1
Posts: 27
C+ N00b
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Neat !!

Planning to use this library in the future.
Will follow the development and made a bookmark to your blog..

Thanks for sharing

Logged

Central MN, USA
Offline Offline
Tesla Member
***
Karma: 72
Posts: 7171
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Really nice, love it!
This is going to save me a lot of time!

But does this work on graphic LCDs too?

As I was re-writing my codes, I found I used the following functions from the standard LiquidCrystal library:

clear() to clear screen
setCursor() to set location of the output
print(char*) to print a string of characters
write(char) to print one character
and createChar(char*) for scroll bar
blink() and noBlink() for blinking box

So if you use a GLCD, does the GLCD support these above functions? I'm planning to port my library to KS0108-compatible displays but need some help figuring out what the GLCD can do.
Logged


Central MN, USA
Offline Offline
Tesla Member
***
Karma: 72
Posts: 7171
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Neat !!

Planning to use this library in the future.
Will follow the development and made a bookmark to your blog..

Thanks for sharing



Hey you're welcome. I've spent many hours on this so may as well share it. I will write more documentation as I go. I still have a few things I would like to implement for the next revision but won't cause major change of function calling protocol anymore. I got many suggestions from the forum on features to include so feel free to ask!
Logged


Central MN, USA
Offline Offline
Tesla Member
***
Karma: 72
Posts: 7171
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Added pictures.
Logged


Fresno, CA, USA
Offline Offline
Full Member
***
Karma: 1
Posts: 153
Arduino rocks (literally, with a WaveShield!)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Dude... this is INCREDIBLE! Seriously. Awesome work.

I think you'll be delighted to know I'm planning on implementing phi_prompt in what could be Arduino's single most real-world-useful with mass-market-appeal project I've still ever seen an Arduino do: in the OpenGauge MPGuino Revision 2 project. The UI of MPGuino is just butt-ugly and near unusable, and my focus is on maintaining its rock-solid stability and incredible accuracy, and even keeping the existing hardware design (since the original developer isn't really on-board with the project since I'm taking it back to its Arduino roots)... but wholly gutting and rebuilding its user interface.

Take a look: http://ecomodder.com/forum/showthread.php/release-two-workspace-fork-name-tbd-16556.html

I had a little bit of difficulty starting off, when I first played around with it in conjunction with a shift-register-based LCD driver library. The library is hard-coded to accept a LiquidCrystal object, but not only that, even if I try to use something else, it still tries to #include LiquidCrystal.h anyway (which "can't be found" if I don't #include it in my own program anyway - so why have the reference?). So I had to edit the actual library code to swap LiquidCrystal for ShiftLCD... was kindofan uncomfortable thing to do, so after testing it and seeing it worked great, I switched it back to LiquidCrystal... but it'd really be nice to have some way to add the LCD library functionality in there. Maybe leave them undefined, and rely on the program to #define the function names itself? Like:
Code:
#define phi_lcdPrint mylcd.print
#define phi_lcdClear mylcd.clear
#define phi_lcdSetCursor mylcd.setCursor
#define phi_lcdWrite mylcd.write
#define phi_lcdCreateChar mylcd.createChar
#define phi_lcdBlink mylcd.blink
#define phi_lcdNoBlink mylcd.noBlink
... or maybe in an array in the same way as passing the buttons:
Code:
phi_lcd *lcd[] = {mylcd.print, mylcd.clear, mylcd.setCursor, mylcd.write, mylcd.createChar, mylcd.blink, mylcd.noBlink};

I think that'd help make it more flexible for different LCD formats, which I've seen has been a bit of a hangup for some people smiley-wink

Little LCD quirks aside, I think this is a truly incredible little library, and I can't wait to see what it can do for our little project on my car's dash smiley-grin
edit: woops, wrong link, it's opengauge.org smiley-red
« Last Edit: June 01, 2011, 01:15:47 am by FalconFour » Logged

Central MN, USA
Offline Offline
Tesla Member
***
Karma: 72
Posts: 7171
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

FalconFour,

I'm glad that you found my library useful. I am trying to make a text-based user interface that the Arduino platform absolutely needs. I believe too many hours have been spent on many peoples' project interfaces where they can be better spent on the project functionality.

I am thinking about porting my library to GLCD and possibly ShiftLCD. Your way of #define is interesting. I could expand it into something like this in case other lcd libraries have different parameter orders or different number of parameters:

#define phi_lcd_setCursor(x,y) lcd.setCursor(x,y) // For standard LCD
#define phi_lcd_setCursor(x,y) glcd.CursorTo(x,y) // For KS0108 GLCD
#define phi_lcd_setCursor(x,y) ShiftLCD.something(x,y) // For shift register LCD, I don't know too much about it yet.

I got a few questions for you smiley

Which Shift LCD version are you using, link?
What functions do you use in the library?
Anything you wish the library had?

Just in case your project code is kept proprietary instead of released to the public for educational and hobby use, please contact me about licensing. My library is free for educational and hobby use and its credits within the files should be kept.
Logged


Fresno, CA, USA
Offline Offline
Full Member
***
Karma: 1
Posts: 153
Arduino rocks (literally, with a WaveShield!)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Of course smiley-grin The only reason I'm able to do work on it is because it's open-source... otherwise the guy doesn't seem like he'd be too willing to let other people mess with it, haha... several people have made attempts at extending and updating the interface, but none have really made a fully functional "new version".

So far I haven't really had a chance to give it a go, as I've been busy trying to consolidate the existing code and come up with a good program structure that still allows the timing to have its way (e.g. updating stats on a regular basis, maintaining the software RTC, checking for system-idle conditions, etc... basically "doing things in the background"). It's kind of a monolithic mess right now, everything in one huge file that compiles to about 18kb of code on-chip. That's with the old UI, though. After gutting the old UI down to its monitoring/processing core (with no output), it only takes about 12kb. Still a lot!

I originally started with this shift LCD code: http://cjparish.blogspot.com/2010/01/controlling-lcd-display-with-shift.html - but I wanted an 8-bit interface (since the shift register is an 8-bit chip, it just makes sense). I don't mind carrying 4 pins: RS, Enable, Clock, and Data (my shifter doesn't have a latch, only reset and A/B, I only use A). So I figured, if it shifts 8 bits out with every shift, it'll never get out of sync. I tweaked the hell outta the code, and tested it. I was right: shifting 8 bits at a time in a tight, no-delays loop updating the LCD using only "lcd.setCursor(0,1); lcd.print(micros(),DEC);", no timing errors and no need for latch/reset. But it's just a modification-of-a-modification of LiquidCrystal, so nothing's really different there, other than the name of the class (ShiftLCD instead of LiquidCrystal). To make it work, I just had to change LiquidCrystal to ShiftLCD in the phi_prompt code smiley-wink

As for what I wish the library had, well... I haven't dabbed much in it so far, but it was a bit of a PITA to get the demo phi_prompt_example_menu code to work. After I got ShiftLCD working, the initial credits page went bonkers... it'd start on the first line, go to the next automatically (Ooh, autoscrolling? Neat!), then again a bit quicker... then again and again and (whoa whoa, hey what?) again and agaignaginagianblblblblbl(end)... om... that's odd. I went in and tried to find the button definitions in the example, but there was nothing to be found (it looked pretty... desolate). Odd. OK, so I poked around the other files and found where the buttons seem to be defined. I changed them to my pins, and it... well, didn't help. Changed to 4-button mode (I only have 4 buttons on my test board), and it did something else: blippiting through the menus like I'm holding "OK" down. Nooot quite right. Then I found the definitions were in 2 places: one for phi-1 and one for phi-2 shields. Urk? Hmm, well, OK, I comment out the #define phi_2_shield line and copy over the button/buzzer definitions to my appropriate values. Bam, everything worked. But it was a bumpy learning curve since I'm used to single-file, monolithic examples and sketches, and this example is sprawled out over 4 files :o

Just thought it'd be worth mentioning my experience... I learned now, but I wonder if there are others going through the same thing when they test it out. =P

As for the functions I plan on using, it'll likely be everything phi_prompt has to offer... I'll need menus as the primary means of navigation and configuration, number entries to enter the engine/timing parameters (stored in EEPROM), and I might need to tweak it a bit to extend it to setting the software RTC (that was a PITA to implement in the old code - the configuration page, that is). The primary "monitoring" display is probably going to be a modified selection list, which may get to be a curious affair. It's supposed to update the display twice a second, and I was hoping to be able to use the arrow/select keys to pick a parameter on-screen to change, as it runs. So, in normal running mode (the mode all modes will fall back to on input timeout or "return to main"), it'll have 4 parameters on-screen, updating every 500ms. The cursor would select a parameter on this screen, and when you select it, you get a list of alternatives you can put in its place (e.g. swap from miles/hr to current MPG). There's also a "big font" mode that shows a single parameter across 2 rows in large font, like phi_big_font, only for numbers, and with a bit smoother-looking custom character set (which I'm sure you can borrow, it was a user-contributed mod anyway). All this should be selectable from the main menu, which I hope to activate by holding the select/OK button for >1s. And when the device is idle (no engine/speed pulses) for over 5 minutes, it dims/shuts off the light (configurable) and displays an idle screen with a clock and a 4x2 animation of some kind using custom character mapping (all pixels of 4x2 are capable of animation by placing characters 0...7 on-screen and tweaking the custom characters - just gotta figure out how to create the animation effect).

All in all, it seems like phi_prompt really saves about 60-75% of the daunting work I was going to have to do... I barely even knew where to begin with the new interface. I was planning on making it some sort of extensible tab-stop-based system, where each "screen mode" had a list of tab stops where the cursor would stop when you use the left/right buttons, and when you "select", that tab stop would be passed to a handler function for that screen that would perform the intended action (change the screen, update a number, make a selection, etc). I just got hung up on the whole... you know... "doing it" thing. Making a servo play Fur Elise seemed more entertaining. smiley-wink
Logged

Central MN, USA
Offline Offline
Tesla Member
***
Karma: 72
Posts: 7171
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I need user inputs like yours to improve the library and its examples. I wrote the button definitions all according to my phi-2 shield hardware so I don't know what problems others encounter until they try the library. Now I'll put "better example code" on my revision notes. Initially you must have defined the up button as auto_button. It's a thing one member requested so minimal input pins can be used. You can use as few as one button to operate the entire thing if you set the "right button" as the only real button with a digital pin, then the up button as auto button, and other buttons as null_button. This way your program doesn't have to be re-vised if you want to lose a few buttons to save pins smiley I guess it worked out to be an obstacle for first timers. I'll make a note in my documentation, which is 75% complete. My documents are usually very detailed so they take forever to finish.

I had a phi-1 shield before the phi-2 shield. Unfortunately two pins had to be swapped between the two versions to make the phi-2 shield compatible with Ethernet shield with sd card, thus the defs. You can ignore them all and make your definition in your main program. Monolithic program is not good for 18K of code, it's about 1,800 lines. I rather break it down into small modules so if I had time I would periodically revise each small module. Plus, Arduino IDE is not built to handle long codes. You can't fold codes. I do have tricks to help you though:

http://liudr.wordpress.com/category/coding/

There are a few posts on organizing your program, optimizing and my trick of the trade included as the very first post. You'll like it.

BTW, in my near future quick add-on update (a few functions that you can use to simplify your programming), I will have things like:
text_area_maximize(Char* long_message) so all you need to do is to supply a string and the text area is maximized on the display.

You're using 16X2 display, right? A text area is really nice on 20X4 display smiley
I will also have simple functions like float get_number(char * prompt_message) so you will have a generic input panel with a line of prompt like "Input speed:" and the function returns a number. It's simple. I'll like it if I were beginner or don't care where exactly the number is displayed. With the full input_integer you can have a series of inputs on one screen for all date and time (see my original phi-1 shield alarm clock videos). But if you want simplicity, you can call a get_number function smiley
Logged


Fresno, CA, USA
Offline Offline
Full Member
***
Karma: 1
Posts: 153
Arduino rocks (literally, with a WaveShield!)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Oh, trust and believe, if I weren't sweating every $30 purchase, I'd've bought a Phi-2 shield in a heartbeat. Unfortunately my primary development platform on Arduino is my Radio Shack "electronics learning lab" board, which is *amazing* for Arduino development after adding an LCD and using a USB BoArduino from Adafruit... but not shield-compatible, so whenever I need to use a shield, I have to break out the Duemilanove and juggle wires with a ScrewShield. Maybe in the near future, though... in fact, the Phi-2 shield MAY actually be a perfect fit for the MPGuino platform, as a user could just wire up the VSS (vehicle speed sensor) and injector inputs on a protoshield and stack the Phi-2 on top of it... bam, a perfectly clean MPGuino build, backlit LCD, buttons, and all! I'd have to make an alternate build for it with different pin definitions, but I think it should work great, especially with the added buttons. The MPGuino board uses a 20MHz clock, though, which is an arguably silly modification, but just needs a few parameter tweaks (I still haven't found if the clock delays are accurate with the Arduino codes, needs a little more testing).

I also think it's a good idea to split the code up into multiple files, which I'll spend a bit of time on with MPGuino to make it more readable. As it is now, it has very clearly defined "segments" of the program (the counters, the trip classes, the user interface, math functions, etc), that could very easily be branched out to separate files for readability. That's probably the first thing I'll do, if just so I could avoid wearing out my scroll wheel so much! It's seriously a PITA to look for a function in that code.

I'm just curious, though... do you do everything in the Arduino IDE? I hear a lot about people using alternate IDEs with Arduino, and with how frustrating Arduino can be sometimes, I wonder if it's worth a try. Like, if I want to reference another project to remember how I did something ("was it PORTD or PORTB? Or is it PIND?", "what pins do I need to use here?", etc), I can't just hit File-Open, because it unpredictably wants to close my current project to open that one, so I often have to open another Arduino instance *then* open the other project. Or god, the "Open" menu, after I've collected a number of projects. First, the examples went off the bottom of the screen, and I have to use the "Examples" submenu (which, itself, is timed to close WAY too fast, so as I zip my cursor down to grab a lower library name, it closes the menu on me). Now, even my sketches list is going off the end of the screen. Augh! =P

edit: Oh, and yeah, all I've got are 16x2 LCDs... one (without backlight) wired up in my Radio Shack board, one in the MPGuino device in my car, and one on its way from Adafruit right now. I keep forgetting there are more styles available when I shop for 'em, haha... I really should try out a 20x4 LCD. smiley
« Last Edit: June 01, 2011, 02:57:03 pm by FalconFour » Logged

Fresno, CA, USA
Offline Offline
Full Member
***
Karma: 1
Posts: 153
Arduino rocks (literally, with a WaveShield!)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Well, here at 3am, thought I'd share my first project experience with phi_prompt...

... I originally started at about 6pm smiley-sad

The biggest issue I ran into... an insurmountable, unbelievably huge issue in my programs' design... is that I can't use phi_prompt *AT ALL* to select options that are generated or changed in the program. For example, if I calculate some possible values and want to make a 2x2 (2x3, etc) list, I just... literally... *can't*. The render_list function is hard-coded to retrieve its values from progmem, instead of allowing the flexibility of, say, "is this an int? float? string?", etc., on an item-by-item basis. I think C allows that kind of type detection through pointer-passing, wouldn't you just have to define multiple versions of the function for different data types coming into the function?

I spent about 3 of those hours writing up a hybrid custom-written + phi_prompt system, where phi_prompt still handles that button detection and scrollbar, but all the LCD drawing, action-processing (up, down, select), and item generation are handled by the function's code. It was really quite a bit of work, not the least of which because I was working directly at the bit-level (I used a 16-byte bitmask to store scan results, then the "list" function would iterate through the bitmask and associate the original address with the bit as it loops and I could make a selection as to which address I want to choose.

The other issue was the lack of documentation, but you've already mentioned you're working on that. I had the phi_prompt source open in the background in Notepad++, and I'd constantly go through there and look for button references, what the return values are, how the parameters are interpreted ("step" was the most confusing), etc. That was fun.

However, at the end of it all, there is a HUGE payoff: the first interactive laptop battery interface for Arduino. Using the menu, I can select to read charging statistics like volts, amps, percentage, and temperature (updated twice a second). Or select "Battery ID" and it'll read out the manufacturer, model, and chemistry. "Statistics" shows the manufacturing date and cycle count. "Control" allows you to send hex commands directly to the battery: write word, read word, read block, using input_panel for all values (0-9 & A-F, memcpy into a 0x0000 template and strtoul to convert to "unsigned int"). It has an SMBus scanner that can locate unknown battery controllers' SMBus addresses, and that's the one that was the hardest to implement (the custom UI), and select it for use in the program.

I'll be posting its own topic shortly, as well as the source code (compiles to 16224 bytes, but I should add "credits" back in there, I took it out since I was originally going to make this a really quick-n-dirty adaptation for personal use). It's a heck of a cool thing to play around with! Bust out some old laptop batteries (partially charged of course) and you can read what's going on in its mind smiley-wink

edit: I also had a huge number of issues with button actions between functions... if I make a menu (list) selection, it immediately passes the action to the select () construct, where it activates the appropriate function... and often does its own button-checking with wait_on_escape(). Problem is, it's usually checking to see if something was pushed. Or held. Hmm. Well, if it's either one ("released" -or- "still being held"), it just zippo's right past the check and flies right into the next action without releasing the button. Errp! So I had to do a lot of this:
Code:
while (wait_on_escape(25)) ; // wait for buttons to be up, may have residual press from menu
while (wait_on_escape(500) == 0) ; // wait for button press
return;
Is there a "wait for clear interface" or "wait for any key" function I'm missing? :/
« Last Edit: June 02, 2011, 05:41:31 am by FalconFour » Logged

Central MN, USA
Offline Offline
Tesla Member
***
Karma: 72
Posts: 7171
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey FalconFour,

Long replies smiley

About the RadioShack platform vs. shield: I have a proto-shield that you can use to pass all arduino Duemilanove connections to a breadboard. I'm getting parts so that this shield can be stacked below any shield. This way you get the benefits of shields and breadboards.

http://liudr.wordpress.com/gadget/phi-connect/

This way you don't have to make all those jumper wire and screw blocks connections every time you connect your Duemilanove to the RadioShack platform.

It would be very nice to have the phi-2 shield run the front end of your system. The side of the phi-2 shield has two RJ45 connections to provide you 16 connections to anything. I'm making a 20X4 display version of the shield. Check it out in a few weeks. Besides, it also has a breakout connection to a popular GPS module, nice addition to your system smiley-wink

I was using Arduino IDE almost 100% time except when I edited my library files since Arduino IDE has no library editor.

You really worked very hard on your project! I only did it up to 2am, only because my wife was prep.ing for exams.

When I first started, I thought about a variable list but I dismissed it as "Not typical for most projects", well,  smiley-eek-blue
I'll put a RAM list in for the next revision, now that you have done it yourself. Most typically numbers are converted into strings before they become list items since most list implementations I know of return a number from 0 to number of item-1 so I'll add a RAM list but the contents are still your work to create. smiley-lol

On the other hand, if you have numbers that are evenly spaced out like 0,5,10,15, you can use integer with step of 5.

Right, the step is a menace right now, due to saving memory. My document covers it but is still not complete  smiley-cry 20 pages already. I've posted the incomplete version on my phi_prompt page. Check it out.

http://liudr.files.wordpress.com/2011/06/phi_prompt-documentation-20110523-incomplete.pdf

It's awesome that you managed to power through so much difficulty and made phi_prompt work for you! You got to post some videos!!

I wasn't aware that sometimes the buttons didn't release. Did you use internal pull-up resistors for the buttons? I didn't have any problems with tactile switches.

If you have phi_buttons bt1(pin_1,LOW) then the active state is LOW, just FYI.
Logged


Fresno, CA, USA
Offline Offline
Full Member
***
Karma: 1
Posts: 153
Arduino rocks (literally, with a WaveShield!)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yeah, I'd just been geeked out a bit with this whole interface thing... it just makes so much sense, it's practically addicting! Half the problem is still getting the values onto the screen the right way, or adapting the data types to the types it's expecting to see (like a pointer... to an array of pointers... to ROM locations that have the actual data, haha). On several occasions I had to make one-off sketches with serial output just as a quick-and-dirty way to figure out what it's actually returning in its values (Serial.print() is INCREDIBLY reliable and honest).

I've been extending the hell out of the simple little battery editor code... right now it has an address selector as well as auto-scan, a full embedded list of the commands (and descriptions) from the datasheet, timeout detection in many places, a crapload of input-smoothing, and... well... about that commands list! Yeah, I copied the names, codes, and return value modes of each of the ~40-odd controller commands, and put them in one huge 1x2 phi_prompt list. The return value of that menu is mapped to the 2-dimensional PROGMEM array of the commands' addresses and return types (like mAh, percent, string, etc). Then, a big switch() handles each case individually, writing to a buffer that's sent to the LCD at the end. Whoo. Best part is, it works! And people can add their own command sets with their own descriptions (just add new command IDs and add a new case in the tiny helper functions).

It compiles to 19kb now, the biggest Arduino program I'd ever written (which to me is a good thing since the poor ATMega chip never gets to use its upper flash area). 580 bytes in command descriptions and codes. And it seems pretty stable...

About the buttons though, it's not that they trigger on their own (and they're defined properly), it's just that wait_on_escape() exits its control when the button is still held down, which is also what's used to check for inputs on a new menu screen. So if that button's still being held down, it'll still accept that input on the new menu, even if that's within 50ms of pressing the button for the last screen. So I have to do a lot of "wait for the button to be released" hangs, which doesn't affect the UI speed at all (thanks to the way wait_on_escape() works), but just seems like kindova silly functionality-or-structure tradeoff smiley-wink

I think I'll try to do some videos right now... I just **FINALLY** got float-to-buffer conversion out of the way (seriously, AVR guys? No standard float-to-buffer function? I can lcd.print, or I can Serial.print, but I can't get that in-between step on its own?) after about 2 hours of tinkering with double and float types... and yeah, I actually got some infuriating compile errors about invalid conversion from double to float, even though it's the same thing here. Yugh. Man, data handling in this thing is a PITA. I'd think the compiler would be able to tell me information about the highest RAM address allocated in the program (i.e. how much memory will be "free") without finding out the hard way (thankfully, I haven't run into that yet).

Oh, and sorry for the long posts... I just like spilling everything. xD

edit: *clicks PDF*... *scrollll*... *headdesk*. Oh, I so coulda used that like 20 hours ago =P
Logged

Fresno, CA, USA
Offline Offline
Full Member
***
Karma: 1
Posts: 153
Arduino rocks (literally, with a WaveShield!)
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

As promised!
http://arduino.cc/forum/index.php/topic,62955.0.html

Now if I just had a way to create a list from generated strings... smiley-wink Next on my "oh, that'd be cool" list is an SD card interface where we could browse through the folder structure using the LCD... using it with the WaveShield, it could be a "holy crap, a single microcontroller is doing all that?!" party trick smiley-grin

I think one way we could use generated lists is with a single buffer delimited by >ASCII characters, like 0xFF. Or a buffer header indicating how many items to render from the buffer. Then use a select method to catch why the function returned (like, was left pressed to go to the next screen? draw more items... or was an item selected? do something with it, etc...). The program could quickly do whatever it needed with the buffer, then loop back to the menu ("phi_prompt_struct.low.i" is keeping track of the position anyway).

The selection list is definitely the most useful part I've seen so far... I don't often have a need to display text, because 32 characters isn't even a full phrase sometimes (plus, without word-wrap, the display admittedly looks kinda goofy), and I don't often need to prompt for a string. I mostly need to pick from a list of options, so I don't always have to watch over the serial console (which is how that battery program was originally designed).

I think the second-biggest request I've got for the library (buffer-generated lists being the first) is that scrolling item selections behave better... right now, the scroll is based on the timer clock, so every item unpredictably jumps around the screen when it's deemed necessary to scroll. Then, it scrolls the whole string off the screen before coming back on, so I often end up seeing "mation"... "ation"... "tion"... "ion"... *ugh* "on"... "n"... "A"... "Au"... "Aut"... "Auto"... "Autom"... /headdesk. It'd be less of an issue if the scroller left just 3 spaces between the end of the line before looping back over on itself, like "tion | Au"... "ion | Aut"... "on | Auto"... "n | Autom", etc. That'd be a nice fix smiley

Also, since custom characters can be updated while they're on-screen, creating a sort of animation effect, I think the scrollbar can be *very* much improved (not putting down what we already have, it's professional fare for most 16x2 devices I'd seen, which is great!) by procedurally generating the scrollbar characters instead of using static custom chars... for example, a custom char consists of 8 bytes of 5 bits each - copy a PROGMEM arrow-tip template to a char array of the same size, then write 0x1F to a series of bytes past the tip to indicate both the size of the content (may have to add another parameter to replace "percent", like "items" and "total"), as well as the scroll position. Then just lcd.createChar(0,modifiedChar); and the screen will immediately update smiley-grin

Just a few ideas...
Logged

Pages: [1] 2   Go Up
Jump to: