Getting started with electronics #4

Pages: Purchase log | Purchase suggestions | Projects & Arnetronics | Board interfacing & programming.

Uploading to Arduino boards

This can be a quite confusing topic initially, and continually. There are several ways to upload to the various boards. The official Arduino UNO R3 boards (and some clones) likely have a small square chip near the USB-B port. This is another microcontroller that manages the communication, and I've found that these boards works on my Mac with no problem. Some boards have a rectangular CH340G or FTDI chip instead. These work on linux no problem (user might have to be member of the "dialout" group though?). This page will cover (using linux) the more obscure upload methods I've delved into.

Arduino Pro Mini & FTDI

FTDI232 (red) connected to an Arduino Pro Mini.

First, let's look at the Pro Mini, one of the smaller, cheaper boards. There's no serial thingamabob onboard (like in the longer Nano board), but it turns out the pins on one side matches that of a FTDI board I have. Apparently there's some sort of standard here.

 Pro Mini:   DTR, TXO, RXI, VCC, GND, GND 
 FTDI thing: DTR, RX,  TX,  VCC, CTS, GND 

Note that RX and TX should swap around like that. Receive->Transmit and vice versa. CTS can apparently go to GND. There's a 5V / 3.3V jumper on the FTDI board. I didn't know what type my Pro Mini board was, but by applying 7V on RAW pin that goes to the (tiny and hard to read) regulator, I could measure (using a multimeter) the regulated VCC pin to 5V, so that jumper should be 5V indeed.

I upload as normal (upload button) with the correct board and port set, and Programmer: AVRISP MkII. As I understand it, MCUs programmed this way (RX, TX serial) need a bootloader which basically listens for uploading orders just as the chip boots after a reset/power-on (uploading will reset the MCU). Without a bootloader, the MCU won't listen, so you can't upload sketches or even a bootloader this way. To upload a bootloader or sketches to MCUs too small to host a bootloader, various ISP methods (instead involving the MISO, MOSI pins) are used. Also, some MCUs have a proper USB interface. My UNO R3 clone has a small black square ATmega32U2 acting as a serial chip, so there are really two MCUs onboard.


Arduino USB tiny ISP

Seen: USBtinyISP by Deek-Robot, and a rather barebones Arduino "bootloader board" with a handy socket and standard Arduino pin breakout. Regular UNO boards have the 2x3pin ICSP header too but if you have 20 chips to burn a lever socket like this is easier to use, hence the name I guess. If you're doing your own boards, you can add a little ICSP header so they can be reprogrammed easily, though it is extra work to wire it up.

I had to redo this photo because I noticed I had the IC flipped the wrong way around. How did I notice? Well, my sticker clearly shows the two clock pins and analog pin 0-5, and those should closely correspond to the board layout, as they do now.

When I ordered some loose ATmega328P-PU chips, one of them refused to accept uploads, likely because it didn't have a bootloader. I had bought an USBtinyISP which supposedly would be able to burn bootloaders via the 2x3 (6 pin) ICSP (In-Circuit Serial Programming) header, but could not get the thing to show up in the IDE's Port menu which was greyed out. Apparently it's supposed to be. In troubleshooting, it's useful to mouse into the IDE's Preferences and turn on both:

Show verbose output during: [x]compilation [x]upload 

Further down the road, the paranoid linux rights policies were of course standing in my way, huffing and puffing. I fixed it by typing console stuff which I promptly forgot and never understood, and could potentially have been malicious. A flaw in the desktop-user security philosophy, me thinks. After clumsily burning the bootloader I thought I'd forget about the ordeal, because I always program using the other method, but... I still had those ATtiny85s laying about...

Digging in a drawer I found an ATtiny85 dev board with no ICSP header or serial chip, but a micro USB... for power? HID purposes? Curious whether it'll do anything at all, I plug it in. The magic smoke escapes out of a wonky tombstoned||S4 diode(?).


So I make new thing.

I made a new, perhaps needlessly complex ATtiny85-ICSP interface test board.

Did the MCU survive? I decide to solder up a board of my own to investigate its health. The board got an ICSP header and FTDI header, a power LED, a MISO blinky LED, reset button, some power supply caps for good measure (just the values I had laying about). It seemed to work but I was back to fighting linux. In console, one can investigate the status of the usbtiny and whatever it is connected to:

sudo avrdude -c usbtiny -p m328p

-c is programmer, -p is target > the ATmega328P in this example! The avrdude manual has a list of target/MCU names. For checking up on the ATtiny85 (and getting more detailed verbose info) I typed:

sudo avrdude -c usbtiny -p t85 -v

This needs to be sudo or there will be permission errors. I set the Programmer to USBtinyISP. I had downloaded some ATtiny... cores (?) (another ordeal now in the past). There might be some extra options for setting target board (variant, Mhz and so). My IDE is v1.6.7, not the older one currently in the apt-get place. When I tried to upload code from the IDE, I still got an error. Looking more closely at the orange error text, I noticed it was a permission error followed two 3-digit numbers which were apparently the current USB bus - 004/017 in my case.

(Temporary fix)

The following console typy thing can be used to probe the rights of this bus/port/place.

ls -al /dev/bus/usb/004/017

-al here means full detailed listing showing rights. The digits increment as things are plugged in and out. The relevant rights were indeed dashed out. To change those rights to read and write:

sudo chmod a+rw /dev/bus/usb/004/017

While I got the numbers (temporary folder / mount place?) from the compiler/upload error, it's easier had from the console. To list all of the usb things:


Anyways, when I tried to upload the blinky code, it worked!     (ノ^ヮ^)ノ*:・゚✧

✧ Oddly enough, I can upload to the ATtiny85 using the upload button, but not to the larger ATmega328. In both cases, the Sketch > Upload using programmer menu should be used... somehow I had forgotten this is how ISP works. Trying to upload to the 328 using the button gave me usb errors and sent me chasing shadows (avrdude reporting: Programmer operation not supported and the IDE upload error: /dev/ttyUSB0: No such file or directory). The right Board, chip, clock, Programmer etc. needs to be selected under the Tools menu of course. Selecting the wrong clock will make timers (used in e.g. delay) too slow or fast.

About that ICSP header

I've been using the 6-pin variety of the ICSP cable/header. The ISP board connects to the target board/chip using 6 wires (likely a cable, unless it's being done on a breadboard).

   USB => ISP board => 6-pin ICSP cable => Target chip/board.

While the USBtinyISP board I've got details the pins, Arduino boards seem to be blank and this makes the header hard to approach. There is a small arrow, but can it be trusted? I finally got somewhere when I decided to look up the header on the Arduino UNO R3 schematic, following the connections. I also used continuity measurements to map out the pins on the various physical boards I've got, GND and pin 12 being easy to find on my UNO boards.

When making a cable the outside 3 wires needs to go around to the inside and vice versa. I got the cable wrong a few times with apparently no harm done to my ATmega328P test board. Because the ISP board supplies power to the target board, no other cables should be plugged in. But apparently in some cases that's not true and external power is needed. Some ISP boards have a jumper for power purposes I believe.

  UNO board    ISP board
  12   5V      MISO  VCC
  13   11      SCK   MOSI
  RST  GND     RST   GND
   \    \       /     /
    \____\_____/     /

For reference, SCK = Serial Clock, MISO/MOSI = Master In/Out Slave Out/In. RST = Reset.

The ATtiny85 only has 8 pins so finding the ICSP pins is easy, using the nice pinout diagrams people have made. Note that the pins on MCUs have many names/functions. The ATtiny85 boots faster than the larger ATmegas, I think because it doesn't actually have a bootloader (which listens for serial RX/TX upload boop). Anyways, I did solder on an FTDI/serial header because I think an ATtiny can sort of wing RX/TX stuff and do HID (act as an USB device). Some Atmel MCUs (like the ATmega32U4 used in the "Leonardo" board) has USB support built-in and does not require serial assistance.

I don't know if the FTDI header makes sense with that reset line. I frankensteined this. While I do have cheap "104" disc ceramics, they measure funnily so I used my newer "224" monolithic ones. Next time I make one of these boards (v2) I'll make a schematic and flip vertically when soldering the backside (or maybe draw in on baking-paper?). This board needs some flanking headers, and maybe jumpers to activity/test LEDs on some more of the pins. And power in. Shame the barrel jacks aren't 0.1" spacing compatible.

Permanent permissions solution for USBtiny and USBasp

I'm by no means a linux expert, so I'll have to guess what's going on here. The user or users of a linux system are part of certain groups. What groups exactly?


These groups have rules for stuff and here we can add a rule to set permissions. Figure out which text editor you have installed. I managed to start "pluma" from console (or is it called terminal?) by just typing pluma. Another common editor is gedit. However, to save a file where we're going, we need to be in sudo mode! We can also tell the editor the folder&filename as an argument. It apparently does not matter what the filename is.

sudo pluma /etc/udev/rules.d/ArduinoPoop.rules

Next, let's write (in the text editor) the actual rule to set the chmod.

SUBSYSTEM=="usb", ATTR{idVendor}=="1781", ATTR{idProduct}=="0c9f", GROUP="plugdev", MODE="0666"

1781:0c9f (idVendor:idProduct) is the USBtiny that I have. While you're at it, add a rule for USBasp (commonly 16c0:05dc).

SUBSYSTEM=="usb", ATTR{idVendor}=="16c0", ATTR{idProduct}=="05dc", GROUP="plugdev", MODE="0666"

Here's my guess what's going on: The == is a comparison check, not an assignment like =. The idVendor and idProduct numbers can be found when using lsusb and looking for the USBtiny device (obviously must be plugged in to show up in the list). I'm adding it to the plugdev group that I saw in my group listing. The 0666 I recognise as being a chmod number (setting generous permissions). I rebooted to see if the chmod would apply automatically. Optional:

lsusb see the devices. On my system, right after boot my figures would be something like:
ls -al /dev/bus/usb/004/003

I found this USBasp hiding, rolled into its cable. I must have bought it early on and forgotten. Some prefer it as an upload method, as the USBtinyISP is limited to programming smaller MCUs. I had to make the 10-pin cable into a 6-pin ICSP cable, which was a little bit tricky and I got the first wiring attempt wrong. It's easy to find the pinout for the male pins on the USBasp device, but the cable needs to be continuity tested from the cable end, which is flipped like a page in the book. Best to do your own thinking & testing here. Mark the GND wire with a black sharpie for later reference, or put a sticker/label on, as the 6-pin plug can mistakenly be plugged in reversed.

On my plug, the 2*5 connections are interleaved out to 1*10 wires:

Device (male)               
              Cable (female)                   6-pin ICSP (female)
+-----------+ +----------+
|  MOSI     | |      MOSI|----------(MOSI)
|       VTG | | VTG      |----------(VCC)
|_  o       | |       o  |--x                 \
        GND | | GND      ¨|---------(GND)  --- \  RST SCK MISO
   RST      | |      RST  |---------(RST)  --- /  GND MOSI VCC
         o  | |  o        |-x                 /
 _ SCK      | |      SCK _|---------(SCK)
|        o  | |  o       |--x
|  MISO     | |      MISO|----------(MISO)
|        o  | |  o       |--x
+-----------+ +----------+

There's a 10 -> 6-pin adapter one can buy (1€), but I didn't want to wait. The USBasp (1.5€) is cheaper than the USBtinyISP (3€). But, the latter also has a 6-pin header and sometimes come with a 6-pin cable so that's something to consider.

2018: Adventures with the ATtiny2313A-SU and USBasp

I bought who ATtiny2313A-SU on a whim, but they're not breadboard friendly so it took until I got a SOP-20 breakout board to have a go. I thought I might not be able to program it due to the limited program space (and perhaps lack of support). However, by using the latest Arduino IDE (1.8.5 writing this) and the GitHub SpenceKonde/ATTinyCore it was almost a breeze. Almost. I enabled LTO and blinky became <700 bytes, which is still probably a lot compared to asm, but I'm satisfied for now.

ATtiny2313A-SU on breadboard

Because I used the USBasp, I could check up on the unit from the linux console:

sudo avrdude -c usbasp -p t2313 -v

I wasn't satisfied with using the slow internal clock though. Well, it's not that I had a project in mind which needed more speed, but I wanted to test out some 20Mhz crystals I had laying about.

After quite a bit of reading about the fuse bits, I decided to use a fuse calculator and then Avrdude to set the "lfuse" from console. I chose 0x0C, which was not the right choice. You see, I had gotten conFUSED!!! MCU looked bricked. It would no longer respond to Avrdude.

Turns out I had inverted the lfuse bits I wanted to set, so now the MCU was looking for an external square-wave clock (on XTAL1 / leg 5). My blink led did eventually come on, and I think the leg floating worked as a chaotic clock pulse. Anyways, I've been playing around a bit with square-wave generation, so I try a 555 outputting 165Khz (randomly chosen, measured by multimeter in Hz mode) on XTAL1. The MCU now runs blink slowly! However, it still does not respond to Avrdude's prodding (it can apparently communicate at this speed if in "slow mode"). Then I program an UNO to generate a faster, 8Mhz signal. Success! Avrdude can now see the MCU, and I use it to set the lfuse to 0xFF instead (default for internal clock was 62?). After unplugging, detaching the 8MHz wire, and putting a crystal across XTAL1&2 with proper caps... everything appears to be working and I can Upload using programmer via USBasp (note that the ATtiny core I used has its own USBasp programmer option down the list).

I've read that one can set fuses with "Burn Bootloader", but... I'm not sure what else that leads too.

Pages: Kickstart, Storage & Extras, Workbench & Locale, Install

Photos/Art by Arne Niklas Jansson