Post Reply 
Generic Calculator Shield for Arduino Photo-journal
03-24-2015, 07:50 PM
Post: #41
RE: Generic Calculator Shield for Arduino Photo-journal
Nice trick mattiaspaul.

I've found another link.

At first glance, it may support n-key rollover with only n diodes.
And using open collector I/O when available will ease software design (no need to select input or output !)

Regards.
JCH
Find all posts by this user
Quote this message in a reply
03-25-2015, 12:38 AM
Post: #42
RE: Generic Calculator Shield for Arduino Photo-journal
(03-23-2015 05:29 PM)matthiaspaul Wrote:  Well, Marcus, there are some rather "unorthodox" design decisions in your proposed solution...
hi matthias, good to hear from you... thank you for your ideas! The idea for this 'unorthodox' design is the kiss principle; keep it simple sweetheart!
(03-23-2015 05:29 PM)matthiaspaul Wrote:  The first is your choice of an analog readout of the keyboard. While this may work for a few keys, it would become unreliable if you'd need to work with more keys per row. Also, it needs hardware or software calibration or active compensation to make it work over a large batch and long time frame and with different voltages.
Not really. True, there needs to be enough resolution on the analog input, which of course the edison and the arduino do brilliantly. Mathematics (simple arithmetic) handles the callibration... even between 1v8, 3v3, and 5v. It works famously.
(03-23-2015 05:29 PM)matthiaspaul Wrote:  It is prone to EMI problems (you will get misreadings near EMI sources), is slow compared to a digital readout and it consumes more energy. All this would make it unsuitable for "commercial grade" applications in mobile devices like calculators, I'm afraid.
As I stated earlier, its is VERY unreliable (that's a given). This is a 'little' like TCP/IP... which is by definition a VERY unreliable protocol (that's the beauty of it). We compensate for the inherent flaws of the hardware (kiss principle) by creating quality firmware to handle the eventual and predictable failures... works famously, and keeps things very simple and easy to build (for DIY community).
(03-23-2015 05:29 PM)matthiaspaul Wrote:  I understand that you need to save I/Os, however, if the current board does not have enough I/Os, perhaps it's not the best possible choice for the job - after all, there are controllers with lots of I/Os.
Saving I|O lines on the Due or the Edison is not an issue... the issue is that this calculator shield is generic and general purpose... is being designed to run on multiple boards, with multiple firmwares (from 4 banger to programmable plotter).
(03-23-2015 05:29 PM)matthiaspaul Wrote:  While a typical keyboard matrix reduces the number of necessary I/Os for (N/2)^2 keys to N already, using some diode tricks you can increase the number of necessary keys to N^2-N.
Interesting idea. I am using four I|O lines and one interrupt line. Polling is not an option. Do you have a proposed schematic; more details would be good.
(03-23-2015 05:29 PM)matthiaspaul Wrote:  Since you are following a distributed controller paradigm anyway, you might also have a look at dedicated keyboard matrix scanner ICs to reduce the number of necessary I/Os on your main controller.
This is a good idea... a dedicated AVR for keyboard handling is essentially the way all PC keyboards work...
(03-23-2015 05:29 PM)matthiaspaul Wrote:  On the software side, you should better draw a clear line between code executed inside and outside of interrupt context. . . stuff the read values into a circular buffer and leave the evaluation and interpretation of the values in the ring buffer to code executed outside interrupt context, so it won't block anything.
Yup. The actual interrupt routines are far from 'ready'. My simple 'driver' code is meant only as proof of concept on a very simple, if 'unorthodox' approach to click-button key encoding. There will be scads of revisions along the way, I'm sure of that.

Thanks again, I'll keep all of this in mind... and I'm gonna want to investigate the diode idea. Thanks.

Cheers,
marcus
Smile

Kind regards,
marcus
Find all posts by this user
Quote this message in a reply
03-25-2015, 01:12 AM (This post was last modified: 03-25-2015 01:20 AM by MarkHaysHarris777.)
Post: #43
RE: Generic Calculator Shield for Arduino Photo-journal
(03-12-2015 07:23 AM)Marcus von Cube Wrote:  
(03-11-2015 10:58 PM)MarkHaysHarris777 Wrote:  But still, even at that, with all 24 bars 'ON' my little display is drawing about 184 mA. Even limiting the current a dual twelve digit seven seg display would draw a little more than 1.3 amp---
I'm not aware of any seven segment display device that is not multiplexed. The human eye is so slow that you will not notice a flicker unless you move the device in front of you. Multiplexing will reduce the power requirements to what a single digit or segment (depending how far you go with multiplexing) draws.

Greetings, well, its Christmas at my house again (also with lights!) as some kind soul has shipped to me (free as in free beer!) a pair of JTRON PN297686 8 digit seven segment multiplexed display units utilizing two(2) 74HC595 built-in shift registers. I'm very impressed that I may actually have a workable solution to my proposed Wang 700c replica (in the sometime near future, but that's another story).
This little display draws a whopping 12 mA with all bars on (multiplexed) and although flickering slightly can be maintained by the Raspberry PI (while doing other things). If I actually put them in my Royal (and I might) I will program an Atmega328 AVR dedicated to the job of MCU over these little gems. A BIG FAT 'Thank You!' to whomever sent these beauties to me... they arrived in the mails yesterday, and I spent some hours over-night writing some python code to handle them. Hi-res pics first, and some code... then some comment:

[Image: raspberry-smiles2.jpg] [Image: raspberry-counting2.jpg]

You can read my seven segment python driver code on-line, or in-line here:

Code:

########################################################################
# JTRON PN297686   2x595 Multiplexed Seven Segment LED Display Driver
#
# jtrondrv.py
#
#   Mark H. Harris
#   24 March, 2015
#
########################################################################
#
#   This sample python code is written for the Raspberry PI b+. 
#
#    author:     Mark H. Harris         harrismh777@gmail.com
#   license:     GPLv3
#
#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
#   CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
#   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
#   MECHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
#   DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#   SPECIAL, EXEMPLARY, OR CONSEQUENCIAL DAMAGES (INCLUDING, BUT
#   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
#   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERUPTION)
#   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
#   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
#   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE
#   EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
########################################################################
#
#   The JTRON PN297686 is an 8 digit multiplexed LED seven segment display
#   utilizing two 74HC595 shift registers, in a small form factor measuring
#   7cm x 2cm x 1cm. The display requires an external MCU of some type (this
#   driver code running on a Raspberry PI) including Arduino type AVR, or
#   other. The display expects a serial write of 16 bits, the high order byte
#   of which is the segment(s) bar code (see digitROM) for displaying the
#   charcter, and the low order byte of which is the digit select; that is
#   which digit will 'turn on'. The bars are cathode, so 1 is off, 0 is on.
#   The digit select is hight order bit(left digit) low order bit(right digit).
#   This sample code logically inverts segments so that the 1's in the digitROM
#   are 'ON' codes. The high order bit is the decimal point, and the other
#   bits follow according to standard with segments g; f; e; d; c; b; a. To
#   turn on the decimal point logically 'OR' the digitROM code with 0x80.
#   The serial write of 16 bits is shifted in high order first. As an example
#   digit code, then position. The code 0x6d80 will display a '5' in the 'first'
#   leftmost digit. (see digitROM below)
#   The MCU must refresh the display constantly. The quicker this occurs the
#   less flicker will occur and the more even the display brightness will be,
#   At any one time only one digit is being powered, but vision persistance
#   makes them appear as if all digits are 'ON' at once. Now a bit about the
#   display pins.
#   Vcc is 3v3 supplied from the Raspberry PI (DO NOT USE the 5v Supply!). Gnd
#   is ground potential. SCLK is the SPI clock (this is the clock that shifts
#   the bits into the display registers. RCLK is the 'latch' strobe pulse; on
#   leading edge signal the registers 'latch' their inputs to the LED bar
#   outputs. DIO is the data I|O pin. These pins are defined further in the
#   code below.
#
#   This is sample code only. Please don't email me and tell me all the things
#   that are wrong with it, how insecure it is, and how best to improve it. It
#   is provided in the hopes that it will help someone else make use of this
#   display with a minimal headache.
#
#   Once the module is imported (an 8 will walk across the display) dispPI() will
#   display the value of PI (you will notice some flicker). The routine called
#   decimalCounter(1000000) will start a counter up to the number you set. There
#   is less flicker here since leading zeros are supressed and less digits are
#   'ON' initially.
#
#   enjoy!  mhh
#
########################################################################


# Get the Raspberry PI GPIO library, to use RPi IDLE3 must be run as sudo
import RPi.GPIO as GPIO
import time

# These are the three magic SPI BCM pins for the JTRON display
# SPI clocking, GPIO BCM pin numbering
sClockPin = 20
# Latch enable, 'latches' register inputs to outputs
rClockPin = 22
# Data I|O, bits are shifted in here
dioPin = 24

# This python dictionary contains the segment codes for the digits 0-9
#    (you, of course, could add hex codes too ! )
digitROM = {0:0x3f,1:0x06,2:0x5b,3:0x4f,4:0x66,5:0x6d,6:0x7d,7:0x07,8:0x7f,9:0x67}

# Initialize the GPIO of the Raspberry PI
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)

# Set the SPI pins for output
GPIO.setup(sClockPin, GPIO.OUT)
GPIO.setup(rClockPin, GPIO.OUT)
GPIO.setup(dioPin, GPIO.OUT)

# This routine provides the clock pulse 'strobe' that shifts in a single bit
def sClock(clockPin):
    GPIO.output(clockPin, 1)
    time.sleep(0.000030)
    GPIO.output(clockPin, 0)

# This clock pulse 'latches' the shift register inputs to the LED outpus
def rClock(clockPin):
    GPIO.output(clockPin, 1)
    time.sleep(0.000010)
    GPIO.output(clockPin, 0)

# Here we are actually shifting xvalue into the shift registers, which is
# accomplished in two 8 bit writes, the first (high order) is the digit, and
# the second (low order) is the position...
def binDisplay(xvalue, dio, sClk, rClk):
    binDigit = int(0x8000)
    for n in range(8):
        if (int(xvalue) & int(binDigit)):
            GPIO.output(dio, 0)
        else:
            GPIO.output(dio, 1)
        sClock(sClk)
        binDigit /= 2
    binDigit = int(0x0080)
    for n in range(8):
        if (int(xvalue) & int(binDigit)):
            GPIO.output(dio, 1)
        else:
            GPIO.output(dio, 0)
        sClock(sClk)
        binDigit /= 2
    rClock(rClk)

# binDisplay() driver used to simply the call in the code elsewhere
def bDisplay(xvalue):
    binDisplay(xvalue, dioPin, sClockPin, rClockPin)

# digit display using digitROM.  dispDigit(7,2) will display a '7' in
#    position 2, numbered from the left at 1.
def dispDigit(digitVal, digitPos):
    if (digitPos==8):
        xvalue=int((digitROM[digitVal]*256 | 0x8000) + 2**(digitPos-1))
    else:
        xvalue=int(digitROM[digitVal]*256 + 2**(digitPos-1))
    binDisplay(xvalue,dioPin, sClockPin, rClockPin)

# This code will display a decimal value using a refresh counter 'scanVal'
# to loop quickly through the digits (yes, there is flicker). Some of the
# refresh 'looping' is shared by the decimalCounter() and some is here...
# Ultimately, a dedicated MCU should refresh these displays.  An Arduino
# type AVR should have the job of keeping the display active, while getting
# serial data for display from external... another project.
def decimalDisp(dValue, scanVal):
    dTemp=dValue
    for m in range(scanVal):
        zeroFlag=0
        dValue=dTemp
        for n in range(8,0,-1):
            tens=int(dValue//(10**(n-1)))
            if (not zeroFlag and tens>0):
                zeroFlag=-1
            rmdr=int(dValue%(10**(n-1)))
            if (zeroFlag):
                dispDigit(tens, n)
            dValue=rmdr

# Our counter will count up to dValue. This loops through the numbers in
# range, calling decimalDip(number, 15) for a display refresh scanVal of 15.
# This is 'one' way to do this, not the best, but we have no dedicated MCU.
def decimalCounter(dValue):
    for n in range(dValue):
        decimalDisp(n, 15)
    bDisplay(0x0000)

# On initialization this code 'walks' an '8' with decimal point across the
# display. This 'resets' the display and tests the digits 'al on' condition.
def testDigits():
    rClock(rClockPin)
    for n in range(16):
        sClock(sClockPin)
    rClock(rClockPin)
    binDigit=int(0x80)
    for n in range(8):
        digit=int(0xff00 + binDigit)
        bDisplay(digit)
        binDigit /=2
        time.sleep(0.50)
    bDisplay(0x0000)

# self explanatory
def clearDisplay():
    bDisplay(0x0000)

# self explanatory
def dispPI():
    while True:
        decimalDisp(int("31415927"), 15)

testDigits()

To actually use these little gems requires programming a dedicated AVR that handles the 'large' data shift register internally and also handles the fast display refresh; a dedicated ATmega328 would do very nicely. Its on my back burner.

Thanks again to the person who sent these displays to me. I really appreciate it.. and I've had a ton of fun working with them. Somebody at the Raspberry PI foundation will appreciate it too, I'm sure... passing the part numbers and python code along for somebody to enjoy. Thanks!

Cheers,
marcus
Smile

Kind regards,
marcus
Find all posts by this user
Quote this message in a reply
04-09-2015, 01:00 PM (This post was last modified: 04-09-2015 01:10 PM by MarkHaysHarris777.)
Post: #44
RE: Generic Calculator Shield for Arduino Photo-journal
Greetings, you can review post 34 and 35 for the back-story... I have updated the analog keyboard somewhat (taking Matthias' comments to heart, regarding the hardware reliability and the interrupt handler complexity); the hardware is now very reliable, and the interrupt handler is now very simple.
The schematic and basic idea have not changed; however, I compressed the voltage divider some (replaced 1k at the top end with 3 k). The biggest change is the addition of a one-shot interrupt pulse generator via a 555 timer circuit. I reworked the bread-board with hi-res Fritzing to make things a bit clearer:

[Image: GenericCalculatorAnalogKeyboard-bb2.jpg]

Essentially, the LM339 (shared by all four input lines) 'senses' when the keyboard is pressed and sends a ground-shot to pin 2 of the 555 timer. The 555 has been setup as a one-shot monostable circuit which, when triggered, produces a *very clean* rising edge interrupt strobe of about 235 mS. The RC circuit is a 2M resistor into a .05 mF cap. The output on 555 pin 3 eliminates contact bounce for the interrupt completely and gives the Edison a very nice hysteresis which has so far by my testing been flawless.

Green lines on the pic are ground potential while red are Vcc 5v. The orange lines are the comparison lines from the voltage divider, the yellow line is the trip wire to the 555, the white line is the interrupt line to the Edison --to read the ADC block (via i2c), and the blue line(s) is sense-data line read in by the interrupt handler.

The interrupt routine with this mod does only two thing very rapidly: 1) sets the key analog registers for later, and sets a flag in my i2c_bus struct, then blows out. A later routine sees the flag, and processes the command line|key entry /

I will include the code, a screen shot or two, and some tips|updates relevant to the Edison on my other blog|journal. As for the Arduino(s) its a fairly easy analog read --- the blue line goes to A5 on the Arduino and the Arduino pulls back a number between 0 - 1023. On the Edison things are a little dicier since it has not got an on-board ADC block... we need to read the ADC via i2c, and that's fairly tricky.

PS I'm really pumped about the analog keyboard at this point... only two lines (not counting Vcc and gnd) and absolutely reliable; so, unorthodox or not, I'm going with it--- its going to be way cool.

Cheers,
marcus
Smile

Kind regards,
marcus
Find all posts by this user
Quote this message in a reply
04-23-2015, 06:22 AM (This post was last modified: 04-23-2015 06:23 AM by MarkHaysHarris777.)
Post: #45
RE: Generic Calculator Shield for Arduino Photo-journal
Greetings, I have begun work on the actual analog keyboard and hope to be testing on both the Arduino and the Edison by the weekend, or early next week... The red-boards are still back-order from Sparkfun so I may have to punt and either make my own, or find another vendor who can deliver them.

I am also taking a look at the recommended LCD and keyboard scanner IC from Texas Instruments / that little guy might be promising at some point. But I'm getting ahead of myself somewhat because I need to become an expert at reflowing my own Hirose 70 pin connectors, without becoming a full lab. I've been talking to guys who have converted a toaster; one guy uses a fry pan... and Dave F on this site said that the convection oven will be just fine... (and I need a test bed... )

I have continued to test with the analog keyboard prototype (that thing is stable, solid, and error free). The worst I have been able to 'make' it do is to fail to register a keystroke when hit fast and also very close together; I'll put it this way... my HP35s and my WP34s both fail more frequently than the analog prototype board, under the same conditions! I'm beginning to think that the prototype board may actually be able to roll-over and buffer keystrokes (if that were necessary). The interrupt mechanism has not failed (since adding the 555 timer). ... since the time of the output pulse is not really critical I think I can get by with ceramic caps.

Cheers,
marcus
Smile

Kind regards,
marcus
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 3 Guest(s)