Optimised libraries for ATtiny

This is an optimised set of C libraries for ATtiny

last update : 2013/05/01

Direct link to the zip file : http://balbarie.com/arduino/TinyLibrariesSet.zip


The provided example run on 16 MHz clock ATtiny45 (internal oscillator).

TinyIrqHandler.h

Full management of PCINT0 . Only one function to install your interrupts routines. Nothing else to handle.

IRQvecteur(byte irq, void (*adresse)())

example:

void MyPin1Routine()
{
   // your code here
}

void MyPin2Routine()
{
   // your code here
}

void MyPin3Routine()
{
   // your code here
}

etc...

void setup
{
   IRQvecteur(1, MyPin1Routine);
   IRQvecteur(2, MyPin2Routine);
   IRQvecteur(3, MyPin3Routine);
}

The library saves the value of micros() at the start of interrupt in the data IRQmicros. I's interesting to enable interrupts at the start or inside your routine by the Arduino's function interrupts(), but if you have to use the value IRQmicros you have to save it before enable interrupts to ensure the value doesn't change because of another interrupt. The provided libraries TinyIRrc5 & TinySerialPlus are always doing this to let the timer's routine execute as soon as possible in order to keep a good synchro on serial transmit.

TinyIRrc5.h

Infrared receive of RC5 codes under interrupts. This library contains 2 functions and one flag data.

IRdemarre(pin number)
int IRdecode()

The repeat bit of RC5 protocole is automatically managed. If the key is a repeat then the high bit of the return is set if not this bit is clear.

Variable IRok indicate an available key.

example:

 IRdemarre(1);

byte car;
 
   // Avec suppression de la répétition
   for (;;)
   {
      if (IRok)
      {
        car = IRdecode();
        if (car < 0x800)     // Test for no repeat key
          {
          switch(car)
	{
	  case 0x41:
	     // your code
               break;
          etc..	

   // Avec répétition
   for (;;)
   {
      if (IRok)
      {
        car = IRdecode() & 0x7FF;    // suppress the repeat bit
        switch(car)
	{
	  case 0x41:
	     // your code
                break;
          etc..

TinySerialPlus.h

Asynchronous send and receive up to 19200 bauds on any pins. The library provides some additional functions to display values and strings and manage blinking of up to 5 independent leds (period is in mS, eg 1000 for 1 Hz with a resolution equal the duration of one bit * 8 (that to say 52 uS * 8 = 416 uS for a serial speed of 19200 bauds).

19200 bauds is the speed limit. If you want to use IR receive during a continuous flow on serial receive you must set the speed to 9600 bauds. At 9600 bauds you can use the IR continuously without any lost or corrupt on serial (with xon/xoff for no lost).

Sending and receiving can be start and use independently but if you want to use xon/xoff on receive you have to start the transmitter (and start the receiver if you want to use xon/xoff on transmit). Without handshaking you can use only one wire to send order or only one wire to receive report.

Defines at the top of the library are useful to set easily clock frequency (in practice 8 or 16 MHz) and speed of the link. Defines can also set the size of the receive buffer and set the Xon/Xoff handshaking for each way. You can also by uncomment the associated define implement serial transmit as AVR stdout (in order to use the AVR printf function)

TXdemarre(byte pin) // start sending
TXwrite(byte) // write a byte

TXprint(char *str, boolean crlf) // write a string with CRLF if crlf true
HEXprint(unsigned int valeur, byte digits) // write in hexa with the number of digits specified (1 to 4)
DECprint(unsigned int valeur) // write in decimal

ledperiode(byte pin, unsigned int periode) // define blink period for a led
ledstate(byte pin, boolean value) // start or stop the blinking

RXdemarre(byte pin) // start receiving
byte RXget() // read a byte of the buffer (don't call if RXcount = 0)

Variable RXcount provides the number of bytes in the buffer.

example:

void setup
{
   RXdemarre(0);
   TXdemarre(2);

   ledperiode(3, 1000);
   ledperiode(4, 1000);

   ledstate(3, true);     // Two leds in alternate blinking
   delay(500);
   ledstate(4, true);
}

void loop()
{
   TXprint("Ready", true);

   for(;;)
   {
     HEXprint(PINB, 1);
     TXprint("", true);
     delay(500);
     if (RXcount)
     {
        if (RXget() == 27)
        {
           break;
        }
   } 
}

Available functions of the example are started by the same keys on both the keyboard and the remote control.

0 --> Display available ram
1 --> Dump Tiny's registers
2 --> Dump Tiny's ram
3 --> Dump Tiny's EEPROM
4 --> Live echo (exit function only by remote control press)
5 --> Hexadecimal echo (ditto)
6 --> Display the RC5 code received (exit function only by keyboard press)

And now the main fact... The link to download : http://balbarie.com/arduino/TinyLibrariesSet.zip

WARNING : The file TinyLibrariesSet.zip can be updated without notification. In order to use the last version you have to compare datim of this file with the one you are using.

JLB

This is the configuration used to write and test these libraries.

The red breadbord with ATmega328P is my ISP programmer. It uses the ARduinoISP software.

The green breadbord with ATtiny45 uses all pins except reset :

  • One for serial RX (0)
  • One for IR (1)
  • One for serial TX (2)
  • One for yellow led (3)
  • One for red led (4)

Both are connected to the computer by USB to serial adaptator with a CP2102 chip. I bought these board by Ebay for 0,99 US $ each one.

These boards needs a little adaptation to get the DTR on a pin. At factory this signal is provided by a hole on the layout. I replace the RST pin by the DTR signal (I don't know what is the original use for this RST pin).

I put on the tiny breadbord a capacitor on reset, like Arduino Uno.

JLB

Are you aware that the BAUD rates are totally out?

I was just trying it and with a tiny85 running at 16MHz, and these defined:

#define TS_CLOCK  16000000     // The best clock
#define TS_BAUDS  19200        // Maximal speed for 16 MHZ clock

I get 10000 Baud for TX.
and i am not sure what the RX baud is as I haven't yet managed to talk to it in a way which it understands.

Furthermore with the way you are using timers, you have failed to account for the massive overhead that the ISR routine adds. In the case of your ISR(TIMER1_COMPA_vect) routine, I count about 154 clock cycles, or about 10uS, that is results in >18% error from the specified baud rate (16300Baud instead of the specified 19200).

I know the clock is running at the correct speed as the led is blinking at the correct 1Hz

19200 bauds gives a 52 uS bit. Transmitting 0 1 0 1 0 1... gives an approximate 9600 Hz on a scope. You confuse...

Try it in full duplex with live echo. It runs fine.

Try to transfert a file by the terminal (Realterm or Hyperterminal but with Hyperterminal you have to configure the automatic end line since this crasy software is filtering the Line Feed). Never a character is corrupted only some missing characters because of the lack of handshaking.

Avalaible cycles are 52 * 16 = 832. TX interrupt has the time to execute.

Your computing is false. Never 18% error !!! Timer interrupt executes each 52 uS in any way.

Other interrupts get the micros() then enable immediatly the TX interrupt (timer).

Try it...

JLB

Torturing the Serial library in all ways, I cannot get only one error...

Tome Carpenter I don't understand your post...

Try it before post unwarranted comment !

The error on the bauds rate is only the error of internal RC oscillator. RX is handled by the recommended "half a bit" method. This works fine without clock adjustement on several chips. What can I do more to satisfy you ???

JLB

jihelbi:
Tome Carpenter I don't understand your post...

Try it before post unwarranted comment !

I don't think it was unwarrented in anyway. I downloaded your zip file. Uploaded your sketch to an Attiny85 running at 16MHz as specified. The transmitted baud rate even though set to 19200 comes out at 10000baud.

I am not sure about recieving as because the two are at different speeds I cant use a serial program to send a byte and then check the response.

You are correct about the timer interrupts, that shouldn't cause an issue, the 18% figure was a moment of misunderstanding (just a delay of 8uS before the start of the packet). However be that as it may, it doesn't change the fact that the sketch I downloaded from your link doesn't put out the correct baud rate for me.

My post was a question asking what could be causing the problem. Now it turns out it was in fact the fuse setting that was wrong and the clock was running at 8 MHz rather than 16MHz that was causing the issue.
Now for the future, instead of shouting at someone who asks a question about how to fix a problem when using something you wrote, you could try and answer it rather than telling them there post was unwarrented.

Oh and my name is Tom, not Tome.

OK.

If you want it I can provide you some boards.txt to fuse correctly the ATtiny's.

Sorry for misunderstanding the real sens of your post but I'm french and not so acute with english language.

You can test full duplex by start the function number 4 (live echo) and then make a text file transfert from hyperterminal or other emulation software.

Sorry for the mistake on your name... In french "Tome" in the name of some kinds of cheese... LOL...

Best regards Tom.

JLB

Don't forget to download the latest version.

JLB

Last update today.

Minor modifications inside the code in order to save some bytes of Flash...

Some changes in the little user's guide provided (in the first post).

RXget() musn't be called if not RXcount !

JLB

Libraries update on 2013/04/15.

Thank you for your work on this! :slight_smile:
And, I appreciate the extra effort communicating in English. Merci :P!

Regards,
-Tomek