No announcement yet.

(still) Seeking simple keyboard object to Led digits routine

  • Filter
  • Time
  • Show
Clear All
new posts

  • (still) Seeking simple keyboard object to Led digits routine


    I have been catching up with the new library and the ease of commands associated with it. One thing I still can not visualize (through the Geni_Arduino language) is how to press several digits on a custom keyboard, creating a numeric string in my Arduino host that can be stored in a buffer and written back to an led digits widget.

    Paul, you alluded to such a procedure in the calculator demo but I am unable to extract the simple "press and store" features I am seeking from all of the math references in the calculator demo. The custom keyboard demo does not even begin to address communicating with/through a host to extract/process the information entered. Across all applications, it seems to me a keyboard ENTRY demo would have the widest application to those embarking on custom projects, as timing requirements are, pretty much, endemic across the world of applications.

    It seems most likely that a demo of this nature already exists and I, simply, am unaware of it. If it does not yet exist, is it because this is viewed as too difficult to demonstrate (unlikely) or not important enough to address? I doubt such a universal function contains proprietary coding.
    /Baran G Galocy/

  • #2


    I sent you a private message with my email which would greatly speed up our communications.

    The handleGenieEvent() of the calculator demo calls calculatorKey(keyboardValue) whenever a keyboard key is pressed. In calculatorKey(), the variable startNewNumber is set to True whenever it is time to begin collecting keyboard digits (that have been pressed) and building a new multi-digit number. A numeric keypress is detected with:

    if (isdigit (key)) // is the pressed key a digit? {
    The code that follows tests startNewNumber and sets the base conditions for the process to begin:

    if (startNewNumber) { startNewNumber = FALSE ; multiplier = 1.0 ; display = 0.0 ; }

    Note that "display" is set to 0.0 and multiplier is set to 1.0 for the first digit pressed. As such, the first key pressed (say a 9) is multiplied by the multiplier (1) and added to the variable "display". As each subsequent numeric key is pressed, the multiplier is multiplied by 10, thus "moving the digit" to the left. A test is also done when a zero is pressed to move the display over by a factor of 10. The following code does this:

    digit = (double)(key - '0') ; // The zero key was pressed if (multiplier == 1.0) // this is the second digit pressed so multiply "display" by 10 display = display * 10 + (double)digit ; else { display = display + (multiplier * digit) ; // Non-zero digit pressed multiplier /= 10.0 ; // increase multiplier by factor of 10 } updateDisplay () ; // Update the display with the updated "display" value return ;

    The rest of the calculatorKey() code deals with other keyboard keys that act on the accumulated "display" value such as squareroot, M+, etc.

    So now you have the "digit accumulator" code and all you need is the modify the other keypress code for your needs.

    I hope this helps!



    • #3
      Hi -- First, I know I saw the calculator demo at one time, but for the life of me I can't find it again... can someone remind me where it is?

      I need to do the exact same thing. Additionally I am trying to generalize my code to work with different cases and keyboards, e.g. one with a decimal point in the LED display and one for integers only (no DP). Based on the 'form' I'll know if I need to divide the displayed number by 1000 for a 3 digit decimal version. Right now I have a different 'form' for each case of digits behind the decimal, and integers only.

      If there is an easier or standard way of doing this I'd love to know. As far as I can tell there is no way to dynamically tell an LED digits where to put (or not) a decimal point. Maybe a hint to doing something like this is buried in the calculator demo? Is there maybe a trick to 'stack'ing LED digits and just 'show'ing the one needed from the stack, based on a decimal point entered??

      In looking at Paul's example snippet, the 'else' didn't make sense to me, especially with the '/=' which I thought must have been a typo (even though it looked like he copied and pasted).

      Every time a 'startNewNumber' occurs, multiplier gets assigned 1.0, and never changes if you don't get into the 'else'. As far as I can tell, you never enter the 'else'.

      I wrote a simple .c program (included below) to help me understand the logic of the digit accumulator. As far as I can tell the '0' detect line,

      digit = (key - '0')

      and the line in the if,

      display = display * 10 + digit

      because of the way c works, those seem to be the only lines that are actually needed.

      Can someone tell me what I am missing here?



      // keysToLED.c #include<stdio.h>#include<stdlib.h>#include<math.h>#include<stdbool.h> // prototypes void KeyboardNumber();void UpdateDisplay (); // globals bool startNewNumber;float multiplier = 3.0;float display = 17.0;char key;int digit; int main (){ while(1) { startNewNumber = true;printf("\nStart a new display number (x to restart, q to quit)\n>>"); while(1) {scanf( "%c", &amp;key );if (key == 'x')break;if (key == 'q')return 0; if (startNewNumber) {startNewNumber = false ;multiplier     = 1.0 ;display        = 0.0 ;} if ( isdigit(key) ) { // is the pressed key a digit?digit = (double)(key - '0');// The zero key was pressedprintf("digit = %d\n", digit); if (multiplier == 1.0)// this is the second digit pressed so multiply "display" by 10display = display * 10 + (double)digit ;else{display = display + (multiplier * digit) ;  // Non-zero digit pressedmultiplier /= 10.0 ;  // increase multiplier by factor of 10printf("..inside else and multiplier is %d\n", (int)multiplier);}UpdateDisplay () ;  // Update the display with the updated "display" valueprintf(">>");}} // end of while(1)} // end of while(1) to return to top of main() return 0;} // end of main()  void UpdateDisplay(){printf("display is now = %d  and multiplier is %d\n", (int)display, (int)multiplier);}


      • #4

        Duh, I finally (re-)found the calculator demo... it is not in one of the app notes, but out on GitHub...


        • #5

          Not sure which demo you are after, but if you go to github and search on 'genie calculator' you will find both.

          If you stack leddigits the one written to will always be on top, not sure how the demo does it.

          The code is definitely a bit sick.

          It al least needs something like (perhaps as an else to the isdigit())
          if (key == '.')
          multiplier = 0.1 ;

          to get it to, at least, look like it might work. Don't know what other bugs are in there.


          • #6

            Thanks again Mark. I found the calculator demo, and looked through the original code. I have my version working fine now. But...

            After trying to debug stuff for a while, trying to write to an LEDdigits of the fixed format, I finally realized there is a 2-byte/16-bit limitation on LEDdigits. I guess that should have been obvious by the msb/lsb, but it wasn't, at least not immediately. Duh.

            Unfortunately this isn't explicitly mentioned in the User Guide or Reference Manual. It is implied by the 2 byte format 0x0000 in the documentation, but never explicitly reinforced. I think it would be useful to mention it, since the LEDdigits object from Visi-Genie allows a user to create almost any size LEDdigits (I seem to be able to create one up to 33 digits on my µLCD-43PT), visually implying there must be some way to use them.

            The application notes (4D-AN-P4012 and 4D-AN-P4015) would be a great place to mention this, since 4D-AN-P4012 explicitly shows changing the number of digits to 6, clearly out of the range of decimal numbers possible (for 0x7FFF or 0xFFFF). Seems like most people getting up to speed on the 4D displays and Visi-Genie start with the application notes.

            Scouring the forums there is little mention of this limitation, or a way to work around it. There is a non-Visi-Genie thread suggesting someone has written 32-bit numbers to LEDdigits. But the rest of what is out there doesn't really just come out and say... "If you want to write a number larger than 2 bytes to an LEDdigits, don't. Use Strings instead. To convert floating points or longs use a c function like sprintf(), e.g.:

            sprintf(buffer, "%f", myFloat);
            --or-- sprintf(buffer, "%ld", myLong);
            As they say, two steps forward, one step back.



            • #7

              Here is an onscreen keyboard controlled from an external 9 button keypad interaction is created:


              also, if you are using Genie and floats or doubles try this: