MiniDrv - simple firmware (source code)

Someone recently asked me for a simple firmware, easy to understand, so I wrote this firmware, and thought I could share it. I named it MiniDrv (as in minimalistic driver) - it only has 18 lines of code (not counting comments).

//MiniDrv -- minimalistic driver firmware (no blinkies)  --  DrJones 2014
#define F_CPU 4800000                    //use fuses  low:0x75  high:0xff
#include <avr/io.h>
#include <util/delay.h>
//change modes here; just change/add/delete values 
uint8_t modes[]={8,90,255};              //PWM values, 5..255
int main() {
  DDRB=2;                                //define PB1 as output
  TCCR0A=0b00100001; TCCR0B=0b00000001;  //PWM setup, 9kHz
  EEARL=4;EECR=1; uint8_t mode=EEDR;     //read from EEPROM
  if (mode>=sizeof(modes)) mode=0;       //check if invalid
  OCR0B=modes[mode];                     //set PWM level
  EEDR=mode+1;                           //next mode
  if(EEDR>=sizeof(modes)) EEDR=0;
  EECR=4;EECR=4+2;  while(EECR&2);       //write to EEPROM
  _delay_ms(1000);                       //delay for memory (or nomemory) to kick in
  EEDR=mode;                             //memory: use this mode again   \  use one of these lines
  //EEDR=0;                                //no memory: restart from 0   /  use one of these lines
  EECR=4;EECR=4+2;  while(EECR&2);       //write to EEPROM
  while(1) {}                            //endless loop
}

Change modes and number of modes in the modes[]={...} line, just add, delete or change values.
Choose between (classic) memory and no-memory by uncommenting one of those lines near the end.

License: Free for registered BLF users.

Use low fuse 0x75 and high fuse 0xFF.

Looks familiar!

Thanks for sharing

That’s great thank you for sharing. One question (im a beginner in C) why is there a while loop, is it for the PWM to keep running? As everything is in Main that just runs once when powered up yes? Im gonna enjoy playing with this :slight_smile:

EDIT: 100th post, better do a give away 0:)

EDIT EDIT, maybe not, staying on 99 which theres been for about the past year, strange. :expressionless:

Thanks DrJones, this is pretty neat!

What are the differences between MiniDrv having 9kHz PWM vs the 18kHz of Nlite or lucidrv, as I also see that lupodrv is 9kHz.

Is the following assumption correct, in saying that 9khz would always be better, performance wise, unless you need a moonlight mode, then 18khz would be able to get “lower”?

is 9kHz “phase correct”?
is 18khz “fast pwm”?

I am trying to remember this correctly, but I believe a stock Qlite driver, runs a “fast pwm”, but only 254 out of 255 pwm cycles are used, and this causes a pwm “blip” where “phase correct” pwm at 9khz would not have this blip?

Nlite has a pwm frequency of 18kHz, is this “fast pwm”, thus also having the same pwm “blip” on high that the Qlite has?

If this thread is the wrong place to ask these kind of questions, please tell me. I have been really really interested in custom firmware for the ATTiny13A based drivers for a while now, and have tried to wrap my head around everything, but have been a little intimidated, as I have no programming experience, aside from Arduino based coding.

Something like MiniDrv, is simple enough for me to not feel completely intimidated to try out. I like when I can understand every line of code, before messing with anything, and this code is about as simple as it gets. I just want to completely understand every part of it.

Then if I can overcome some of my fears, and get accustomed to this process, then maybe I can try some more complicated firmware in the future.

P.S. I have already done reflashing of atmel based MCU’s in the past, so the reflashing process itself doesn’t scare me at all. I just need to understand the code, in order to want to mess with it at all. I’ve learned doing Arduino projects, that it’s not fun at all if you just connect stuff, run someone elses code that you don’t understand, and simply watch the board “do stuff”. It’s much funner if you can understand the code enough to be able to at least modify it to your needs.

It's pretty much the same with me: I don't like to use code I don't understand.

The only advantage of 18 kHz (fast PWM) is that 9 kHz (phase correct) sometimes gives an audible noise. lupodrv has 9kHz because it's older.

The only disadvantage of fast PWM is that, depending on the exact mode, '0' doesn't completely switch off, or 255 doesn't completely switch on. NLITE doesn't have the 'blip', 255 is completely on, but 0 isn't completely off. However since with 18kHz you need a minimum value of around 7 to activate the AMC7135, the value 0 doesn't activate them. It would be a problem with driving faster electronics (like a FET) though. In phase correct PWM, both 'ends' are fine which is why I chose it here.

Very nice and very easy to understand.
Still up to date there is no code example how to achieve 18kHz PWM (but at 9, I didn’t see PWM even with a fan test).

You can always make attiny run at 9.6MHz with low fuse: 0x76 and F_CPU 9600000 resulting in 18kHz PWM…

Nice job! Simple, elegant and gets the job done.

Couple thoughts:

- Phase correct PWM doesn’t offer any benefit in this application, ordinary sawtooth PWM works fine and gives a higher frequency.

- With 4.8MHz main clock and sawtooth PWM with a top value of 255, you get a 18.75KHz PWM frequency.

- With a 9.6MHz main clock, you get 37.5MHz (just mind figure 18-1 in the Tiny13A datasheet - the chip needs 2.7V for 9.6MHz operation)

- If you change the top value (use timer mode 7, and store a top value in OCR0A) you can get higher frequencies - eg, a top value of 127 and 9.6MHz operation gives you 75KHz PWM.

  • If you replace the ATTiny13A with an ATTiny25V and use its 64MHz PLL as the timing source, and use a top value of 63, in theory you’d get 1MHz PWM. But that probably won’t work :smiley:

I just tried the program, but I can't get it to work. Tried several times. Between each attempt, I flashed other programs and they worked. I'll again later to see what is going wrong. Only change I made was to this line:

uint8_t modes[]={8,90,255};              //PWM values, 5..255

Changed to:

uint8_t modes={5,25,75,255}; //PWM values, 5…255

Does it compile without any errors or warnings?

Yes it does. Also, I erase memory prior to flashing. Have you tried this program yet?

Very nice DrJones! No need for the added complexity of the Watchdog Timer. And people can easily switch to fast-PWM by setting TCCR0A = 0x23 if they'd like since the PWM value is never 0 (the only issue I see with fast-PWM).

Program runs fine here.
Only cons for me is the no memory mode, it is not how I like it, I like to go to the next mode with a click(or doubleclick) but this always starts from 1st mode. I made the delay bigger to solve this
I also would suggest to add sleepmode, especially in the moonlight mode it makes a huge differents if you can save 1mA and it doesnt makes it harder to read in my eyes…

Thank you Werner. Good to hear that. I will figure out what I did wrong.

Thank you Dr.jones for the very useful code and the many others you have contributed here. Not to many years back this was all just a dream for most of us, having the modes we liked and eliminating the one’s we didn’t like. You have made a big difference in the enjoyment of this hobby for me and many others, your work is much appreciated! :wink:
.
I would like to know if there is any way to make a lower moonlight mode besides adding a resistor and turning the amc7135’s off. The pwm value of 5 in luxdrv gives me 5 ma if I remember correctly. But when you start stacking more chips the moonlight mode increase.
So Is there any way to have say a 1 ma current or less with a 2800ma driver just by changing the code in some way? Is it even possible?

Try a PWM value of 4 instead of 5. You can do a test version with 1,2,3,4,5... and see which is the lowest that'll light the LED.

I tried pwm value 4 several times with different 2800ma drivers but they always seem to start to flicker after a few minutes. 5 has always been stable.

On my 2.8A drivers, PMW 4 run fine while 3 is not enough to light up.
It’s mostly drivers that came with light from Banggood.

I’m pretty sure all that I tested come from lightmalls, that’s the only place I have purchased any in a year or so.
What is the current at pwm value 4?
Mine acts like they want to work at 4 but start to flicker shortly after. Its not a on and off flicker, more of a brightness flicker, not super noticeable, but I can see it flicker in a dark room where very low lumens show up more.