Can't write EEPROM chip - Page 1
Forum section: electronics / projects

author: sci4me
author_rank: Regular Contributor
timestamp: May 19, 2018, 01:14:06 am
content: Hey guys, I'm trying to use an Arduino Nano and a couple 74HC595s to write data into a GLS29EE010-70-4C-PHE EEPROM (https://www.greenliant.com/dotAsset/40840.pdf) chip. The datasheet specifies that you must write a specific sequence of bytes to the specified addresses to begin a page-write operation; this operation simultaneously enables "Software Data Protection". Once the three-byte sequence is written, 128 bytes may be written to the selected page. Well, that's what I'm doing... but no luck. Or at least that's what I think I'm doing...I'll just dump the raw code I have (it's in-flux since I'm just trying to get this thing to work...):Code:#define ROM_LEN 0xFF#define LED 13#define SER 9#define RCLK 8#define SRCLK 7#define WE 3#define OE 4#define A16 2#define D0 11#define D1 12#define D2 A5#define D3 A4#define D4 A3#define D5 A2#define D6 A1#define D7 A0#define COMMAND_READ 1#define COMMAND_WRITE 2#define COMMAND_ERASE 3void setup() {digitalWrite(WE, HIGH);digitalWrite(OE, HIGH);pinMode(WE, OUTPUT);pinMode(OE, OUTPUT);pinMode(A16, OUTPUT);pinMode(LED, OUTPUT);pinMode(SER, OUTPUT);pinMode(RCLK, OUTPUT);pinMode(SRCLK, OUTPUT);digitalWrite(SER, LOW);digitalWrite(RCLK, LOW);digitalWrite(SRCLK, LOW);Serial.begin(38400);while(!Serial);}void writeMode() {pinMode(D0, OUTPUT);pinMode(D1, OUTPUT);pinMode(D2, OUTPUT);pinMode(D3, OUTPUT);pinMode(D4, OUTPUT);pinMode(D5, OUTPUT);pinMode(D6, OUTPUT);pinMode(D7, OUTPUT);}void readMode() {pinMode(D0, INPUT);pinMode(D1, INPUT);pinMode(D2, INPUT);pinMode(D3, INPUT);pinMode(D4, INPUT);pinMode(D5, INPUT);pinMode(D6, INPUT);pinMode(D7, INPUT);}void updateCRC(int *crc, char b) {*crc = *crc ^ (int) b << 8;char i = 8;do {if(*crc & 0x8000)*crc = *crc << 1 ^ 0x1021;else*crc = *crc << 1;} while(--i);}long readU32() {long a = 0;a |= (Serial.read() << 24);a |= (Serial.read() << 16);a |= (Serial.read() << 8);a |= Serial.read();return a;}void setAddress(long addr) {shiftOut(SER, SRCLK, MSBFIRST, (addr >> 8) & 0xFF);shiftOut(SER, SRCLK, MSBFIRST, addr & 0xFF);digitalWrite(RCLK, HIGH);digitalWrite(RCLK, LOW);digitalWrite(A16, addr >= 0x10000);}char readByte() {char a = 0;if(digitalRead(D0)) a |= 1;if(digitalRead(D1)) a |= 2;if(digitalRead(D2)) a |= 4;if(digitalRead(D3)) a |= 8;if(digitalRead(D4)) a |= 16;if(digitalRead(D5)) a |= 32;if(digitalRead(D6)) a |= 64;if(digitalRead(D7)) a |= 128;return a;}void writeByte(char b) {digitalWrite(D0, b & 1);digitalWrite(D1, b & 2);digitalWrite(D2, b & 4);digitalWrite(D3, b & 8);digitalWrite(D4, b & 16);digitalWrite(D5, b & 32);digitalWrite(D6, b & 64);digitalWrite(D7, b & 128);}void pulseWE() {digitalWrite(WE, LOW);//delayMicroseconds(1);digitalWrite(WE, HIGH);//delayMicroseconds(1);}void loop() {if (Serial.available() > 0) {int command = Serial.read();digitalWrite(LED, HIGH);switch (command) {case COMMAND_READ: {readMode();for(long i = 0; i < ROM_LEN; i++) {setAddress(i);while(Serial.availableForWrite() < 1);digitalWrite(OE, LOW);delayMicroseconds(1);Serial.write(readByte());digitalWrite(OE, HIGH);}setAddress(0);break;}case COMMAND_WRITE: {writeMode();/*int crc = 0;for (long i = 0; i < ROM_LEN; i++) {setAddress(i);while (Serial.available() < 1);int b = Serial.read();updateCRC(&crc, b);// TODO: write b}Serial.write((crc >> 8) & 0xFF);Serial.write(crc & 0xFF);*/setAddress(0x5555);writeByte(0xAA);pulseWE();setAddress(0x2AAA);writeByte(0x55);pulseWE();setAddress(0x5555);writeByte(0xA0);pulseWE();writeByte(0x50);for(long i = 0; i < ROM_LEN / 128; i++) {for(long j = 0; j < 128; j++) {setAddress((i << 7) | j);delayMicroseconds(5);pulseWE();delayMicroseconds(10);}delay(11);}setAddress(0);break;}case COMMAND_ERASE: {writeMode();setAddress(0x5555);writeByte(0xAA);pulseWE();setAddress(0x2AAA);writeByte(0x55);pulseWE();setAddress(0x5555);writeByte(0x80);pulseWE();writeByte(0xAA);pulseWE();setAddress(0x2AAA);writeByte(0x55);pulseWE();setAddress(0x5555);writeByte(0x10);pulseWE();delay(50);break;}}digitalWrite(LED, LOW);}}When I read the data out, I get all 0xFD... very weird. I've triple-checked the connections... so I'm 99.999% sure it's a software problem. Any ideas?EDIT: I've redone some of the wiring just to improve it a little and now I'm getting 0xFF instead of 0xFD when I read the chip... But still no ability to write to the damn thing...EDIT 2: After more messing around it seems that I am actually writing SOME of the bytes but not most of them. Weird!! I suspect it's a timing issue? But I can't really see what I'm .. doing wrong.. as far as that goes...But it gets even weirder: I was suspicious that the address/data bits may have been reversed so I manually reversed the bits for the address/data of the three byte commands for the SDP and it turns out that it makes no difference! What the hell?!

author: amyk
author_rank: Super Contributor
timestamp: May 19, 2018, 03:57:11 am
content: There's no minimum frequency, so slow down the timings to "human scale" (seconds) to eliminate any timing issues, maybe even make it so that you have to press a key to advance to the next write --- that way you can inspect the pins with a multimeter to see that they're at the correct levels.

author: sci4me
author_rank: Regular Contributor
timestamp: May 19, 2018, 04:14:13 am
content: I have already tried checking every pin individually multiple times, both with an LED, and with a multimeter. I assume 4.6 volts is plenty to drive these inputs?As for timing, I do see a maximum of 100µs "Byte Load Cycle Time"... I've tried slower timings but I'll continue to mess with it...But, I don't know, I'm REALLY starting to lose my mind over this thing. I'm convinced that the hardware is good. It's not the chip either; I've tried multiple others of the same chip. It's got to be a software issue...

author: bson
author_rank: Unknown
timestamp: May 19, 2018, 06:24:53 am
content: Check your wiring to make sure the data and addr buses are properly connected. If not, the magic sequence won't unlock it.I suspect the real reason it doesn't work is your code might be too slow. If WE isn't pulsed for 100µs the EEPROM writes the page, which is probably why only some bytes changed - with all the bit banging going on you're not filling the page buffer fast enough.Also, you probably also should move the 3 byte unlock sequence into the outer page loop, so it's done for every page:Code:for(long i = 0; i < ROM_LEN; i += 128) {setAddress(0x5555);writeByte(0xAA);pulseWE();setAddress(0x2AAA);writeByte(0x55);pulseWE();setAddress(0x5555);writeByte(0xA0);pulseWE();writeByte(0x50);for (long j = 0; j < 128; j++) {setAddress(i + j);delayMicroseconds(5);pulseWE();delayMicroseconds(10);}delay(11);}

author: sci4me
author_rank: Regular Contributor
timestamp: May 19, 2018, 06:29:59 am
content: Doh! How did I not notice that! Of course I need to write that magic sequence for every page. However, even with removing as much delay as possible, that doesn't seem to make a difference...Is the bit-banging really that slow? I suppose I should try writing directly to the ports instead of using digitalWrite?EDIT: I didn't realize how much slower digitalWrite is; it works now!! Thank you!

author: sci4me
author_rank: Regular Contributor
timestamp: May 19, 2018, 05:11:17 pm
content: Sorry to bump but I'm still having a little bit of trouble; probably just some stupidly written code. I did get writing to the EEPROM working but ... now I can't get it to write the correct data; in this code, I'm just trying to write a counter which goes from 0 to 0x7F. When I write and then read back the data, I get all0x7Fs...0x43 and then repeating 0x80 and 0xC0...Also when I try the ERASE command, I get back all0x10s0x10 then 0xAF and 0xEF repeating?!Here's the code:Code:#define ROM_LEN 0x100#define LED 13#define SER 9#define RCLK 8#define SRCLK 7#define WE 3#define OE 4#define A16 2#define D0 11#define D1 12#define D2 A5#define D3 A4#define D4 A3#define D5 A2#define D6 A1#define D7 A0#define COMMAND_READ 1#define COMMAND_WRITE 2#define COMMAND_ERASE 3void setup() {digitalWrite(WE, HIGH);digitalWrite(OE, HIGH);pinMode(WE, OUTPUT);pinMode(OE, OUTPUT);pinMode(A16, OUTPUT);pinMode(LED, OUTPUT);pinMode(SER, OUTPUT);pinMode(RCLK, OUTPUT);pinMode(SRCLK, OUTPUT);digitalWrite(SER, LOW);digitalWrite(RCLK, LOW);digitalWrite(SRCLK, LOW);Serial.begin(38400);while(!Serial);}inline void writeMode() {pinMode(D0, OUTPUT);pinMode(D1, OUTPUT);pinMode(D2, OUTPUT);pinMode(D3, OUTPUT);pinMode(D4, OUTPUT);pinMode(D5, OUTPUT);pinMode(D6, OUTPUT);pinMode(D7, OUTPUT);}inline void readMode() {pinMode(D0, INPUT);pinMode(D1, INPUT);pinMode(D2, INPUT);pinMode(D3, INPUT);pinMode(D4, INPUT);pinMode(D5, INPUT);pinMode(D6, INPUT);pinMode(D7, INPUT);}inline void updateCRC(int *crc, unsigned char b) {*crc = *crc ^ (int) b << 8;unsigned char i = 8;do {if(*crc & 0x8000)*crc = *crc << 1 ^ 0x1021;else*crc = *crc << 1;} while(--i);}unsigned char reverse(unsigned char b) {b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;b = (b & 0xCC) >> 2 | (b & 0x33) << 2;b = (b & 0xAA) >> 1 | (b & 0x55) << 1;return b;}inline long read32() {long a = 0;a |= (Serial.read() << 24);a |= (Serial.read() << 16);a |= (Serial.read() << 8);a |= Serial.read();return a;}inline void setAddress(long addr) {//shiftOut(SER, SRCLK, MSBFIRST, (addr >> 8) & 0xFF);//shiftOut(SER, SRCLK, MSBFIRST, addr & 0xFF);//digitalWrite(RCLK, HIGH);//digitalWrite(RCLK, LOW);//digitalWrite(A16, addr > 65535);for(unsigned char i = 0; i < 16; i++) {if(addr & (1 << (15 - i))) PORTB |= 2; else PORTB &= ~2;PORTD |= 128;PORTD &= ~128;}PORTB |= 1;PORTB &= ~1;if(addr & 0x1000) PORTD |= 4; else PORTD &= ~4;}inline unsigned char readByte() {unsigned char a = 0;//if(digitalRead(D0)) a |= 1;//if(digitalRead(D1)) a |= 2;//if(digitalRead(D2)) a |= 4;//if(digitalRead(D3)) a |= 8;//if(digitalRead(D4)) a |= 16;//if(digitalRead(D5)) a |= 32;//if(digitalRead(D6)) a |= 64;//if(digitalRead(D7)) a |= 128;a |= (PINB >> 3) & 3;a |= reverse(PINC) & 0xFC;return a;}inline void writeByte(unsigned char b) {//digitalWrite(D0, b & 1);//digitalWrite(D1, b & 2);//digitalWrite(D2, b & 4);//digitalWrite(D3, b & 8);//digitalWrite(D4, b & 16);//digitalWrite(D5, b & 32);//digitalWrite(D6, b & 64);//digitalWrite(D7, b & 128);PORTB = (b & 3) << 3;PORTC = (reverse(b >> 2) >> 2) & 0x3F;}inline void pulseWE() {//digitalWrite(WE, LOW);//digitalWrite(WE, HIGH);PORTD &= ~8;delayMicroseconds(1);PORTD |= 8;delayMicroseconds(1);}void loop() {if (Serial.available() > 0) {int command = Serial.read();digitalWrite(LED, HIGH);switch (command) {case COMMAND_READ: {readMode();for(long i = 0; i < ROM_LEN; i++) {setAddress(i);while(Serial.availableForWrite() < 1);PORTD &= ~16;delayMicroseconds(1);Serial.write(readByte());delayMicroseconds(1);PORTD |= 16;}setAddress(0);break;}case COMMAND_WRITE: {writeMode();/*int crc = 0;for (long i = 0; i < ROM_LEN; i++) {setAddress(i);while (Serial.available() < 1);int b = Serial.read();updateCRC(&crc, b);// TODO: write b}Serial.write((crc >> 8) & 0xFF);Serial.write(crc & 0xFF);*/for(long i = 0; i < ROM_LEN; i += 128) {writeByte(0xAA);setAddress(0x5555);pulseWE();writeByte(0x55);setAddress(0x2AAA);pulseWE();writeByte(0xA0);setAddress(0x5555);pulseWE();for(long j = 0; j < 128; j++) {long k = i + j;writeByte(j);setAddress(k);pulseWE();}delay(12);}setAddress(0);break;}case COMMAND_ERASE: {writeMode();writeByte(0xAA);setAddress(0x5555);pulseWE();delayMicroseconds(1);writeByte(0x55);setAddress(0x2AAA);pulseWE();delayMicroseconds(1);writeByte(0x80);setAddress(0x5555);pulseWE();delayMicroseconds(1);writeByte(0xAA);pulseWE();delayMicroseconds(1);writeByte(0x55);setAddress(0x2AAA);pulseWE();delayMicroseconds(1);writeByte(0x10);setAddress(0x5555);pulseWE();delay(50);break;}}digitalWrite(LED, LOW);}}

author: rstofer
author_rank: Super Contributor
timestamp: May 19, 2018, 06:08:02 pm
content: I take it that you don't have an oscilloscope...Looking at the timing in the datasheet and your use of delays, I wonder if you should just remove all the delays and let the slow pin operations account for the delays.The fact that the chip times out if you don't fill the buffer fast enough tells me you should probably have the byte data in an array and do a port write as fast as you can.If you don't have a scope, maybe you can look at the compiler output and count CPU cycles. This is tedious but it will give you some idea of the timing.

author: sci4me
author_rank: Regular Contributor
timestamp: May 19, 2018, 06:18:48 pm
content: Yeah unfortunately I don't have access to a scope at the moment. What I find is that even after removing all delays, it is not behaving properly. Is it possible that the Arduino Nano is not running at 16MHz?Perhaps the code can be written to be even faster, not sure...How slow is the port manipulation anyway? I thought that by doing that instead of digitalWrite, I'd be fast enough for sure... I mean, the timeout is 100 microseconds...EDIT: I've used the micros() function to time when each byte gets written; there is a maximum of 20 microseconds between bytes... sooooo.....EDIT 2: So upon further testing, I've found that 2/6 of the EEPROMs I have actually does work..... so... could 4/6 of them be DOA? Seems unlikely to me...EDIT 3: So also, one of the EEPROMs responds to the ERASE command, one does not. Both of them read and write just fine. The other four don't respond to ERASE or WRITE commands at all...EDIT 4: So now both of the working EEPROMs respond to the ERASE command. Also, I suspected that maybe the issue was the power supply wasn't good enough so I tried a better one but it made no difference. The chip doesn't seem to mind 4.58V as its input. a 5V input changed nothing. USB power is good enough as far as I can tell.This is really driving me nuts. Like, am I doing something wrong or are these chips dead? I'm starting to debate just purchasing a programmer.....

author: TerraHertz
author_rank: Super Contributor
timestamp: May 20, 2018, 05:13:53 am
content: Quote from: sci4me on May 19, 2018, 06:18:48 pmThis is meant as helpful criticism, please don't be upset.In general it's an absolute waste of time trying to do any low level coding and hardware driving, without a scope as a sanity check when things don't go as you'd expect. Which is very often.Really, buy a cheap scope of some kind. Maybe one of the small USB ones? Or a traditional one second hand. Then you won't ever again have this unpleasant experience of completely mysterious problems driving you nuts.Even when something does work, you should still use a scope (or LA, etc) to look at what's _actually_ happening. Because it still may not be what you expect.Inspection is priceless, everything else is guesswork and fudgery.Just make sure the scope bandwidth limits are adequate for your application. Otherwise you are _still_ not actually inspecting anything.

author: sci4me
author_rank: Regular Contributor
timestamp: May 20, 2018, 05:28:31 am
content: Quote from: TerraHertz on May 20, 2018, 05:13:53 amNo, I totally agree. I definitely do need to get a scope. But I'll have to wait a few paychecks before I do.But the issue really is strange; some of the chips are working, most aren't. Is this due to slight, subtle differences in the chips themselves? Or might I have killed a bunch of them somehow?

author: TerraHertz
author_rank: Super Contributor
timestamp: May 20, 2018, 12:18:01 pm
content: Quote from: sci4me on May 20, 2018, 05:28:31 amAre you sure? Have you actually tried searching aliexpress for usb oscilloscope, and sorting by price?The cheapest is $4, and by the time you get to the $40 to $60 range, there are many pretty decent looking ones.QuoteHaving a known working commercial chip programmer would also be a big help. For checking chips are functional, and also to check that when you think you wrote something to a chip, the data is actually what and where you expect.You don't know anyone who has a chip programmer you could borrow?And have you looked at costs from China? I just bought some USB flash chip programmers for $2.44 each. They only do a subset of chips though. But for just a few dollars more you can get quite versatile ones.What country are you in? You haven't set your country flag. if you do, someone nearby may offer to help out, or even donate something.

author: sci4me
author_rank: Regular Contributor
timestamp: May 20, 2018, 05:43:22 pm
content: Quote from: TerraHertz on May 20, 2018, 12:18:01 pmYeah I suppose I might be able to find something for cheap but it has to be able to capture the fast pulses; not many nanoseconds long. As for programmers, so far I have yet to find a programmer that actually supports this chip..... still looking...EDIT: What about this Logic Analyzer?https://www.circuitspecialists.com/34-ch-usb-logic-analyzer-la-5034.html?otaid=gpl&gclid=Cj0KCQjwuYTYBRDsARIsAJnrUXDd99M6PtDJCvAj-GwVeZtmMZc9JZj33O0CymS8juI1f8L74KN4IKsaAoziEALw_wcBI'm no expert but it looks like a great deal to me.

author: David Chamberlain
author_rank: Frequent Contributor
timestamp: May 20, 2018, 07:23:34 pm
content: Im surprised no one has ask already so let me be the first. Please post a schematic or photo of your setup.

author: sci4me
author_rank: Regular Contributor
timestamp: May 20, 2018, 07:37:56 pm
content: Quote from: David Chamberlain on May 20, 2018, 07:23:34 pm

author: TerraHertz
author_rank: Super Contributor
timestamp: May 22, 2018, 02:13:52 am
content: That LA seems nice, but do not buy a LA until you already have a scope. Logic analysis assumes all the signals are actually being valid logic levels, and doesn't illustrate failures of that assumption.Now I've seem your board layout, I can't emphasize that enough. I can _immediately_ see a grounding mistake you've made, the nature of which reveals you haven't yet learned that everything is fundamentally analog, including so-called digital circuitry. And without a scope you can't learn about the boundary between ideal digital functioning, and real world parasitics hell.See the ground pin on your flash chip? It's wired to the lower horizontal power-ground strip. Linked at left to the vertical power-ground rail, then to the top horizontal power-ground strip. I see a 0.1uF cap at the plus supply pin of the chip, but the ground leg of that presumably goes to the top power-ground rail and has a looooong loop to get back to the chip ground pin. So you have effectively no supply decoupling on your flash chip.When you tell the chip to do anything, it will cause sharp variations in the chips supply current draw. Because your setup has no supply decoupling, those current spikes are traveling along your long ground lines. Inductance of those lines results in quite a lot of voltage differential transients between the various 'ground' points in the circuit. The flash chip doesn't know its local ground isn't the same as the ground of the chip driving inputs to the flash chip. It just sees glitches on those signals. Very short glitches, but they cause logic upsets. Google 'ground bounce'.That's one of many issues.I suspect the obscure problems you are having, and differing behavior of different ICs, has a lot to do with poor grounding layout and cross coupling between signal lines. Those kind of effects always are so flakey they drive you mad.For starters, use just one horizontal power-ground strip. Make sure every chip has a decoupling cap wired directly to the chip's power pin strips. That might make a difference.But in general those proto boards also have a lot of capacitance between adjacent pin rows, which often causes problems with fast logic circuits.

author: sci4me
author_rank: Regular Contributor
timestamp: May 22, 2018, 02:56:08 am
content: Quote from: TerraHertz on May 22, 2018, 02:13:52 amDOH! You can tell I'm a newbie XDI'm almost a little embarrassed about this one, but it's all part of the learning process. It's definitely a great lesson for me. After fixing the grounding and decoupling issues, it works! ALL of the chips work! But it is very very unreliable. Need to rewire it and make it less horrible maybe...Can't say thank you enough! Sure won't make that mistake again.

author: DaJMasta
author_rank: Super Contributor
timestamp: May 22, 2018, 04:17:25 am
content: Have you tried lowering the speed at which you write the data to the EEPROM? I see there are some delays built into your code, and I haven't gone through to try to see specifically where, but just because you are using a combination of lines from the 595s and the micro itself means there's potential for there to be some misalignment there (propagtion delay of the cascaded registers plus the delay in the write time for daisy chaining them vs. the toggling of the bit from the micro) - so maybe an additional delay after all the registers have been written to the 595s and the output pin before you actually tell the EEPROM to read/write.There could also be an issue with powering the whole thing from the Nano - if you're going over USB your current should be high enough but the voltage may be a bit low on the 5V pin because of the way it switches between VUSB and +5V from the onboard regulator in different powering conditions. If you're powering from the onboard regulator, current capability is more of a potential issue, but it's likely just that some extra bulk capacitance on the output could help it cope with the additional load better. I think checking the actual voltage being supplied to your breadboard is a good place to start, and putting a couple hundred microfarad worth of bulk capacitance right on that 5V pin is probably a good thing.There's also the fact that moving to a soldered breadboard may further improve your reliability/performance. Something using sockets would still let your parts be replaceable, but each row on a solderless breadboard has considerably more capacitance than a pad, so when working with high speed pulses you will get much better edges and responsiveness when you move to a regular board. You'd also be able to get the wires closer together (and not running all in parallel) to reduce parasitic inductance and crosstalk.While I don't know if those things are the cause of issues with your current design, they can certainly lead to issues similar to what you're seeing, and they can be very difficult to identify without a scope and an idea of how these signals can interact on a board. It's worth mentioning that a single one of these issues happening only in a relatively special case can be the cause of intermittent digital issues, so they can sometimes be tricky to track down. Software side is usually easier to correct, but rule of thumb good practices for designs can help alleviate some of the hardware-centric issues without being able to properly analyze them (i.e. no scope etc.)

author: sci4me
author_rank: Regular Contributor
timestamp: May 22, 2018, 09:08:34 pm
content: I definitely think that grounding and decoupling was not and is not the *only* issue with what I have as of now. I was able to get the other chips working but at this moment, I'm having a hard time with all of them, even the ones that were working perfectly before. The reliability is close to zero. I'm seriously debating redoing the wiring at this point and trying as hard as humanly possible to improve the setup.As for voltage, the Nano is providing about 4.6 volts through the USB port. I have tried an external power supply powering the Nano and got 5 volts, but that didn't make a difference. Not sure if that was due to the Nano's power supply or anything.

author: TerraHertz
author_rank: Super Contributor
timestamp: May 22, 2018, 11:19:43 pm
content: Cool. Yes, a great learning experience.By the way, another problem with those cheap protoboards (in addition to the capacitance and grounding problems) is that sometimes the contacts can be unreliable. It only takes one not-very-good pin contact somewhere to make the whole circuit flakey. Maybe that's your new problem, after a few more IC removals and insertions.Now you know your design can work, as DaJMasta points out, a soldered board would be a good next step. But use high quality IC sockets, or after a few insertions you'll have exactly the same kind of bad contact gremlins. The round machined-pin sockets are the best; the types with exposed springs bearing against the lead flats, next best. I'd recommend a ZIF socket for your flash chip.Consider the board layout to get the shortest ground and power line paths. These days with cheap and fast PCB manufacture, many people would go straight for a PCB version. But for fairly small circuit prototyping I still prefer hand-wired, on bare 0.1" hole grid matrix board. Once you're familiar with the method below, it's quite quick and easy to do.Use thickish tinned bare wire for the power rails, then kynar wire-wrap wire for all the logic. See pics (a board I did many years ago.) Only tools needed are the small hand wire-wrap tool (just used to strip the kynar insulation) and needle-nosed pliers.Sequence: Put in the sockets. Form the power rails of thick wire, solder short links from the rails to the socket pins using thin stripped kynar wire. Add all the decoupling caps, soldering to IC socket pins and/or the rail wires. Usually the decoupling caps can go in the center cavity of the IC sockets.At this point add extras like- Drill mounting holes.- Nice big, solid ground loops for scope probe ground clips. Use same bare wire as used for the power rails.- Test points.- IO and power connectors.- Power indicator LED.etcThen the wiring.Method: Strip off several inches of kynar insulation initially. Segments of insulation slide very easily along the wire. So say you want to do a wiring run with several contact nodes. Can be done with all one piece of wire, sliding down each segment of insulation as you solder each node.To start, place the insulated wire against a pin-to pin segement and mark the insulation length needed by putting a little kink in the wire with a fingernail. With the stripper, push that kink into the stripper slot with your thumbnail, then pull the wire to separate that segment of insulation. Slide it a little along the bare wire length. Repeat for as many more node to node segments as you'll do in one wire section.Now use the pliers to put a little loop in the bare wire end, to fit over an IC socket or component pin. Put it on the pin, Squeeze it tight with the pliers so it doesn't pop off when you let go of the wire. You now have two hands free - solder it. The loop also stops the wire springing free if you need to solder more wires on that point later.Now slide the segment of insulation down to that soldered point. Pull the now insulated wire over to the next pin, and wrap the bare wire tightly once around that pin. You should have stripped enough insulation to make the wire span a little loose, so it can be moved around to get out of the way when doing other pins in the area. Solder the second pin. Slide down the next insulation segment, repeat. After the last joint, snip off the extra wire flush with the joint.Doing it this way, you waste no wire at all.Use a highlighter pen to mark off each wire on a printed schematic as you do it. Be fanatical about this, otherwise you'll end up forgetting a few interconnections. It takes less time to do the marking, than to find the culprits later.Other readers: could someone in the USA possibly help him get a decent oscilloscope?

author: sci4me
author_rank: Regular Contributor
timestamp: May 23, 2018, 01:18:32 am
content: Frankly I'm very tempted to just go straight to a PCB; I could have a socket for inserting the Arduino Nano and a ZIF socket for the flash. Would cost, what, 30 bucks with shipping for the PCB. Might be overboard but also might be worth it since I'll want to be programming and reprogramming the chips...As for a scope, I'm considering a DS1054Z on my next paycheck but we'll see.

author: chris_leyson
author_rank: Super Contributor
timestamp: May 23, 2018, 01:24:28 am
content: Glad you got it working in the end, it's a good learning experience. I've just been there and done the software/hardware "why doesn't it work" thing about an hour ago with a PWM DC motor driver. Hooked up a scope up to the current sense resistor and the answer was obvious, I'm using the wrong motor to test the hardwareIt had nothing to do with the software or hardware just tested it with the wrong motor.A scope will tell you a lot about signal integrity like signal levels and timing whereas a logic analyzer will only tell you about the 1's and 0's. If you don't have good return paths for the signal currents then your logic chips could be seeing the wrong logic levels at the wrong time. For fast rise and fall time logic outputs the signal currents are quite high but only for a very short time and if those currents have to flow back to the souce through a short length of wire then the voltage at one end of the wire won't be the same as the other end. Why ? Simple, because the ground return wire has inductance and that's why ground planes are used for high speed logic to minimise inductance. If you're driving chips with parallel buses lets say 8-bit data and 16-address for example then you have 24 return currents to deal with.If you're prototyping high speed logic avoid breadboards and use perfboard with a groundplane if you can. You might not think of Arduino boards as being high speed but the processors have high speed drivers on their outputs and if you are driving 16 or 24 signals lines all at once then you need a short low inductance return path. With serial buses like I2C you don't have worry too much and you can even use short wire lengths for SPI but for parallel buses you've got potentially much bigger peak currents. Sorry about the long post but go for a ground plane if you're doing a pcb layout and a DS1054 ain't too bad for a first scope.