Arduino UNO R3

The UNO R3 is the classic 5 V UNO board based on the 8-bit Microchip ATmega328P. Juno compiles for it with its AVR backend and links against the arduino:avr core; the ArduinoUno device facade is the entry point for the board's peripherals. With 2 KB of SRAM it is Juno's smallest target: the arena is 1 KB, and programs should allocate once at startup and stay small.

Arduino UNO R3

Core specification

Characteristic UNO R3
Main microcontroller Microchip ATmega328P
CPU architecture 8-bit AVR
CPU clock 16 MHz
Program flash 32 kB; 0.5 kB is used by the bootloader
SRAM 2 kB
EEPROM 1 kB
Logic and operating voltage 5 V
Digital I/O 14 pins, D0-D13 (6 with PWM: D3, D5, D6, D9, D10, D11)
Analog inputs 6 pins, A0-A5, 10-bit ADC
USB connector USB Type-B, through an ATmega16U2 USB-to-serial converter
Built-in LED D13
Wireless connectivity None (Wi-Fi through the Arduino WiFi Shield)
Arduino CLI FQBN arduino:avr:uno
Juno board id arduino-uno-r3

What Juno supports

Feature Status Notes Example
Gpio, DigitalOutput, Delay, Clock ✓ Standard Arduino GPIO and timing calls. Blink
analogRead, analogWrite ✓ Analog reads on A0–A5 through the 10-bit ADC; PWM output on D3, D5, D6, D9, D10 and D11.
Serial ✓ Through the ATmega16U2 USB-to-serial path.
Classes, interfaces and inheritance ✓ Larger object graphs may exceed the 1 KB arena or the flash. Inheritance, Interfaces
BigInteger, BigDecimal, MathContext ✓ Bounded by the 1 KB arena and 2 KB of SRAM.
@Watchdog ✓ ATmega328P hardware watchdog, at most 8 seconds.
Non-cryptographic UUIDs (PortNoise) ✓ The R3 has no hardware entropy, so UUID.randomUUID() is rejected; PortNoise gives best-effort node identities, never secrets. WeakUuid
Wifi, Udp, Tcp, plain-HTTP HttpClient ✓ Through the Arduino WiFi Shield; no access point or HTTPS. SocketDatagramEcho, PlainHttpWeather
SdCard ✓ On the Data Logger Shield's microSD slot. StorageOccupancy
Grove Base Shield ✓ Passive: every socket is an UNO pin.
9 Axis Motion Shield ✓ BNO055 over I2C; its reset line D7 is also the WiFi Shield's handshake. NineAxisMotionShieldSerial
LCD Keypad Shield ✓ Cannot be stacked with the WiFi Shield. LcdKeypadDemo

Features

These need only the UNO R3 and its USB cable.

DigitalOutput led = DigitalOutput.of(ArduinoUno.getGpio().getBuiltinLed());

while (true) {
    led.high();
    Delay.millis(500);
    led.low();
    Delay.millis(500);
}

Blink is the complete program; it builds for any board, so pass -Djuno.board=arduino-uno-r3.

Shields

Seat each shield directly on the UNO R3. Check which pins a shield uses before stacking two: the WiFi Shield reserves D4, D7 and D10, which the LCD Keypad Shield also uses, so the compiler rejects a program that combines them, and the 9 Axis Motion Shield's sensor reset is also D7.

Arduino WiFi Shield

Arduino WiFi Shield

The R3 has no radio, so ArduinoUno.getWifi() does not compile for it: take the Wifi from the retired Arduino WiFi Shield instead. The shield runs Arduino's legacy WiFi library over SPI; it joins networks only (no access point) and speaks plain HTTP, not HTTPS. The credentials are read at build time from the JUNO_WIFI_SSID and JUNO_WIFI_PASSWORD environment variables (or a .env file through juno:env):

Wifi wifi = new ArduinoWifiShield().getWifi();
wifi.begin(System.getenv("JUNO_WIFI_SSID"), System.getenv("JUNO_WIFI_PASSWORD"));

while (wifi.status() != Wifi.STATUS_CONNECTED) {
    Delay.millis(1000);
}

Only small network programs fit next to the library: build them with -Djuno.Xmx=512, as SocketDatagramEcho, SocketEcho, SntpTime and PlainHttpWeather do.

Grove Base Shield

Grove Base Shield

The Grove Base Shield is passive: every socket is an ordinary UNO pin, and GroveBaseShield names them so programs don't hard-code numbers. Plug a Grove module in and pass the socket's getter to its driver; the socket supplies the module's GND and VCC. A Grove DHT22 temperature and humidity sensor in the D4 socket:

GroveBaseShield shield = new GroveBaseShield();
GroveDht22 dht = new GroveDht22();
int[] reading = new int[GroveDht22.READING_LENGTH];
int[] frame = new int[GroveDht22.FRAME_LENGTH];

if (dht.read(shield.getD4(), reading, reading.length, frame, frame.length)) {
    Serial.print(reading[GroveDht22.TEMPERATURE_TENTHS_CELSIUS]);
    Serial.println(" tenths of a degree");
}

GroveDht22Monitor prints a DHT22's readings; it is written for the UNO WiFi Rev2, and the snippet above is the same read for the R3. See Grove for the sensor drivers. The WiFi Shield also uses D4, so plug sensors into other sockets when the two are stacked.

Arduino 9 Axis Motion Shield

Arduino 9 Axis Motion Shield

The shield's Bosch BNO055 fuses its accelerometer and gyroscope itself and reports the heading in degrees. NineAxisMotionShield reads it over I2C (A4/A5) as plain Java, with no Arduino library. The heading is relative to the direction the sensor pointed at begin(). begin() drives D7, the sensor's reset line, so don't use D7 for anything else; the WiFi Shield's handshake line is also D7, so the two cannot be stacked:

NineAxisMotionShield imu = new NineAxisMotionShield();
if (imu.begin()) {
    int start = imu.headingDegrees();
    while (true) {
        Serial.println(imu.turnedSince(start));   // degrees turned, clockwise positive
        Delay.millis(200);
    }
}

NineAxisMotionShieldSerial prints heading, pitch, gyro and calibration readings.

LCD Keypad Shield

LCD Keypad Shield

A 16 × 2 character LCD with five buttons read through one analog pin (A0). LcdKeypadShield needs no extra library: the LCD uses D4-D9 and its backlight D10.

LcdKeypadShield lcd = new LcdKeypadShield();
lcd.begin();
lcd.print("Hello, Juno");

while (true) {
    if (lcd.readButton() == LcdKeypadShield.SELECT) {
        lcd.setCursor(0, 1);
        lcd.print("SELECT pressed");
    }
    Delay.millis(100);
}

LcdKeypadDemo shows each button press.

AZDelivery Data Logger Shield

AZDelivery Data Logger Shield

A microSD socket on the UNO's SPI pins (chip select D10, MOSI D11, MISO D12, SCK D13), plus a DS1307 real-time clock that Juno does not drive. Format the card as FAT16 or FAT32.

SdCard sd = new DataLoggerShield().getSdCard();
if (sd.begin()) {
    Serial.print("used KiB: ");
    Serial.println(sd.totalKiB() - sd.freeKiB());
}

StorageOccupancy reports the card's used and total space.

Build and run

Install the AVR core once, and the legacy WiFi library for programs that use the WiFi Shield. Then compile and upload an example, for instance the UUID demo, which prints over serial:

arduino-cli core install arduino:avr
arduino-cli lib install WiFi
./mvnw -f juno-examples/pom.xml compile juno:upload \
  -Djuno.main=io.github.jabrena.juno.language.WeakUuid \
  -Djuno.board=arduino-uno-r3

Open the serial monitor in another terminal:

./mvnw -f juno-examples/pom.xml juno:monitor \
  -Djuno.board=arduino-uno-r3

The monitor uses 115200 baud by default, matching Serial.begin(BaudRate.BAUD_115200).