2015/03/26

SAM4S development board

SAM4S development board

There is a ton of development boards on the internet and I'd like to share my own. This time it's for Cortex-M4 from Atmel, the ATSAM4S in 0.5mm pitch 64-pin LQFP. The board is also good for any pin-compatible processor, such as SAM3S. I use ATSAM4S8B-AU, a 120MHz processor with DSP functions, 512 kB Flash and 128 kB RAM.

The board is not the smallest or cheapest one but it has been proved to work (it's revision 3.0 after all) and has all the necessary stuff without useless BS. It is programmed via JTAG or (micro)USB.
The pitch between the two pin headers is 1.6" and fits many larger breadboards.

The DevBoard

 

Features

  • All I/O pins routed to pin headers.
  • 12MHz crystal oscillator.
  • Fully ESD-protected USB.
  • Power supply either externally or from USB. Routed via 0.5A Schottky to 0.5A 3.3V LDO. TVS protection on the 3.3V line.
  • Precision 2.048V voltage reference can be connected via jumper, when disconnected, external voltage reference can be applied.
  • Reset button and erase jumper.
  • Full 20-pin JTAG header for connecting programmers like SAM-ICE.

 

Schematic and board

You can download Eagle schematic and board from my Google Drive. The board can be ordered from OSH Park for something under 20 USD per three boards.

Complete schematic of the development board

2015/03/21

MightyWatt resource page

This page contains the most up-to-date resources for MightyWatt. 

 

New version R3 available on Tindie with its own resource page here! If you have version 2 to 2.5, continue using this page for resources.

 
Click here to view Google Drive folder with all the resources.

 

Resources also available on GitHub.


 
Please, contact me if you find a bug or have a software request.

Latest hardware revision: 2.5

Latest sketch (firmware) version: 2.5.9 (2.5.9 calibration)

Latest Windows control program version: 1.3.1.0

Warning: You will need FW 2.5.7 or higher for Windows client 1.3.0.0 and higher.


Guides

Detailed guide: All you need to know for calibrating and running MightyWatt.
Case assembly instructions: If you have the original acrylic layered case for MightyWatt + Arduino Uno or Arduino Zero (M0/M0 Pro), these are the instructions on how to assemble it.
Communication protocol description: If you wish to use your own PC-side control program with the original sketch, this guide has information about the communication protocol which is used by MightyWatt.
Booster pack guide: A guide for the official Booster pack accessory. Increases the maximum power dissipation with a power resistor.

Arduino sketches 

Main sketch (firmware): This is the program that runs in Arduino. As of version 2.5.7, it is compatible with Arduino Zero (M0/M0 Pro), Uno and Due boards. Please note that on Due boards, it is necessary to solder its AREF (BR1) jumper to EXT (external).
Calibration sketch: Use this for calibration of MightyWatt.

Schematic and board 

Eagle: Schematic and board plus a PNG image of the schematic.

Bill of Materials

PDF file: List of all the components you need to make MightyWatt.

Windows control program

Complete C# project: A PC-side program that controls MightyWatt. Program has manual control, advanced measurement programs and data logging. The executable is located in C#/bin/Release/MightyWatt.exe
Changelog: A file containing description of changes to the Windows program.

Charts

Excel macro: A macro-enabled workbook that can import data from MightyWatt Log File and automatically update it, thus showing charts in real-time.

Calibration aid

Excel spreadsheet: Calculates the calibration values.

Acrylic layered case

SVG drawing: Contains drawings of the layers. Numbers in parentheses indicate how many layers are needed for one case.


 

How to update to firmware version 2.3.1 (and higher) and Windows program 1.0.1.1 (and higher):


Windows program version 1.0.1.1 (and higher) is only compatible with firmware version 2.3.1 (and higher). It is, however, possible to upgrade any 2.0 or higher board to this version. You will have to modify the calibration values though. Download the new calibration aid and copy the source (measured, ADC and DAC) values from your old calibration aid to the new calibration aid (or make a new calibration). You will get a set of new values which you will put into the new sketch. Also, don't forget to comment "#define ZERO" and "#define DUE" and uncomment "#define UNO" line in the sketch. I recommend reading the Detailed guide.

2014/08/26

Touch buttons with Atmel SAM4S (or similar)

I often use ATSAM4S microprocessor and one of the neat functions is capacitive sensing for touch buttons. There is a proprietary technology, QTouch, that does it. But you can make a simple touch button even easier and with half the pins. QTouch needs two pins, a capacitor and a resistor for each channel (button). I can do it with only the resistor (protection resistor, no need for a precise value) and one pin per channel.

The principle is very similar to QTouch sensing. First, you attach a button through a protection resistor (3k3 works fine) to a general purpose I/O pin. The button may be simply a piece of metal on a cable or it can be printed on the circuit board. It only has to be covered by an insulating layer. Solder mask, paper or a not very thick acrylic work well. This creates one of the plates of a capacitor and the dielectric. The second part is your finger. By approaching the button, your finger increases the capacitance and this can be measured to detect the presence of the finger thus producing a touch event.

Each pin has three possible states: high, low and high-impedance (measuring). In addition, each pin can be pulled down or high by an internal resistor, whose value is approximately 100 kOhm. We are going to use this. First, we need to discharge the capacitor. That can be easily done by pulling the pin low for sufficiently long time. A sufficiently long time is arbitrary but 5 time constants is more than enough. The RC time constant is dependent on the protection resistor and the total capacitance. A button together with parasitic capacitance can reach few tens of picofarads. So to be absolutely sure, lets use 100 pF as the capacitance value and 3k3 as the protection resistor. This translates to a time constant of 0.33 microseconds. Five time constants is 1.65 microseconds. Thus, if you rely on the built-in delay.h function delay_us(), then set two as its argument. You can see that only two microseconds are needed to prepare the button for measurement. Because you can do this in parallel for all channels, it is really fast.

Next thing is to measure the time needed to charge the capacitor. We set the pin to high-impedance mode and pull it high using the internal 100 kOhm resistor. This will form another RC series circuit, this time with a different time constant, RC = (100k + 3k3) × (button + pin capacitance). If the total capacitance is, say, 20 pF, then the time constant is 2.066 microseconds. But the internal resistor value is VERY approximate so for any accurate capacitance measurement a calibration would be needed. Having said that, we don’t need an accurate measurement at all! We only need to detect changes in capacitance. So after pulling the pin high, we simply wait until it reads 1. You can either continually poll the pin input register or set an interrupt and count the time it takes the pin to set. With 2-microsecond time constant, the pin will be high quickly so the whole measurement process is fast. One way to measure the time is to simply set a loop and wait until the pin sets. The iterator value corresponds to the charge-up time and is the result of measurement. You will need to keep a baseline time value for the untouched button. Then compare each measurement to this value to determine if the button has been (value will be higher) or hasn’t been touched. Do the measurement regularly to provide swift user interface experience. Protip: If you set the pin low after each measurement, you don't have to wait for discharge the next time.

Sample code (download here) uses touch.c and touch.h. Define the I/O port in touch.h, then call touch_init() once to setup the line and call touch_measure() to get a value proportional to port's capacitance. In the main program, watch for this value increasing, thus indicating a touch event.

touch.h:

/*
 * touch.h
 *
 * Created: 26.8.2014 19:00:00
 *  Author: Kaktus
 */

/*
 * Description:
 * Simple touch sensor demonstration.
 * Connect touch button to the defined port via approximately 3k3 resistor.
 * No other components needed.
 */

#ifndef TOUCH_H_
#define TOUCH_H_

#define TOUCH_PIOPORT PIOA
#define TOUCH_PIOLINE 0
#define TOUCH_PMC PMC_PCER0_PID11

void touch_init(void);
uint32_t touch_measure(void);

#endif /* TOUCH_H_ */


touch.c:

/*
 * touch.c
 *
 * Created: 26.8.2014 19:00:00
 *  Author: Kaktus
 */

#include <asf.h>
#include "delay.h"
#include "touch.h"

void start_discharge(void);

void touch_init()
{
    PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD;
    PMC->PMC_PCER0 |= TOUCH_PMC;
    TOUCH_PIOPORT -> PIO_WPMR = (0x50494F << 8); // registry unlock
    TOUCH_PIOPORT -> PIO_PER |= (1 << TOUCH_PIOLINE); // peripheral disable
    TOUCH_PIOPORT -> PIO_IFDR |= (1 << TOUCH_PIOLINE); // glitch filter disable
    TOUCH_PIOPORT -> PIO_PPDDR |= (1 << TOUCH_PIOLINE); // pull down disable
    start_discharge();
}

uint32_t touch_measure()
{
    TOUCH_PIOPORT -> PIO_ODR |= (1 << TOUCH_PIOLINE); // output disable
    TOUCH_PIOPORT -> PIO_PUER |= (1 << TOUCH_PIOLINE); // pull up enable
    uint32_t t = 0;
    while (!((TOUCH_PIOPORT -> PIO_PDSR) & (1 << TOUCH_PIOLINE)))
    {
        t++;
    }
    start_discharge();
    return t;
}

void start_discharge()
{
    TOUCH_PIOPORT -> PIO_PUDR |= (1 << TOUCH_PIOLINE); // pull up disable
    TOUCH_PIOPORT -> PIO_OER |= (1 << TOUCH_PIOLINE); // output enable   
    TOUCH_PIOPORT -> PIO_CODR |= (1 << TOUCH_PIOLINE); // output low
    delay_us(2); // set > 5 RC time constants; you can comment this line if you measure at longer intervals than the set delay
}

2014/07/23

MightyWatt revison 2: Now 50% mightier!

I've been using my MightyWatt electronic load for the last few months and I got some ideas to make it better. I am introducing the MightyWatt, revision 2. This time, you can buy it as a kit (fear not, most parts are assembled) on Tindie.

Complete schematic of the revision 2.

Four-wire connection
MightyWatt has now four input terminals. You can switch between remote (4-wire) and local (2-wire) voltage measurement. The signals are routed by a relay. This gives you the opportunity to exclude the resistance of cables from your measurement.
I have also redesigned the dual-range voltmeter from single-ended to differential.

Better DAC
I have replaced the cheap Microchip's DAC in favour of a higher-end DAC from Analog Devices with internal 2 ppm/°C voltage reference (AD5691RBRMZ). It is more expensive but the accuracy will be improved. The original DAC (MCP4726) is not a bad part, though. It only has somewhat larger inlinearity which cannot be eliminated by simple linear calibration. Feel free to use the MCP4726 if you don't need the improved accuracy.

Better gate driver
I have added additional compensation to the MOSFET gate driver so the current ripple is much reduced.

No LED
Because the temperature is monitored in software, I never experienced an overheat. I have decided to drop the red LED that was supposed to indicate overheat.

Input protection
There were occassional problems when transient voltages were present on the USB line. Some PC power supplies have problems filtering transients in the grid (e.g. motor switching) and it resulted in disconnection of the load. I have added a 5V transient voltage suppressor at the power-entry point.

New software and firmware
Because the load can do 4-wire measurement now, I also updated the software (C#) and the firmware (Arduino sketch). This means that revision 2 software is not backwards compatible with the first version. You can find all the relevant source files on my Google Drive (original revision 2). All the resources for the latest version can be found here: http://kaktuscircuits.blogspot.cz/2015/03/mightywatt-resource-page.html.
  • Eagle board and schematic
  • Bill of materials
  • Arduino sketch for firmware
  • Arduino sketch for calibration
  • Excel file to calculate calibration values
  • Windows software for MightyWatt control, as a C# Visual Studio project

2014/07/13

Reverse polarity and overvoltage protection

Circuits that are connected to outside world should be reasonably protected. Who knows when somebody just plugs in a different power adaptor (of course with twice the voltage and polarity in reverse). So how to account for this?

Protection circuits
Reverse polarity
You can use a diode in series and zener diode (or better – a transient voltage suppressor) in parallel in combination with a fuse. But you can do it better. First, the diode in series can be replaced by P-channel MOSFET (Q1). Drain connected to input and source to output. Gate is connected to ground. The transistor appears to be reversed and it is. But on purpose. Suppose the voltage is reversed. Then, gate is on V+ so the transistor is closed. Its intrinsic diode is reverse biased so no current flows. 
During normal operation, the current flows through its intrinsic diode but the gate, being grounded, has also lower voltage than the source so the transistor conducts in active mode. It is fully open and its resistance is the Rds(on) value. Which can be very low. In this way, the diode drop is eliminated and energy loss on transistor is negligible.
If you need to protect against voltages that are larger than the gate-source breakdown voltage (Vgs), then a voltage-limiting zener diode (D1) and a current-limiting resistor (R1) have to be added to the gate.

Overvoltage
It is possible to automatically disconnect a circuit when the input voltage exceeds a predefined level. This is different from parallel transient voltage suppressor and fuse. Blow fuses have the obvious problem of being a one-time devices. PTC resettable fuses tend to be slow and they can conduct significant amount of current even in tripped state (to stay tripped, the fuse needs to maintain itself hot). You can use electronic fuses for overcurrent conditons though.
With just two P-MOSFETs and a few components, it is possible to automatically limit the input voltage. The principle is this: A zener diode (D2) is chosen with value slightly lower than the maximum allowed voltage on the output. Then, when the voltage is higher than the zener voltage, D2 starts conducting and voltage drops across resistor R2. This lowers the voltage on the gate of Q2, which will open, raising the voltage drop across R4. The gate of Q3 sees higher voltage and Q3 thus closes, disconnecting the protected circuit from excess voltage. All without tripping any fuses or causing excessive current flow. Neat! Because you can get P-MOSFET with very low Rds(on), the losses can be minimal.
Resistor R3 and two zeners, D3 and D4, are there for gate protection just like D1 and R1. 

2014/06/22

BFuse – Electronic Fuse for Breadboard

Prototyping is a dangerous job. Not for a person if you keep the voltage down but for the components. On breadboard misplaced chips, loose connection and other errors can blow the components. To save them a fuse is a good idea. Having said that, standard fuses are not very suitable for breadboarding. Blow fuses have the inherent problem of being a one-time component. And during prototyping, a lot of overcurrent conditions can happen.

A better way is to use a resettable fuse, also known as PTC. After tripping, it turns into a high-impedance state and remains tripped until the overcurrent condition is removed. But they have disadvantages too. Just like the ordinary blow fuse, the tripping time depends on how much current is passed. For example, to achieve 1 millisecond breaking time a quick blow 1-amp fuse needs to pass 10 amps. For 1-amp PTC at 10 amps, the tripping time is around 100 milliseconds. That is way too long and way too much current. Moreover, resettable fuse still leaks some current in its tripped state because it has to keep being hot.

This leads me to a more advanced solution for overcurrent protection: Electronic fuses. They are devices made to sense the current and disconnect the load when an overcurrent is detected. This is usually achieved by FET switches, which are very fast compared to both blow fuses and PTCs.

You can make your own electronic fuse with only some transistors but the more advanced devices are mixed-signal. There are electronic fuses made by Texas Instruments, Linear Technology and STMicroelectronics. Usually used in final products because they are often optimized for single voltage. 

My BFuse

What I made is an adjustable and programmable electronic fuse especially designed for breadboards – a breadboard fuse, or BFuse. It is powered from the same line it protects. The trip current can be set from 50 mA to 1 A but it can measure current up to 6 A. BFuse consumes less than 10 mA and works in the voltage range from 3.3 to 12 V. It has reverse polarity protection (by P-FET), transient voltage suppressors both on its input and output and two LEDs for indication. A green one indicates power-good and red indicates tripped state. A reset button resets the fuse. Its on-state resistance is less than 100 milliohm, which is less than 1A blow fuses and comparable to 1A PTCs. But this resistance is the same in the whole range of trip currents. Shortest trip time is about 200 microseconds and the fuse has been successfully tested on a Statron 22A power supply.

Complete schematic of BFuse

The adjustable trip current is set by a trimmer but the fuse is programmable. Its core is a well-known ATTiny25 from Atmel. Set current and actual current (measured by current shunt monitor) can be compared using ATTiny's built-in comparator or sampled by the ATTiny's ADC. Then, the microprocessor controls a P-FET switch that opens or closes the power supply. The switch operates on high-side so there is no messing with the ground.

In-system programmable using SPI, the fuse can do a lot of tricks. It can emulate fast blow fuses, slow blow fuses, it can be latching or auto-restart or it can allow some inrush current at startup to charge capacitors without tripping. Because it can measure up to 6A, there is a lot of space for tailored operation. It is also small, only 18×36 mm, and takes very little space on breadboard. 

BFuse on breadboard

To be fair, there are some drawbacks too. First, it is more expensive than a simple PTC and needs some minimum voltage. Second, it is not as fast as a commercial electronic fuse, nor it can limit current in linear mode. BFuse can only switch on and off. But it is a great tool for breadboarding and it definitely saved me many components.

If you're interested, you can find source files (code, schematic and board) on my Google Drive. The code uses ADC and allows inrush current at startup. You should set the ATTiny to 1 MHz and turn on the 2.7V brown-out fuse (BODLEVEL = 0b101).
 

2014/05/02

Zero Resistance Ammeter

Is it sorcery to make an ammeter with zero resistance? Not really. This kind of design has been used for ammeters in corrosion science where any voltage drop would influence the experiment.

Most commonly, current is measured by passing it across a shunt resistor, then measuring the voltage drop. You can even get specialized amplifiers for that purpose (INA210-series, INA199, ZXCT1110). But such a technique creates the necessary voltage drop. What if you want not to drop any voltage and yet measure the current? There are Hall-effect probes which measure the magnetic field created by flowing current. They are good especially for larger currents. For everything else, there's Mastercard Zero Resistance Ammeter.

The ZRA is an active device; it needs a current source equal to the current being measured. For low currents, only a single op-amp is needed for maintaining equal voltages on the two input terminals. For larger currents you can boost its capabilities by a single transistor. A second op-amp (or current shunt monitor) is needed to scale the voltage drop for external measuring device or ADC.

Complete schematic of the zero resistance ammeter

My design uses a single 1.2V NiMH battery as the power source. Because the op-amp needs at least 2.2V, I put a small DC switching boost regulator to increase the voltage. A switched-capacitor type would work likewise.

The positive terminal is connected to ground. Current is sinked and for the negative terminal it is sourced from the battery. The current passes through a NPN transistor, a Schottky diode (to block reverse polarity) and a shunt resistor to the negative terminal. I used a dual op-amp, OPA2376, which has a very small input offset voltage. It would work well with a cheaper type though. One op-amp senses the voltage at the negative terminal and adjusts the current to the base of the NPN in such a way that the voltage at the negative terminal is kept zero. The NPN works in linear mode, lowering the voltage from the battery. The second op-amp only amplifies the voltage at the shunt resistor by a factor of 100 to have 1V = 1A. Capacitors C1 and C2 are needed for stability.

Assembled on breadboard

In the picture above, the shunt resistor is actually 0R02 and the gain was thus only 50.
From left: Trimmer for gain, OPA2376, shunt resistor, Schottky diode SS14 (bottom), FZT853 NPN, TLV61220 boost regulator with capacitors and inductor soldered directly to adaptor board, Sanyo Eneloop 1.2V NiMH battery.

1.003 V (= 1.003 A) and true zero voltage drop

The maximum current is mostly affected by heat sinking of the NPN. With a FZT853 in a rather small SOT-223, it is good for 1A. With beefier transistor, it would go somewhere around 4A, where both the current to base and the current from the battery will limit further expansion. On breadboard, keep it under 1A. I learned the hard way that at 2A, the board sometimes melts :-)