Menu

Array not declared, Missing bit in SET?

2007-08-10
2013-05-30
  • Hank Fletcher

    Hank Fletcher - 2007-08-10

    I'm having trouble compiling the following bit of code.  It's been abbreviated, but the part not shown here is working (I think!).  When I try to compile I get this error message:

    first RCD-1 program.txt (274): Array/Function FINGERPORT has not been declared
    first RCD-1 program.txt (274): Missing bit in SET command
    first RCD-1 program.txt (278): Array/Function FINGERPORT has not been declared
    first RCD-1 program.txt (278): Missing bit in SET command

    The lines these error messages refer to are in the "FOR FingeringBit... NEXT FingeringBit" loop.  Here's the code:

    #chip 16F88, 8
    #config OSC = INTRC_IO, MCLR_ON

    DIM FingerPort(8)       

    #define FingerPort(1) PORTB.1  
    #define FingerPort(2) PORTB.2
    #define FingerPort(3) PORTB.3
    #define FingerPort(4) PORTB.4
    #define FingerPort(5) PORTB.5
    #define FingerPort(6) PORTB.6
    #define FingerPort(7) PORTB.7
    #define FingerPort(8) PORTA.0

    DIR PORTA OUT
    DIR PORTB OUT    

    DIM Fingering(80)
    DIM Wind(80
    DIM Duration(80)

    'first note
    Fingering(1) = 125
    Wind(1) = 27
    Duration(1) = 127

    'second note
    Fingering(2) = 14
    Wind(2) = 27
    Duration(2) = 63

    'etc, for as many notes as there are in the music, up to 80
    'eightieth note
    Fingering(80) = 255
    Wind(80) = 27
    Duration(80) = 60

    FOR Note = 1 to 80
    FOR FingeringBit = 1 TO 8  
    ROTATE Fingering(Note) RIGHT SIMPLE
    IF Fingering(Note) < 128 THEN SET FingerPort(FingeringBit) OFF
    IF Fingering(Note) > 127 THEN SET FingerPort(FingeringBit) ON   
    NEXT FingeringBit

    HPWM 1, 16, Wind(Note)  

    WAIT Duration(Note) 10ms        

    NEXT Note

     
    • Hugh Considine

      Hugh Considine - 2007-08-11

      This is not due to a bug in GCBASIC, but rather it is due to a limitation that would be difficult to remove and is simple (if a little tedious) to work around.

      Currently all that an array element can store is a value between 0 and 255, so setting it to reference a pin will not work.

      To make your program work, the first thing you need to do is to get rid of the brackets from the defines, such as:
      #define FingerPort1 PORTB.1

      Next, you'll need to alter the inner for loop. I'd get rid of it completely, and replace it with something like this:
      TempValue = Fingering(Note)
      FingerPort1 = TempValue.0
      FingerPort2 = TempValue.1

      ...

      TempValue is used to avoid having to access an array more than necessary - GCBASIC can access a single element variable in 1 CPU cycle, but needs around 4 to read or write an array. These changes should be all it takes to make your program compile.

      Another tip - perhaps you could use a data table to store the notes? Have a look at http://gcbasic.sourceforge.net/help/readtable.htm for more info.

       
    • Hank Fletcher

      Hank Fletcher - 2007-08-11

      Thanks for that.  I presumed that my problem was due to an inherent (and perhaps necessary) limitation of arrays, but I wasn't sure.  I'll give your work around a try.

      I had thought of using a data table, but I wasn't sure what would make more sense to me in the course of the rest of the program.  Is it preferable to use a data table as oppose to arrays, for instance, is it more conservative when it comes to the associated assembly code?
      Hank.

       
    • Hugh Considine

      Hugh Considine - 2007-08-15

      A data table is a lot more efficient for storing data that is known when the program is compiled.

      When using arrays, a byte of RAM is need to store each value, in addition to 8 instructions worth of program memory to load each value into RAM. A data table uses a single instruction space to store each value, and no extra RAM (a single temporary variable is used to store the last value read).

      I can see how a long data table could be difficult to read or edit - perhaps you could enter the values into a spreadsheet, and then copy the necessary columns into the GCBASIC data table one at a time?

       
    • kent_twt4

      kent_twt4 - 2007-08-15

      Excuse me for having a one-track sort of mind, a real flaw that gets me in trouble all the time.  Instead of a table for notes, or the fingerport() array for that matter, why not use a subroutine?  You could use an initNotes sub at the beginning of the code so that the hefty #define's code is at the bottom of the program, just like the ReadTable command would.  In this way the code would be much more readable at least?

      To somehow automaticaly set up a melody using arrays, instead of manual setup, is beyond the scope of my thought process.  The with exception being, running up and down a scale?  Any clarification in this direction would be instructive.

      ...
      ...
      initNotes
      ...
      Main:
      ...
      'first note
      PortB = FingeringA  ;Set fingering for this note
      Wind(1) = 27
      Duration(1) = 127
      ...
      goto Main

      sub intitNotes  ;All 255 of them?
      #define FingeringA b'01111101'  ;dec 125, bin shows fingering pattern
      #define FingeringB b'00001111'  ;dec 15
      ...
      ...
      etc.
      end Sub

       

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.