laser_sims — Esp32 Devkit C V4 simulation

An interactive Esp32 Devkit C V4 circuit simulation you can run free in your browser on Velxio, by precioustruth2003.

Components

Sketch code

const byte DATA_PIN = 2;

const unsigned long BIT_TIME_US = 104;
const unsigned long HALF_BIT_US = 52;

volatile bool startDetected = false;
volatile bool receiving = false;

void IRAM_ATTR startBitDetected()
{
    if (!receiving)
    {
        startDetected = true;
    }
}

void setup()
{
    pinMode(DATA_PIN, INPUT);

    Serial.begin(115200);

    attachInterrupt(
        digitalPinToInterrupt(DATA_PIN),
        startBitDetected,
        FALLING
    );

    Serial.println("Optical UART receiver started.");
}

void receiveByte()
{
    // Move to middle of start bit
    delayMicroseconds(HALF_BIT_US);

    // Confirm start bit
    if (digitalRead(DATA_PIN) != LOW)
    {
        return;
    }

    byte receivedByte = 0;

    // Move to middle of D0
    delayMicroseconds(BIT_TIME_US);

    for (int i = 0; i < 8; i++)
    {
        int bit = digitalRead(DATA_PIN);

        if (bit == HIGH)
        {
            receivedByte |= (1 << i);
        }

        delayMicroseconds(BIT_TIME_US);
    }

    // Stop bit
    int stopBit = digitalRead(DATA_PIN);

    if (stopBit != HIGH)
    {
        Serial.println("UART framing error");
        return;
    }

    Serial.print("HEX: 0x");

    if (receivedByte < 0x10)
        Serial.print("0");

    Serial.println(receivedByte, HEX);

    Serial.print("ASCII: ");

    if (receivedByte >= 32 && receivedByte <= 126)
    {
        Serial.println((char)receivedByte);
    }
    else
    {
        Serial.println("[non-printable]");
    }
}

void loop()
{
    if (startDetected && !receiving)
    {
        noInterrupts();

        startDetected = false;
        receiving = true;

        interrupts();

        receiveByte();

        noInterrupts();

        receiving = false;

        interrupts();
    }
}