uninitialized variable ISD1760

I have a nifty ISD1760 break-out board. It uses the ISD1760 28-DIP and brings most everything you need out to pins that can be easily connected to the Arduino.

It is marked YL-65, googling will turn up the usual sources. Inexpensive!

After tiring of using the on-board buttons I looked around for some code to use with its SPI functionality.

In these forums I found an old but very useful thread and a good example sketch, viz:

In fact, most code I found seems to have inherited form and shape from this early example. Unfortunately they inherited a bit of an error also. An error the compiler might catch and read something like

/var/folders/gz/t92bgl156gdf2066kn0xpc7w0000gq/T/arduino_modified_sketch_981957/myISD.ino: In function 'ready_wait()':
/var/folders/gz/t92bgl156gdf2066kn0xpc7w0000gq/T/arduino_modified_sketch_981957/myISD.ino:99:19: warning: 'byte3' is used uninitialized in this function [-Wuninitialized]
   counter = byte1 + byte2 + byte3;

But I had to go out of my way to get provoke this message. The original error (use of uninitialized variable ) goes unremarked.

I found the error the old fashioned way. I think much of the difficulty and random problems people have had working with might be traced to this error.

Here is the fixed-up original example. It has a “ready_wait” function that actually works - I just changed a while to a do/while. I also adds ready_waiting after the FWD.

Of course time is just wasted in ready_wait, but that’s a matter for another day. With this sketch one can test and sort out all the pieces.

/*
  original code from this thread
  http://forum.arduino.cc/index.php?topic=38867.0

  powers up the 1700
  plays from the current pointer on the chip memory
  waits until the sample is done
  forwards to next recording

  loops

  here with an improved ready_wait()
*/

//define pins
#define DATAOUT     11   //mosi
#define DATAIN      12   //miso
#define SPICLOCK    13   //sck
#define SLAVESELECT 10   //ss

//opcodes
#define PU          0x01
#define STOP        0x02
#define RESET       0x03
#define CLR_INT     0x04
#define RD_STATUS   0x05
#define RD_PLAY_PTR 0x06
#define PD          0x07
#define RD_REC_PTR  0x08
#define DEVID       0x09
#define PLAY        0x40
#define REC         0x41
#define ERASE       0x42
#define G_ERASE     0x43
#define RD_APC      0x44
#define WR_APC1     0x45
#define WR_APC2     0x65
#define WR_NVCFG    0x46
#define LD_NVCFG    0x47
#define FWD         0x48
#define CHK_MEM     0x49
#define EXTCLK      0x4A
#define SET_PLAY    0x80
#define SET_REC     0x81
#define SET_ERASE   0x82

void setup() {
  byte clr;
  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK, OUTPUT);
  pinMode(SLAVESELECT, OUTPUT);

  digitalWrite(SLAVESELECT, HIGH); //disable device

  SPCR = B01111111; //data lsb, clock high when idle, samples on falling

  clr = SPSR;
  clr = SPDR;
  delay(10);

  Serial.begin(9600);

  digitalWrite(SLAVESELECT, LOW);
  spi_transfer(PU); // power up
  spi_transfer(0x00); // data byte
  digitalWrite(SLAVESELECT, HIGH);
  delay(100);

  digitalWrite(SLAVESELECT, LOW);
  spi_transfer(CLR_INT); // clear interupt and eom bit
  spi_transfer(0x00); // data byte
  digitalWrite(SLAVESELECT, HIGH);

  Serial.println("...setup");
}

void loop() {
  digitalWrite(SLAVESELECT, LOW);
  spi_transfer(PLAY);
  spi_transfer(0x00);
  digitalWrite(SLAVESELECT, HIGH);

  ready_wait();

  digitalWrite(SLAVESELECT, LOW);
  spi_transfer(FWD); // ?? clear interupt and eom bit
  spi_transfer(0x00); // data byte
  digitalWrite(SLAVESELECT, HIGH);

  ready_wait();
}

void ready_wait() {
  int counter;
  byte byte3;
 
  counter = 0;
  do {
    counter++;
    digitalWrite(SLAVESELECT, LOW);
    spi_transfer(RD_STATUS);
    spi_transfer(0x00);
    byte3 = spi_transfer(0x00);
    digitalWrite(SLAVESELECT, HIGH);
  } while (byte3 << 7 != 128);

//  Serial.println(counter);
//  delay(100);
}

char spi_transfer(volatile char data)
{
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1 << SPIF)))   // Wait for the end of the transmission
    ;

  return SPDR;                    // return the received byte
}

alto777

The original error (use of uninitialized variable ) goes unremarked.

Presumably that is because you have not selected the "All" option for "compiler warnings" in the IDE preferences.
Here's a slightly modified snippet of your code:

  byte clr,fred;

  clr = SPSR;
  clr = SPDR+fred;

The verbose output is:

sketch_jul25a: In function 'void setup()':
sketch_jul25a:48: warning: variable 'clr' set but not used 
   byte clr,fred;

        ^

sketch_jul25a:59: warning: 'fred' is used uninitialized in this function 
   clr = SPDR+fred;

                  ^

Pete

Presumably not. I had the setting at "more", so you are half right. Setting it to "all" still does not catch the error IDE 1.6.13. "More" catches the one in your snippet, and was in fact how I was able to see it could even catch anything at all.

This is an example of the actual error missed in "ready_wait()".

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  byte myByte;
  int nevermind;


  while ((myByte & 0x80) != 1) {
    nevermind++;
    myByte++;
  }

}

Caveat Coder!

alto777

The value of neither variable is used after the while loop, so the compiler optimizes that code out of existence, which removes the uninitialized warning(s).
If you print either variable after the loop, the warning will be generated.

Pete

Well we must be in different parallel universes, as I tried printing myByte and never mind after the loop and did not get any warning. Did you do this and get a different result? Can we account for this?

In any case, the original missed use of a variable whose value was yet without meaning, perfectly recognizable by the compiler (I assume), went unremarked.

This function

void ready_wait(){

 byte byte1;
 byte byte2;
 byte byte3;

 while(byte3<<7 != 128){
 
   digitalWrite(SLAVESELECT,LOW);
   byte1 = spi_transfer(RD_STATUS); // clear interupt and eom bit
   byte2 = spi_transfer(0x00); // data byte
   byte3 = spi_transfer(0x00); // data byte
   digitalWrite(SLAVESELECT,HIGH);

 }
 
 delay(100);
 
}

does not work. It does not work because the first use of byte3 comes before it has been given a meaningful value, and the compiler, set at the “all” level of peskinessss, does not issue a warning.

alto777