MrDEB
Well-Known Member
Tumbleweed sent me this code which works BUT when the buzzer sounds the led 6 or 7 do not come on but the buzzer still sounsds.
Yes the leds do work. When a mismatch input is entered all the leds light up.
just a glitch in the code but?
code is using Swordfish basic from the Swordfish site which I can't acess since I installed Nortons. Tried numerious times.
Yes the leds do work. When a mismatch input is entered all the leds light up.
just a glitch in the code but?
code is using Swordfish basic from the Swordfish site which I can't acess since I installed Nortons. Tried numerious times.
Code:
//progran notes
//add a routine to increase / decrease speed of challenge
//added a s_core routine to track players progress
//s-core equals 0 after each game maaybe?
// need to add portA.4 for auto shutoff feature
Program simon
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"
Include "convert.bas"
// this option enables playing a tone when an led is turned on
// set it false to exclude using tone.bas
#option USE_TONE_LIB = true
#if (USE_TONE_LIB)
Include "TONE2.bas"
#endif
// 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
Dim INDEX As Byte
Dim note As Word
Dim NOTE_PAUSE As Word
Dim grats As Word
Dim wrong As Word
Dim S_core As Byte
Dim Duration As Word
Dim Auto_On As PORTA.4 //for auto on feature
// this option limits the max numbers of PORTB keys used, from 1-8
// if the ICSP programmer is connected, limit this to 6 (no RB6 or RB7)
#option MAX_NUM_KEYS = 8
#if Not (MAX_NUM_KEYS in (1 to 8))
#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 chars (button presses)
#option MAX_SEQ_LENGTH = 6
#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
// set initial number of sequences in the challenge
// normally, this would be set to 1, but if you want to start with
// a different number of challenges change this (up to MAX_SEQ)
Const START_SEQ = 1
//-------------------------------------
// subroutines and functions
//-------------------------------------
// given an ledno 1-8, turn it off (0) or on (>0)
// if ledno = 0 then set them all on or off
// optional: play a note when an led is turned on (#option USE_TONE_LIB=true)
Sub SetLED(ledno As Byte, onoff As Byte)
#if (USE_TONE_LIB)
Dim note As Word
Select (ledno)
Case 0
If (onoff > 0) Then
onoff = $FF
EndIf
LED_PORT = onoff
// note = NOTE_PAUSE
Case 1
LED0 = onoff
note = NOTE_A4
Case 2
LED1 = onoff
note = NOTE_D4
Case 3
LED2 = onoff
note = NOTE_C5
Case 4
LED3 = onoff
note = NOTE_F4
Case 5
LED4 = onoff
note = NOTE_A6
Case 6
LED5 = onoff
note = NOTE_B4
Case 7
LED6 = onoff
note = NOTE_A4
Case 8
LED7 = onoff
note = NOTE_D4
End Select
// if led is turned on then play the note for 500ms
If (onoff > 0) Then
tone2.play(note, 500)
tone2.wait()
EndIf
#else // don't use tone library
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
#endif // (USE_TONE_LIB)
End Sub
// flash an LED on-off with delay
Sub FlashLED(ledno As Byte)
Const FLASH_DELAY = 500 //use this to speed up or slow down led ON/OFF
SetLED(ledno, 1) // turn on the corresponding LED
DelayMS(FLASH_DELAY ) // wait a bit...
SetLED(ledno, 0) // and turn led off
DelayMS(FLASH_DELAY)
End Sub
// wait for a keypress and return key number, 1-8
// turns on LED while the key is pressed
Function GetKey() As Byte
Const KEY_BOUNCE_DELAY = 50 // msec delay for key bounce
// 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 the max number of supported keys
If (result > MAX_KEY) Then
result = 0
EndIf
Until (result <> 0)
// turn on the corresponding LED
SetLED(result, 1)
// now wait for all keys to be released
While ((SW_PORT And KEY_MASKS(MAX_KEY)) <> KEY_MASKS(MAX_KEY))
DelayMS(KEY_BOUNCE_DELAY)
End While
// wait a bit for any release bounce
DelayMS(KEY_BOUNCE_DELAY)
// turn off the LED
SetLED(result, 0)
End Function
// 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(reseed As Byte=0)
If (reseed = 0) Then
GLFSR = 1
LCG = 84
EndIf
LCG = reseed
GLFSR = LCG Xor $55 // just making the start values very different - not really important
If (GLFSR = 0) Then // except that GLFSR must not be zero
GLFSR=1
EndIf
End Sub
Sub C_grats() //use a counter to select congrat
Select (grats)
Case 0 WriteAt(1,1,"GOOD JOB")
DelayMS(2000)
Cls
Case 1 WriteAt(1,1,"GREAT JOB")
DelayMS(2000)
Cls
Case 2 WriteAt(1,1,"DOING GREAT!")
DelayMS(2000)
Cls
Case 3 WriteAt(1,1,"KEEP IT UP")
DelayMS(2000)
Cls
Case 4 WriteAt(1,1,"COLLEGE BOUND? ")
DelayMS(2000)
Cls
Case 5 WriteAt(1,1,"COLLEGE GRAD!")
DelayMS(2000)
Cls
Case 6 WriteAt(1,1," ANOTHER ")
WriteAt(2,1," EINSTEIN?")
DelayMS(2000)
Cls
Case 7 WriteAt(1,1,"YOU ARE")
WriteAt(2,1,"REALLY GOOD!")
DelayMS(2000)
Cls
End Select
DelayMS(2000) //time to read
grats = grats +1
If grats = 7 Then
grats = 0
// MAX_NUM_KEYS = MAX_NUM_KEYS +1
End If
End Sub
Sub IN_sults()
Cls
Select(wrong)
Case 0 WriteAt(1,1,"DID YOU EVEN")
WriteAt(2,1,"GO TO SCHOOL?")
DelayMS(2000)
Case 1 WriteAt(1,1,"ARE YOU BLIND?")
DelayMS(2000)
Cls
Case 2 WriteAt(1,1,"THIS GAME IS")
WriteAt(2,1,"TWO HARD 4 U!")
DelayMS(2000)
Cls
Case 3 WriteAt(1,1,"KEEP IT UP")
WriteAt(2,1,"YOU COULD BE")
DelayMS(1000)
WriteAt(1,1,"PRESINDENT")
DelayMS(2000)
Cls
Case 4 WriteAt(1,1," A DOG ")
WriteAt(2,1,"COULD DO BETTER!")
DelayMS(2000)
Cls
Case 5 WriteAt(1,1,"2ND GRADE GRAD!")
WriteAt(2,1,"DON'T THINK SO")
DelayMS(2000)
Cls
Case 6 WriteAt(1,1," ANOTHER ")
WriteAt(2,1," EINSTEIN?")
DelayMS(2000)
Cls
Case 7 WriteAt(1,1,"ZOMBIES EAT ")
WriteAt(2,1," BRAINS ")
DelayMS(1500)
Cls
WriteAt(2,1,"YOUR SAFE")
DelayMS(2000)
Cls
Case 8 WriteAt(1,1,"DID YOU SLIP ")
WriteAt(2,1,"INTO A COMA ?")
DelayMS(2000)
Cls
Case 9 WriteAt(1,1,"YOUR BIRTH ")
WriteAt(2,1,"CERTIFICATE")
DelayMS(1500)
Cls
WriteAt(1,1,"IS A DOCTORS ")
WriteAt(2,1," APPOLOGY ")
DelayMS(2000)
End Select
DelayMS(2000) //time to read
// wrong = wrong +1
//If wrong = 7 Then
//wrong = 0
'End If
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_KEY
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
Dim seq 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
// init tone module (if enabled)
#if (USE_TONE_LIB)
tone2.init()
#endif
//turn off all LEDs
SetLED(0, 0)
// wait for user to press a key
// use the response time to seed the random number generator
LCG = 0
LCD.WriteAt(1,1,"WELCOME TO ")
LCD.WriteAt(2,1," WICKED 8 ")
DelayMS(2000)
LCD.WriteAt(1,1,"press key 1-", MAX_KEY+Byte("0"), "...")
While ((SW_PORT And KEY_MASKS(MAX_KEY)) = KEY_MASKS(MAX_KEY))
LCG = LCG + 1
End While
initRND(LCG)
// check to see if there are initial seqs required
// if so then add random numbers to the challenge string
seq = 1
While (seq < START_SEQ) //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
n = GetRND() // get a new random number from 1 to MAX_KEY
AddToString(challenge, n) // add it to the challenge string
seq = seq + 1
//add a decremewnting routine with wrong answera
End While
initRND(LCG)
tone2.init()
NOTE_PAUSE = 0
grats = 0
wrong = 0
S_core = 8
Duration = 500
// do forever
While true
// start off with both strings empty
challenge = ""
user = ""
//turn off all LEDs
SetLED(0, 0)
For seq = START_SEQ To MAX_SEQ
// get a random number and add it to the challenge string
n = GetRND() // get a new random number from 1 to MAX_KEY
AddToString(challenge, n) // add it to the challenge string
// display the challenge seq so far
LCD.Cls
LCD.WriteAt(1,1,"challenge ", DecToStr(seq), "...")
DelayMS(1000)
LCD.WriteAt(1,1," COPY BUTTON ")
LCD.WriteAt(2,1," SEQUENCE ")
DelayMS(2000)
For i = 1 To seq
n = GetFromString(challenge, i)
FlashLED(n) // show rand number using LEDs
Next
// get user response
LCD.Cls
LCD.WriteAt(1,1,"enter ", DecToStr(seq), " keys...")
DelayMS(1000)
user = ""
For i = 1 To seq
n = GetKey() // get user keypress (shown on LEDs)
AddToString(user, n) // add it to the user response
// compare the current char as we go
// if no match then end this game and start a new one
If (GetFromString(challenge, i) <> n) Then //checks for match
SetLED(0, 1) // turn on all leds
DelayMS(1000)
SetLED(0,0) //turn off all leds
//S_core = S_core - 1 //when score hits 3 then game ends
Break //leave this routine
EndIf
Next
//add a S_core here so after 3 attempts the play ends
// compare the two strings to show match
LCD.Cls
If (challenge = user) Then
C_grats()
S_core = S_core+1 //ADD FOR CORRECT PRESS
Cls
LCD.WriteAt(1,1," VERY GOOD LETS ")
LCD.WriteAt(2,1," ADD SOME KEYS ")
DelayMS(1000)
Cls
LCD.WriteAt(1,1,"score : ",DecToStr( S_core))
DelayMS(3000)
//increment number of keys
Else
LCD.WriteAt(1,1,"WRONG MATCH")
wrong = wrong + 1
IN_sults()
DelayMS(2000)
S_core = S_core - 1 //decrimate SCORE FOR WRONG PRESS
'cls
'LCD.WriteAt(1,1,"score : ",dectostr( S_core))
// delayms(3000)
EndIf
'DelayMS(2000)
Next
//led0=(FLASH_DELAY)
// this game is over
// show the strings (up to 10 chars on a 16x LCD)
LCD.Cls
'LCD.WriteAt(1,1,"gen : ", challenge)
'LCD.WriteAt(2,1,"user: ", user)
'DelayMS(2000)
LCD.WriteAt(1,1,"score = ",DecToStr( S_core))
LCD.WriteAt(2,1,"INCORRECT = ",DecToStr( wrong))
DelayMS(3000)
End While
End Program