Using micros() the sketch compiles to 398 bytes and times at 1400-1800us (with very inconsistent timing)
Using millis() the sketch compiles to 414 bytes, and times at 1120ms consistently.
In constrast, the new delay() and delayMicroseconds routines give:
delayMicroseconds(1000) compiles to 266 bytes, times at 1064us
delay(1000) compiles to 252 bytes, times at 1070ms
An obvious problem with using millis() or micros() is that the timer overflow counter is only incremented every 256 clock cycles, ie. every 213us at 1.2MHz. With millis() this is then scaled by 5/19/37 for 1.2/4.8/9.6MHz. These don't quite give exact ms values. At 1.2MHz for example, 2565=1280 clock cycles and 12800.833=1066us.
micros() fares even worse, since the time has increased by 213us for each ovrf++ (at 1.2MHz). And because there's no way of controlling exactly when these functions are executed, ovrf may have increased beyond the required timing value, being some multiple of 213us larger than desired. (Unless 213 happens to be an aliquot part of your required duration.) This also means that micros() can't deal with periods less than 213us.
I think that with higher clock speeds and with longer delays millis() and micros() are probably adequate. But micros() is not too good for actually counting microseconds.
Using micros() the sketch compiles to 398 bytes and times at 1400-1800us (with very inconsistent timing)
Using millis() the sketch compiles to 414 bytes, and times at 1120ms consistently.
This is quite expected from the current micros() routine at clock clock rates
I am very surprised they are so large though
In constrast, the new delay() and delayMicroseconds routines give:
delayMicroseconds(1000) compiles to 266 bytes, times at 1064us
delay(1000) compiles to 252 bytes, times at 1070ms
An obvious problem with using millis() or micros() is that the timer overflow counter is only incremented every 256 clock cycles, ie. every 213us at 1.2MHz. With millis() this is then scaled by 5/19/37 for 1.2/4.8/9.6MHz. These don't quite give exact ms values. At 1.2MHz for example, 2565=1280 clock cycles and 12800.833=1066us.
Well I am seriously thinking that I am going to increase the timer interrupt rate in a future version
I think that with higher clock speeds and with longer delays millis() and micros() are probably adequate. But micros() is not too good for actually counting microseconds.
I am fully aware of the limitations on the uS routines. However I will work on improvements.
The problem with your routines is they fail completely on clock speeds below 1 MHz. Not a huge deal with uS since "microsecond"
timing and overhead would be pretty awful at 128 or 600 khz. BUT working millisecond timing is important.
I may set it up so it switches routines based on clock speed
Yeah, I need to have a look at the slower clock speeds. 600kHz might not be too terrible, but I can see 128kHz being awkward. I'll give it some thought. (Perhaps 1MHz << 8 is close enough?)
A reasonable millis() can be done, but a robust micros() eludes me at present. With some modified functions I can get these results:
Been a bit busy last few weeks, but tried a couple of alternative ways to improve the timing functions. None were much better sadly.
Did discover a couple of other things while playing about:
Removing the init() function from wiring.c and pasting the code into main() (main.cpp) seems to save 92 bytes if you don't need the timing functions. A "bare minimum" sketch normally compiles to about 194 bytes, but moving the init() code reduces it to 102 bytes. The overhead comes back if you call any timing function, but it doesn't if you're not using those.
Is there a reason for "(val / 4) * 4"? Replacing it with "OCR0B = val" should work and avoids the overheads
On the subject of analogWrite, I needed full control over the PWM output so wrote this:
void configPWM(uint8_t pwmmode, uint16_t prescaler) // set PWM mode and prescaler frequency
{
if (pwmmode){
TCCR0A = _BV(WGM00);} // set to phase correct PWM mode.
if (!pwmmode){
TCCR0A = _BV(WGM00)|_BV(WGM01);} // set to fast PWM
if (prescaler == 8){
TCCR0B = _BV(CS01);} // clk/8 prescaler
else if (prescaler == 64){
TCCR0B = _BV(CS01) | _BV(CS00);} // clk/64 prescaler
else if (prescaler == 256){
TCCR0B = _BV(CS02);} // clk/256 prescaler
else if (prescaler == 1024){
TCCR0B = _BV(CS02) | _BV(CS00);} // clk/1024 prescaler
else{
TCCR0B = _BV(CS00);} // no prescaler (Default setting.)
}
I've tested it at 1.2MHz and the measured outputs are pretty close to the theoretical - slightly lower, but possibly just due to chip tolerances. The nominal FAST output (pwmmode=1) with prescaler=1 should be 4687Hz, I measure it at about 4460Hz. The nominal PHASE CORRECT output (pwmmode=0) with prescaler=1024 should be 2.3Hz, I measure it at about 2.1Hz.
The function compiles to 68 bytes, with an additional 8 bytes for every reuse.
I just like this tiny13 MCU , even more than ATtiny85, some litle effort and you can do great things with little resource.
Many thanks to smeezekitty - you did great job with this core.
I find some fine two channel volt meter here - MrПоделкинЦ Blog: Двух канальный вольтметр на Attiny13 и 74CH595
and with this small serial library - Nerd Ralph: AVR half-duplex software UART supporting single pin operation
( only 64 bytes more on flash work also great with ATtiny85) i manage to do some modifications and to create this small ATtiny13 two chanel Console terminal volt meter.
I use LP2950ACZ-5.0 (5V - 0.5%) LDO for power supply and for reference also ( 100mA max. current), 10KOhm input resistors , and result is pretty accurate ( 4.096 V , 0.728 V with my cheap volt meter ). And a little unnecessary graphics purely to try to see what can do with so little memory.
#include <BasicSerial.h> // Samo TX ( SALJE Serial)
//#include <BasicSerial3.h> // TX i RX( SALJE I PRIMA Serial) #include <util/delay.h>
//////////////////////////////////////////////////////////////////////////////////////////////////////
// #define UART_Tx 3 - U BasicSerial.S tj. Po defaultu Pin 3 ( PB3 ) - 115.2kbps ako je 9.6 MHz-a
void serOut(const char* str){
while (*str) TxByte (*str++);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
#include <avr/pgmspace.h>
// Ispis na istoj poziciji u externoj konzoli - pre svake komande mora Escape - \033 ( Umesto \033 moze \x1B ):
// \033 - Escape
// [2J - Clear screen
// [H - Go to home position (0,0)
// [0;36m - color tirkiz
// [0;34m - plava , [1;34m - svetlo plava
// [?25l - hide_cursor
// [4m - underscore
// [0;m - Normal color za sve
// [0;5m"; - blink
// [1;5m"; - blink bold
// \033[m - stop za blink
prog_char Message0[] PROGMEM = {
"\033[H\n\033[1;34m#\033[0;31m-------- \033[0;36mQ"};
prog_char Message1[] PROGMEM = {
"\033[H\n\n\033[1;34m#\033[0;31m-------- \033[0;32mQ"};
prog_char Message2[] PROGMEM = {
"\033[1;34m### \033[0;m\033[1;5mATTINY13 VOLT METER\033[m \033[1;34m###\033[?25lQ"};
prog_char Message3[] PROGMEM = {
" \033[0;31m--------\033[1;34m#Q"};
prog_char Message4[] PROGMEM = {
"\033[1;34m###########################Q"};
Thanks for sharing. Although it begs the question on why you are overriding the ADC functions.
To kosine:
I have noticed your feedback but I haven't had time to implement anything.
That /4 line was for testing and somehow it slipped through. It will be fixed in the next release
Just received two attiny13a PU.
Plan 1: use it to drive a 4-pin RGB led. User shud be able to control intensity of each color using a push-button.
Plan 2: use it to drive a single(may be multiple, but don't really need it now) WS2812 based neoPixcel. Here also user should be able to control the individual color using push buttons.
In both of above case, either 3 push switch can be used to change individual color intensity with a step value of say 32 or 64. OR 2 push switch can be used; one for select the color to change and other to change the color intensity by a step value.
Should I burn a bootloader to the tiny? Please suggest how can I keep the code below 1K.
sudhirkhamari:
Plan 2: use it to drive a single(may be multiple, but don't really need it now) WS2812 based neoPixcel. Here also user should be able to control the individual color using push buttons.
I did THIS on attiny13a, most is not relevant here, but I wrote a fast ws2812 driving routine in assembler which works a treat !!
Thanks mcnobby. I hv gone through your post on dmx/attiny. I am planning to leverage from the same. This is the t13 i bought:http://m.ebay.com/itm/201190520005?nav=SEARCH
Could you please suggest me what should i put in boards.txt file.