One of the unique things with the Cosa platform is that the full range of integrated classes can be used for all Arduino boards and ATtiny/ATmega processors. Cosa allows code to be developed on a standard Arduino board and more or less reconfigured and compiled for an ATtiny. No extra cores are necessary.
With todays technology it is both easy and cheap to program micro
controllers. The Cosa framework together with the
Arduino IDE makes it possible to achieve a very fast prototype turn-around development loop. From code change to test on the ATtinyX5 (ATtiny25/45/85) typically within a minute.
![]() |
| Fig.1: Arduino DIY Programmer Shield |
![]() |
| Fig.2: The ATtiny breadboard version of CosaButton example sketch |
![]() |
Fig.3: DIY Programmer Shield wiring
|
The Cosa ISP sketch is part of the Cosa example tools code and may be found in the Cosa example menu (File>Sketchbook>hardware>Cosa>Tools>CosaISP). The Cosa core contains support for ATtiny (ATtinyX4, ATtinyX5 and ATtinyX61).
When using a new ATtiny for the first time it is important to burn the "bootloader", i.e. set the fuse bits. If you forget this the sketches will not run correctly. Especially the Cosa Watchdog/RTC timer will not work correctly.
![]() |
| Fig.4: Burn ATtiny45/85 Bootloader (Fuse bits) |
Insert the chip into the ZIF socket, select the "Serial Port" for the Cosa ISP in the Tools menu, select the ATtiny45/861/85 in the board menu, and then select "Burn Bootloader". You only need to do this once per chip. Programming is now simply inserting the chip into the ZIF socket, uploading through the Arduino Programmer to the ATtiny and then removing the chip and inserting it into the breadboard or socket on a PCB.
I would recommend that you always get the sketch running first on a standard Arduino and then port the sketch to the ATtiny. When porting it is important to fully understand the footprint of the sketch and reduce it to the available memory on the ATtiny. This might require trimming away to get within the limited memory size both program and data memory. Especially the amount of data and stack memory (SRAM) used. Remember that the ISRs must be able to execute "on top" of the deepest function call in the sketch. The Arduino IDE reports the program memory size and will not build if the sketch is too large.
Debugging on the ATtiny is even more difficult than on the Arduino. Most applications will need all pins and hardware units. Cosa provides serial output from the ATtiny using a single pin and a simple software UART transmitter. It is implemented with the serial output support, OutputPin::write() method, and mimics an UART output port.
namespace Soft {
class UART : public IOStream {
public:
...
virtual int putchar(char c)
{
// Add start and stop bits and write to output pin with given pulse width
uint16_t d = ((0xff00 | c) << 1);
m_pin.write(d, m_bits + m_stops + 1, m_us);
return (c);
}
...
};
};
A synchronized delay loop is used instead of a timer and interrupt service routine to keep the memory footprint low and not allocate other hardware resources. Special care must be taken to avoid affecting the sketch timing as interrupt handling is turned off during the transmission of a character. At baudrate of 9600 that is in the range of 1 milli-second.
On the ATtiny you should/must alway place literal strings (constants) in program memory. The Trace support macros in Cosa does this for you but when using the IOStream always use PSTR() together with IOStream::print_P() and IOStream::printf_P().
![]() |
| Fig. 5: USB to UART module |
A USB to UART module can be used to establish a connection to the Arduino IDE serial monitor on your host machine. These module are very cheap (approx. $2 on eBay) and work nicely as they
contain internal buffers for the input and output UART data stream and can power your breadboard circuit with both 5V and 3.3V (check current limits). You could also connect to one of the extra UART ports on an Arduino Mega. Please remember that only serial output is currently available. No code changes are necessary to achieve trace output from the ATtiny. And only a single output pin is required.
It is also possible to use an LCD for sketch and trace output. The Cosa PCD8544 LCD driver is available for the ATtiny. There is a reduced version of the system font (5x7) to keep program memory footprint down. Replacing Soft UART output with the LCD is made easy as both are Cosa IOStream::Device's. In many cases only a single line of code needs changing.
In the Cosa example sketch folder there are a few demonstration sketches specifically for the ATtiny85. You can find them in the folder named Tiny. The CosaTinyReceiver is especially interesting as it uses the LCD driver together with the Virtual Wire Interface Receiver. The sketch will wait for messages from an Arduino and/or ATtiny running the CosaVWIsender sketch and display the measurements together with some statistics, battery status and tick count.
![]() |
| Fig.6: CosaTinyDHT11 and CosaTinyReceiver with PCD8544 LCD |
Let us take a look at a full example sketch. The below sketch acts as a wireless DHT11 sensor and reports humidity and temperature readings back to the CosaTinyReceiver or CosaVWIreceiver sketches. With the support in Cosa the code is very straight forward.
// Allocate instances and bind to pins
DHT11 sensor(Board::D1);
VirtualWireCodec codec;
VWI::Transmitter tx(Board::D2, &codec);
const uint16_t SPEED = 4000;
...
// Message with DHT11 reading
struct msg_t {
uint16_t nr;
int16_t humidity;
int16_t temperature;
};
...
void setup()
{
// Start watchdog and virtual wire interface
Watchdog::begin();
VWI::begin(SPEED);
tx.begin();
}
...
void loop()
{
// Read sensor and send message every two seconds
static uint16_t nr = 0;
SLEEP(2);
msg_t msg;
if (!sensor.read(msg.humidity, msg.temperature)) return;
msg.nr = nr++;
tx.send(&msg, sizeof(msg));
tx.await();
}
VirtualWireCodec codec;
VWI::Transmitter tx(Board::D2, &codec);
const uint16_t SPEED = 4000;
...
// Message with DHT11 reading
struct msg_t {
uint16_t nr;
int16_t humidity;
int16_t temperature;
};
...
void setup()
{
// Start watchdog and virtual wire interface
Watchdog::begin();
VWI::begin(SPEED);
tx.begin();
}
...
void loop()
{
// Read sensor and send message every two seconds
static uint16_t nr = 0;
SLEEP(2);
msg_t msg;
if (!sensor.read(msg.humidity, msg.temperature)) return;
msg.nr = nr++;
tx.send(&msg, sizeof(msg));
tx.await();
}
More details on Arduino as an ISP may be found here.
[Update: 2013-06-05]
The Cosa now supports ATtinyX4, ATtinyX5 and ATtinyX61. A SPI master driver is now implemented (USI), and the SPI drivers (ADXL345 and NRF24L01P) are available for ATtiny.
A TWI slave device is also available. This allows ATtiny's to be used as slave units on the TWI bus. This could be for a standard Arduino or even a Raspberry Pi and may be used to bridge other interfaces such as OneWire and VirtualWire.
All LCD drivers work with ATtiny.
[Update: 2013-07-16]
The USI based I2C slave and master device driver for ATtiny has now been completed and device drivers are being ported.
![]() |
| Fig.7: ATtiny85 running LCD device driver benchmark (CosaLCDspeed). |
The TWI master device driver allows ATtiny85 to connect to an LCD (HD44780) using an I2C IO expander.
![]() |
| Fig.8: ATtiny84 acting as a Virtual LCD device (I2C slave device) |
Also a Virtual LCD device driver (VLCD) has been introduced. It allows higher performance I2C LCD connection and may be used with for instance an ATtiny84 running the 4-bit parallel implementation of the LCD device driver. In fig.8 above the Arduino Nano connects to a Virtual LCD device on the I2C bus. The device is implemented with an ATtiny84 running LCD device driver in 4-bit parallel access mode.
[Update 2014-01-05]
The Cosa Tools directory (in examples) contains an implementation of the STK500v1 protocol and may be used as an ISP alternative. There is also a TWI scanner to help debug TWI drivers.
[Update 2014-03-01]
The Cosa Nucleo support for multi-tasking may be used with ATtiny. Please see the Nucleo example sketches. They include a variant of the blink sketch that will run three threads; one for the LED, one for LED controller that changes the blink frequency and the main thread in the background. The main thread will also power down while waiting for the next watchdog tick.














