Shop OBEX P1 Docs P2 Docs Learn Events
Storing value from Keypad — Parallax Forums

Storing value from Keypad

Hello all,

I am trying to use the keypad membrane to change a temperature ('Setpoint') which would be a 3 digit number. I am unsure how to do this, it would be a matter of displaying what ever the user inputs on the keypad onto the LCD and once they press the new temperature in, to use the value as the new temperature ('Setpoint'). All help is welcomed!

Here is what I have so far

' {$STAMP BS2}
' {$PBASIC 2.5}


' -----[ Title ]-----------------------------------------------------------
' Process Control - IncubatorOnOff.bs2

' -----[ Declarations ]----------------------------------------------------
ADC_ByteValue VAR Byte ' Analog to Digital Converter data
V_Offset VAR Word ' Temperature/voltage for ADC offset
V_Span VAR Word ' Temperature/voltage for ADC Span
TempF VAR Word ' Calculated temperature in hundredths
SetPoint VAR Word ' Heater control setpoint
ADC_CS PIN 13 ' ADC Chip Select pin
ADC_Clk PIN 14 ' ADC Clock pin
ADC_Dout PIN 15 ' ADC Data output
ADC_VRef PIN 10 ' Filtered PWM for ADC Vref

ADC_Vminus PIN 11 ' Filtered PWM for ADC Vminus
Heater PIN 8 ' Incubator heater
Fan PIN 12 ' Incubator cooling fan

row         VAR  Nib                        ' Variable space for row counting
column      VAR  Nib                        ' Variable space for column counting
keypad      VAR  Word                       ' Variable space to store keypad output
keypadOld   VAR  Word                       ' Variable space to store old keypad output
temp        VAR  Nib                        ' Variable space for polling column states

' -----[ Initialization ]--------------------------------------------------
LOW Heater ' Ensure heater off
LOW Fan ' Ensure fan off
PAUSE 1000 ' Allow connection to stabilize with StampPlot
SEROUT 9, 84,[22, 17]
'GOSUB ReadSP_Span ' Read StampPlot for ADC
SetPoint = 10100
V_Offset = 70
V_Span = 50

' -----[ Main Routine ]----------------------------------------------------
DO
' GOSUB ReadSP_Controls
GOSUB DriveFan
GOSUB DisplayLCD
GOSUB UserInput
GOSUB SetADC
GOSUB ReadADC
GOSUB CalcTemp
GOSUB Drive_Heater
PAUSE 500
LOOP

' -----[ Subroutines ]-----------------------------------------------------

ReadSP_Span: ' On connection, get ADC range
DEBUG CR,"!READ (txtTMin)",CR ' Request/store offset
DEBUGIN DEC V_Offset
PAUSE 50
DEBUG "!READ [(txtTMax),-,(txtTMin)]",CR ' Request/store Span (Max-Min)
DEBUGIN DEC V_Span
PAUSE 50
RETURN

ReadSP_Controls:
DEBUG "!READ [(txtSetPoint),*,100]",CR ' Obtain setpoint in hundredths
DEBUGIN DEC SetPoint
PAUSE 50
DEBUG "!READ (swFan)",CR ' Request/control Fan state
DEBUGIN Fan
PAUSE 50
RETURN

SetADC:
PWM ADC_Vminus, V_Offset * 255/500,100 ' Set Voltage for ADC Vminus
PWM ADC_Vref, V_Span * 255/500,100 ' Set voltage for ADC Vref
RETURN

ReadADC: ' Read ADC 0831
LOW ADC_CS ' Enable chip
SHIFTIN ADC_Dout, ADC_Clk, MSBPOST,[ADC_ByteValue\9] ' Clock in ADC data

HIGH ADC_CS ' Disable ADC
RETURN

CalcTemp: ' Transfer function for temperature in hundreths
TempF = (V_Span * 100)/255 * ADC_ByteValue + (V_Offset * 100)
RETURN
Drive_Heater:
IF TempF > SetPoint THEN ' Determine heater state
LOW Heater ' Above setpoint - Heat off
ELSE
HIGH Heater ' Below setpoint - Heat on
ENDIF
RETURN


DriveFan:
IF TempF > (SetPoint + 300) THEN
  HIGH Fan
ELSE
  LOW Fan
ENDIF
RETURN

DisplayLCD:
SEROUT 9, 84, [128,"Set Point:", 138, DEC5 SetPoint, 148,"Temp:",154, DEC5 TempF]
RETURN


' -----[ Subroutine - ReadKeypad ]-------------------------------------------------
' Read keypad button states
ReadKeypad:
  keypad = 0
  OUTL   = %00000000                        ' Initialize IO
  DIRL   = %00000000

  FOR row = 0 TO 3
    DIRB = %1111                            ' Set columns (P7-P4) as outputs
    OUTB = %0000                            ' Pull columns low (act as pull down)
    OUTA = 1 << Row                         ' Set rows high one by one
    DIRA = 1 << Row

    temp = 0                                ' Reset temp variable to 0
    FOR column = 0 TO 3
      INPUT (column + 4)                    ' Set columns as inputs one by one
      temp = temp | (INB & (1 << column))   ' Poll column state and store in temp
    NEXT

    keypad = keypad << 4 | (Temp REV 4)     ' Store keypad value
  NEXT
RETURN

UserInput:
GOSUB ReadKeypad
    IF Keypad.BIT12 THEN                    ' If "A" is pressed
    GOSUB ChangeTemp
    ENDIF
RETURN

ChangeTemp:
SEROUT 9,84,[148,"Input Temp"]

RETURN

Comments

  • I would start out by making sure I knew what ReadKeyPad returned.
    do
    gosub readkeypad
    debug BIN16 keypad, CR
    LOOP
    

    Now I would know how to interpret the value that ReadKeyPad returns in keypad

    Then I would write a subroutine
    GetTempFromKeyPad
    GOSUB ReadKeyPad
    MyTemp = 100 * ****interpreted value from keypad
    GOSUB ReadKeyPad
    MyTemp = MyTemp + 10 *  ***interpreted value from keypad
    GoSub ReadKeyPad
    MyTemp = MyTemp + ***interpreted value from keypad
    

    I would call my new routine instead of the debugin statement where you get a new set temperature.
  • How would I interpret the binary output that is produced from the keypad? So far I only need a range of 100- 105... If I can get a range of 95 to 105 it would be better.
  • It will have one bit set to '1' corresponding to the key that is pressed. That's what I was talking about in the first code fragment. Run that and see what the key/bit correspondence is. Then you will be able to interpret the result using, for example, LOOKDOWN.
  • Thank you for the help tomcrawford, it worked.
Sign In or Register to comment.