Sunday, April 28, 2013

Programming ATtiny

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
This blog post describes the basic steps to compile, run and debug Cosa example sketches for the ATtiny. The Cosa Soft UART (Soft::UART) transmitter makes it possible to reuse all the Cosa IOStream support directly for the ATtiny and run trace output over the Soft UART without modification of sketch code. The implementation only requires a single output pin.  

Fig.2: The ATtiny breadboard version of CosaButton example sketch
Before starting you will need some equipment. Other than the ATtiny you will need a Programmer. If you have available an Arduino and a breadboard you can use them for a Programmer. More frequently programming of ATtiny devices may require either investing in an ISP or building a DIY Programmer Shield from a prototype shield and a universal ZIF socket (component cost approx. $5-6 on eBay). The available LEDs on the prototype shield may be used for the Programmers state. The soldering required is very basic. See below.

Fig.3: DIY Programmer Shield wiring
A ZIF socket allows you to connect and disconnect the chip without having to power down the Arduino. Just insert the ATtiny into the ZIF socket and fasten it by pulling down the lever, then upload the sketch as you would for an Arduino, unfasten the chip and move it to your breadboard test circuit or PCB prototyping board.

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();
}

Both 1-Wire and the Virtual Wire Interface (VWI/RF433) are available together with drivers for InterruptPin, ExternalInterruptPin, EEPROM, DHT11/22 (Temperature/Humidity), TSOP4838 (IR Receiver), NEXA Remote Receiver (RF433), HCSR04 (Ultrasonic Range Module), Soft UART Transmitter, PCD8544 LCD and the Cosa Object-Oriented Pin handling. So there is plenty to get started with.

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. 

9 comments:

  1. I have several errors when I try to burn the bootloader onto an attiny85 with an arduino Uno (R3).
    At first I put the cosa ISP-sketch onto the Uno (no problems). But when I try to burn the bootloader onto the tiny85, I get this error:
    "
    java.lang.NullPointerException
    at cc.arduino.packages.uploaders.SerialUploader.burnBootloader(Unknown Source)
    at processing.app.Editor$47.run(Editor.java:2563)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:715)
    at java.awt.EventQueue.access$400(EventQueue.java:82)
    at java.awt.EventQueue$2.run(EventQueue.java:676)
    at java.awt.EventQueue$2.run(EventQueue.java:674)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:86)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:685)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
    "

    I also tried to upload the blink-sketch from the tutorial above, but it wont work at all.
    error:
    "
    avrdude: verification error, first mismatch at byte 0x0000
    0x07 != 0x0f
    avrdude: verification error; content mismatch
    "
    ====================
    OS: OSX 10.9.2
    Software: Arduino 1.6.0
    Board: Cosa Breadboard (attiny85, 8 Mhz internal clock)
    programmer: Arduino as ISP

    Can you PLEASE help me to get this stuff working?
    greetings from germany

    ReplyDelete
  2. Install the latest version and please try again.

    ReplyDelete
  3. thanks for the fast reply, but I tried version 1.6.1 and updated my Java, but I had no luck. Have You ever tested the libraries, cores and s.o. on OSX? I have no Idea where that errors come from...

    ReplyDelete
  4. Do not have an OSX based machine but there are a fair number of Cosa users that do. Please post the error messages. It is impossible to help with no info at all.

    There is a workaround to burn the fuse/bootloader. Download one of the ATtiny cores and run that. Then switch to Cosa and do the application compile and upload.

    ReplyDelete
  5. I already posted the error code in my first reply:

    when I try to burn the bootloader onto the tiny85, I get this error:
    "
    java.lang.NullPointerException
    at cc.arduino.packages.uploaders.SerialUploader.burnBootloader(Unknown Source)
    at processing.app.Editor$47.run(Editor.java:2563)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:715)
    at java.awt.EventQueue.access$400(EventQueue.java:82)
    at java.awt.EventQueue$2.run(EventQueue.java:676)
    at java.awt.EventQueue$2.run(EventQueue.java:674)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:86)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:685)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
    "

    I also tried to upload the blink-sketch from the tutorial above, but it wont work at all.
    error:
    "
    avrdude: verification error, first mismatch at byte 0x0000
    0x07 != 0x0f
    avrdude: verification error; content mismatch
    "

    ReplyDelete
  6. If I understand you correctly you have the same error message from the Java run-time and when from avrdude on upload. In that case I would recommend that you try the workaround by burning the fuses with one of the other attiny cores and then after that try to upload the Cosa sketches. Please remember to select the correct board setting in the Arduino IDE. Cheers!

    ReplyDelete
  7. I've uploaded the CosaISP to my Uno and that seemed to work fine, no error messages, but when I try to either upload a sketch or burn a bootloader to my attiny85 via the uno i get this error message:
    "
    Arduino: 1.6.12 (Mac OS X), Board: "Cosa Breadboard (ATtiny85, 8 MHz internal clock)"

    avrdude: stk500_recv(): programmer is not responding
    Error while burning bootloader.

    This report would have more information with
    "Show verbose output during compilation"
    option enabled in File -> Preferences.

    "
    Any idea what i might be doing wrong?

    ReplyDelete
  8. After uploading the CosaISP to the Uno it must not be allowed to reset. This is done with forcing the RESET high with a resistor. Also the ATtiny85 bootloader is just for setting the fuses correctly. Last, check that you are using the ISP upload.

    ReplyDelete
    Replies
    1. So I tried using a 10k resistor between RST and VCC, I assume 10k is the correct value as thats what others have been saying. Again I was able to upload the CosaISP but still unable to upload anything to the ATtiny85 getting the same errors as last time.
      When you said check that I'm using the ISP upload I assume you mean "Arduino as ISP" as programmer?

      Delete