Skip to content

Week 4

Our assignment:

Group Assignment: demonstrate and compare the toolchains and development workflows for available embedded architectures

Individual Assignment: 1. browse through the data sheet for a microcontroller 2. write and test a program for an embedded system using a microcontroller to interact (with input &/or output devices) and communicate (with wired or wireless connections)


Group Assignment

For the group assignment this week linked here, I focused on using the Arduino IDE, which I'll document below as well...

Arduino IDE (angela)

Using the Arduino IDE as the development environment, I started off with an Arduino Nano board, which uses the ATmega328P microcontroller. Then I went through the following steps with the guidance of my instructor:

  1. Downloaded Arduino IDE
  2. Walked through the ATmega328P datasheet to take a look under the hood and get an overview of its architecture, memory segments, and features
  3. Set up the Arduino Nano board with the breadboard and plugged into my computer using USB-C cable
  4. Perused some of the available example code under File>>Example menu
  5. Selected my port and board in the Arduino IDE interface
  6. Ran through simple practice programs, adding various components to the breadboard accordingly (ex. LED, potentiometer, resistor)

Programming Practice

Blink (with built-in LED)

For the first practice test, we used the example code available in the Arduino IDE for "blink" which turns an LED on for one second than off for one second repeatedly. I quickly found out that the very thorough documentation and notes within the code make it easy to understand what each line of code is doing. For example, pinMode(LED_BUILTIN, OUTPUT) signifies an initializing of the digital pin of the LED already built into the Nano board as an output. This means the subsequent code will apply to this pin.

After selecting the board and hitting upload, the LED on the board began to blink! By raising the value within the delay code line we could make the LED blink slower and vice versa.

blink code

Push button

Then we hooked up a button to the board, putting it in D5 (a digital port) since the button is a digital component. Using the button example code template, I set pin number for the button at 5 and I also ended up tweaking the setup so that the initial setup up of the button when not pressed has the LED on by adding "INPUT_PULLUP" in the code. Uploaded and the button worked.

button code

Dim light

Next, I learned how to go about dimming lights after hooking up an LED to the breadboard with the help of Addie. Since the LED is a digital component, it just turns on or off. To practice with dimming, I learned that we could use the blink code and experiment with the rate at which we blink the light to give the illusion that the light is dimming. After experimenting with the values input for the delay code which dictate how long between the LED turning on and off, I found a time that worked and the light appeared dimmer (even though in reality it is actually turning on and off at a rate faster than the human eye can detect).

dim code

dim code

Note: the button component is not programmed I just left it on the breadboard from the last practice

Dim light with potentiometer

After learning about the potentiometer component (an analog component) and how to set that up on the breadboard, my final challenge in class was to figure out code for how to dim the light using the potentiometer. I learned that the potentiometer has three legs -- one to connect to power, one in the middle to connect to the analog pin which reads the variable voltage as you move the dial, and one to connect to ground and complete the circuit.

From my earlier practice, I know I would need to define the constant pin number where my LED light would be which I put at 5. I would use the code used to dim light but now needed to also inlcude other components in the set-up. After some instruction on initial set up for potentiometer code (setting the pin at A3 and initalizing serial communication at 9600 which essentially establishes a communication channel between the Arduino and computer for reading the variable inputs), I then added in the LED as an output. For the loop, I also learned about how to set up the potentiometer so that it could be read and so that its reading would print. From there, I had to figure out what to write in the rest of the code so that the potentiometer input would correlate to the dimming of the light. After some trial and error I found out the I could use the printed "reading" within the delay code. Since the number for the reading goes as high as 1024, I ended up multiplying it by 15 (value used in the previous challenge) and dividing that by 1024. That worked pretty well!

dim analog

Lesson Learned

In experimenting with this workflow, some interesting lessons learned:

  • If not pulled, pins will float around which we don't want. We want them to be pulled to a known state, either pull pins high (5V) or low (ground). You do this within the program code.
  • Do not forget semicolons! Just forgetting ";" will cause errors
  • code written in all capital letters indicates a constant
  • Define variables and constants in the code before the set up and loop functions
  • how to use a multimeter to measure voltage, current, and resistance. For example, when you don't pull a pin you can use the multimeter and see that its "floating" do to the variance in voltage rather than staying constant.
  • analog vs digital - digital signal is something on or off (1 or 0) whereas an analog signal is something that will continuously vary. The Arduino nano board has a side of pins for analog and another side for digital.
  • how to use a potentiometer which is an analog, variable resistor

Quick Notes on Thonny

For the group assignment, Castor took on Thonny and then walked me through what he learned (which he uploaded on our group site) so I got to experiment with using python. Some notes to self to remember:

  • hold the boot button on the chip while plugging it in to initially set it up
  • ensure the chip is set up in thonny properly using the bottom right hand menu where you initially "configure interpreter"
  • up top is where you can write a program, down low is the shell
  • Thonny allows you to run just one line of code as it is an interpreted language whereas C is a compiled language where you must run the full program

After this walkthrough, we had some fun with programming the LED on our chip to flash different colors. Here's one based on code that Will wrote:

thonny code color LED


Data Sheet

This week I browsed through the ATmega328P Datasheet. I also took notes from Will on this chip. I first began practice using an Arduino Nano board which has this microcontroller. The ATmega328P chip is a low power AVR 8-bit microcontroller I was most thorough in reading through its features, pin configurations, overview diagrams, CPU Core, AVR memories, and system clock sections. Some quick notes on its features:

Pin Configurations

pin configuration diagram

diagram of pinout from the datasheet

The pin configuration section laid out descriptions for each pin along the chip's perimeter. This includes VCC (power supply), GND (ground), and ports (which can be for general or specialized use). I/0 ports are ports with input/output capabilities.

Overview

overview diagram

block diagram of AVR architecture from the datasheet

Spent alot of time digesting this diagram and the AVR CPU diagram referenced below. Took note of....the oscillator which is an internal clock that sets the speed at which instructions happen (like the heartbeat of the chip). The databus are the like the internal lanes/communication channels between features. The analog comparator is a tiny analog device that can control voltages. USART, SPI, and TWI are communication ports using the same pins as some of the ports. And the AVR CPU is the control processing unit and essentially the conductor of the chip.

This microcontroller also has an elaborate clock system where clocks can be put to sleep to preserve power.

AVR CPU Core

Zooming in a level of abstraction...

cpu diagram

diagram of AVR CPU Core

As the datasheet notes, the main function of the CPU is "to ensure correct program execution" and must "access memories, perform calculations, control peripherals, and handle interrupt."

Inside the CPU, we find the Arithmetic Logic Unit (ALU) which does lots of math really fast and operates directly with all of the 32 general purpose working registers. Its operations fall under three categories: arithmetic, logical, and bit-functions. In the loop of an instruction cycle, a program is loaded into a block of memory, and the instruction register is where the current instruction is loaded wheras the instruction decoder decodes the instructions with control over the outgoing lines kind of like an operator. SRAM and EEPROM are where the memory is organized. The AVR architecture ahs two main memory spaces: data memory space and program memory space. It also has EEPROM memory for data storage. The CPU must also handle interrupts from the interrupt unit which let's you set a priority system for which chunks of code to run.

Ports and Registers

Ports are groupings of pins on the microcontroller and can function as a set to manage pins collectively.

Registers are high speed memory storage locations that are 8 bits wide in general used to efficiently hold data or control information communicating with internal hardware. Each bit in the register acts as a switch and flipping the state of the bit in the register associated with the port from 0 to 1 or from 1 to 0 changes what the microcontroller does.

Analog-to-Digital Converter (ADC)

This chip has a 10-bit successive approximation ADC. This ADC connects to an 8-channel analog multiplexer each with single-ended voltage inputs. The ADC has a separate analog supply voltage pin AVcc and converts analog input voltage to a 10-bit digital value where the minimum value is ground. I was interested in learning more about this because my initial practice involved using a potentiometer, an analog device.

Embedded System

For my final challenge of the week, I wanted to figure out how to program a small LCD screen. I found a ping pong program and accompanying online instructions within the Arduino example library that uses potentiometers to control the game. This example used a different type of screen so I found another website that walks through how to use a 0.91'' OLED Display with Arduino here.

To start I decided to work on getting familiar with the particular OLED display pin and walked through set up instructions including installing the necessary Adafruit libraries and used code provided on the site. The screen wasn't connecting right for some reason and since I had learned to use my multimeter I whipped that out and found there was no power going in--I had my wiring to the wrong side of the breadboard. Lesson learned!

Hello, Arduino!

Code from website:

//#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// Define OLED screen size
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32

// Initialize OLED display (I2C address 0x3C)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup() {
    Serial.begin(115200);

// Start OLED display
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println("SSD1306 allocation failed");
    for (;;);
}

display.clearDisplay();  // Clear buffer
display.setTextSize(1);  // Text size
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 10);
display.println("Hello, Arduino!");
display.display(); // Show text on screen
}

void loop() {
    // Nothing here (text is static)
}

hello arduino!

Not pictured: me jumping for joy when the "Hello, Arduino!" message popped up on the OLED display screen

Drawing shapes

Code from website:

void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();

// Draw a rectangle
display.drawRect(10, 10, 50, 20, SSD1306_WHITE);

// Draw a filled circle
display.fillCircle(90, 16, 10, SSD1306_WHITE);

display.display();
}

void loop() {}

I modified the first code used with the above. This resulted in a rectangle and a filled circle displaying on the screen.

Scrolling Text

Here's the code to modify used again from the above website:

void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();

display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 10);
display.println("Scrolling Text...");
display.display();

// Start scrolling
display.startscrollleft(0x00, 0x0F); 
}

void loop() {}

This displayed scrolling text of "Scrolling Text..." I changed the text to send funny messages to my family members. I noticed that if the message got longer it would break it down into multiple lines at a time which made it clunky. It'd be good to learn how to have continous scroll.

Ping Pong!

Now that I've properly set up my OLED display, I wanted to hook up the potentiometers to see if I could run the ping pong program. I went back to the Arduino documentation on the pong game and soon realized the program relies on the library associated with a different screen type. I got into the weeds a bit but for time's sake I went to Deepseek and used the prompt: "Can you code a pong game like the Arduino TFT pong documentation does but for using an 0.91" OLED Display, and Arduino nano board? I have two potentiometers on my breadboard which are wired to pin A0 and pin A1. Your first example only allowed me to use one potentiometer - can you make it a two player game where each player uses a potentiometer to control their respective rectangle?" The code produced worked great. See the file for this code here.

playing the pong game!

Supplemental Learning

Since all of this is brand new, I delved into several resources to gain more familiarity with fundamentals. Still working through them but sharing links below as a personal note:

  1. TinkerCad Circuits Simulator
  2. PBS' Crash Course on Computer Science available on Youtube
  3. Hackaday U's 5-part Class on Raspberry Pi Pico and RP2040 which walks through the RP2040 Datasheet
  4. MicroPython.org has a simulator on its website

Will also shared a Python for Beginners: A Crash Course Guide book by Timothy C. Needham with me which was an easy introduction for me. So far, I've learned:

  • Write code with the assumption that someone else will read it and be able to reproduce it >> use comments that the computer ignores with the '#' to explain what the program is doing (can also functionally comment out lines of code)
  • python is high-level (human readable then translated by an interpreter into machine code) and open-source
  • you can save code to a file and use the name of that file with a python program rather than having to type out all o fthe commands
  • to find out what signatures are needed for using functions, you can ask for help (ex. 'help(turtle.color)' )
  • with Thonny as my interface, I completed simple practice exercises including...
    • turtle - a python feature that's like an etch-a-sketch.
    • using variables which store all kinds of data like numbers, strings (a string is a piece of text); this "i" variable stands ofr 'index' and is a common variable name
    • using loops to simplify iterative, repetitive code - indented lines are the lines of code looped

turtle fun python

having fun drawing in python code with turtle