One area I changed a bit was to remove the on board USB logic instead using a 'service port' to bring out TTL signals via a 6-pin header. Then a low cost USB <--> TTL adapter can be used across many boards, saving space as well as cost. Much the same way the Arduino Pro and Pro-mini do things. External adapters are readily available with prices ranging from under $2 to around $20, depending on the supplier and chipset used. And also how they handle the 3.3v vs. 5v issue. . . Therein lies the problem with Reset.
A core capability needed by the Arduino IDE is the ability to reset the Atmel CPU and have it look for a new sketch to be downloaded. The bootloader takes care of this by searching the serial port for a special series of bytes indicating the IDE wishes to synchronize with the target board. Once synchronization is made the new sketch binary can be downloaded updating the target boards program. This all depends on getting a reset signal to the Atmel CPU.
In the Arduino Uno, and most other related designs, the falling edge of the DTR pin is routed through a capacitor to produce a negative spike, resetting the CPU. This design is simple and reliable and allows the Arduino IDE to reset the CPU into the bootloader. A typical design looks like this:
Typical Arduino reset circuit, DTR is in Pin #1 of the Service connector. (Not shown is another 10K pull up resister on the left side of C20) |
DTR from the USB <--> TLL adapter board is connected to Service pin #1. When DTR is brought low, C20 will fall as well and then be recharged back up via another 10K pull up (not shown) connected to the ~Reset line. This causes a negative pulse to be presented to the ATmega328 CPU's reset pin - resetting the CPU. Here is what it should like:
Results of the standard Arduino Reset circuit with a 5v DTR voltage level |
While checking out the latest revisions of the controller I was verifying signals vs. the ATmega328 data sheet - timing as well as voltage levels - and I found the reset spiked down to only a bit under 2v, not all the way to ground. The spec sheet calls for a reset voltage levels of under 0.5v (0.1*Vcc); even though the CPUs seem to reset - it is out of spec.
After a bit of digging I determined the cause: The USB <--> TTL adapter I am using is based on the CP2102 chip. It works on 3.3v voltage levels - not 5v. So when DTR fell from 3.3v to ground, it pulled the other side of C20 from 5v to 1.7v (5v - 3.3v) before starting to raise up. The problem is the DTR from the CP2102 chip only has a 3.3v swing, not the full 5v swing, and hence I can not pull the ~RESET line from 5v down to 0v. Giving a waveform like this:
Results of the standard Arduino Reset circuit with a 3.3v DTR voltage level |
Notice how the ~RESET pulse only goes down to about 1.5v - not what we want.
The two most common USB <--> TTL adapter chips seems to be the CP2102 and the FTDI232, with an occasional PL2303 or CH340 chip in the mix. Of these the FTDI232 is considered the most mature (and was even used in some versions of Arduino's), while the CP2102 is about 1/2 the price and shows up on lower costs adapters. (The PL2303 and CH340 is even lower cost, but I have not seen too many of them sold in stand-alone adapters). All three chips run at 3.3v, output 3.3v signal levels, and will have this out-of-spec reset signal issue shown above. However, the FTD232 has the ability to optionally select 5v signal levels via the VCCIO pin. Some of the better adapter boards have a 5v / 3.3v jumper to control which voltage is sent to not only Power-Out pin, but by also routing to VCCIO are able to adjust the signal voltage levels (including DTR) as well. 5v signal levels for DTR in a 5v system. (Make sure to check the schematics, not all adapter boards enable this capability).
The CP2102 and PL2303 lack this capability, but surprisingly the CH340 has it! Again, all depends on how the board is wired.
How much of a problem is this? Not sure. The spec sheet is to guarantee a reset, but in the many boards I have tried out I have never had a problem with this out of spec reset pulse. Even so, it bothers me. My option was to start using $10-$15+ adapters, (vs the $1.80 I pay now), or find another way.. Here is what I came up with:
Addition of Q5 to provide 3.3v to 5v level shift of the DTR signal. (Still not shown is an additional 10K pull up resister on the left side of C20) |
Q5 is added in a common-base configuration to provide a 3.3v to 5v level transformation. R69/R70 biases Q5 at 2.5v so that any time the emitter falls below approx. 1.9v Q5 will start conducting. At rest when DTR is not active (High) it will be above this trip point. Independent of of a 3.3v or 5v adapter being used Q5 will not conduct leaving R28 to pull up C20 to a 5v level. As DTR falls past the 1.9v trip point towards 0v, Q5 will start conducting and soon saturate - thus following DTR, pulling down C20, and giving us a full 5v level swing. Even when DTR is presents 3.3v levels. R71 reduces the chance of noise giving false triggers when nothing is connected to the service port.
After implementing the above circuit, the waveforms now look like this:
Results of the modified Arduino Reset circuit with a 3.3v DTR voltage level |
DTR is first shifted from its 3.3v level to 5v level before being applied to C20. Allowing the reset pulse to be pulled down below our needed 0.5v. A DTR already at 5v will give the same results.
This solution adds under $0.10 of cost to the boards and will work for 5v as well as 3.3v adapters. Though I have never had a problem to date, I will be adding this level shifter to my future designs, meeting the specs of the ATmega CPUs, and allowing the use of the low cost USB <--> TTL adapters.
No comments:
Post a Comment