Menu

problems with compileing

Help
2008-02-16
2013-05-30
  • Nobody/Anonymous

    I have a 5x5 LED matrix multiplexed with a 5x5 switch array (so i only use 15 pins to run both the LED's and read the switches)
    the problem i have is when I try to compile my code.

    for switch = 1 to 5
    switchr + 1 = switchr
    set row(switchr) hi 'Array/Function ROW has not been declared & Missing bit in SET command
    if col1 hi then light1 = 1
    if col2 hi then light2 = 1
    if col3 hi then light3 = 1
    if col4 hi then light4 = 1
    if col5 hi then light5 = 1
    for ledchk = 1 to 5
    ledr + 1 = ledr
    set led(ledr) hi 'Array/Function ROW has not been declared & Missing bit in SET command
    if light1 = 1 then set led1 hi else set led1 lo
    if light2 = 1 then set led2 hi else set led2 lo
    if light3 = 1 then set led3 hi else set led3 lo
    if light4 = 1 then set led4 hi else set led4 lo
    if light5 = 1 then set led5 hi else set led5 lo
    set led(ledr) lo 'Array/Function ROW has not been declared & Missing bit in SET command
    next
    set row(switchr) lo 'Array/Function ROW has not been declared & Missing bit in SET command
    next

    now, the code should set 1 row hi and keep all others lo, then read each col. After that it should set the correct led hi and continue on the loop, but for some reason im getting both set errors and variable not defined errors.
    obviously it doesn't like how im setting the rows and led's, but i don't know how to code it correctly...

     
    • Hugh Considine

      Hugh Considine - 2008-02-22

      The problem is with the way you're selecting the rows. There is no way to fill an array with references to pins.

      There are a couple of ways you could solve this. If the pins you're using to select the row are not all on the same port, you'll need some code like this:

      switchr += 1
      Select Case switchr
      Case 1: Set RowPin1 On
      Case 2: Set RowPin2 On
      Case 3: Set RowPin3 On
      Case 4: Set RowPin4 On
      Case 5: Set RowPin5 On
      End Select

      Where RowPin1 through 5 are constants specifying the pins used. This code would go at the start, where "set row(switchr) hi" is now. You'd need to copy, paste and alter it to suit in the other places where the row is selected.

      If the row select pins are all next to each other on one port, you could also use the rotate command. This would be faster and take up less space, but it might not be suitable depending on the pinout you've used.

       
    • Nobody/Anonymous

      My rows are on pins portb.0-portb.4 on a 16F877A
      I got it to compile correctly when I made each row it's own subroutine (uses a lot more space then id like though)
      How would I get the rotate command to work? (preemptive question since im not at my main computer right now)

       
    • Hugh Considine

      Hugh Considine - 2008-02-23

      Something like this would be suitable:

      RowMask = 1
      For switch = 1 to 5
        PORTB = PORTB And b'11100000' Or RowMask
        Set STATUS.C Off
        Rotate RowMask Left

      ...

      Next

      The And clears all of the bits in PORTB except for the three on the left (7, 6 and 5). The Or then sets one of the bits in PORTB high, depending on the value of RowMask. STATUS.C needs to be cleared, or ones could be rotated in to the right hand side (bit 0) of RowMask by the Rotate command.

      This will start out with PORTB.0 high, then PORTB.1, and so on. To make it go the other way, change the first line to "RowMask = 32", and have the Rotate command rotate right instead of left.

      The downside to this approach is that you'll always need to keep the row pins together, but if this is not a problem then this code is far better.

       
    • Nobody/Anonymous

      Ok so, i have 2 questions for you now (im a beginner, please forgive my newbness)

      Im guessing the workings of the code you posted go like this (sorry to re-state what you just said, but i want to be clear)

      RowMask = 1 ' sets a variable equal to 1
      For switch = 1 to 5 'simple for loop to keep the active pins from going beyond portb.4
      PORTB = PORTB And b'11100000' Or RowMask 'rotates the high port left from no high port to portb.0
      Set STATUS.C Off 'honestly, I can't find any documentation on this command other then it returns a 1 or 0 under some conditions, and is N/A under others.
      Rotate RowMask Left 'moves the variable to the left once, to begin reading portb.1

      ...

      Next

      So im thinking after each rotate I want to read all the columns And store them somewhere for use by my program. Can I also use the rotate command there?
      my old (updated) code is as follows

      readrow1:
      set row1 hi
      if col1 hi | sw11 true then
      set led1 hi
      sw11 = true
      end if
      set led1 lo
      if col2 hi | sw21 true then
      set led2 hi
      sw21 = true
      end if
      set led2 lo
      if col3 hi | sw31 true then
      set led3 hi
      sw31 = true
      end if
      set led3 lo
      if col4 hi | sw41 true then
      set led4 hi
      sw41 = true
      end if
      set led4 lo
      if col5 hi | sw51 true then
      set led5 hi
      sw51 = true
      end if
      set led5 lo
      set row1 lo
      goto main

      thats just the code to read all the columns off row1 and store a bit so the program can use later to tell which LED's to keep lit and which to turn off.

      If I could shorten that up using rotate (each col is on porta.0-4) Id save a lot more space for the eventual application rather then using up a lot of it just making the program ready to work, But I dont know how to store which col's have been pressed

      sorry to ask suck newbish questions, but im extremely new to GCbasic (last things I used basic with were a TIbasic for the ti-83 and Qbasic for DOS) but that was MANY years ago....

       
    • Nobody/Anonymous

      Also (since i can't edit my last post)
      Id like to say thank you for your help, Id be stuck without it.

       
    • Hugh Considine

      Hugh Considine - 2008-02-27

      Your explanation of the code is correct. STATUS.C is a bit that has several functions. When used with the Rotate command, it acts as a ninth bit. The best way to think of what is happening is to think of a 9 bit variable being rotated - 8 bits come from the actual variable in the code, and the ninth from STATUS.C. In a left rotate, STATUS.C (bit 8) gets set to bit 7 of the variable, bit 7 of the variable gets set to bit 6, etc. Bit 1 of the variable gets set to bit 0, and bit 0 gets set to STATUS.C.

      To read PORTA bits 0 to 4, into a temporary variable, this would be suitable:

      Columns = PORTA And b'00011111'

      You could also use an array here to store the values from the port, something like:

      RowMask = 1
      For switch = 1 to 5
        PORTB = PORTB And b'11100000' Or RowMask
        Set STATUS.C Off
        Rotate RowMask Left
       
        Columns(switch) = PORTA And b'0001111'
       
      Next

      I'm assuming here that you've got all of the buttons on PORTA 0 to 4, and want to put them into an array for use later.

      If you've used QBASIC, GCBASIC shouldn't be too much of a jump - there are more operations for single bits and controlling hardware, but a lot of stuff is either similar or the same.

      Always happy to help!

       
    • Nobody/Anonymous

      Ok so debug your code again (sorry, gotta figure out how it works in my head)

      RowMask = 1  'sets a variable to 1
      For switch = 1 to 5 'starts a for loop
      PORTB = PORTB And b'11100000' Or RowMask 'sets a porb.0 pin high
      Columns(switch) = PORTA And b'0001111' 'saves the bits from porta 0.4 to a variable called colums(switch) where (switch) is the variable 1-5
      Set STATUS.C Off 'keeps the 9th bit from rotating over
      Rotate RowMask Left 'rotates the active pin from portb.0 to portb.1 and so forth through the loop

      The later use is actually immediate and later use. The program should read what switch was pressed and light the corisponding LED while also storing it as a variable (perhaps an array) so I can use it later to keep certian LED's lit and turn others off.

      Im gonna see about making a simple animation to explain this more in-depth, but for now i'll post a schmatic someone suggested I start with (need to change some of the components, but this should give you an idea on how the thing works [ignore the speaker and LCD lines as they're for future revisions])

      http://forum.microchip.com/photo_view.aspx?file=0;313739

       
    • Hugh Considine

      Hugh Considine - 2008-02-27

      Thanks for posting the schematic, it really helps.

      The code works exactly as you've stated. Only a few extra lines are required to flash the LEDs at the right time.

      RowMask = 1 
      For switch = 1 to 5 
      PORTB = PORTB And b'11100000' Or RowMask 
      Set STATUS.C Off 
      Rotate RowMask Left 

      Columns(switch) = PORTA And b'0001111'

      PORTD = (PORTD And b'11100000') Or (PORTA And b'00011111')
      Wait 1 ms
      PORTD = PORTD And b'11100000'

      Next

      The first extra line:
      - Gets the current value of PORTD, with the bits used to control the LEDs set to 0
      - Gets the current value of PORTA, with the bits used to read the buttons left as they are and the other bits cleared
      - Ors the 2 values together. It's a little hard to explain exactly what this does, but basically it combines the 3 high bits from the first And with the 5 low bits from the second And.
      - Stores the result of the Or back into PORTD

      The second line is a delay so that the LEDs stay on for long enough to be seen - you'll probably need to experiment with the amount of time in the delay. If you can't see the LEDs coming on increase the delay, if the LEDs appear to flicker decrease the delay.

      The third line clears the 5 low bits of PORTD again.

      It's usually best to use And and Or where possible to manipulate multiple bits simultaneously - it saves a lot of Ifs and Sets. Other operations are Xor, Not, and a function named Swap4 which swaps the highest and lowest nibbles (groups of 4 bits) in the variable. You probably won't need them for this program, but here are a few examples of how to use them just in case:

      Var = Something Xor b'01010101'
      OtherVar = Not SomeVar
      SomeVar = Swap4(Var)

       
    • Nobody/Anonymous

      Thanks again for your help.

      I should have my first prototype built next month (using a breadboard) so I'll post my results then.

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.