Showing entries with tag "Arduino".

Found 7 entries

Using Arduino interrupts to read RPM from a fan

I need to read the RPMs of some 12v PC fans so I wrote up a quick sketch to have an ESP32 monitor and log the RPM for me. You need to use an external interrupt that triggers every time the fan rotates (it triggers 2x per full rotation). I was having crashes before I added the ICACHE_RAM_ATTR parameter to the function. ICACHE_RAM_ATTR tell Arduino to store this function in RAM instead of on the flash. The logic here is that your interrupt function will probably be getting called a lot so it needs to be fast.

Connect the yellow RPM wire from your fan to pin 4, and the ground wire from the fan to the ground of the Arduino. Without the ground wire connected you will now have a shared ground between the Arduino and the fan and the interrupt will not fire.

const uint8_t tachoPin    = 4;
volatile uint32_t counter = 0;

ICACHE_RAM_ATTR void countPulses() {
    counter++;
}

void setup() {
    pinMode(tachoPin, INPUT_PULLUP);
    attachInterrupt(digitalPinToInterrupt(tachoPin), countPulses, FALLING);
    Serial.begin(115200);
}

void loop() {
    delay(1000);
    Serial.printf("%u fan revolutions in the last second\n", counter / 2);

    counter = 0;
}

Note: This code will work on an Arduino Uno without the ICACHE_RAM_ATTR which can be confusing.

Note: Using the internal pull-up resistor on the ESP32 means you can connect the yellow fan wire directly to the MCU. On an Arduino Uno an external pull-up resistor is required.

Leave A Reply

Arduino: Using an ATX power supply as a hobbyist power source

Running some RGB LEDs had me thinking about alternate sources of power. Specifically I need a mix of +5v and +12v to power different types of LEDs. Old ATX computer power supplies are a good/cheap source of power because they are easy to harvest from old PCs. They're also usually rated for high wattage.

After some research I found that you need to do a little work to turn on a PC power supply that's not hooked up to a motherboard. Specifically you need to short the green PS-ON pin to ground. This simulates pressing the power button on your PC and triggers the supply to turn on. You can tell the power supply is on when the fan starts to spin. This can be accomplished by cutting the green and (any) black wire out of the ATX connector and connecting them together.

Alternately the power supply will supply +5v of power even in off or standby mode if you use the purple +5vSB line. If all you need is a small amount (less than 2 amps) of 5v power using the +5vSB line is a great alternative and will be quieter because the fan will not be on.

Once the power supply is on you can use the other wires as follows:

Color Type
Black Ground
Orange +3.3v
Red +5v
Yellow +12v

Other pins are less useful but available:

Color Type
Green Power Supply On
Blue -12v
White -5v
Purple +5v standby

Be sure to check the amperage ratings for each voltage on the side of your power supply before use.

Leave A Reply

Arduino: Get IP and MAC address

Here is a quick way to get the IP address and/or MAC address from your Arduino device as a String.

String get_mac_addr() {
    uint8_t mac[6];
    WiFi.macAddress(mac); // Put the addr in mac

    char buf[18] = "";
    snprintf(buf, sizeof(buf), "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);

    return (String)buf;
}
String get_ip_addr() {
    IPAddress ip = WiFi.localIP();

    char buf[16];
    snprintf(buf, sizeof(buf), "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);

    return (String)buf;
}
Leave A Reply

Arduino: Connect to WiFi

Quicky helper function to connect to WiFi on Arduino so I don't have to re-invent the wheel every time I start a new project.

void init_wifi(const char *ssid, const char *password) {
    WiFi.mode(WIFI_STA); WiFi.begin(ssid, password);

    while (WiFi.status() != WL_CONNECTED) {
        delay(500); Serial.print(".");
    }

    Serial.printf("\r\nConnected to: \"%s\"\r\n",ssid);
    Serial.print("IP address  : "); Serial.println(WiFi.localIP());
    Serial.print("MAC address : "); Serial.println(WiFi.macAddress().c_str());
}
Leave A Reply

Arduino: ESP32-S2 USB modes

I picked up some new ESP32-S2 boards to play around with. These newer boards come with native USB on board, instead of a separate USB to serial chip to handle communications. With this new chip, there are some new USB acronyms in the Arduino menus. I kept getting them confused so I looked them all up and am committing them here for future reference.

Mode Explanation
USB DFU Device Firmware Upgrade: Upload mode
USB CDC Communication and Data Control: UART/Serial mode
USB MSC Mass storage device class
USB HID Human Interface Device: Mouse/Keyboard emulation
Leave A Reply

Arduino Relay shield on a Wemos D1

I bought an Arduino Relay Shield to use on my Wemos D1 (ESP8266). After some poking around here is the mapping for which pins enable which relays:

Pin Relay
GPIO13 Relay #1
GPIO12 Relay #2
GPIO14 Relay #3
GPIO4 Relay #4

To enable the relays on this shield you pull the appropriate pin HIGH. Other relay boards I've seen require you to pull the pin LOW, so don't get confused.

Here is the Tasmota template I used for the relay shield.

{"NAME":"Relay Shield","GPIO":[0,0,0,0,24,0,0,0,22,21,23,0,0],"FLAG":0,"BASE":18}
Leave A Reply

Arduino calculate prime numbers

I wrote some code to stress test my Arduino. The code below will make your Arduino calculate prime numbers.

long start       = 0;
int  max_seconds = 30;
long i           = 2; // Start at 2
long found       = 0; // Number of primes we've found

void setup() {
    Serial.begin(115200);

    while (!Serial) { }

    Serial.println("");
    Serial.print("Running prime benchmark for ");
    Serial.print(max_seconds);
    Serial.println(" seconds...");

    start = millis();
}

void loop() {
    int prime = is_prime(i); // Check if the number we're on is prime

    if (prime == 1) {
        found++;

        if (found % 2000 == 0) {
            Serial.print(".");
        }

        if (found % 50000 == 0) {
            Serial.print("\n");
        }
    }

    int running_seconds = (millis() - start) / 1000;

    if (max_seconds > 0 && (running_seconds >= max_seconds)) {
        Serial.print("\nFound ");
        Serial.print(found);
        Serial.print(" primes in ");
        Serial.print(max_seconds);
        Serial.println(" seconds");
        delay(10000);

        i     = 2;
        found = 0;
        start = millis();
    }

    i++;
}

int is_prime(long num) {
    // Only have to check for divisible for the sqrt(number)
    int upper = sqrt(num);

    // Check if the number is evenly divisible (start at 2 going up)
    for (long cnum = 2; cnum <= upper; cnum++) {
        long mod = num % cnum; // Remainder

        if (mod == 0) {
            return 0;
        } // If the remainer is 0 it's evenly divisible
    }

    return 1; // If you get this far it's prime
}
Leave A Reply - 1 Reply