current control with attiny45

Thread Starter


Joined Oct 31, 2019
Hi, just posting some progress on the current control project, I've gotten all my functionality into the attiny as far as blinking, fade in-fade out, strobe, etc. some fun stuff, I was working on figuring out how to digitally do what I was doing with the op amps and RC's in software and decided to write a base 2 running average algorithm, the goal being speed, code below, feel free to tear it apart haha. I haven't written it into a class yet, just wrote it in the main arduino loop to proof it out. so far it works well on the scope, the finished code will have a maximum current that can't ever be exceeded without going into shutdown mode, but the running average threshold will be lower, basically a "slow blow" fuse. the maximum current trigger will be tested every roughly 100uS, on the ADC interrupt, so any screwdrivers across the terminals will result in 100uS or less of the mosfet driving screwdriver current until it is shut down...

byte runningAverage[32];   //the buffer for samples
byte currentAverage;        //the current average (runningSum >> 5)

volatile byte count;
unsigned int runningSum;
byte counter;
byte counterA;

void setup() {
  for (byte i=0; i<31; i++)
    runningAverage[i] = 0;
  DDRB = 0b00000010;
  TCCR1 = 0b01100111;
  OCR1C = 0xFF;
  OCR1A = 0x20;
  TIMSK = 0b01000110;

  ADMUX = 0b00100011;
  ADCSRA = 0b11101111;
  ADCSRB &= 0b11111000;

  counter = 0;
  counterA = 1;

void loop() {


ISR (TIMER1_OVF_vect){


ISR (ADC_vect){
  if (count == 255){
    //OCR1A = ADCH;
    count = 0;


//this method should store the sample in the array adds the sample to the running sum, and subtract
//the n-32 term from the running sum
void takeSample(byte sample){
  runningAverage[counter] = sample;           //store the sample in the buffer
  runningSum += sample;                       //add the sample to the running sum
  runningSum -= runningAverage[counterA];     //subtract the oldest sample from the running sum

    if (counter >= 32)
      counter >>= 5;
    if (counterA >= 32)
      counterA >>= 5;
  currentAverage = (runningSum >> 5) & 0xFF;           //divide sum by 32 to get average
  OCR1A = currentAverage;


Joined Mar 10, 2018
I like the attiny a lot, use if tor many low end solutions.

The issue you have I think is 100 uS is a long time in the life of a low Rdson MOSFET
looking into a short. Thats a recipe for hot spot silicon melting on the die. Its just too
long a time to exceed safe area considerations.

An alternative shown below, design is single chip, might be of interest. The design I think
will kill drive < 1 uS, I would need to verify but datasheet specs seem to indicate it. The com-
parator is good for 150 nS approximately, I think the kill signal on the PWM happens in a
gate delay, maybe 10 - 20 nS, I would have to verify that.

The IDAC and external R develop the Vref needed for the comparator. Comparator configed
for 10 mV hysteresis for noise considerations.

The comp sets the D to kill the PWM output, A register write is used to reset the D and PWM
when fault clears. I just realized I should add another 1 bit register in order to poll fault cleared
coming from comparator. Or just add some simple internal HW to detect and clear the D.

Note most of the parts other resources not used, right hand window shows resources used/left.

This is PSOC 4M, low end family, dev board is $ 10, compiler and IDE free, PSOC Creator.


The symbols on schematic are drag and drop from onchip component library. "Component"
is an onchip resource. Attached is a catalog of the onchip components. Note this list is for
PSOC 5LP, the 4 family a subset.

You wire them up with a tool, internally and to pins, hit the build button, and IDE generates
API code for use and other setup code for chip startup.

The MOSFET and R's are offchip.

Note I initially looked at using onchip SAR to do the Current sense as it will do a differential
measurement of a shunt in ~ 6 uS. But that seemed to long to me so comparator was choice.

Regards, Dana.


Last edited:

Thread Starter


Joined Oct 31, 2019
I'll look into that design, I don't know much about the psoc stuff you're mentioning but will investigate. I can easily configure the adc to run at a much higher sampling rate, since I'm not using the full 10 bit resolution anyway, I think I can get it down to a couple uS, I'll just need to change the interval of sampling for the averaging algorithm, shouldn't really slow anything down beyond a few nS for the add during the ADC interrupt, I was basing my assumption of 100uS being safe based on the cranking amps of the typical battery that will be used in this system, as well as the specs of the FET, faster fault during a short is of course, always a good thing


Joined Mar 14, 2008
You need to look at the safe-area graph in the data sheet for the MOSFET you are using.
Example below or a BUZ11 MOSFET: