6. Embedded Programming¶
Basically week 2 in our collection of subjects that dive deeper and deeper into the electronics side. In week 4 I learned how to mill and solder a PCB. This week we went one step farther back along the full design process and learned how to design the outline and traces of a PCB and some basics about the main components found on boards, such as resistors and capacitors.
Assignments¶
Our tasks for this week are:
Group assignment:
- browse through the data sheet for your microcontroller
- compare the performance and development workflows for other architectures
Individual project:
- write a program for a microcontroller development board that you made, to interact (with local input &/or output devices) and communicate (with remote wired or wireless devices)
- extra credit: use different languages &/or development environments
- extra credit: connect external components to the board
Group Assignment¶
Click here to group work.
From this group work, I learn about different specification, and function between XIAO-RP2040 and XIAO-ESP32C3. And I also learn something about PWM:
Pulse-width modulation (PWM), also known as pulse-duration modulation (PDM) or pulse-length modulation (PLM),[1] is any method of representing a signal as a rectangular wave with a varying duty cycle (and for some methods also a varying period).
PWM: digital signal –> analog signal, such as human –> human voice (analog signal); using a digital signal generating device to realize the analog signal is equivalent to using a machine to simulate human speech.
Individual Project¶
For details, you can take refference from Seeed Studio XIAO RP2040 with Arduino
Arduino Setup¶
Check Arduino IDE, download the correct version according to your operating system.
Arduino Configuration¶
Preferences - Additional boards manager URLs:
https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
Manager icon - type ‘RP2040’ - install the package:
Select Board and Port:
Arduino realizes RED light flashing based on Seeed Studio XIAO RP2040¶
1- First time to read Schematic Diagram¶
For Chinese, check this tutorial;
I am going to use my designed board on from week 4 and program it. I am going to use button as the ‘input’ and the RGB light on the board as ‘output’.
For LED_RGB (use as Output):
I check XIAO-RP2040 and its schematic diagram;
It shows that the port of LED DIN
connects to GPIO12
of RP2040 chip. LED VCC
connects to GPIO11
of RP2040. Once LED is powered on, GPIO12
is the ouput port, so I will use GPIO12
port as the chip port.
For the button (use as Input) :
Picture shows that once the switch is powered on, D1
is the input port.
About the workflow of my project¶
The 3.3v voltage is transmitted to the D1 port of the chip through the switch (input-the switch inputs voltage and current to the chip), the chip supplies power to LED_RGB through GPIO 11 (output-the chip outputs voltage and current to the LED), and the signal is transmitted to the LED through GPIO12;
2- Embedded Programming¶
Create a new Sketch¶
Arduino Syntax¶
For Arduino Syntax; Arduino - Language Refference;
Once A new Sketch created, there are 2 basic functions, setup();loop();
RED light flashing based on Seeed Studio XIAO RP2040¶
Install Header File¶
Header file Adafruit_NeoPixel.h
is needed, follow this:
Sketch - Include Library - Manage Libaries ; or select the third icon on the left navigator.
Type keyword ‘Adafruit_NeoPixel’, add this library.
Code¶
I provided the schemetic diagram and Xiao’s Pinout for ChatGPT, and my project description. It generated this program:
The first version- work-swtich doesn’t function
#include <Adafruit_NeoPixel.h>
#define LED_PIN 12 // Define the pin connected to DIN of the RGB LED
#define VCC_PIN 11 // Define the pin connected to VCC of the RGB LED
#define SWITCH_PIN D1 // Define the pin connected to the switch (D1)
#define NUMPIXELS 1 // Number of LEDs
Adafruit_NeoPixel pixels(NUMPIXELS, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
pinMode(VCC_PIN, OUTPUT); // Set the VCC pin as output
pinMode(SWITCH_PIN, INPUT_PULLUP);// Set the switch pin as input with pull-up resistor
pixels.begin(); // Initialize the NeoPixel library
}
void loop() {
if (digitalRead(SWITCH_PIN) == LOW) { // Check if the switch is pressed (active low)
digitalWrite(VCC_PIN, HIGH); // Power on the RGB LED
// Flash Red
pixels.setPixelColor(0, pixels.Color(255, 0, 0)); // Red
pixels.show();
delay(500);
// Flash Green
pixels.setPixelColor(0, pixels.Color(0, 255, 0)); // Green
pixels.show();
delay(500);
// Flash Blue
pixels.setPixelColor(0, pixels.Color(0, 0, 255)); // Blue
pixels.show();
delay(500);
// Flash Yellow
pixels.setPixelColor(0, pixels.Color(255, 255, 0)); // Yellow
pixels.show();
delay(500);
// Flash Cyan
pixels.setPixelColor(0, pixels.Color(0, 255, 255)); // Cyan
pixels.show();
delay(500);
// Flash Magenta
pixels.setPixelColor(0, pixels.Color(255, 0, 255)); // Magenta
pixels.show();
delay(500);
// Flash White
pixels.setPixelColor(0, pixels.Color(255, 255, 255)); // White
pixels.show();
delay(500);
}
else {
digitalWrite(VCC_PIN, LOW); // Power off the RGB LED
pixels.setPixelColor(0, pixels.Color(0, 0, 0)); // Off
pixels.show();
}
}
I modified the first version - take refference from Matthew 2024
#include <Adafruit_NeoPixel.h>
int Power = 11;
int PIN = 12;
int ButtonPin = 27; // 按钮连接的引脚
#define NUMPIXELS 1
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
pixels.begin();
pinMode(Power, OUTPUT);
digitalWrite(Power, HIGH);
pinMode(ButtonPin, INPUT_PULLUP); // 将按钮引脚设置为输入,并启用内部上拉电阻
}
int colorIndex = 0; // 当前颜色索引
bool lastButtonState = HIGH; // 上一次按钮状态
void loop() {
bool currentButtonState = digitalRead(ButtonPin);
// 检测按钮从未按下到按下的状态变化
if (lastButtonState == HIGH && currentButtonState == LOW) {
colorIndex++; // 切换到下一个颜色
if (colorIndex > 4) {
colorIndex = 0; // 如果超出颜色范围,则重置为0
}
setColor(colorIndex); // 设置LED颜色
}
else if (currentButtonState == HIGH){
// pixels.Color(0, 0, 0); // 0
pixels.clear();
pixels.setPixelColor(0, pixels.Color(0, 0, 0)); // 设置指定颜色
pixels.show();
// delay(400); // 延时以便观察颜色变化效果
}
lastButtonState = currentButtonState; // 更新按钮状态
// delay(50); // 简单的消抖延时
}
void setColor(int index)
{
uint32_t colors[] = {
pixels.Color(15, 25, 205), // 蓝色
pixels.Color(103, 25, 205), // 紫色
pixels.Color(233, 242, 205), // 浅黄色
pixels.Color(233, 23, 23), // 红色
pixels.Color(12, 66, 101) // 深蓝色
};
pixels.clear();
pixels.setPixelColor(0, colors[index]); // 设置指定颜色
pixels.show();
// delay(400); // 延时以便观察颜色变化效果
}
Upload the code¶
- Select Board and Port:
- Upload the program to the chip:
if it fails a lot, try upload serveral times, and you can try this: after click ‘upload’ icon, hold on ‘Boot’ button, press ‘Reset’ button.
Result/Hero shot¶
I modified the second version by myself, in this way, I understand the code much better.
#include <Adafruit_NeoPixel.h>
int Power = 11;
int PIN = 12;
int ButtonPin = 27; // 按钮连接的引脚
#define NUMPIXELS 1
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
void setup() {
pixels.begin();
pinMode(Power, OUTPUT);
digitalWrite(Power, HIGH);
pinMode(ButtonPin, INPUT_PULLUP); // 将按钮引脚设置为输入,并启用内部上拉电阻
}
// int colorIndex = 0; // 当前颜色索引
bool lastButtonState = HIGH; // 上一次按钮状态
void loop() {
int time = 50;
bool currentButtonState = digitalRead(ButtonPin);
// 检测按钮从未按下到按下的状态变化
if (lastButtonState == HIGH && currentButtonState == LOW) {
// Flash Red
pixels.clear();
pixels.setPixelColor(0, pixels.Color(255, 0, 0)); // Red
pixels.show();
delay(time);
// Flash Green
pixels.clear();
pixels.setPixelColor(0, pixels.Color(0, 255, 0)); // Green
pixels.show();
delay(time);
// Flash Blue
pixels.clear();
pixels.setPixelColor(0, pixels.Color(0, 0, 255)); // Blue
pixels.show();
delay(time);
// Flash Yellow
pixels.clear();
pixels.setPixelColor(0, pixels.Color(255, 255, 0)); // Yellow
pixels.show();
delay(time);
// Flash Cyan
pixels.clear();
pixels.setPixelColor(0, pixels.Color(0, 255, 255)); // Cyan
pixels.show();
delay(time);
// Flash Magenta
pixels.clear();
pixels.setPixelColor(0, pixels.Color(255, 0, 255)); // Magenta
pixels.show();
delay(time);
// Flash White
pixels.clear();
pixels.setPixelColor(0, pixels.Color(255, 255, 255)); // White
pixels.show();
delay(time);
}
else if (currentButtonState == HIGH){
// pixels.Color(0, 0, 0); // 0
pixels.clear();
pixels.setPixelColor(0, pixels.Color(0, 0, 0)); // 设置指定颜色
pixels.show();
}
}
Note1 - what are the indexing (/numbers) for ?¶
you may see digits (11,12,13,…) and GPIO11, GPIO12,…;
Digits is for the index/order number, ‘11’ means this is the 11th Pin, for us reading and identify, which could be used for underlying language/assembly language programming.
GPIO12: this is an actual microcontroller pin , and ‘12’ is the programmable pin.
Defining Pin Levels: HIGH and LOW¶
They are constans in Arduino language, see here.
A pin may also be configured as an INPUT with pinMode(), and subsequently made HIGH with digitalWrite(). This will enable the internal 20K pullup resistors, which will pull up the input pin to a HIGH reading unless it is pulled LOW by external circuitry.
In my case (my MCU), when the pull-up resistor (located inside the RP2040 board, the chip of RP2040 board’s datasheet) is pulled-up, the input pin (P27 to which the button is connected) will be set to high potential.
Terminology - GPIO¶
GPIO stands for General-Purpose Input/Output. It’s a digital signal pin on an electronic circuit board or integrated circuit that can be used as an input, output, or both. GPIOs are controllable by software and have no predefined purpose.
Question:
I found that when I assign the following variables to Pin, my MCU had the same effect. so, What is the exact difference between P27 and D1? int Pin= 27; int Pin= P27; int Pin = D1Answer :P27,A1,D1 they are constants in the board, they are actually the same physical pin.