r/arduino

▲ 30 r/arduino

Controlling LEDs using Minecraft!

I made a Java mod that, whenever a button or lever was activated, searched the nearby blocks for a sign, extracted the text from it, and printed it into a .txt file.

Then, I made a Python script that, in real time, grabbed the latest line from that txt file and sent it to the Arduino’s serial monitor. Using a bunch of if statements, the Arduino decided which LED should turn on!

Later, some professors told me I could’ve used Java’s ServerSocket instead of using Python as a middleman, but I didn’t know about it at the time. Honestly though, doing it my way was way more fun! :D

u/jotaaltda — 8 hours ago

OLED SPI Display keeps on glitching

I successfully uploaded the code on this project Arduboy Pocket Watch from https://www.hackster.io/tusharmagar/arduboy-pocket-watch-d19a1c to my Arduino Pro Micro but it only works when I reset it. I've tried burning the bootloader but the screen keeps on glitching and crashing and looking not at all coherent. Attached below is the code, photo of OLED display's current state and the circuit diagram I followed. For the circuit diagram I've only connected the OLED, RTC, button and Pro Micro on a breadboard. Battery charging module and LIPO battery should be ignored.

https://preview.redd.it/ethylga4ng2h1.jpg?width=1039&format=pjpg&auto=webp&s=17686e2bb94cbcf1f093647629ed23d0fd90901a

#include <Arduboy2.h>

#include <SPI.h>
#include <Wire.h>
#include <Time.h>
#include <TimeLib.h>
#include <DS1307RTC.h>

#include "Tinyfont.h"
#include "limits.h"

#define GROUND_HEIGHT       46
#define OBSTACLE_DELAY_MAX  512
#define OBSTACLE_DELAY_MIN  96
#define BONUS_DELAY_MAX     1024
#define BONUS_DELAY_MIN     512

tmElements_t tm;

enum State {
    Intro,
    Play,
    Pause,
    Over,
    Credits
};

struct Position {
    int x;
    int y;
};
struct Velocity {
    int x;
    int y;
};
struct Size {
    unsigned int width;
    unsigned int height;
};

struct Object {
    Position pos;
    Velocity vel;
    Rect     box;
    unsigned int frame;
    unsigned int type;
    boolean action;
};
struct Star {
    Position pos;
    unsigned int frame;
};
struct Particle {
    Position pos;
    unsigned int life;
    unsigned int lifeCount;
};

const byte spriteLogoA[] PROGMEM = {
    0x3e, 0x63, 0xc9, 0x9d, 0x39, 0x7b, 0xf2, 0xf6, 0xf4, 0xe4, 0xc8, 0xd8, 0x90, 0xb0, 0xa0, 0x20, 0x60, 0xc0, 0x80, 0x80, 0xc0, 0x60, 0x20, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x20, 0x60, 0x40, 0x40, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1, 0x7, 0xc, 0x19, 0x73, 0xc7, 0x9f, 0x3f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfc, 0xfd, 0xfd, 0xfc, 0xff, 0xff, 0xff, 0x9f, 0xf, 0xf, 0xf, 0xf, 0x1f, 0x1f, 0x1e, 0x3c, 0x3d, 0x7d, 0xf9, 0xfb, 0xf2, 0xe6, 0xcc, 0x98, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xf0, 0x1f, 0xc3, 0xf8, 0xff, 0xff, 0xf3, 0x5, 0x3, 0x45, 0x8b, 0x17, 0xaf, 0x5f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfc, 0xfc, 0xf8, 0xf8, 0xf0, 0xe0, 0xc0, 0x1, 0x3, 0xf, 0x1f, 0x7f, 0xff, 0xfe, 0xf8, 0xf3, 0xc6, 0x1c, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xf0, 0x1f, 0xc0, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfc, 0xfc, 0xfc, 0xfe, 0xff, 0x7f, 0x3f, 0x9f, 0xf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf0, 0x80, 0x00, 0x1, 0xf, 0xff, 0xff, 0xff, 0xfc, 0x1, 0xff, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x7, 0x70, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x8f, 0xe3, 0xf9, 0xfc, 0xfe, 0x3f, 0x87, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x80, 0xf0, 0xff, 0xff, 0xff, 0x1f, 0xc0, 0x7f, 0x00, 0x00, 0x00, 0xc0, 0x41, 0x47, 0x4c, 0x49, 0x6b, 0x2b, 0xab, 0xab, 0xbb, 0x99, 0xdd, 0xcc, 0xee, 0xe7, 0xf7, 0xf3, 0xf9, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x9f, 0xc7, 0xf0, 0xf8, 0xfe, 0x7f, 0x3f, 0x8f, 0xe7, 0x31, 0x1c, 0x7, 0x00, 0x00, 0x00, 0x00, 0x7, 0xc, 0x19, 0x13, 0x37, 0x27, 0x6f, 0xcf, 0x9f, 0xbf, 0xbf, 0x3f, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0x7f, 0x3f, 0xbf, 0xbf, 0xbf, 0x9f, 0xcf, 0x67, 0x27, 0x33, 0x19, 0xc, 0x6, 0x3, 0x1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1, 0x1, 0x3, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x3, 0x1, 0x1, 0x1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

const byte spriteBackgroundA[] PROGMEM  = {
    0xc0, 0xf0, 0xf8, 0xfc, 0xfc, 0xfe, 0xfe, 0xfe, 0xfe, 0xfc, 0xfc, 0xf8, 0xf0, 0xc0, 0x00, 0xc0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0, 0xe0, 0xc0, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf, 0xf,
};
const byte spriteBackgroundB[] PROGMEM  = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x4, 0x2, 0x2, 0x2, 0x4, 0x18, 0x20, 0x10, 0x10, 0x10, 0x20, 0x18, 0x4, 0x2, 0x2, 0x2, 0x4, 0x18, 0x20, 0x10, 0x10, 0x10, 0x20, 0x8a, 0x55, 0xa2, 0x54, 0x8a, 0x55, 0xa2, 0x54, 0x8a, 0x55, 0xa2, 0x54, 0x8a, 0x55, 0xa2, 0x54, 0x8a, 0x55, 0xa2, 0x54, 0x8a, 0x55, 0xa2, 0x54,
};

const byte spriteMoon[] PROGMEM = {
    0xe0, 0xf8, 0xfc, 0xfe, 0xe, 0x3, 0x1, 0x1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7, 0x1f, 0x3f, 0x7f, 0x7f, 0xfc, 0xf8, 0xf8, 0xf0, 0xf0, 0xf0, 0x70, 0x78, 0x38, 0x1c, 0x7,
};

const byte spriteStar_0[] PROGMEM  = { 0x00, 0x00, 0x00, 0x00, 0x8, 0x00, 0x00, 0x00 };
const byte spriteStar_1[] PROGMEM  = { 0x00, 0x00, 0x00, 0x8, 0x1c, 0x8, 0x00, 0x00 };
const byte spriteStar_2[] PROGMEM  = { 0x00, 0x00, 0x00, 0x8, 0x14, 0x8, 0x00, 0x00 };
const byte spriteStar_3[] PROGMEM  = { 0x00, 0x00, 0x8, 0x8, 0x36, 0x8, 0x8, 0x00 };
const byte spriteStar_4[] PROGMEM  = { 0x00, 0x00, 0x8, 0x00, 0x2a, 0x00, 0x8, 0x00 };
const byte *animationFramesStar[] = { spriteStar_0, spriteStar_1, spriteStar_2, spriteStar_3, spriteStar_4 };

const byte spriteUnicorn_0[] PROGMEM  = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x18, 0x8, 0x7c, 0x1c, 0x1c, 0x1e, 0x7f, 0x2, 0x3, 0x3, 0x00, 0x00, 0x00,
};
const byte spriteUnicorn_1[] PROGMEM  = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, 0x20, 0x30, 0x10, 0x38, 0x78, 0x38, 0x38, 0x38, 0x7c, 0x3e, 0x5, 0x6, 0x6, 0x00, 0x00,
};
const byte spriteUnicorn_2[] PROGMEM  = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0xc0, 0xe0, 0x50, 0x68, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2, 0x3, 0x1, 0xf, 0x3, 0x3, 0x3, 0xf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
const byte spriteUnicornMask_0[] PROGMEM  = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0xa0, 0xd0, 0x20, 0x00, 0x00, 0x00, 0x10, 0x28, 0x24, 0x74, 0x82, 0x62, 0x22, 0x61, 0x80, 0x7d, 0x4, 0x4, 0x3, 0x00, 0x00,
};
const byte spriteUnicornMask_1[] PROGMEM  = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0xa0, 0x40, 0x00, 0x20, 0x50, 0x48, 0x28, 0x44, 0x84, 0x44, 0x44, 0x44, 0x82, 0x41, 0x3a, 0x9, 0x9, 0x6, 0x00,
};
const byte spriteUnicornMask_2[] PROGMEM  = {
    0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x40, 0x20, 0x10, 0xa8, 0x94, 0x9a, 0x64, 0x00, 0x00, 0x00, 0x2, 0x5, 0x4, 0xe, 0x10, 0xc, 0x4, 0xc, 0x10, 0xf, 0x00, 0x00, 0x00, 0x00, 0x00,
};
const byte *animationFramesUnicorn[] = { spriteUnicorn_0, spriteUnicorn_1, spriteUnicorn_2 };
const byte *animationFramesUnicornMask[] = { spriteUnicornMask_0, spriteUnicornMask_1, spriteUnicornMask_2 };

const byte spriteStar[] PROGMEM  = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4, 0x6c, 0x7c, 0x3f, 0x37, 0x7c, 0x6c, 0x4, 0x00, 0x00, 0x00, 0x00,
};
const byte spriteStarMask[] PROGMEM  = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4, 0x6a, 0x92, 0x83, 0x40, 0x48, 0x83, 0x92, 0x6a, 0x4, 0x00, 0x00, 0x00,
};
const byte spriteGhost[] PROGMEM  = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x33, 0x3f, 0x3f, 0x33, 0x3f, 0x3e, 0x18, 0x10, 0x00, 0x00, 0x00,
};
const byte spriteGhostMask[] PROGMEM  = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x21, 0x4c, 0x40, 0x40, 0x4c, 0x40, 0x41, 0x26, 0x28, 0x18, 0x00, 0x00,
};
const byte *spritesObject[] = { spriteGhost, spriteStar };
const byte *spritesObjectMask[] = { spriteGhostMask, spriteStarMask };

boolean btnPressed, dpadPressed;

unsigned int counterState, counterBackgroundA, counterBackgroundB = 0;
int scoreBonusDuration = 0;

long score, scoreHI = 0;

Arduboy2 arduboy;
Tinyfont arduboyTinyFont = Tinyfont(arduboy.sBuffer, Arduboy2::width(), Arduboy2::height());

State state = Intro;

Object unicorn, objects[3];
Particle particles[24];
Star stars[9] = {
    { { 2,  13  }, 1 },
    { { 23,  3  }, 4 },
    { { 27,  24 }, 2 },
    { { 42,  7  }, 0 },
    { { 59,  16 }, 4 },
    { { 77,  8  }, 1 },
    { { 92,  21 }, 0 },
    { { 109, 9  }, 3 },
    { { 116, 17 }, 0 }
};

// ------------------------------------------------------------------------------------
void setup() {
  RTC.read(tm);
    arduboy.begin();
    particlesReset();
    statePlayReset();

    scoreHI = EEPROM.read(EEPROM_STORAGE_SPACE_START);
}
void loop() {
    arduboy.clear();
    if (!arduboy.nextFrame()) {
        return;
    }

    if (arduboy.everyXFrames(32)) {
        randomSeed(analogRead(0)); // reset random
    }

    stateUpdate();

    arduboy.display();
}

// ------------------------------------------------------------------------------------
void stateUpdate() {
    counterState = ((counterState + 1) > UINT_MAX) ? 0 : counterState;

    switch (state) {

        case State::Play:
            statePlayUpdate();
            break;

        case State::Over:
            stateOverUpdate();
            break;

        default:
            stateIntroUpdate();
            break;
    }
}
void stateSwitch(State stateNew) {
    counterState = 0;
    counterBackgroundA, counterBackgroundB = 0;

    switch (stateNew) {
        case State::Intro:
            statePlayReset();
            break;
    }

    state = stateNew;
};

// STATE INTRO: -----------------------------------------------------------------------
void stateIntroUpdate() {
    counterState += 1;

    arduboy.drawBitmap(10, 0, spriteLogoA, 50, 58, WHITE);

    arduboyTinyFont.setCursor(15, 60);
    for (byte i = (8 - intLength(scoreHI)); i > 0; i--) {
        arduboyTinyFont.print("0");
    }

    arduboyTinyFont.print(scoreHI);

//////////////////////////////////////////////////////////////////////////////
arduboy.setCursor(70,15);
arduboy.setTextSize(2);
arduboy.print(tm.Hour);
arduboy.print(":");
arduboy.print(tm.Minute);
arduboy.setCursor(70,40);
arduboy.setTextSize(1);
arduboy.print(tm.Day);
arduboy.write('/');
arduboy.print(tm.Month);
arduboy.write('/');
arduboy.print(tmYearToCalendar(tm.Year));
arduboy.display();

    if ((arduboy.pressed(A_BUTTON) || arduboy.pressed(B_BUTTON)) && !btnPressed) {
            stateSwitch(State::Play);
    }
    btnPressed = (arduboy.pressed(A_BUTTON) || arduboy.pressed(B_BUTTON));
}



// STATE Over: ---------------------------------------------------------------------
void stateOverUpdate() {
    arduboy.setCursor(37, 18);
    arduboy.print("GAME OVER");

    for (byte i = 0; i < 3; i++) {
        if (objects[i].type == 0) {
            objectRender(objects[i]);
        }
    }

    unicornRender();
    scoreRender();

    if (arduboy.pressed(B_BUTTON) && !btnPressed) {
        if (score > scoreHI) {
            scoreHI = score;
            EEPROM.update(EEPROM_STORAGE_SPACE_START, scoreHI);
        }

        stateSwitch(State::Intro);
    }
    btnPressed = arduboy.pressed(B_BUTTON);
}

// STATE PLAY: ------------------------------------------------------------------------
void statePlayUpdate() {
    counterState += 1;
    
        if (arduboy.pressed(B_BUTTON) && unicorn.action) {
            unicorn.vel.y = -3;
            counterState = 0;
        }
        
    btnPressed = (arduboy.pressed(A_BUTTON) || arduboy.pressed(B_BUTTON));

    backgroundLayerOneRender();
    backgroundLayerTwoRender();
    backgroundLayerThreeRender();

    objectsUpdate();
    unicornUpdate();

    scoreUpdate();
}
void statePlayReset() {
    score = 0;
    scoreBonusDuration = 0;

    unicornSetup();
    objectsSetup();
}


// UNICORN ----------------------------------------------------------------------------
void unicornSetup() {
    unicorn = { { 48, GROUND_HEIGHT }, { 0, 0 }, { 0, 0, 7, 8 }, 0, 7, true };
}
 void unicornUpdate() {

    if (counterState%10 == 0) {
        unicorn.vel.y += 1;
    }

    unicorn.pos.y = min(unicorn.pos.y + unicorn.vel.y, GROUND_HEIGHT);
    unicorn.pos.x = min(unicorn.pos.x + unicorn.vel.x, arduboy.width() - 12);
    unicorn.pos.x = max(unicorn.pos.x + unicorn.vel.x, -4);

    unicorn.box.x = unicorn.pos.x + 4;
    unicorn.box.y = unicorn.pos.y - 9;

    if (unicorn.pos.y >= GROUND_HEIGHT) {
        unicorn.action = true;
        unicorn.vel.y = 0;
    }
    else {
        unicorn.action = false;
    }

    unicornRender();
    particlesRender();
}
void unicornRender() {
    if (unicorn.action) {
        if (arduboy.everyXFrames(6)) {
            unicorn.frame = ((unicorn.frame + 1) > 2) ? 0 : unicorn.frame + 1;
        }
    }
    else {
        unicorn.frame = 0;
    }

    arduboy.drawBitmap(unicorn.pos.x, unicorn.pos.y - 15, animationFramesUnicornMask[unicorn.frame], 16, 16, BLACK);
    arduboy.drawBitmap(unicorn.pos.x, unicorn.pos.y - 15, animationFramesUnicorn[unicorn.frame], 16, 16, WHITE);
}

// OBJECTS ---------------------------------------------------------------------------
void objectsSetup() {
    objects[0] = { { -16, GROUND_HEIGHT }, { -1, 0 }, { 0, 0, 8, 8 }, 0, 0, true };
    objects[1] = { { -16, GROUND_HEIGHT }, { -1, 0 }, { 0, 0, 8, 8 }, 0, 0, true };
    objects[2] = { { -16, 22 },            { -1, 0 }, { 0, 0, 8, 8 }, 0, 1, true };

    for (byte i = 0; i < 3; i++) {
        objects[i] = objectReset(objects[i]);
    }
}
void objectsUpdate() {
    for (byte i = 0; i < 3; i++) {
        objects[i].pos.x += objects[i].vel.x;
        objects[i].box.x = objects[i].pos.x + 4;
        objects[i].box.y = objects[i].pos.y - 8;

        if (objects[i].pos.x >= -8) {
            Rect boxA = { unicorn.box.x, unicorn.box.y, unicorn.box.width, unicorn.box.height };
            Rect boxB = { objects[i].box.x, objects[i].box.y, objects[i].box.width, objects[i].box.height };

            if (arduboy.collide(boxA, boxB)) {
                if (objects[i].type == 0) {
                    state = State::Over;
                }
                else if (objects[i].type == 1){
                    objects[i] = objectReset(objects[i]);

                    if (scoreBonusDuration <= 0) {
                        particlesReset();
                    }
                    scoreBonusDuration += 50;
                }
            }

            objectRender(objects[i]);
        }
        else {
            objects[i] = objectReset(objects[i]);
        }
    }
}
void objectRender(Object object) {
    arduboy.drawBitmap(object.pos.x, object.pos.y - 15, spritesObjectMask[object.type], 16, 16, BLACK);
    arduboy.drawBitmap(object.pos.x, object.pos.y - 15, spritesObject[object.type], 16, 16, WHITE);
    // arduboy.drawRect(object.box.x, object.box.y, object.box.width, object.box.height, 1); // Collision Box Debug
}
Object objectReset(Object object){
    if (object.type == 0) {
        object.pos.x = arduboy.width() + random(OBSTACLE_DELAY_MIN, OBSTACLE_DELAY_MAX);

        for (byte i = 0; i < 3; i++) {
            if (objects[i].type == 0) {
                if (objects[i].pos.x >= arduboy.width()) {
                    if ((rand()%4) > 2) {
                        object.pos.x = objects[i].pos.x + 10;
                        object.pos.y = GROUND_HEIGHT;
                    }
                    else {
                        object.pos.x = objects[i].pos.x + random(OBSTACLE_DELAY_MIN, OBSTACLE_DELAY_MAX);
                        object.pos.y = GROUND_HEIGHT - random(0, 12);
                    }
                }
            }
        }
    }
    if (object.type == 1) {
        object.pos.x = arduboy.width() + random(BONUS_DELAY_MIN, BONUS_DELAY_MAX);
    }

    return object;
}

// BACKGROUND -------------------------------------------------------------------------
void backgroundLayerOneRender() {
    arduboy.drawBitmap(12, 4, spriteMoon, 16, 16, WHITE);

    for (byte i = 0; i < 9; i++) {
        if (arduboy.everyXFrames(8)) {
            stars[i].frame = ((stars[i].frame + 1) > 4) ? 0 : stars[i].frame + 1;
        }

        arduboy.drawBitmap(stars[i].pos.x, stars[i].pos.y, animationFramesStar[stars[i].frame], 8, 8, WHITE);
    }
}
void backgroundLayerTwoRender() {
    if (arduboy.everyXFrames(2)) {
        counterBackgroundA = ((counterBackgroundA + 1) >= 24) ? 0 : counterBackgroundA + 1;
    }

    for (byte i = 0; i <= 6; i++) {
        arduboy.drawBitmap(((i * 24) - counterBackgroundA), 28, spriteBackgroundA, 24, 36, WHITE);
    }
}
void backgroundLayerThreeRender() {
    if (arduboy.everyXFrames(1)) {
        counterBackgroundB = ((counterBackgroundB + 1) >= 24) ? 0 : counterBackgroundB + 1;
    }

    for (byte i = 0; i <= 6; i++) {
        arduboy.drawBitmap(((i * 24) - counterBackgroundB), 41, spriteBackgroundB, 24, 24, BLACK);
    }
}

// SCORE -----------------------------------------------------------------------------
void scoreUpdate() {
    if (arduboy.everyXFrames(16)) {
        scoreBonusDuration = max(0, (scoreBonusDuration - 1));

        if (scoreBonusDuration > 0){
            score += 10;
        }

        score = min(99999999, (score + 1));
    }

    scoreRender();
}
void scoreRender() {
    if (score > scoreHI) {
        arduboyTinyFont.setCursor(77, 4);
        arduboyTinyFont.print("HI");
    }
    else {
        arduboyTinyFont.setCursor(87, 4);
    }

    for (byte i = (8 - intLength(score)); i > 0; i--) {
        arduboyTinyFont.print("0");
    }

    arduboyTinyFont.print(score);
}

// HELPERS ----------------------------------------------------------------------------
int intLength(int i) {
    int j = 0;

    for(; i; i /= 10) j++;

    return (j == 0) ? 1 : j;
}

void particlesRender() {
    if (scoreBonusDuration <= 0) {
        return;
    }

    for (byte i = 0; i < 24; i++) {
        particles[i].pos.x -= 1;

        if (particles[i].lifeCount > particles[i].life) {
            particles[i].life = 8 + rand()%32;
            particles[i].lifeCount = 0;

            particles[i].pos.y = unicorn.pos.y - 3 + ((rand()%2 > 0) ? (rand()%4 * -1) : rand()%4);
            particles[i].pos.x = unicorn.pos.x + 4;
        }
        else {
            particles[i].lifeCount += 1;
        }

        arduboy.drawPixel(particles[i].pos.x, particles[i].pos.y - 1, 0);
        arduboy.drawPixel(particles[i].pos.x, particles[i].pos.y, 1);
    }
}
void particlesReset() {
    for (int i = 0; i < 24; ++i) {
        particles[i] = { { 0, 0 }, 0 };
    }
};

https://preview.redd.it/v80nw4q4ng2h1.jpg?width=1039&format=pjpg&auto=webp&s=40350cae872fbb250a22fbe475659bb6ba57cb76

https://reddit.com/link/1tjf572/video/6hqrbwl0lg2h1/player

reddit.com
u/Easy_Ingenuity5811 — 11 hours ago

How do I get the DC motor to start after the servo finishes it's part?

Hey, I'm currently working on a rover which needs to push cubes off. I've got most of the code to work. My only issue is that after the servo pushes the block then returns to its original position I need the DC motor to start again but it just gets stuck repeating that section of the code. Is there anyway for me to fix this? Any help or advice would be greatly appreciated.

This is the code I have:

#include <Servo.h>

Servo myservo; // create servo object to control a servo

// twelve servo objects can be created on most boards

int led=5;

int buzzer=6;

const int buttonPin = 7;

int buttonState = 0; // variable for reading the pushbutton status

int pos = 0; // variable to store the servo position

int in1=9;

int in2=10;

// the setup function runs once when you press reset or power the board

void setup() {

// initialize digital pin LED_BUILTIN as an output.

pinMode(led, OUTPUT);

pinMode(buzzer, OUTPUT);

pinMode(buttonPin, INPUT);

pinMode(in1, OUTPUT);

pinMode(in2, OUTPUT);

myservo.attach(8); // attaches the servo on pin 9 to the servo object

}

// the loop function runs over and over again forever

void loop() {

digitalWrite(in1, HIGH);

digitalWrite(in2, LOW);

buttonState = digitalRead(buttonPin);

if (buttonState == LOW) {

//Motor stops when object detected

digitalWrite(in1, HIGH);

digitalWrite(in2, HIGH);

// turn LED on:

digitalWrite(led, HIGH);

delay(1000); // wait for a second

digitalWrite(led, LOW); // turn the LED off by making the voltage LOW

delay(1000); // wait for a second

digitalWrite(buzzer, HIGH);

delay(1000);

digitalWrite(buzzer, LOW);

delay(1000);

for (pos = 0; pos <= 180 ; pos += 1) {

myservo.write(pos);

delay(5);

}

delay(1000);

for (pos = 180; pos>= 0; pos -= 1) {

myservo.write(pos);

delay(5);

}

delay(1000);

digitalWrite(in1, HIGH);

digitalWrite(in2, LOW);

}

else {

digitalWrite(in1, HIGH);

digitalWrite(in2, LOW);

digitalWrite(led, LOW);

digitalWrite(buzzer, LOW);

}

}

reddit.com
u/EnglandUndead1 — 13 hours ago
▲ 464 r/arduino+1 crossposts

Today was the first full scale test of my mural plotter Dot-Bot using 3 motor stations and real spray cans. In my last timelapse, the canvas was small and the loads were negligible but here, the third motor station really makes a huge difference taking the bulk of the forces in the upper center

For years now, I am working iteratively on my wall plotter project called Dot-Bot. During the first full scale tests, we ran into issues with the forces being too high on the side motors when the gondola moves in the upper middle portion of the canvas. This led to wavy lines since the GT2 belts started to oscillate like guitar stings under high loads. With this third center station, we are able to decrease the force on the side motors dramatically improving quality noticeably where it matters the most, in the center of the wall.

u/Oli_Vier_0x3b29 — 1 day ago
▲ 0 r/arduino+3 crossposts

How Can I Make My QClaw Agentic Agent Faster on Arduino Uno Q?

I created QClaw as an on-device agentic AI assistant for the Arduino Uno Q. It writes, compiles, and uploads Arduino sketches; captures camera frames; drives Linux-side LEDs; reports network state; and scans I²C buses, all running entirely on the board. No internet. No API keys. No cloud.

My biggest issue is that I want to improve the tokens/sec generation speed, which I've only been able to max out at 9 tokens/sec. Is it possible to use the Adreno GPU that's on the Arduino Uno Q to improve the speed of QClaw?

QClaw: A Fully Local Agentic Assistant on the Arduino Uno Q

u/Away-Ad-8572 — 16 hours ago
▲ 0 r/arduino+1 crossposts

I have 2,000+ components across 15 boxes and my inventory system is my own brain. It's not working anymore.

Mechanical engineer here, been doing Arduino and Raspberry Pi projects as a hobby for years.

My current "inventory system":
- Components spread across cardboard boxes, plastic bins, and random containers on my desk
- No labels, no spreadsheet, no app
- Everything lives in my head

Last month I spent 45 minutes looking for a specific 10kΩ resistor. Found three of them. In three different boxes. After I had already ordered more.

The worst part isn't buying duplicates. It's when I start planning a project, build the BOM, and have no idea if I actually have the parts or need to order. So I either order everything "just in case" (expensive) or start building and realize mid-project that I'm missing one component (frustrating).

I've tried:
- Excel → works until it doesn't, gave up after 2 months
- PartsBox → powerful but overkill and pricey for a hobbyist
- PartKeepr → self-hosted, spent more time setting it up than using it
- Just memorizing → worked until I hit ~500 components

I'm a mechanical engineer who also codes, so I'm building something to fix this for myself. The concept is simple: know what you have, know what project it's allocated to, know what you need to order. Nothing more.

**If you have this same problem, I'd appreciate knowing:**
1. How do you currently manage your component inventory?
2. What's the most painful moment — buying duplicates, mid-project missing parts, something else?
3. Would you pay ~$7-10/month for a tool that actually solves this cleanly?

Not selling anything. Building in public and trying to understand if this is just my problem or a real gap.

[Form Link](https://tally.so/r/gDJ8pd) - Takes 2 minutes =)
u/Acceptable_Sea_2409 — 21 hours ago
▲ 56 r/arduino

This robot car can move forward, backward, turn left, turn right, and even move sideways. All you need is four mecanum wheels to make this kind of movement possible.”

u/CallmeLee1999 — 1 day ago
▲ 29 r/arduino

Inflation's so bad I had to make my own metronome

This is my first project I'm actually proud of! Next step is to connect a display to show the current tempo but I don't really feel like doing it now lol

u/tayx361 — 1 day ago
▲ 44 r/arduino

I designed a quadcopter where the PCB frame and circuit board are the same object - here's what I learned after a year of building

Been working on this for about a year and wanted to share what I learned - both the hardware design decisions and the mistakes.

The idea was simple - instead of a separate carbon or plastic frame, the PCB arms are the airframe. An ESP32 sits at the centre as the flight controller. Four brushless motors clip directly to the board corners.

Using Arduino and esp32.

#arduino #esp32 #drone

Built a little firmware automation tool to save my own sanity. What features would you want?

I got incredibly tired of manually compiling and flashing my ESP32 every single time I made a minor code change, so I spent some time building a tool called FlashBot to automate the entire loop.

Right now, the workflow is completely hands-off. Here is what it does:

Auto-detection: Uses Linux udev events to detect the board the second it's plugged in.

Smart matching: Looks up the correct sketch from a config file (or prompts me to choose if I have multiple sketches mapped to that specific board).

Compile & Flash: Pulls everything together via arduino-cli and flashes it automatically.

History: Logs every single flash into a local SQLite DB so I don't lose track of versions.

Current Status: The core detection and flashing logic are fully stable. Right now, I'm working on polishing up a serial test suite and the logging system.

What I'm planning to build next:

Serial validation: Automatically open the port, send a test command, and verify the response post-flash to make sure the firmware is actually alive.

Differential builds: Only recompile if the sketch or dependencies actually changed.

Broadening hardware support: Moving beyond standard Arduino/ESP32 to natively handle STM32.

Mass flashing: Parallel flashing for when you need to push the same firmware to a handful of boards at once.

The goal isn't to replace your IDE or build system—it’s just to completely cut out the tedious "plug, compile, click flash, open serial, check" routine.

If you do a lot of hardware prototyping, does this hit a pain point for you? What kind of features would make a tool like this actually useful in your day-to-day workflow?

reddit.com
u/Rolex_37 — 1 day ago
▲ 18 r/arduino

Built a cyberpunk-style ESP32 smart desk companion!!

Built a cyberpunk-style ESP32 smart desk companion from scratch.

Features: • OLED analog + digital clock • Date, temperature & humidity display • Firebase-powered remote dashboard • Push notifications to the OLED • Timer + alarm system • RGB ambient lighting modes • Offline MP3 music player using SD card • Real-time synced lyrics display (.lrc support) • Browser-based music control UI • Wi-Fi AP mode for offline control • Dual-core ESP32 task handling • Automatic/manual time sync fallback

The whole thing runs on a single ESP32 with:

  • SH1106 OLED
  • DHT11 sensor
  • RGB LED
  • Buzzer
  • SD card module
  • custom web dashboard hosted on GitHub Pages

One button controls:

  • clock face switching
  • music mode
  • alarm/timer stopping

Long press enables a completely offline music player mode where the ESP32 creates its own Wi-Fi network and streams songs directly from the SD card to your phone.

Probably the most overengineered clock I’ve ever built 😭

Beginner

I have exam of iot where parts are given I have to made project can you anybody suggest yt videos for beginner of esp how to connect to arduino code wire connecting please

reddit.com
u/No_Butterfly6242 — 1 day ago
▲ 42 r/arduino

Question regarding this connection + usb input

Working on a project using Arduino Nano to control WS2811 LED strip (24V). I have the Arduino and light strip both powered from a 24v power supply. Arduino is supplied through a buck converter bringing it to 5v. The circuit works fine, shares ground, no issues. Data line is sent through D5. Arduino power input is thru 5V and grounded to GND.

My question is: with the current setup, if I kept the nano plugged in in a “permanent” build, would I still be able to plug the usb in from my laptop to upload new code while the build is powered? I have read a bit about back voltage and how it could mess up my laptop or the nano. Was wondering if my situation would create such a situation or would be fine.

u/goroyo_9090 — 1 day ago
▲ 64 r/arduino

I Made an Interactive PCB Map of the East Bay in California

I designed the board in KiCad using the image converter. The roads are copper traces, the water is solder mask, and the bare board is the land. An LED panel behind the board can draw locations and images. The panel is controlled by an ESP32 getting commands over MQTT.

I documented the whole thing with the design files and source code for the software: https://www.robopenguins.com/pcb-map/

u/curatorcat — 1 day ago
▲ 129 r/arduino

How can i improve my code for my line follower robot?

i've been working hard on the code, but even so, i can't reach to something satisfactory yet. How can I make that my robot doesn't make any mistakes like looping in circles or turning around. this is my current code:

#include "MeMegaPi.h"
//codigo antiguo 
MeMegaPiDCMotor motorIzq(PORT1); //motor izquierdo
MeMegaPiDCMotor motorDer(PORT2); //motor derecho
MeLineFollower moduloIzq(PORT5);
MeLineFollower moduloCen(PORT6);
MeLineFollower moduloDer(PORT7);
//parametros de velocidad
const int VEL_RECTA = 90;
const int VEL_CURVA_SUAVE = 80;
const int VEL_CURVA_FUERTE = 70;
const int VEL_MAX = 110;
//PID
float Kp = 20.0;
float Kd = 40.0;
int ultimoError = 0;


unsigned long tiempoBlanco = 0;
bool perdiendoLinea = false;
const int sentido_ORC = 2; //Preferencia de sentido de aguja del reloj, si es 1 es izquierda si es 2 es derecha.
bool arranqueORCResuelto = false; //variable de giro preferencial forzado al arranque 


void setup() {
  delay(1500);
}


void loop() {
  int stI = moduloIzq.readSensors();//sensor izquierda
  int stC = moduloCen.readSensors();//sensor centram
  int stD = moduloDer.readSensors();//sensor derecho
//condicionales
//condicion giro izquierdo en caso de T
  if (stC != 3 &amp;&amp; stI != 3 &amp;&amp; stD == 3) {
    mover(-125, 135);
    perdiendoLinea = false;
    tiempoBlanco = 0;
    ultimoError = 0;
    return;
  }
//condicion giro derecho en caso de T
  if (stC != 3 &amp;&amp; stD != 3 &amp;&amp; stI == 3) {
    mover(135, -125);
    perdiendoLinea = false;
    tiempoBlanco = 0;
    ultimoError = 0;
    return;
  }
//Recta
  if (stC == 0) {
    mover(VEL_RECTA, VEL_RECTA);
    perdiendoLinea = false;
    tiempoBlanco = 0;
    ultimoError = 0;
    return;
  }
//condicional en caso de que todo sea negro, si no se ha resuelto el arranque orc, usar sentido preferencial ORC.
  if (stC != 3 || stI != 3 || stD != 3) {
    ejecutarPID(stI, stC, stD);
    perdiendoLinea = false;
    tiempoBlanco = 0;
  } else {
    if (!perdiendoLinea &amp;&amp; !arranqueORCResuelto) {
      if (sentido_ORC == 1) mover(-135, 135);
      else mover(135, -135);
      arranqueORCResuelto = true;
      tiempoBlanco = millis();
      perdiendoLinea = true;
    }
    if (!perdiendoLinea) {
      tiempoBlanco = millis();
      perdiendoLinea = true;
    }
    unsigned long duracionBlanco = millis() - tiempoBlanco;
    if (duracionBlanco &lt; 130) { //Delay de reacciob principal
      mover(VEL_RECTA - 20, VEL_RECTA - 20); //girar
    } else if (duracionBlanco &lt; 900) { //tiempo que el robot espera para girar a otro lado
      if (ultimoError &gt; 0) mover(135, -135);
      else mover(-135, 135);
    } else if (duracionBlanco &lt; 1700) { //modo recuperacion
      if (ultimoError &gt; 0) mover(-135, 135);
      else mover(135, -135);
    } else if (duracionBlanco &lt; 2800) {
      if ((duracionBlanco / 200) % 2 == 0) mover(-100, -60);
      else mover(-60, -100);
    } else {
      mover(-90, -90);
    }
  }
}
//ejecucion del PID
void ejecutarPID(int stI, int stC, int stD) {
  int error = calcularError(stI, stC, stD);
  float correccion;
  if (abs(error) &lt;= 1) {
    correccion = error * Kp;
  } else {
    correccion = (error * Kp) + ((error - ultimoError) * Kd);
  }
  int velBaseActual = (abs(error) &lt;= 1) ? VEL_RECTA : VEL_CURVA_SUAVE;
  int vI = velBaseActual + (int)correccion;
  int vD = velBaseActual - (int)correccion;
  if (abs(error) &gt;= 9) {
    if (error &gt; 0) vD = -125;
    else vI = -125;
  }
  mover(constrain(vI, -VEL_MAX, VEL_MAX), constrain(vD, -VEL_MAX, VEL_MAX));
  if (error != 0) ultimoError = error;
}
//Paramemtros de PID en errores
int calcularError(int stI, int stC, int stD) {
  if (stC == 0) return 0;
  if (stC == 2) return -1;
  if (stC == 1) return 1;
  if (stI == 1) return -4;
  if (stI == 0) return -7;
  if (stI == 2) return -11;
  if (stD == 2) return 4;
  if (stD == 0) return 7;
  if (stD == 1) return 11;
  return ultimoError;
}
//funcion de mover motores
void mover(int izq, int der) {
  motorIzq.run(izq);
  motorDer.run(-der);
}
 #include "MeMegaPi.h"
//codigo antiguo 
MeMegaPiDCMotor motorIzq(PORT1); //motor izquierdo
MeMegaPiDCMotor motorDer(PORT2); //motor derecho
MeLineFollower moduloIzq(PORT5);
MeLineFollower moduloCen(PORT6);
MeLineFollower moduloDer(PORT7);
//parametros de velocidad
const int VEL_RECTA = 90;
const int VEL_CURVA_SUAVE = 80;
const int VEL_CURVA_FUERTE = 70;
const int VEL_MAX = 110;
//PID
float Kp = 20.0;
float Kd = 40.0;
int ultimoError = 0;


unsigned long tiempoBlanco = 0;
bool perdiendoLinea = false;
const int sentido_ORC = 2; //Preferencia de sentido de aguja del reloj, si es 1 es izquierda si es 2 es derecha.
bool arranqueORCResuelto = false; //variable de giro preferencial forzado al arranque 


void setup() {
  delay(1500);
}


void loop() {
  int stI = moduloIzq.readSensors();//sensor izquierda
  int stC = moduloCen.readSensors();//sensor centram
  int stD = moduloDer.readSensors();//sensor derecho
//condicionales
//condicion giro izquierdo en caso de T
  if (stC != 3 &amp;&amp; stI != 3 &amp;&amp; stD == 3) {
    mover(-125, 135);
    perdiendoLinea = false;
    tiempoBlanco = 0;
    ultimoError = 0;
    return;
  }
//condicion giro derecho en caso de T
  if (stC != 3 &amp;&amp; stD != 3 &amp;&amp; stI == 3) {
    mover(135, -125);
    perdiendoLinea = false;
    tiempoBlanco = 0;
    ultimoError = 0;
    return;
  }
//Recta
  if (stC == 0) {
    mover(VEL_RECTA, VEL_RECTA);
    perdiendoLinea = false;
    tiempoBlanco = 0;
    ultimoError = 0;
    return;
  }
//condicional en caso de que todo sea negro, si no se ha resuelto el arranque orc, usar sentido preferencial ORC.
  if (stC != 3 || stI != 3 || stD != 3) {
    ejecutarPID(stI, stC, stD);
    perdiendoLinea = false;
    tiempoBlanco = 0;
  } else {
    if (!perdiendoLinea &amp;&amp; !arranqueORCResuelto) {
      if (sentido_ORC == 1) mover(-135, 135);
      else mover(135, -135);
      arranqueORCResuelto = true;
      tiempoBlanco = millis();
      perdiendoLinea = true;
    }
    if (!perdiendoLinea) {
      tiempoBlanco = millis();
      perdiendoLinea = true;
    }
    unsigned long duracionBlanco = millis() - tiempoBlanco;
    if (duracionBlanco &lt; 130) { //Delay de reacciob principal
      mover(VEL_RECTA - 20, VEL_RECTA - 20); //girar
    } else if (duracionBlanco &lt; 900) { //tiempo que el robot espera para girar a otro lado
      if (ultimoError &gt; 0) mover(135, -135);
      else mover(-135, 135);
    } else if (duracionBlanco &lt; 1700) { //modo recuperacion
      if (ultimoError &gt; 0) mover(-135, 135);
      else mover(135, -135);
    } else if (duracionBlanco &lt; 2800) {
      if ((duracionBlanco / 200) % 2 == 0) mover(-100, -60);
      else mover(-60, -100);
    } else {
      mover(-90, -90);
    }
  }
}
//ejecucion del PID
void ejecutarPID(int stI, int stC, int stD) {
  int error = calcularError(stI, stC, stD);
  float correccion;
  if (abs(error) &lt;= 1) {
    correccion = error * Kp;
  } else {
    correccion = (error * Kp) + ((error - ultimoError) * Kd);
  }
  int velBaseActual = (abs(error) &lt;= 1) ? VEL_RECTA : VEL_CURVA_SUAVE;
  int vI = velBaseActual + (int)correccion;
  int vD = velBaseActual - (int)correccion;
  if (abs(error) &gt;= 9) {
    if (error &gt; 0) vD = -125;
    else vI = -125;
  }
  mover(constrain(vI, -VEL_MAX, VEL_MAX), constrain(vD, -VEL_MAX, VEL_MAX));
  if (error != 0) ultimoError = error;
}
//Paramemtros de PID en errores
int calcularError(int stI, int stC, int stD) {
  if (stC == 0) return 0;
  if (stC == 2) return -1;
  if (stC == 1) return 1;
  if (stI == 1) return -4;
  if (stI == 0) return -7;
  if (stI == 2) return -11;
  if (stD == 2) return 4;
  if (stD == 0) return 7;
  if (stD == 1) return 11;
  return ultimoError;
}
//funcion de mover motores
void mover(int izq, int der) {
  motorIzq.run(izq);
  motorDer.run(-der);
}

I would apreciatte it if any of you guys help me, thanks anyway :)

u/Dominetdude — 2 days ago
▲ 2.2k r/arduino+2 crossposts

Hey, 12 days ago I posted my 4-knob LED pattern controller here and the response was way bigger than I expected.

What changed since then:

- Designed my first PCB in KiCad (PCBway sponsored the manufacturing after seeing the original post — huge thanks)

- Swapped all 4 potentiometers for rotary encoders with push switches

- Cleaner case design to fit the new PCB and encoders

- All files on GitHub: schematics, PCB artwork (Gerber), 3D models for the case, firmware

I also built a website and just wrote the first post on it — a long build log looking back at the whole journey, in both English and Korean. Wrote it today while pausing to think about where this is heading.

GitHub: https://github.com/engmung/PatternFlow

Site + build log: https://patternflow.work/journal/v1-30-days

If it's useful to you, a star on the repo would mean a lot.

u/Aran_PCBWAY — 3 days ago

How to create a PC program

Im not quite sure how to phrase this question, but I would ultimately like to hand someone a disk and say "Here, install this onto your computer"

For example, I would like to take serial data coming out of an arduino and graph it using python on a PC. Naturally, the person would plug the arduino into a USB port but would the person also hv to install arduino/python onto their PC for it to work?

Does that mk sense?

Thanks

reddit.com
u/Frequent_Addition_23 — 2 days ago

connecting jack input arduino uno

Hello everyone,

I am currently trying to connect a jack input to an Arduino Uno. Which components do I need for this, and how should I connect everything?

My goal is to read the frequencies of an electric guitar. What do I need, and how should I wire it up? ChatGPT has not been able to help me any further. So I was wondering if any of you could help me.

Thank you!

reddit.com

Just Got My First ESP32 — Need Beginner Project Ideas 😅

Hey guys,
I recently started learning ESP32 and microcontrollers, and honestly I’m a bit overwhelmed with where to begin. I have an ESP32, a few basic components like LEDs, IR sensor, and a servo motor.

Can you suggest some fun beginner projects that helped you learn? I’d love projects that are simple but actually teach useful concepts along the way.

Any tutorials, YouTube channels, or beginner tips are also welcome. Thanks :)

reddit.com
u/rutherford_098 — 1 day ago

Open Source PCB Question

Hi I am a college student learning pcb design and I have seen a few people that designed their own Arduino boards on this reddit in the past. I was wondering if anyone knows the best resources for attempting this myself using Altium Designer? I found one open source project on Github but half of the components used on that project are obsolete or not available directly in Altium. If anyone has personal experience with doing this I'd love some input, thanks!

reddit.com
u/SimpleIronicUsername — 2 days ago