Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

SIMON game with more umph!

Status
Not open for further replies.

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.
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
 
The original seemed to work ok for me, and I don't see anything in the changes you made that would effect the keys/leds.

Attached is a simple key/led test program that uses the same routines as that program.
When you press a key the LED should turn on and stay on while the key is pressed.
Once you release the key, a half-second later that same LED should flash again.

Run it and see what happens.
 

Attachments

  • mrd_ledkey.bas
    4.3 KB · Views: 218
HERE IS THE SCHEMATIC I ran a simple port test and something is wrong. need to recheck my wiring as one of the three boards works as planed but only when battery power is supplied. Going to jumper around the auto ON/off circuit.**broken link removed**
 
After I made circuit changes (removed the ON/OFF componets and rerouted Vcc.
All seams to work now.
 
What sort of help do you want?
I have pcboard files as well as the swordfish files.
I built several and everyone I gave a game to enjoys it. Even my 2 year old grandson as well as a 7 year old that had a brain tumor and he does not function as a 7 year old but he has improved his eye hand cordination using this version of my enhanced game version.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top