Remembering how to Arduino

Eternal Draft 🤨
This post is more like a living document, it get's added to and updated over a long time

First started

Total updates
2

Last updated

I pull out an Arduino to try doing electronics stuff about once a year. That's a short enough period to fool me into thinking I can knock something together easily, but not short enough for me to retain any useful memory of how electronics work. This is an attempt to retain information for myself next time.

I've bough most of my Arduino stuff from Jaycar so this document references those modules a lot.

I have an original Arduino Uno so most of this has to do with that board.

How to use a multimeter

Continuity

You can use a multimeter to test the continuity of a cable (i.e. is it capable of conducting a circuit between the two terminals of your multimeter). This is especially useful fro those crap jumper wires, they are constantly breaking invisibly internally and can screw up a circuit you were certain would work.

The symbol on my multimeter looks like a play button with a line at the end. Set your multimeter to that. The display reads 1. Now, touch the each terminal of the multimeter to each end of a jumper lead. If the number dips from 1000 towards near zero, you have continuity.

This ifixit article looks useful. The continuity mode is in the same position on my multimeter.

If all else fails, jam an LED in somewhere to check if there's a circuit.

Hall Effect Sensor Module

Used to detect the presence of a strong magnetic field. Can't give a quantitative value as far as I'm aware, just on or off. I have a XC-4434 module.

Pin reference:

Use a 10k ohm resister across the signal and 5V pins, apparently to smooth out the signal.

30 gauss activation strength of the magnets? Check your magnet strength.

Some code that will fire an "interrupt" when the Hall Effect sensor is connected to Arduino pin 2, and the sensor detects a magnet:

#define HALL_SENSOR_PIN 2

// volatile!
volatile byte currentLED;

// This function is called whenever a magnet/interrupt
// is detected by the arduino
void magnet_detect_session() {
currentLED++;
}

void setup() {
currentLED = 0;
// Initialize the interrupt pin (Arduino digital pin 2)
attachInterrupt(
digitalPinToInterrupt(HALL_SENSOR_PIN),
magnet_detect_session,
FALLING
);
}

void loop() {
// magnet_detect_session();
}

Variables referenced inside interrupts should be volatile for some reason.

WS2812B LED Strip

Got a WS2812B strip online, it was $18 when I bought it, now seems to be $43??

External power for Arduino Uno and LEDs

MP-3480

You can jam this thing in the Arduino (barrel) circular connector. You can also buy a barrel connector and attach it to the LED strip, and power the arduino from the LED strip. Check polarity first.

Markings

USB to Serial Adaptor Module

Used to send/receive data to/from the Arduino without having to use a USB connection. You'd want to do this if you are powering the Arduino from a different source (e.g. the LED strip, see above) but still want to read or send data to the Arduino from your computer.

UART serial control flow!? Necessary for sending a reset signal to the Arduino so it can load a program from Serial. Can't get it to work.

XC-4464

Something about the pin needed to signal that a program should be loaded in.

Serial comms on /dev/tty.* or /dev/cu.*

Mini USB lol

Here's something that almost worked

Except you have to press the hardware reset button to get it working after hitting upload

This is the post that finally twigged for me

From USB serial module -> Arduino:

Could this be why the reset doesn't work?

Some code about all this

This code lights up some LEDs when it detects magnets on the hall effect sensor pins. It also prints the total number of magnet detections to serial.

This was used to power a project to measure the number of wheel rotations on an exercise bike. That project would warrant its own post.

#include <FastLED.h>

#define HALL_SENSOR_PIN_1 2
#define HALL_SENSOR_PIN_2 3
#define LED_CONTROL_PIN 7

// #define NUM_LEDS 144 // 1 strand
#define NUM_LEDS 288 // double strand
#define SERIAL_BAUD 115200
#define SESSION_ID_LENGTH 20

#define FRAMERATE 15

// in mA
#define MAX_POWER_DRAW 500 // USB hub
// #define MAX_POWER_DRAW 3000 // 5V external power pack

volatile byte currentLED;
volatile byte currentLED2;

volatile byte session1Revolutions;
volatile byte session1Revolutions2;

volatile byte session2Revolutions;
volatile byte session2Revolutions2;

String sessionID1;
String sessionID2;

CRGB leds[NUM_LEDS];

// This function is called whenever a magnet/interrupt is detected by the arduino
void magnet_detect_session_1() {
// Serial.println("YO");
leds[currentLED] = CRGB(
rainbow_calc(currentLED, NUM_LEDS / 2, 0),
rainbow_calc(currentLED, NUM_LEDS / 2, 1),
rainbow_calc(currentLED, NUM_LEDS / 2, 2));
currentLED++;
if (currentLED >= NUM_LEDS / 2) {
currentLED = 0;
reset_leds(0, NUM_LEDS / 2);
}
if (session1Revolutions == 254) {
session1Revolutions2++;
}
session1Revolutions++;
}

// This function is called whenever a magnet/interrupt is detected by the arduino
void magnet_detect_session_2() {
// Serial.println("YO");
leds[currentLED2 + (NUM_LEDS / 2)] = CRGB(
rainbow_calc(currentLED2, NUM_LEDS / 2, 0),
rainbow_calc(currentLED2, NUM_LEDS / 2, 1),
rainbow_calc(currentLED2, NUM_LEDS / 2, 2));
currentLED2++;
if (currentLED2 >= NUM_LEDS / 2) {
currentLED2 = 0;
reset_leds(NUM_LEDS / 2, NUM_LEDS);
}
if (session2Revolutions == 254) {
session2Revolutions2++;
}
session2Revolutions++;
// Serial.println("Signal2");
}

// Clear all LEDs
void reset_leds(int start, int end) {
for (int i = start; i < end; i++) {
leds[i] = CRGB(0, 0, 0);
}
FastLED.show();
// Serial.println("Reset");
}

int rainbow_calc(double pixel, double maxPixels, double rgb_colour_id) {
double result = abs(
255 * cos((pixel / maxPixels) * (2 * PI) + (rgb_colour_id * (2 * PI) / 3)));

// Serial.println(result);
return result;
}

void setup() {
currentLED = 0;
session1Revolutions = 0;
session1Revolutions2 = 0;

currentLED2 = 144;
session2Revolutions = 0;
session2Revolutions2 = 0;

//Initialize the intterrupt pin (Arduino digital pin 2)
attachInterrupt(digitalPinToInterrupt(HALL_SENSOR_PIN_1), magnet_detect_session_1, FALLING);
attachInterrupt(digitalPinToInterrupt(HALL_SENSOR_PIN_2), magnet_detect_session_2, FALLING);

FastLED.addLeds<WS2812, LED_CONTROL_PIN, GRB>(leds, NUM_LEDS);
FastLED.setMaxPowerInVoltsAndMilliamps(5, MAX_POWER_DRAW);

Serial.begin(SERIAL_BAUD);

randomSeed(analogRead(0));
sessionID1 = "left_" + generate_session_id();
sessionID2 = "right_" + generate_session_id();
Serial.println("Session ID 1 " + sessionID1);
Serial.println("Session ID 2 " + sessionID2);

reset_leds(0, NUM_LEDS);
}

String generate_session_id() {
String newID = "";
int generated = 0;
while (generated < SESSION_ID_LENGTH) {
byte randomValue = random(0, 26);
char letter = randomValue + 'a';
if (randomValue > 26)
letter = (randomValue - 26);
newID += letter;
generated++;
}
return newID;
}

void loop() {
// magnet_detect_session_1();
FastLED.show();

// fill_rainbow(leds, 40, 200);
// fill_noise8(leds, 40, 2, 1,255, 5, 6, 255, 6);
// fadeLightBy(leds, 20, 250);

// char letter = random(0, 26);

int revs = session1Revolutions + (session1Revolutions2 * 254);
Serial.println(sessionID1 + " : " + revs);

int revs2 = session2Revolutions + (session2Revolutions2 * 254);
Serial.println(sessionID2 + " : " + revs2);
// Serial.println(letter);
// leds[0] = CRGB(255, 0, 0);
// FastLED.show();

delay(1000 / FRAMERATE);
// Serial.println("oh heck");
// leds[1] = CRGB(0, 255, 0);
// FastLED.show();
// delay(500);
// leds[2] = CRGB(0, 0, 255);
// FastLED.show();
// delay(500);
// leds[3] = CRGB(150, 0, 255);
// FastLED.show();
// delay(500);
// leds[4] = CRGB(255, 200, 20);
// FastLED.show();
// delay(500);
// leds[5] = CRGB(85, 60, 180);
// FastLED.show();
// delay(500);
// leds[6] = CRGB(50, 255, 20);
// FastLED.show();
// delay(500);
}

Comments

Instead of building a comments section, I've offloaded that job to twitter. You can just tweet @Dermah.