Week 08: Embedded Programming

Group assignment: compare the performance and development workflows for other architectures

Personal assignment: read a microcontroller data sheet, program your board to do something, with as many different programming languages and programming environments as possible

This week, I:

set up a simple input/ouput circuit for the Arduino Uno

Due to my board from week 06 not working, as it was soldered incorrectly, and we didn't have adequate lab access to fix the board or mill another board, I opted to use an Arduino Uno and focus on programming the ATmega328P via port manipulation this week.

I decided to make a simple LED/slide switch circuit, so I could test if I could successfully both read input and produce output. I used the circuit from this tutorial on using a toggle switch.

fritzing01

arduino01

programmed the circuit using port manipulation

I referred to the datasheet for the ATmega328P to determine which ports I was using. On the Arduino, I used pin 3 for the switch (input), and pin 6 for the LED (output).

Datasheet

pinout01

I realized I had to use the pinout diagram for the Arduino Uno, not for the ATmega328P, because I wasn't able to trace the connections on the board to see which of the header pins corresponded to the microcontroller pins.

pinout02

According to the pinout diagram, pin 3 = PD3, and pin 6 = PD6. I followed this tutorial: Port Manipulation to figure out how to use this information.

Since my pins were in the 'D' port, I used the following designations in my code:

B denotes the beginning of a binary number. The following 8 digits designate the state of pins 7-0, left to right.

I wanted to set PD3 as input, and all other pins in port D as outputs, so I used:

            DDRD = DDRD | B11110100;

in setup. This set up pin 3 as input, pins 2, 4-7, as output, and does not affect pins 0 and 1, which are RX and TX respectively, which are reserved for serial communication.

Using these three variables, DDRD, PORTD, and PIND, I could set the pins for input/output, turn the pins off/on, and read the state of the pins. I used these to read the state of pin 3 (switch) and affect the state of pin 6 (LED). Please see the attached .ino file to see the full code.

As I was programming an Arduino Uno, instead of a custom circuit board, I was able to use the Arduino IDE to program it.

It worked!

Note: In the future, I will be programming a custom circuit board that I design myself, using a UPDI programmer. This was a stopgap solution so I could practice port manipulation while the lab was unavailable.

used an ATTiny1614 on a board

In week 11, I designed a board using an ATTiny1614 as the microcontroller and programmed it using a UPDI programmer and pyupdi: here. While we used the Arduino IDE to write the program, we uploaded it quite differently. First, we powered the board using a USB-to-FTDI board. Then, we attached the UPDI programmer board to the milled board, in this somewhat absurd configuration:

boards_01

We also had to install support for the tiny boards in Arduino using megaTinyCore. This is designed to work with UPDI programmers. The code was compiled using the Arduino IDE; however, we used the .ino.hex file instead of uploading it through the IDE. The command to program it was:

        pyupdi.py -d tiny1614 -b 19200 -c COM7 -f "filepath.ino.hex" -v

While this process seems considerably more complex than using the Arduino IDE, it also allowed me to build my own custom microcontroller board, which is quite valuable if I want to make specialized PCBs in the future. I would recommend thorough testing of your FTDI and UPDI connections/boards however, as they slowed me down a lot when I didn't realize that they were malfunctioning, thereby causing my code to error out instead of uploading.

Files

Code, .ino format

RGBW strand test code, .ino.hex format