code: interfacing a chipcorder isd1760

this is a work in progress but im happy enough with the following example and should prove a good starting point for anyone using the chip. it is a recording chip with mic amp and speaker output as well as pushbutton controls. this example does the following:

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


all of the opcodes are defined, but you will need to look up the datasheet to see how many and what type of data bytes you need to send after it.

also to check if the message is done, i am checking the first bit of the 3rd miso byte, which is the second status register on the chip.

for hooking up the chip i used the manual in the design guide for pushbutton control, then added the spi. it should be noted that the caps marked with a * on the vcc lines next to the .1uf caps, should be 10uf, you can see what i mean by downloading the evaluation board datasheet you can find it here:

with a microphone and speaker attached i have 12 caps, 4 10uf, 2 4.7uf, 6 .1uf which seems like alot lol.

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

#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    0x49
#define SET_REC     0x81
#define SET_ERASE   0x82

void setup() {

  byte clr;
  pinMode(DATAIN, INPUT);
  digitalWrite(SLAVESELECT,HIGH); //disable device  
  SPCR = B01111111; //data lsb, clock high when idle, samples on falling

  //start serial
  spi_transfer(PU); // power up 
  spi_transfer(0x00); // data byte

  spi_transfer(CLR_INT); // clear interupt and eom bit
  spi_transfer(0x00); // data byte


void loop() {

  spi_transfer(PLAY); // clear interupt and eom bit
  spi_transfer(0x00); // data byte
  spi_transfer(FWD); // clear interupt and eom bit
  spi_transfer(0x00); // data byte

void ready_wait(){

  byte byte1;
  byte byte2;
  byte byte3;

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


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

some info regarding direct memory access:

many of the commands let you specify a range in memory to start and stop at. to automate playback ... recording etc...

my chip is the 60second version, the max memory location you can specify is 0x1EF or 495

each locaton is 10 bits long.

if you wanted to play from: 001 00100001 - 289 to 001 01000111 - 327

this chip will never use the first 2 bits, but the 240 second version will, its max value is 111 10001111 - 1935

the second byte you send is actually the first 3 bits of the number, the chipcorder is just lsb so its a little odd. this spi command will do that (binary for readability

  spi_transfer(SET_PLAY); // clear interupt and eom bit
  spi_transfer(0x00); // data byte
  spi_transfer(B00100001); // data byte start
  spi_transfer(B00000001); // data byte last 3 bits
  spi_transfer(B01000111); // data byte stop
  spi_transfer(B00000001); // data byte last 3 bits
  spi_transfer(0x00); // data byte blank

now how about a better way to do this?

  int start = 289;
  int end   = 327;
  spi_transfer(SET_PLAY); // clear interupt and eom bit
  spi_transfer(0); // data byte
  spi_transfer(start%256); // data byte start
  spi_transfer((int)start/256); // data byte last 3 bits
  spi_transfer(end%256); // data byte stop
  spi_transfer((int)end/256); // data byte last 3 bits
  spi_transfer(0); // data byte blank

you could use also (read should probably) use bitmask also say start&255 then start>>8

  spi_transfer(SET_PLAY); // clear interupt and eom bit
  spi_transfer(0); // data byte
  spi_transfer(start&255); // data byte start
  spi_transfer(start>>8); // data byte last 3 bits
  spi_transfer(end&255); // data byte stop
  spi_transfer(start>>8); // data byte last 3 bits
  spi_transfer(0); // data byte blank

Cool, given recent threads on projects that could use a chip like this I'm sure your code will be appreciated.

Thanks for making the effort to post it.


yeaha. cool. great. awesome. i got me one these chips last week. thank you very much for sharing. i didn't start with it yet, but your code encourages very much to just jump into it.

thanks! kuk

ps: and yes, the number caps needed did scare me off a little as well. do you know which of them are really needed to get started?

i'm developing a prototype for presentation using the winbond ESD17240. trying to access my audio using the 'stand alone' setting (push-buttons) was causing undesirable delays. i'm determined to get the SPI working, and your code postings are great in concert with the SPI examples on the arduino site. thanks! my application will require asking for PLAY_PTR and REC_PTR positions. looks like i'll be able to take saturday off this week! by the way, i've worked with the winbond chips numerous times and have nothing but good results. great documentation on their website and very helpful reps. (shocking, i know!)

some errata:

the set_play above has the wrong value defined

it should be 0x80 not 0x49

corrected code:

#define SET_PLAY    0x80

also one user reported the isd worked with with the decimilia but not the older arduino. thanks eggplant.

also a brain fart on the last example it should be end>>8 and not start>>8

corrected code:

  spi_transfer(end&255); // data byte stop
  spi_transfer(end>>8); // data byte last 3 bits

I am developing a programmer for isd1730, but i have some problems. Some commands work and some others do not. i.e. PU is working properly, also SET_PLAY, but SET_REC sometimes is working and some other times isn't. I am not sure if you can understand what i am trying to say. Weird things happen! If sb can help....

Hey unsped, I am working with an ISD17120 COB demo. I'm trying to adapt your code to work with the 120.

I'm kinda alt-tabbing back and forth between your code, the EEPROM tutorial and the ISD 17XX design guide, trying to figure out why the code is not working. As of now, I cannot get the code to make the Winbond board do anything. :'(

I had two really stupid noob questions for you:

  • Does the ISD17120 have a different number of bits to initialize it than the ISD1760? (I am going to do more research on this myself; hopefully I can figure this out instead of getting stuck)

  • I think I understand how to access the memory in the Winbond (like you described above) but I'm not sure where that chunk of code is supposed to fit into the program in your second post - do I access the memory location of my sound in the setup, or in the loop, or...?

Dear Eggplant...and everybody...

I use ISD1760 first on standalone mode, i want to optimize standalone need help from you guys..

How to make ISD 1760 automatic running, when i give them power supply, the IC automatic run and play one message only and than stop although maybe the supply still on. When supply off, every body stop :))

when i give ISD1760 with supply again, the cycle like above will work. i need only one cycle - one message run only. Before i use 17xx, i use ISD25xx and this is very simple to make like above. But that's ICs not produce again, replace with ISD1760 with "serial data for addressing messages". i don't know how to make easy like before (ISD25xx).

Please help me for a moment and ASAP...! :'( :'(

Thank You.


To other Arduino/Winbond interfacers and anyone else who is interested in trying out this project, here are some hints/tips/tricks worth trying:

  1. The ISD1760 COB seems to have problems interfacing with the Arduino, no matter what. I’ve been back and forth with the Winbond guy about this and, despite checking timing, software (my code,) hardware configurations, scope traces, etc., I still can’t get the COB to work.

  2. However, I have gotten the ISD1760 PDIP to work with the Arduino using unsped’s code. For anyone who might claim that his code doesn’t work, I will defend it, as I’ve checked it up one side and down the other! ;D For example, his SPCR is correct, although you can TRY changing the SP0 and SP1 if you want to mess around with the timing. (I’ve got mine set at 11, which, if you check out the Atmega168’s data sheet, means the Atmega’s fosc is like 8/128 Mhz or something - long story short, it’s a nice slow, steady clock rate.)

If you’ve connected everything in the push-button configuration found in the ISD1760’s data sheet, you’ve verified your SPI connections between the ISD1760 and the Arduino and you’re STILL not getting anything, try putting a 10kohm resistor (or higher, I’ve been messing with the resistance and had varying timing results) between pin 7 of the Winbond (the SS) and the GND of the ARDUINO. I’m not sure if this causes any sort of charge buildup, but I do know that all of my capacitors have remained relatively cool for about a half-hour of operation, so I don’t think I’m burning anything. Somebody can correct me on this if you want.

The important point about the above is that, at least for me, it got the Arduino/Winbond SPI interface working. I’ve got plenty of notes about getting these puppies to talk with each other, too, so I’ll try and post them over the next few weeks as well.

Would this SP1 interface to the ISD allow me to perform time sensitive operations while the sound is playing? I see delays in the code which are a problem, are those necessary?

I can not use the waveshield because it is causing timing issues that seem to be integrated into the device (interupts are screwing up IR data sending and pulseIn() reading).