MrDEB
Well-Known Member
MAKING SOME PROGRESS
it runs but it drops some of the leds on the challenge (not enabled)
got several MATCHES but I addd to the DELAYS and added CLS before writing to LCD.
changed the number of challenge helped but still not right. leds donot concide with the challenge. Seems to miss the 5th led/button combo
it runs but it drops some of the leds on the challenge (not enabled)
got several MATCHES but I addd to the DELAYS and added CLS before writing to LCD.
changed the number of challenge helped but still not right. leds donot concide with the challenge. Seems to miss the 5th led/button combo
Code:
{
*****************************************************************************
* Name : UNTITLED.BAS *
* Author : [select VIEW...EDITOR OPTIONS] *
* Notice : Copyright (c) 2021 [select VIEW...EDITOR OPTIONS] *
* : All Rights Reserved *
* Date : 11/4/2021 *
* Version : 1.0 *
* Notes : *
* : *
*****************************************************************************
}
device = 18F43K22
clock = 16
// int osc and IO pin libraries
include "intosc.bas"
#option DIGITALIO_INIT = true // automatically call setalldigital
include "setdigitalio.bas"
// lcd
#option LCD_DATA = PORTD.4
#option LCD_RS = PORTD.2
#option LCD_EN = PORTD.3
include "LCD.bas"
// hardware
dim SWT0 as PORTB.0
dim SWT1 as PORTB.1
dim SWT2 as PORTB.2
dim SWT3 as PORTB.3
dim SWT4 as PORTB.4
dim SWT5 as PORTB.5
dim SWT6 as PORTB.6
dim SWT7 as PORTB.7
dim SW_PORT as PORTB
dim LED0 as PORTC.0
dim LED1 as PORTC.1
dim LED2 as PORTC.2
dim LED3 as PORTC.3
dim LED4 as PORTC.4
dim LED5 as PORTC.5
dim LED6 as PORTC.6
dim LED7 as PORTC.7
dim LED_PORT as PORTC
// this option limits max numbers of PORTB keys, from 1-8
// if the ICSP programmer is connected, limit this to 6 (no RB6 or RB7)
#option MAX_NUM_KEYS = 4
#if not (MAX_NUM_KEYS in (1 to 4))
#error MAX_NUM_KEYS, "MAX_NUM_KEYS must be 1-8"
#endif
const MAX_KEY = MAX_NUM_KEYS
const KEY_MASKS(9) as byte = ($00, $01, $03, $07, $0F, $1F, $3F, $7F, $FF)
// this option controls the max length of the challenge sequence, from 1-23
#option MAX_SEQ_LENGTH = 4
#if not (MAX_SEQ_LENGTH in (1 to 23))
#error MAX_SEQ_LENGTH, "MAX_SEQ_LENGTH must be 1 to 23"
#endif
const MAX_SEQ = MAX_SEQ_LENGTH
//-------------------------------------
// subroutines and functions
//-------------------------------------
// wait for a keypress and return key number, 1-8
function GetKey() as byte
// wait for a key press
repeat
if (SWT0 = 0) then
result = 1
elseif (SWT1 = 0) then
result = 2
elseif (SWT2 = 0) then
result = 3
elseif (SWT3 = 0) then
result = 4
elseif (SWT4 = 0) then
result = 5
elseif (SWT5 = 0) then
result = 6
elseif (SWT6 = 0) then
result = 7
elseif (SWT7 = 0) then
result = 8
else // no valid key press
result = 0
endif
// limit response to max number of supported keys
if (result > MAX_KEY) then
result = 0
endif
until (result <> 0)
// now wait for any/all keys to be released
while ((SW_PORT and KEY_MASKS(MAX_KEY)) <> KEY_MASKS(MAX_KEY))
delayms(50)
end while
// wait a bit for release bounce (for next time)
delayms(50)
end function
// given an ledno 1-8, turn it off (0) or on (>0)
// if ledno = 0 then set them all on or off
sub SetLED(ledno as byte, onoff as byte)
select (ledno)
case 0
if (onoff > 0) then
onoff = $FF
endif
LED_PORT = onoff
case 1
LED0 = onoff
case 2
LED1 = onoff
case 3
LED2 = onoff
case 4
LED3 = onoff
case 5
LED4 = onoff
case 6
LED5 = onoff
case 7
LED6 = onoff
case 8
LED7 = onoff
end select
end sub
// given a number n=1-8, convert it to a char and append it to the string s
sub AddToString(byref s as string, n as byte)
dim ch as char
ch = n + byte("0")
s = s + ch
end sub
// given a string s and an index n=1-8, get the char value
function GetFromString(byref s as string, n as byte) as byte
dim ch as char
// convert n to 0-based index
if (n > 0) then
n = n - 1
endif
// get nth char from string
ch = s(n)
// convert numeric char to value 0-9
result = byte(ch) - byte("0")
end function
// random number generator
// based on https://www.sfcompiler.co.uk/wiki/pmwiki.php?n=SwordfishUser.PseudoRandomNumberGenerator
dim LCG,GLFSR as byte
sub initRND()
GLFSR = 1
LCG = 84
end sub
function GetRND() as byte
// init rand (just in case)
if (LCG = 0) or (GLFSR = 0) then
initRND()
endif
'LCG
LCG=(7*LCG+17)
'Galios LFSR
if (GLFSR and 1) = 1 then
GLFSR = GLFSR xor 135 '135 is the tap
GLFSR = (GLFSR >> 1) or $80
else
GLFSR = (GLFSR >> 1)
endif
result = GLFSR xor LCG
// for our application we want a number from 1 to MAX_KEYS
result = (result mod MAX_KEY) + 1
end function
//-------------------------------------
// main program variables
//-------------------------------------
dim challenge as string // challenge pattern
dim user as string // user input
dim i as byte
dim n as byte
//-------------------------------------
// start of main program
//-------------------------------------
main:
// init hdw
TRISC = 0 // LED port - all outputs
TRISB = $FF // SW port - all inputs
WPUB = $FF // PORTB pullup mask - all PORTB pullups
INTCON2.bits(7) = 0 // RBPU bit - turn on pullups
//turn off all LEDs
SetLED(0, 0)
// init random number generator
initRND()
// do forever
while true
// start off with both strings empty
challenge = ""
user = ""
cls
// generate a random 8-char challenge string
// as the string is generated, light the LEDs
lcd.writeat(1,1,"challenge...")
for i = 1 to MAX_SEQ
n = getRND() // get a new random number from 1 to 8
AddToString(challenge, n) // add it to the challenge string
SetLED(n, 1) // turn on the corresponding LED
delayms(1000) // wait a bit...
SetLED(n, 0) // and turn led off
next
// get user response
cls
lcd.writeat(1,1,"enter keys...")
for i = 1 to MAX_SEQ
n = GetKey()
AddToString(user, n) // add it to the user response
SetLED(n, 1) // turn on the corresponding LED
delayms(500) // wait a bit...
SetLED(n, 0) // and turn led off
next
cls
// compare the two strings
if (challenge = user) then
lcd.writeat(1,1,"match")
delayms(2000)
else
lcd.writeat(1,1,"NO MATCH")
delayms(2000)
endif
delayms(2000)
cls
// show the two strings
lcd.writeat(1,1,"challenge", challenge)
lcd.writeat(2,1,"user", user)
delayms(3000)
end while
end program