6. Embedded Programming¶
For this week we began working on embedded programming via programmable microcontorllers like the arduino and adafruit boards
Microcontroller x Intro¶
A microcontroller is a small computer on a single integrated circuit containing a processor core, memory, and programmable input/output peripherals. Microcontrollers are designed for embedded systems, which are systems that control other devices or machines. They are commonly used in a wide range of applications such as automotive systems, industrial automation systems, consumer electronics, and medical devices.
Microcontrollers typically have a small amount of on-chip memory, as well as some programmable input/output (I/O) ports, and often have peripheral devices such as timers and ADCs built in. They are programmed using a specific programming language, such as C or assembly, and often come with development kits that include a compiler and a programmer to upload the code to the microcontroller.
There are many different microcontroller manufacturers, such as Atmel, Microchip, NXP, and Texas Instruments, and microcontrollers are available in a wide range of sizes, performance levels, and price points. Some popular microcontroller families include the AVR microcontrollers, the PIC microcontrollers, and the ARM Cortex-M microcontrollers.
Chosen x Microcontroller¶
Paired in different groups, I was paired with Maryam AlSadadi to research and play with the Arduino MKR 1010. Below are some details about this board that we gathered from our research:
The Arduino MKR 1010 is a compact board that combines the power of the Microchip ATSAMD21 microcontroller and the Wi-Fi module ESP32. The board is based on the 32-bit Arm Cortex-M0+ microcontroller and features a low-power architecture, making it ideal for battery-powered projects. Some of the key specifications of the Arduino MKR 1010 include:
Microcontroller: ATSAMD21G18A with 256 KB flash memory and 32 KB SRAM Operating voltage: 3.3V Input voltage: 7-12V Digital I/O Pins: 14 PWM Pins: 6 Analog Input Pins: 8 Clock speed: 48 MHz Wi-Fi: ESP32 module with 802.11 b/g/n protocol and WPA2 PSK security Bluetooth: 4.2 LE USB connector: Micro-B Power-efficient architecture: active mode: 150 µA, sleep mode: 3 µA On-board crypto chip for secure communication Pinout and form factor: compatible with the Arduino MKR form factor The board also features an on-board crypto chip that enables secure communication, and it is compatible with the Arduino IoT Cloud, a platform that allows you to easily build IoT projects.
It also has a number of interfaces and sensors to interact with external components and devices, including a micro-USB connector, a 14-pin header with 8 analog inputs, 14 digital I/O pins, and 6 PWM pins, and a 32.768 kHz crystal for RTC.
The board is designed for a wide range of IoT applications, including home automation, remote monitoring, and wireless sensor networks.
The board is programmable using languages including but not limited to: C, C++, Arduino (based on C and C++), CircuitPython (derivative of Micropython which is based on Python).
The board has no sensors onboard (pun not intended).
For additional information on the other boards the other groups worked with please click here!
Blink x Blink!¶
(The ‘Hello World’ of microcontrollers)
For the first program to ensure that everything is working appropriately we wrote the blink program. As the name implies this code simply makes the built-in led in the microcontroller turn on and off at a certain rate. The code for this can be found below:
void setup() {
pinMode(LED_BUILTIN, OUTPUT); //declaring where the pin input is and that it is an output
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(150); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(500);
}
A video of this blink program will be uplaoded very soon pending technical issues:
Imagine video of blinking led
Blink x Python!¶
While the previous program was done using the Arduino IDE and using the Arduino programming language, there are other ways to do this. For instance using CircuitPython, which is an open-source programming language based on Python, designed to simplify the process of programming microcontrollers, such as the ones used on Arduino boards, Adafruit boards and other development boards. It is developed and maintained by Adafruit Industries.
CircuitPython is designed to be easy to use for beginners, and it adds several features that make it more suitable for use on microcontrollers than standard Python. These features include:
A simplified file system that allows you to easily access and manipulate files on the microcontroller’s storage. A built-in library of modules that provide access to the microcontroller’s peripherals, such as sensors, displays, and motors. Support for hardware-accelerated cryptography, which enables secure communication on small microcontrollers. A serial REPL (Read-Eval-Print Loop) that allows you to interact with the microcontroller over a serial connection, making it easy to debug and test code. CircuitPython is compatible with a wide range of microcontroller boards, including the Adafruit Metro, Feather, and PyBadge boards, as well as other boards that use the Atmel SAMD21, SAMD51, and nRF52 microcontrollers. It also supports a variety of different types of displays, such as OLED and TFT displays, and a variety of sensors, such as temperature and light sensors.
CircuitPython is a powerful and flexible programming language that makes it easy to develop microcontroller-based projects, and it is especially suitable for beginners.
I used Mu Editor which is a lightweight IDE to write and compile circuitpython, the code for the blink program is as such:
import time
import board
import digitalio
led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT
while True:
led.value = True
time.sleep(0.5)
led.value = False
time.sleep(0.5)
Same video as last time, different background
User x Input¶
For my next challenge on the arduino I set out to make the rate at which the led blinks to be selected by the user themselves. For this I simply used the serial monitor which allows me to ask for user input while the program is running. Furthermore, I utilized threads so that the led can blink even if the user didnt make an input when asked. The code can be found below:
#include <SoftwareSerial.h>
#include <pt.h>
//Variable to store duration of LED blink
int duration = 1000;
// Initialize pt struct
static struct pt pt1;
void setup() {
// Initialize pt struct
PT_INIT(&pt1);
// Set the built-in LED pin as output
pinMode(LED_BUILTIN, OUTPUT);
// Start serial communication at 9600 baud rate
Serial.begin(9600);
}
// Function to handle protothreading
static int protothread1(struct pt *pt) {
PT_BEGIN(pt);
while(1) {
// Wait until user input is received
PT_WAIT_UNTIL(pt, getUserInput());
// Turn on the built-in LED
digitalWrite(LED_BUILTIN, HIGH);
// Wait for the specified duration
delay(duration);
// Turn off the built-in LED
digitalWrite(LED_BUILTIN, LOW);
// Wait for the specified duration
delay(duration);
}
PT_END(pt);
}
// Function to get user input
bool getUserInput(){
if (Serial.available()) {
// Update duration with the value entered by user
duration = Serial.parseInt();
}
return true;
}
void loop() {
// Call protothread1 function
protothread1(&pt1);
}
A video of this blink program will be uplaoded very soon pending technical issues:
Imagine variable rate blinking led
– — .-. … . x -.-. — -.. .¶
For my final challenge I coded a program that would take any string (text) and convert it into morse code. The code looks long but it is quite simple. I created a dictionary which corresponds to the morse translation of each alphabetical letter and numbers. Then I wrote a function that translates each dit (.), dah (-), and pause (/) into an led output with the appropriate delay. Finally, I wrote a simple loop that goes through every letter of the input string, converts it into morse through the dictionary, and finally runs that into the function that blinks the led for every morse character. The code for this can be found below:
#include <SoftwareSerial.h>
// The lookup table maps each letter to a string of dots and dashes
const char* morseLookup[26] = {
".-", // A
"-...", // B
"-.-.", // C
"-..", // D
".", // E
"..-.", // F
"--.", // G
"....", // H
"..", // I
".---", // J
"-.-", // K
".-..", // L
"--", // M
"-.", // N
"---", // O
".--.", // P
"--.-", // Q
".-.", // R
"...", // S
"-", // T
"..-", // U
"...-", // V
".--", // W
"-..-", // X
"-.--", // Y
"--.." // Z
};
// Function converts single character to morse code
String charToMorse(char c) {
if (c >= 'a' && c <= 'z') {
// find lowercase in lookup table
return morseLookup[c - 'a'];
} else if (c >= 'A' && c <= 'Z') {
// find uppercase in lookup table
return morseLookup[c - 'A'];
} else if (c >= '0' && c <= '9') {
//If Character is number
switch (c) {
case '0': return "-----";
case '1': return ".----";
case '2': return "..---";
case '3': return "...--";
case '4': return "....-";
case '5': return ".....";
case '6': return "-....";
case '7': return "--...";
case '8': return "---..";
case '9': return "----.";
}
} else if (c == ' ') {
// If the character is a space
return "......";
} else {
// Otherwise empty string
return "";
}
return "";
}
// convert string to morse
String textToMorse(String text) {
String morse = "";
// Iterate through text
for (int i = 0; i < text.length(); i++) {
char c = text[i];
morse += charToMorse(c);
// Add space
morse += " ";
}
morse.trim();
return morse;
}
void blink(on, off){
digitalWrite(LED_BUILTIN, HIGH);
delay(on);
digitalWrite(LED_BUILTIN, LOW);
delay(off);
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(9600);
}
void loop() {
String text = "hello world";
String morse = textToMorse(text);
for (int i = 0; i < morse.length(); i++) {
char c = morse[i];
if (c == '.') {
blink(250, 250);
Serial.print('.');
} else if (c == '-') {
blink(750, 250);
Serial.print('-');
} else if (c == ' ') {
blink(0, 1750);
Serial.print('/');
}
}
}
Imagine v cool morse led