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:
'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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
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.
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.
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?
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