Scott Zitek - Fab Academy 2014

Embedded programming

Week 8 Assignment

The assignment for this week is to read a microcontroller data sheet and program our board to do something, with as many different programming languages and programming environments as possible. Our "board" refers to the hello.ftdi.44.echo circuit board that we created two weeks ago as part of the electronics design assignment. The original hello.ftdi.44.echo circuit board has an ATtiny44a and a FTDI USB to serial interface. I modified the design to make a circuit board with these features plus a pushbutton input and an LED output. When I made the board two weeks ago, I tested the FTDI interface echo function. However, I did not test the pushbutton or LED functions so I am not positive that they both work.



Reading a microcontroller data sheet

I started out by getting a copy of the data sheet for the Atmel ATtiny 44a microcontroller. It is incredible that a $1 microcontroller has so many features that it takes 258 pages to explain. I found a lot of useful information but also found many details that I did not understand.

Data sheet highlights


Gerd's AVR assembler gavrasm in Linux

  1. I began by finding an example program from Anna Kaziunas France

  2. Example asm program:
    ; Modified.Hello.Echo.Blink LED.44.asm
    ;
    ; blink LED when button is pressed
    ;
    ; Code Created At FAB ACADEMY AS220
    ; by Shawn Wallace & Elliot Clapp
    ; Last Modified 08/05/2010  - Anna Kaziunas France
    ;
    ; Permission granted for experimental and personal use;
    ;The behavior is that the LED is always on – but when the button is pressed, it turns off.;
    
    .device attiny44
    .org 0
    cbi DDRA, 1
    sbi DDRB, 2
    loop:
    	sbic PINA,1
       	sbi PORTB, 2
     	sbis PINA,1
      	cbi PORTB, 2
    rjmp loop
    
  3. I then "reverse engineered" the program to figure out how it worked. I used a plain text editor to add comments and modified it to work with the pins I had used for the pushbutton and LED.

  4. My modified and documented asm program:
    ; hello.ftdi.44.io.asm
    ;
    ; control LED with pushbutton
    ;
    ; Code Created At FAB ACADEMY AS220
    ; by Shawn Wallace & Elliot Clapp
    ; Last Modified 03/20/2014  - Scott Zitek
    ;
    ; Permission granted for experimental and personal use;
    ; 
    ; The behavior is that the LED is always on – but when the button is pressed, it turns off.;
    ;
    ; Program explanation
    ;
    ; .device attiny44 	-- directive that defines which device to assemble for (an ATtiny44)
    ; .org 0		-- directive that sets the programs origin
    ; cbi DDRA, 3 		-- CBI(reg,bit): Clears a bit of a register. DDRA is a data direction register A, 
    ;			-- clearing DDRA bit 3 makes PA3 (pin 10) an input to monitor my pushbutton 
    ; sbi DDRA, 7 		-- SBI(reg,bit): Sets a bit of a register.  DDRA is a data direction register A
    ;			--Setting DDRA bit 7 makes PA7 (pin 6) an output to control my LED
    ; loop:			-- label (must start with a letter and end with a colon)
    ;	sbic PINA,3	-- SBIC will skip the next command if the bit is clear
    ;  	sbi PORTA,7	-- Sets a bit of a register
    ; 	sbis PINA,3	-- SBIS will skip the next command if a selected bit in a port is set
    ;  	cbi PORTA,7	-- Clears a bit of a register
    ; rjmp loop		-- relative jump to label called loop (notice no colon), use jmp for really long jumps
    ;
    
    .device attiny44
    .org 0
    cbi DDRA, 3
    sbi DDRA, 7
    loop:
    	sbic PINA,3
       	sbi PORTA, 7
     	sbis PINA,3
      	cbi PORTA, 7
    rjmp loop
    
  5. I installed AVRdude, gcc-avr, gavrasm, etc.

  6. Ubuntu terminal commands to install several embedded programming software packages:
    sudo apt-get install flex byacc bison gcc libusb-dev avrdude 
    
    sudo apt-get install gcc-avr
    
    sudo apt-get install avr-libc
    
    sudo apt-get install libc6-dev
    
  7. I downloaded gavrasm. I used terminal to go to the folder where I un-archived the gavrasm files, and typed in the command gavrasm. I received the error "gavrasm: command not found."

  8. Modifications to get gavrasm to run
    sudo chmod 777 gavrasm
    
    sudo mv gavrasm /usr/bin/
    
    gavrasm
    
    -- it worked, the reply was:
    
    +------------------------------------------------------------+
    | gavrasm gerd's AVR assembler Version 3.3 (C)2012 by DG4FAC |
    +------------------------------------------------------------+
    
    
  9. I compiled my asm program (hello.ftdi.44.io.asm) using gavrasm

  10. Compiling using gavrasm
    gavrasm hello.ftdi.44.io.asm
    
    +------------------------------------------------------------+
    | gavrasm gerd's AVR assembler Version 3.3 (C)2012 by DG4FAC |
    +------------------------------------------------------------+
    Compiling Source file: hello.ftdi.44.io.asm
    -------
    Pass:        1
    34 lines done.
    
    Pass 1 ok.
    -------
    Pass:        2
    34 lines done.
    
    
    7 words code, 0 words constants, total=7 =  0.3%
    
    No warnings!
    Compilation completed, no errors. Bye, bye ...
    
  11. This resulted in a hex file called hello.ftdi.44.io.hex

  12. Contents of hello.ftdi.44.io.hex
    :020000020000FC
    :0E000000D398D79ACB99DF9ACB9BDF98FBCF92
    :00000001FF
    
  13. I then used avrdude and an avrisp Mkii ISP to set the fuses and download the program to my circuit board. I had problems getting a make file to work so I just typed the commands in directly. Using a Ubuntu terminal in the folder where my hello.ftdi.44.io.hex file is located, I typed in the following commands:

  14. Commands to set fuses and download program to the circuit board.
    sudo avrdude -p t44 -P usb -c avrisp2 -U lfuse:w:0x5E:m
    
    	avrdude: AVR device initialized and ready to accept instructions
    
    	Reading | ################################################## | 100% 0.00s
    
    	avrdude: Device signature = 0x1e9207
    	avrdude: reading input file "0x5E"
    	avrdude: writing lfuse (1 bytes):
    
    	Writing | ################################################## | 100% 0.00s
    
    	avrdude: 1 bytes of lfuse written
    	avrdude: verifying lfuse memory against 0x5E:
    	avrdude: input file 0x5E contains 1 bytes
    	avrdude: reading on-chip lfuse data:
    
    	Reading | ################################################## | 100% 0.00s
    
    	avrdude: verifying ...
    	avrdude: 1 bytes of lfuse verified
    
    	avrdude: safemode: Fuses OK
    
    	avrdude done.  Thank you.
    
    sudo avrdude -p t44 -P usb -c avrisp2 -U flash:w:hello.ftdi.44.io.hex
    
    	avrdude: AVR device initialized and ready to accept instructions
    
    	Reading | ################################################## | 100% 0.00s
    
    	avrdude: Device signature = 0x1e9207
    	avrdude: NOTE: FLASH memory has been specified, an erase cycle will be performed
            	 To disable this feature, specify the -D option.
    	avrdude: erasing chip
    	avrdude: reading input file "hello.ftdi.44.io.hex"
    	avrdude: input file hello.ftdi.44.io.hex auto detected as Intel Hex
    	avrdude: writing flash (14 bytes):
    
    	Writing | ################################################## | 100% 0.01s
    
    	avrdude: 14 bytes of flash written
    	avrdude: verifying flash memory against hello.ftdi.44.io.hex:
    	avrdude: load data flash data from input file hello.ftdi.44.io.hex:
    	avrdude: input file hello.ftdi.44.io.hex auto detected as Intel Hex
    	avrdude: input file hello.ftdi.44.io.hex contains 14 bytes
    	avrdude: reading on-chip flash data:
    
    	Reading | ################################################## | 100% 0.01s
    
    	avrdude: verifying ...
    	avrdude: 14 bytes of flash verified
    
    	avrdude: safemode: Fuses OK
    
    	avrdude done.  Thank you.
    
  15. It worked! The LED on my circuit board lit up and the LED went off when I pressed the pushbutton. This seemed kind of backwards to me. So I modified the asm program, compiled it and downloaded the revised version to my circuit board. I only had to change two instructions to swap the condition when the LED would be on (note sbis and sbic instructions)

  16. Revised pushbutton LED program, I called hello.ftdi.44.io2.asm
    ; hello.ftdi.44.io2.asm
    ;
    ; control LED with pushbutton
    ;
    ; Code Created At FAB ACADEMY AS220
    ; by Shawn Wallace & Elliot Clapp
    ; Last Modified 03/20/2014  - Scott Zitek
    ;
    ; Permission granted for experimental and personal use;
    ; 
    ; The behavior is that the LED is always off – but when the button is pressed, it turns on.;
    ;
    ; Program explanation
    ;
    ; .device attiny44 	-- directive that defines which device to assemble for (an ATtiny44)
    ; .org 0		-- directive that sets the programs origin
    ; cbi DDRA, 3 		-- CBI(reg,bit): Clears a bit of a register. DDRA is a data direction register A, 
    ;			-- clearing DDRA bit 3 makes PA3 (pin 10) an input to monitor my pushbutton 
    ; sbi DDRA, 7 		-- SBI(reg,bit): Sets a bit of a register.  DDRA is a data direction register A
    ;			--Setting DDRA bit 7 makes PA7 (pin 6) an output to control my LED
    ; loop:			-- label (must start with a letter and end with a colon)
    ; 	sbis PINA,3	-- SBIS will skip the next command if a selected bit in a port is set
    ;  	sbi PORTA,7	-- Sets a bit of a register
    ;	sbic PINA,3	-- SBIC will skip the next command if the bit is clear
    ;  	cbi PORTA,7	-- Clears a bit of a register
    ; rjmp loop		-- relative jump to label called loop (notice no colon), use jmp for really long jumps
    ;
    
    .device attiny44
    .org 0
    cbi DDRA, 3
    sbi DDRA, 7
    loop:
    	sbis PINA,3
       	sbi PORTA, 7
     	sbic PINA,3
      	cbi PORTA, 7
    rjmp loop
    


C programming and avr-gcc

  1. I then found several examples online of programs written in c that blink an LED. I again "reverse engineered" them to figure out they worked. I used a plain text editor to add comments and make a program to work with the pins I had used for the pushbutton and LED. The example program also lit the LED all the time and then blinked a pattern while the pushbutton was pressed. I modified the program to keep the LED off and to blink the LED quickly while the pushbutton is being pressed.

  2. Contents of blink2.c
    #include < avr/io.h >
    #include < util/delay.h >
    
    
    #define bit_get(p,m) ((p) & (m)) 
    
    #define bit_set(p,m) ((p) |= (m)) 
    
    #define bit_clear(p,m) ((p) &= ~(m)) 
    
    #define BIT(x) (0x01 << (x)) 
    int main()
    {
    //SETUP
    //Button is on PA3
    //LED is PA7  
    
    bit_clear(DDRA,BIT(3)); //clear DDRA bit 3 makes PA3 (pin 10) an input to monitor my pushbutton - I don’t need pull-up resistor
    
    bit_set(DDRA,BIT(7)); //Set DDRA bit 7 makes PA7 (pin 6) an output to control my LED
    
    //LOOP
    while (1)
    {
    if(bit_get(PINA,BIT(3)))//button is not pushed
    {
    bit_clear(PORTA,BIT(7));//LED is off
    
    }
    else // button is pushed
    {
    bit_set(PORTA,BIT(7));//LED is on
    _delay_ms(10);
    bit_clear(PORTA,BIT(7));//LED is off
    _delay_ms(10);
    }
    } 
    
    }
    
  3. When I tried to compile this program using avr-gcc in Ubuntu it would not work. I kept receiving an error that it could not find the io.h and delay.h files. I found copies of io.h and delay.h and put them in a local folder. avr-gcc still could not find them. I looked online for possible solutions.

  4. After spending too much time and effort, I installed WINavr and avr-gcc on my Windows 7 computer. I was able to compile blink2.c to blink2.c.hex without any problems on the Windows computer. I then downloaded the hex file using avrdude on the Ubuntu computer as before. The circuit and program worked very well.


C programming and Atmel Studio

Next I installed Atmel Studio 6.2 on my Windows 7 computer. Since Atmel Studio is made by the same company that makes the ATtiny microcontroller the two worked very well together.

  1. I selected New Project from the start page.

  2. I then chose the GCC C Executable Project template.

  3. I found ATtiny44A from within a huge list of devices to program.

  4. I typed in my c program using the built in text editor. This editor is nicer than the plain text editors I have been using because it color codes the parts of the program (e.g. comments are in a green font). Atmel Studio also tries to identify errors in your programs. For example, it warned me that the F_CPU value was undefined in the delay.h program. So I needed to add #define F_CPU 20000000UL // 20 MHz
  5. blinkas1.c program as displayed in Atmel Studio's built-in editor


    Contents of blinkas1.c
    /*
     * blinkas1.c
     *
     * Created: 3/20/2014 3:24:35 PM
     *  Author: Scott
     */ 
    
    #define F_CPU 20000000UL  // 20 MHz
    
    #include < avr/io.h >
    #include < util/delay.h >
    
    #define bit_get(p,m) ((p) & (m))
    
    #define bit_set(p,m) ((p) |= (m))
    
    #define bit_clear(p,m) ((p) &= ~(m))
    
    #define BIT(x) (0x01 << (x))
    
    int main()
    {
    	//SETUP
    	//Button is on PA3
    	//LED is PA7
    
    	bit_clear(DDRA,BIT(3)); //clear DDRA bit 3 makes PA3 (pin 10) an input to monitor my pushbutton - I don’t need pull-up resistor
    
    	bit_set(DDRA,BIT(7)); //Set DDRA bit 7 makes PA7 (pin 6) an output to control my LED
    
    	//LOOP
    	while (1)
    	{
    		if(bit_get(PINA,BIT(3)))//button is not pushed
    		{
    			bit_set(PORTA,BIT(7));//LED is on
    
    		}
    		else // button is pushed
    		{
    			bit_clear(PORTA,BIT(7));//LED is off
    			_delay_ms(10);
    			bit_set(PORTA,BIT(7));//LED is on
    			_delay_ms(10);
    		}
    	}
    
    }
    
  6. I then used Atmel Studio to compile the program and download it to my circuit using my avrisp mkii ISP. Not only can fuses be set using Atmel Studio but it was also easy to read the existing fuse settings for my ATtiny44a.
  7. Atmel Studio has the ability to read fuse settings from a microcontroller such as the ATtiny44A.


    Atmel Studio also has the ability to read information about the ATtiny chip, calibrate the oscillator etc.


  8. I liked Atmel Studio. It has a pretty intuitive interface and good help files.


Using Arduino 1.0.5-r2 IDE to program the ATtiny on a 64-bit windows 7 computer

  1. I downloaded and installed the Arduino program.

  2. I then downloaded a file called ATtiny_master.zip that contained information about the ATtiny chips. The folder attiny had to be added to a folder called hardware in the Arduino sketchbook location. Once I did this,
  3. Once configured, all you need to do is pick the ATtiny44a and clock configuration from the optional "boards" in the Arduino tools pull-down menu.


  4. Arduino comes with many example programs. I picked an example program called Blink. Then I edited the program to correspond with the pin I had selected to connect my LED to. However, Arduino uses different pins numbering than the ATtiny. so I had to consult a conversion chart to determine that my LED is connected to the ATiny44A pin 6 which is considered pin 7 on the Arduino. The example Arduino blink program does not use the pushbutton.

  5. Contents of Arduino Blink example program modified for my ATtiny circuit board.
    /*
      Blink
      Turns on an LED on for one second, then off for one second, repeatedly.
     
      This example code is in the public domain.
     */
     
    // Pin 13 has an LED connected on most Arduino boards.
    // give it a name:
    // My LED is connected to ATtiny pin 6 which is equivalent to Arduino pin 7
    int led = 7;
    
    // the setup routine runs once when you press reset:
    void setup() {                
      // initialize the digital pin as an output.
      pinMode(led, OUTPUT);     
    }
    
    // the loop routine runs over and over again forever:
    void loop() {
      digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
      delay(1000);               // wait for a second
      digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
      delay(1000);               // wait for a second
    }
    
  6. I then selected Verify/Compile from the Arduino Sketch pull-down menu. After a short delay, a message appeared indicating "Done Compiling" and the "Binary sketch size: 892 bytes (of a 4,096 maximum). If I am interpreting this correctly, this simple tiny little blink program requires almost 1/4 of all the available memory in the ATtiny. That doesn't sound right.

  7. This is where I got stuck. I was not able to get Arduino to work with my avrisp mkii ISP. When I try to upload using Arduino I receive the error, avrdude: usbdev_open(): did not find any USB device "usb".

  8. I did however; figure out that when you compile or attempt to upload using Arduino, it creates a temporary hex file on the hard drive. In my case the file was called "Blink_attiny_sz.cpp.hex". I assume that I could transfer this hex file to the ATtiny using avrdude etc.

  9. I did some research and found an online article entitled How to configure the Atmel AVRISP MKii to work with Arduino IDE. The first point in the article is "DO NOT install the Atmel AVR Studio software suite. It installs the "Jungo USB" driver which is not compatible with AVRdude (which the Arduino IDE uses). You can either use one of the other, not both at the same time." This page has been read 10946 times so it looks like this might be a common problem. I am not sure this is the issue but when I installed Atmel Studio I remember it installing the Jungo USB drivers. I don't want to break Atmel Studio to get Arduino to work on my Windows 7 computer.


Using Arduino IDE to program the ATtiny on a 64-bit Ubuntu 12.04 LTS computer

Since I couldn't get it to work on my Windows 7 computer, I installed Arduino on my 64-bit Ubuntu 12.04 LTS computer

  1. I downloaded the 64-bit Linux version of Arduino and extracted into a folder in the home directory. Just like I did with the Windows install, I downloaded a file called ATtiny_master.zip that contained information about the ATtiny chips. The folder attiny had to be added to a folder called hardware in the Arduino sketchbook location.

  2. When attempted to run the Arduino file nothing happened. So I went online again to find out what more had to be done to install Arduino. It turns out that the Arduino GUI interface uses Java. So I used Ubuntu Software Center (previously Synaptic Package Manager) to install the Openjdk-6-jre(Java Runtime Environment). Arduino also uses gcc-avr, binutils-avr, avr-libc, avrdude, and more. I did not install the FTDI virtual COM port (VCP) driver because it is supposed to be built into Ubuntu 12.04.

  3. After doing all this, the Arduino GUI worked. It was even able to see the avrisp mkii when I plugged it in to the USB port.

  4. I recreated the Arduino blink program modified for my ATtiny board LED connection and tried to burn the bootloader. It turns out that avrdude needs sudo access in order to send your Arduino code to the board. You will need to run avrdude as sudo. Mac users do not need to do this. So I followed the directions on how to give avrdude sudo access that I found here

  5. I used verify/compile (CTRL+R) from the Arduino Sketch pull-down menu.

  6. I then used Burn bootloader from the Arduino Tools pull-down menu.

  7. I then selected Upload from the Arduino pull-down menu and the LED on my board started slowly blinking. I unplugged the avrisp mkii and the circuit still continued to blink.

  8. I revised the blink program to change the delays from 1000 (1 second) intervals to 100 (1/10 second) intervals.

  9. Contents of Arduino Blink example program modified to blink faster.
    /*
      Blink
      Turns on an LED on for 1/10 second, then off for 1/10 second, repeatedly.
     
      This example code is in the public domain.
     */
     
    // Pin 13 has an LED connected on most Arduino boards.
    // give it a name:
    // My LED is connected to ATtiny44A pin 6 which is equivalent to Arduino pin 7
    int led = 7;
    
    // the setup routine runs once when you press reset:
    void setup() {                
      // initialize the digital pin as an output.
      pinMode(led, OUTPUT);     
    }
    
    // the loop routine runs over and over again forever:
    void loop() {
      digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
      delay(100);               // wait for 1/10 second
      digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
      delay(100);               // wait for 1/10 second
    }
    
  10. I then saved, compiled, and tried to download the revised blink program to the ATtiny using just the FTDI connection. It did not work! I received the error -- avrdude: usbdev_open(): did not find any USB device "usb". Not again! this is the same error I had with Arduino using Windows 7.

  11. I noticed that avrisp mkii (dev/ttyUSB0) was the only device listed under the Arduino pull-down menu list of serial ports. I had a similar problem working on my Week 4 assignment when configuring our old Modela mill to work with Fab Modules on a different computer. The solution was to add my user account to the dialout group:
  12. 	sudo gpasswd --add scott dialout   <-- scott is the login account
    
  13. I had to log out and log back in again for the changes to take effect. When I plugged the FTDI cable into the USB port, it appeared as dev/ttyS4 under the Arduino pull-down menu serial port list. I selected dev/ttyS4 as the serial port to use so there was a check mark in front of it.

  14. I again selected Upload from the Arduino pull-down menu. It still did not work. I again received the error -- avrdude: usbdev_open(): did not find any USB device "usb".
  15. The dreaded Arduino "did not find any USB device" error that I received in both Windows and Ubuntu.


  16. I tried several other things but none of them made a difference. I could write programs to my ATtiny circuit using the avrisp mkii but not with just the FTDI alone. The FTDI cables only function appeared to be to power the circuit.

  17. Then I read here : Burn the bootloader - "this doesn't actually burn a bootloader onto the board; you'll still need to upload new programs using an external programmer.)". I am confused. I thought that the entire point of Arduino was to have an easy to use IDE with a bootloader so that the programs can be changed using just an FTDI connection. If I understand this right, without the FTDI programming ability on the ATtiny44a, Arduino is basically avr-gcc c programming IDE with additional maybe 12 Arduino specific commands to make it easier to use.


Conclusions

The vast majority of my time this week was spent installing numerous Integrated Development Environments (IDE) and troubleshooting all the different problems related to installing the different toolchains. I would have much rather focused my time on learning and experimenting with the programming languages. However, now that I have several different IDE/toolchains setup on multiple computers, I should have more flexibility and be more productive on future assignments.

Programming languages:

IDE /Toolchains:


Project files


Back to index