My issue is that when I use the result of digitalRead to create an integer used as the index of an array, the wrong array value is selected.
I have an array of uint32_t in progmem - FreqRegisters[832].
{update - I am starting to wonder if uint32_t is allowed on Atmega328p - Arduino Uno R3 as word size in an array }
It is arranged in four banks. Each bank holds 13 register values for 16 synthesizers.
A 2-bit code read on pins 18 and 19 determines the Bank offset (0,208,416,624).
Then, depending on which synthesizer is to be programmed, I calculate an offset within the bank to get to the first register for that synthesizer. I can calculate the needed offsets from constants or variables untiI I introduce the digitalReads to get the bits.
I am aware that digitalRead returns HIGH or LOW and that the returned result should not be treated as anything else. I have tried to use the HIGH/LOW results directly and I have not been successful. For example, I tried to determine the value of BankNew as below.
//if (( digitalRead(19) == LOW) && (digitalRead(18) == LOW)) { BankNew = 0;}
//if (( digitalRead(19) == HIGH) && (digitalRead(18) == LOW)) { BankNew = 1;}
//if (( digitalRead(19) == LOW) && (digitalRead(18) == HIGH)){ BankNew = 2;}
//if (( digitalRead(19) == HIGH) && (digitalRead(18) == HIGH)){ BankNew = 3;}
BankNew would print correctly in this case, but it could not be used in an array index as expected. If I set it with "BankNew = 3 " just after the above code, the code that followed worked OK.
When I could not make that work, I reworked the code with some other options, one that works and another one that does not. I will use this as my example,
FreqRegisters is defined as const uint32_t FreqRegisters[ 832 ] PROGMEM = {0,1,2,3 .......}
void WriteRegister32(uint32_t value, byte SynthNum) is a routine above in the source. I don't think that routine is relevant because my prints capture the problem before I call it .
void loop(){
int i,FCRI,A,B,BankNew,BankOld,Value,Synth;
BankOld = 3;
BankNew = 0;
//Pins 18 and 19 are setup to be Input_pullup and they are working properly
/* Assignment Option 1 - Assign digitalRead results to ints */
/* Both are tied low */
//A=digitalRead(19);
//B=digitalRead(18);
/* Assignment Option 2 - Force assignment to ints */
A=LOW;
B=LOW;
The rest works when I use Assignment option 2. Works means that when BankNew is used to calculate FRCI and FRCI is used as the index of FreqRegisters, I get the expected results. Read on to see what I mean.
if (( A == LOW) && (B == LOW)) { BankNew=0;}
if (( A == HIGH) && (B == LOW)) { BankNew=1;}
if (( A == LOW) && (B == HIGH)) { BankNew=2;}
if (( A == HIGH) && (B == HIGH)) { BankNew=3;}
In both cases, I get the expected results when I print A,B and BankNew. For example 0:0:0. Also, for FCRI below I get 0 and for FCRI+2 I get 2. However, the FreqRegisters index calculated from FCRI + 2 is incorrect for option 1.
FreqRegisters[FCRI + 2] = 3099113656 for option 1 (Not correct)
FreqRegisters[FCRI + 2] = 12587898 for option 2 = 0xc0137a (correct)
In FreqRegisters[0+2] is 0xc0137a
Also - If I set it to 0,1,2,3 with BankNew = 0 , what follows works.
String p1=";";
Serial.println(A + p1 + B + p1 + BankNew);
SPI.beginTransaction(SPISettings(7000000, MSBFIRST, SPI_MODE0));
for (Synth=0;Synth<1;Synth++) // Cut the loop to 1 for my test
{
FCRI = (BankNew * 16 * 13) + (Synth * 13);
Serial.println(FCRI); << As expected
Serial.println(FCRI+2); << As expected
Serial.println(FreqRegisters[FCRI]); << Incorrect for option1
Serial.println(FreqRegisters[FCRI + 2]); << Incorrect for option1
/*And so what follows is incorrect for option 1 */
WriteRegister32(FreqRegisters[FCRI + 2],Synth); //10
WriteRegister32(FreqRegisters[FCRI + 8],Synth); //4
WriteRegister32(FreqRegisters[FCRI + 10],Synth); //2
WriteRegister32(FreqRegisters[FCRI + 11],Synth); //1
WriteRegister32(FreqRegisters[FCRI + 12],Synth); //0
WriteRegister32(FreqRegisters[FCRI + 8],Synth); //4
delayMicroseconds(225);
WriteRegister32(FreqRegisters[FCRI + 12],Synth); //0
delayMicroseconds(500);
}
SPI.endTransaction();
}