What are Micrcontrollers?
A microcontroller or MCU works very simmilar to a miniature computer having many of the same parts including RAM, a CPU, I/O ports, interrupt controls,
timers, and so forth. However unlike computers they are are far more compact, and cannot have their internals replaced. For a brief run down, a CPU is the
central processing unit where everything gets executed. In the CPU there are registrars which will store small amount of information and the ALU, artithmetic
and logic unit, which will run calculations with information in registrers. This information comes from RAM or random access memory which will store information
likely to be needed by the CPU for fast transfer to the CPU when needed. However all the information itself is stored on ROM or read only memory which will store
the binaries themselves to be read by the RAM.
In addition due to their simplicity, they are significantly weaker than a computer, and typically not capable of running multiple processes at the same time. For this reason when we program most
microcontrollers the only thing we program the controller with is just a hex file, which is the binary of the executable itself, and nothing more. Unlike
computers and rasberry pi's where we can just toss on the whole python interpreter if we want to and just run a python script, most microcontrollers are not
capable of handling a full interpreter.
To program these boards though the end result is a binary, we typically use higher level compiled languages most notably C/C++. Arduino, a form of C++ is
the most commonly used language for programming microcontrollers by hobbyists. To program these boards we require the code itself, which will be compiled using
avr-gcc a C compiler for avr boards, such as the attiny. In addition we use avr dude and pyupdi to transfer the data to board itself. The problem is though
that our computers typically only have USB we can use an USB to UART adapter then using some clever written code convert the serial RX and TX signal into
UPDI to program our boards. To make the program itself we can write it in a text file if we chose to then run the appropriate executables and commands to program the
boards using the programs previosly mentioned, or we can use IDEs which will build in the compiling and programming to be done with a single step such as arduino
and platformio.
Generic Microcontroller
Arduino
Platform IO
Microcontroller Comparison
Here we went through as a group and made a list of a bunch of mictrocontrollers, and attempted to program a few of them, as well as discuss
there stats. For each board we had we found what microcontroller was on the board, and we found its bus width (the number of bits that can be
sent to the CPU simultaneously) their family, the clock speed (how fast can the CPU process the information), the memory, the number of I/O pins,
the logic level voltage, and the package style. Most of the microcontrollers were close to one another except for ARM family which were significantly
more powerful than the rest.
We then went through and coded a few in this case I programmed a Atmega328, which belongs to the AVR Mega family, and a ARM Cortex M7 which belongs
to the Cortex family.To program both of the boards was fairly straightfoward. Starting the the Atmega328 being a standard Arduino Uno all
that I had to do was select the settings in arduino for arduino UNO, and compile and run the code. For the ARM Cortex a bit more work had to be
done where I had to install the compiler from a third party website, and put it into the appropriate arduino subfolder where I then had the
choice to select the board and program it. Both boards were prorgammed with the standard blink code. I then used platform io to program the teensy
with the blink code as well. To do this I just opened platform IO selectect the teensy as the board when making the project, and wrote a quick
blink code, and all that was left was to compile and run it with the teensy connected no need to use thre third party installer like for arduino.
Following programming both boards we then tested the clock speed of the boards, and set a teensy board and a feather board, two boards form the
same family to blink with no delay. We then used an osciloscope to compare the clock speeds of the board. We found that the teensy was capable of
cyclying over ten times as fast which is comparable ot their differences in clock speeds. We then calculated the frequency using the information
and determined in one second how many cycles happened. It should be noted the teensy is the only one of these boards powerful enough to infact just have
a whole python interpreter if wanted.
MCU Comparison Chart
Teensy Programmer
Teensy Board
Setting Arduino to Program Teensy
Blink Arduino
Arduino Uno
Teensy Platform Project
Platform IO Blink
Oscilloscope Comparison
Programming with Arduino
For the next task we programmed the attiny 1616 with two different IDEs Arduino and Platform IO. Starting with Arduino we got the SpencerKonde
library MegaTinyCore, and installed it in Arduino, hooked up the board combine the Tx and Rx from the USB to UART adapter to make a UPDI programmer, and
programmed the board with a blink sketch. I was hoping to do the exact same thing on Platform IO, but was told more was expected from me...
Blink Sketch
Attiny Settings in Arduino
Programmed Microcontroller
Platform IO
For this next part I programmed the board in platformIO. Platform IO is an extension for VS Code which itself is not an IDE,
but can get extensions to make it an IDE like plaform IO. Platform IO will automatically install most of the required dependencies, which makes programming
the boards significantly easier. In order to program a board just go to home, new project, select the board, and name the file, then go to src and open main.cpp.
Unfortunately to upload the board it requires pyupdi which you need to install yourself first using pip, then go to the config files and tell it to use pyupdi.
Due to me not knowing how to add stuff to PATH on windows, I had to just give it the full path to access pyudi. I wrote a quick blink code and
ran it to make sure everything was working.
Home Screen
Make a new Project
Blank Main cpp
pip to get pyupdi
VS Code File Directory
Config File
Final Program
I then made a final program for my board with two leds and a button in platform io. My plan was to make a program that would cycle through different
led patterns when the button is pressed. To do this I first set up all my variables so declare my constants, made a class to cycle through the led patterns,
and declared all the functions in my program. I then have my set up function which sets the two leds as outputs, and sets the button as an input with an
internal pull up in order for the pin to not be floating. I then set the pin of the button to be an interrupt when it detects the voltage rise, so when the button
is pressed and released. This interrupt will call the function that will make the led patter switch. I then wrote the loop function which is simply a switch statement
that will run a different function depending on which pattern is currently set. Following I made the method that will return the current pattern, the method to
switch to the next pattern or return to the first if at the last, and the interrup function which will run the next pattern method. Initially I made this function
the board was skipping patterns, and I realized this was due to bounce, so I added a times using millis to make a software debouncer.
Each communication protocol works differently. Because I am lazy I used the easier one being serial communication which work using a transmit and receive terminals. The Tx pin hooks up
to the Rx and the Tx to the Rx. Boards can then communicate by sending one bit at a time and checking the value on the clock to see if the message is rising or falling
to determine the if the bit is a 1 or 0. In the group project which I do not have more photos of since we did it as a group and the board is dissasembled we connected the Boards
this way Rx to Tx and Tx to Rx. In my personal design though I put two microcontrollers on one board and went FTDI to MC1 to MC2 back to FTDI daisy chaning them
devices in an unconverntial way allowing for serial communication between three devices as long as they are programmed properly to pass on messages not designed for them (sort of like
how I2C where slaves will ignore messages not for their address but a lot less good) Also check out my final project where I connected both my sensing board
and servo board via i2c as slave devices to a rasberry pi as the master device.