Cosplay Arduino programming

Part #13 of the "Roger Writes" series - June 2024

What?

We recently had some friends staying over a weekend, and had a day of cosplay Arduino programming.
The goal was to create the code/electronics for a basic "gadget" with some flashing lights, and for it to react to button presses.

Basic Arduino hardware

The Arduino is a simple micro controller board based on the ATMEGA328P chip.
It's best to start with a simple kit like this one.
After installing the IDE you connect the board via USB, write programs, then press the build/download button.

Basic Arduino code

You start with just two basic functions:

// The setup function does things once at power on
void setup() {
}

// The loop function runs things over and over until turned off
void loop() {
}

1. Flash Internal LED

This can be used to flash an LED:
// This code flashes the built-in LED

// The setup function does things once at power on
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
}

// The loop function runs things over and over until turned off
void loop() {
digitalWrite(LED_BUILTIN, HIGH);// turn the LED on (HIGH is the voltage level)
delay(1000);// wait for a second
digitalWrite(LED_BUILTIN, LOW);// turn the LED off by making the voltage LOW
delay(1000);// wait for a second
}

2. Flash External LED

This can be used to flash an external LED, here is some simple wiring:

The resistor is 220ohms (red,red,brown), which gives about (5.0-1.7/220)=0.015=15mA, which is a reasonable brightness.

// This code flashes an external LED

const byte PIN_LEDR = 5;// Pin the Red LED is attached to (should be a PWM pin)

// The setup function does things once at power on
void setup() {
// initialize digital pin PIN_LEDR as an output.
pinMode(PIN_LEDR, OUTPUT);
}

// The loop function runs things over and over until turned off
void loop() {
digitalWrite(PIN_LEDR, HIGH);// turn the LED on (HIGH is the voltage level)
delay(1000);// wait for a second
digitalWrite(PIN_LEDR, LOW);// turn the LED off by making the voltage LOW
delay(1000);// wait for a second
}

3. Fade External LED

The pin chosen for the external LED is a PWM (Pulse Width Modulated) pin, these are marked with a "~" next to the pin number. Instead of just on/off, these can be set to quickly switch on and off (about 1000 times per second). But varying the amount of on time and off time the apparent brightness changes. By default the PWM code uses a value of 0 (fully off) to 255 (fully on).

// This code sets the external LED to different brightness levels

const byte PIN_LEDR = 5;// Pin the Red LED is attached to (should be a PWM pin)

// The setup function does things once at power on
void setup() {
// initialize digital pin PIN_LEDR as an output.
pinMode(PIN_LEDR, OUTPUT);
}

// The loop function runs things over and over until turned off
void loop() {
analogWrite(PIN_LEDR, 255);// Set the Red LED brightness to 255 (full on)
delay(500);// wait half a second
analogWrite(PIN_LEDR, 192);// Set the Red LED brightness to 192 (75% on)
delay(500);// wait half a second
analogWrite(PIN_LEDR, 128);// Set the Red LED brightness to 128 (50% on)
delay(500);// wait half a second
analogWrite(PIN_LEDR, 64);// Set the Red LED brightness to 64 (25% on)
delay(500);// wait half a second
analogWrite(PIN_LEDR, 0);// Set the Red LED brightness to 0 (fully off)
delay(1000);// wait for a second
}

4. Button input

Let's add some extra LEDs and a button:

The LED resistors are 220ohms (red,red,brown), the button pull-down resistor is 10Kohms (brown,black,orange).

// This code flashes the Red LED if the button is down, then the Yellow, then the Green LED.

const byte PIN_LEDR = 6;// Pin the Red LED is attached to (should be a PWM pin)
const byte PIN_LEDY = 9;// Pin the Yellow LED is attached to (should be a PWM pin)
const byte PIN_LEDG = 5;// Pin the Green LED is attached to (should be a PWM pin)
const byte PIN_BUT = 2;// Pin the Button is connected to (button pressed=HIGH)

// The setup function does things once at power on
void setup() {
// initialize LED pins as outputs
pinMode(PIN_LEDR, OUTPUT);
pinMode(PIN_LEDY, OUTPUT);
pinMode(PIN_LEDG, OUTPUT);
// initialize Button pin as input
pinMode(PIN_BUT, INPUT);
}

// The loop function runs things over and over until turned off
void loop() {
if (digitalRead(PIN_BUT)) {// Check if the button is pressed
digitalWrite(PIN_LEDR, HIGH);// turn the Red LED on
delay(500);// wait 500 milli seconds (half a second)
digitalWrite(PIN_LEDR, LOW);// turn the Red LED off
delay(500);// wait 500ms
}
digitalWrite(PIN_LEDG, HIGH);// turn the Green LED on
delay(500);// wait 500ms
digitalWrite(PIN_LEDG, LOW);// turn the Green LED off
delay(500);// wait 500ms
digitalWrite(PIN_LEDY, HIGH);// turn the Yellow LED on
delay(250);// wait 250 milli seconds (a quarter of a second)
digitalWrite(PIN_LEDY, LOW);// turn the Yellow LED off
delay(250);// wait 250ms
}

5. State based version of button input

The previous examples uses what's known as sequential programming. The code is in the sequence it's run in.
This is the easiest to understand, but does limit the code to doing one thing at a time. Using state variables, we can give the illusion of different things happening at once.
The state functions get called, update their state, do something, then return. After they have all been called, there is a single 25milli-second delay. So the state functions all get called every 25 milli-seconds.
Let's change the button example to use state machines, so that the Red/Yellow/Green LEDs all flash at the same time:

// This code flashes the Red LED if the button is down, while flashing the Yellow and Green LEDs at different speeds

const byte PIN_LEDR = 6;// Pin the Red LED is attached to (should be a PWM pin)
const byte PIN_LEDY = 9;// Pin the Yellow LED is attached to (should be a PWM pin)
const byte PIN_LEDG = 5;// Pin the Green LED is attached to (should be a PWM pin)
const byte PIN_BUT = 2;// Pin the Button is connected to (button pressed=HIGH)

// The setup function does things once at power on
void setup() {
// initialize LED pins as outputs
pinMode(PIN_LEDR, OUTPUT);
pinMode(PIN_LEDY, OUTPUT);
pinMode(PIN_LEDG, OUTPUT);
// initialize Button pin as input
pinMode(PIN_BUT, INPUT);
}

int state_flash_r=0;// Define a state variable for red LED
int state_flash_y=0;// Define a state variable for yellow LED
int state_flash_g=0;// Define a state variable for green LED

// The do_flash_r function updates the state_flash_r, and does something with the Red LED
void do_flash_r() {
if (state_flash_r==0 && !digitalRead(PIN_BUT)) return;// We're waiting for the button, but it's up, so just bail out of function
state_flash_r++;// Increment state_flash_r, this is a short form of state_flash_r=state_flash_r+1
if (state_flash_r<20) {// Time since button pressed is under 20*25=500ms
digitalWrite(PIN_LEDR, HIGH);// turn the Red LED on
} else
if (state_flash_r<40) {// Time since button pressed is under 40*25=1000ms
digitalWrite(PIN_LEDR, LOW);// turn the Red LED off
} else {
// All done reset state
state_flash_r=0;
}
}

// The do_flash_y function updates the state_flash_y, and does something with the Yellow LED
void do_flash_y() {
state_flash_y++;// Increment state_flash_y
if (state_flash_y<10) {// Time since start of state, is under 10*25=250ms
digitalWrite(PIN_LEDY, HIGH);// turn the Yellow LED on
} else
if (state_flash_y<20) {// Time since start of state, is under 20*25=500ms
digitalWrite(PIN_LEDY, LOW);// turn Yellow LED off
} else {
// All done reset state
state_flash_y=0;
}
}

// The do_flash_g function updates the state_flash_g, and does something with the Green LED
void do_flash_g() {
state_flash_g++;// Increment state_flash_g
if (state_flash_g<20) {// Time since start of state, is under 20*25=500ms
digitalWrite(PIN_LEDG, HIGH);// turn the Yellow LED on
} else
if (state_flash_g<40) {// Time since start of state, is under 40*25=1000ms
digitalWrite(PIN_LEDG, LOW);// turn Yellow LED off
} else {
// All done reset state
state_flash_g=0;
}
}

// The loop function runs things over and over until turned off
void loop() {
// Call all of the state update functions
do_flash_r();// Call the do_flash_r function
do_flash_y();// Call the do_flash_y function
do_flash_g();// Call the do_flash_g function
delay(25);// wait 25ms (1/40th of a second)
}

6. State based LED example, with a random, and fading LED

Now that we have the separate R/Y/G control, lets do something different with the LEDs

// This code flashes the Red LED if the button is down, while flickering the Yellow LED, and fading the Green LED up and down

const byte PIN_LEDR = 6;// Pin the Red LED is attached to (should be a PWM pin)
const byte PIN_LEDY = 9;// Pin the Yellow LED is attached to (should be a PWM pin)
const byte PIN_LEDG = 5;// Pin the Green LED is attached to (should be a PWM pin)
const byte PIN_BUT = 2;// Pin the Button is connected to (button pressed=HIGH)

// The setup function does things once at power on
void setup() {
// initialize LED pins as outputs
pinMode(PIN_LEDR, OUTPUT);
pinMode(PIN_LEDY, OUTPUT);
pinMode(PIN_LEDG, OUTPUT);
// initialize Button pin as input
pinMode(PIN_BUT, INPUT);
}

int state_flash_r=0;// Define a state variable for red LED
int state_flash_g=0;// Define a state variable for green LED

// The do_flash_r function updates the state_flash_r, and does something with the Red LED
void do_flash_r() {
if (state_flash_r==0 && !digitalRead(PIN_BUT)) return;// We're waiting for the button, but it's up, so just bail out of function
state_flash_r++;// Increment state_flash_r, this is a short form of state_flash_r=state_flash_r+1
if (state_flash_r<20) {// Time since button pressed is under 20*25=500ms
digitalWrite(PIN_LEDR, HIGH);// turn the Red LED on
} else
if (state_flash_r<40) {// Time since button pressed is under 40*25=1000ms
digitalWrite(PIN_LEDR, LOW);// turn the Red LED off
} else {
// All done reset state
state_flash_r=0;
}
}

// The do_flash_y function does something with the Yellow LED
void do_flash_y() {
analogWrite(PIN_LED_Y, random(20, 255));// Set the Yellow LED to random brightness 20...255
}

// The do_flash_g function updates the state_flash_g, and uses this value to fade the Green LED up and down
void do_flash_g() {
state_flash_g++;// Increment state_flash_g
if (state_flash_g<256) {// Fading up
analogWrite(PIN_LED_G, state_flash);// Set the Green LED to fade up level
} else
if (state_flash_g<512) {// Fading down
analogWrite(PIN_LED_G, 511-state_flash_g);// Set the Green LED to fade down level
} else {
// All done reset state
state_flash_g=0;
}
}

// The loop function runs things over and over until turned off
void loop() {
do_flash_r();// Call the do_flash_r function
do_flash_y();// Call the do_flash_y function
do_flash_g();// Call the do_flash_g function
delay(25);// wait 25ms (1/40th of a second)
}

Next steps

You'll find examples for Arduino for just about anything you want to do. You can copy+paste a lot of code.
With a bit of thought you can change the example to use states, and add extra state functions/code to add them to your existing code.

Note: If you want to add a servo or two, then best to avoid the PWM pins, as it can mess up the LED timing, also watch out for power. The Arduino built in 5V regulator can only supply 100...500mA (depending on board, clones tend to be 100mA). So this is about 6 LEDs or one mini servo.
I'll do an example for many LEDs, and servo control next month!!

The Roger Writes series

I research / dabble with lots of things, and figured that if I write my notes here, I can quickly reference them, also, sometimes, they are useful to others!
Here is what I have so far:





Homepage.
This page was lasted updated on Sunday, 30-Jun-2024 20:52:33 BST

This content comes from a hidden element on this page.

The inline option preserves bound JavaScript events and changes, and it puts the content back where it came from when it is closed.

Click me, it will be preserved!

If you try to open a new Colorbox while it is already open, it will update itself with the new content.

Updating Content Example:
Click here to load new content