CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-arduino-firmata

Node.js implementation of the Arduino Firmata protocol for controlling Arduino boards from JavaScript applications

Overview
Eval results
Files

analog-io.mddocs/

Analog I/O and PWM

Analog input reading and PWM output control for interfacing with sensors, controlling motor speeds, LED brightness, and other analog devices.

Capabilities

Analog Output (PWM)

Generate PWM (Pulse Width Modulation) signals for controlling analog devices like LEDs, motors, and servo positions.

/**
 * Write analog value to a PWM-capable pin
 * Automatically configures pin for PWM output
 * @param pin - PWM-capable pin number (typically 3, 5, 6, 9, 10, 11 on Arduino UNO)
 * @param value - PWM value from 0 (0% duty cycle) to 255 (100% duty cycle)
 * @param callback - Optional callback function called when value is written
 */
analogWrite(pin: number, value: number, callback?: Function): void;

PWM Value Range:

  • 0 - 0% duty cycle (always LOW, equivalent to digitalWrite(pin, false))
  • 127-128 - ~50% duty cycle (half power)
  • 255 - 100% duty cycle (always HIGH, equivalent to digitalWrite(pin, true))

Usage Examples:

// Set LED to half brightness
arduino.analogWrite(9, 127);

// Fade LED in and out
let brightness = 0;
let direction = 1;

setInterval(function() {
  arduino.analogWrite(9, brightness);

  brightness += direction * 5;
  if (brightness >= 255 || brightness <= 0) {
    direction = -direction;
  }
}, 50);

// Control motor speed (0 = stopped, 255 = full speed)
arduino.analogWrite(6, 200); // ~78% speed

// With callback
arduino.analogWrite(9, 100, function() {
  console.log('PWM value set to 100');
});

Analog Input

Read analog voltage values from Arduino analog input pins for sensor data collection.

/**
 * Read current analog value from an analog input pin
 * @param pin - Analog pin number (0-5 on Arduino UNO, corresponds to A0-A5)
 * @returns Current analog reading as integer from 0 to 1023
 */
analogRead(pin: number): number;

Value Range:

  • 0 - 0V input voltage
  • 512 - ~2.5V input voltage (half of 5V reference)
  • 1023 - 5V input voltage (or reference voltage)

Usage Examples:

// Read potentiometer on analog pin 0
const potValue = arduino.analogRead(0);
console.log(`Potentiometer reading: ${potValue} (${(potValue/1023*100).toFixed(1)}%)`);

// Read multiple analog sensors
for (let pin = 0; pin < 6; pin++) {
  const reading = arduino.analogRead(pin);
  const voltage = (reading / 1023) * 5.0; // Convert to voltage
  console.log(`A${pin}: ${reading} (${voltage.toFixed(2)}V)`);
}

// Convert reading to percentage
const lightLevel = arduino.analogRead(1);
const lightPercentage = Math.round((lightLevel / 1023) * 100);
console.log(`Light sensor: ${lightPercentage}%`);

Real-time Analog Change Monitoring

Monitor analog pin value changes in real-time using events.

// Event: analogChange
// Fired when an analog pin value changes
// Event object properties:
interface AnalogChangeEvent {
  pin: number;     // Analog pin number that changed (0-5)
  value: number;   // New analog reading (0-1023)
  old_value: number; // Previous analog reading
}

Usage Example:

arduino.on('analogChange', function(event) {
  console.log(`Analog pin A${event.pin} changed from ${event.old_value} to ${event.value}`);

  // Example: Light sensor trigger
  if (event.pin === 1 && event.value > 800 && event.old_value <= 800) {
    console.log('Bright light detected!');
    arduino.analogWrite(9, 255); // Turn on LED at full brightness
  }

  // Example: Potentiometer controlling LED brightness
  if (event.pin === 0) {
    const brightness = Math.round((event.value / 1023) * 255);
    arduino.analogWrite(9, brightness);
    console.log(`LED brightness set to ${brightness}/255`);
  }
});

Complete Analog I/O Example

const ArduinoFirmata = require('arduino-firmata');
const arduino = new ArduinoFirmata();

arduino.connect();

arduino.on('connect', function() {
  console.log('Arduino connected - Analog I/O ready');

  // Read analog sensors periodically
  setInterval(function() {
    const pot = arduino.analogRead(0);      // Potentiometer
    const light = arduino.analogRead(1);    // Light sensor
    const temp = arduino.analogRead(2);     // Temperature sensor

    console.log(`Sensors - Pot: ${pot}, Light: ${light}, Temp: ${temp}`);

    // Use potentiometer to control LED brightness
    const brightness = Math.round((pot / 1023) * 255);
    arduino.analogWrite(9, brightness);

  }, 1000);

  // Real-time analog monitoring for immediate responses
  arduino.on('analogChange', function(event) {
    // Quick response to light sensor changes
    if (event.pin === 1) {
      if (event.value < 300) { // Dark environment
        arduino.analogWrite(10, 200); // Turn on status LED
      } else { // Bright environment
        arduino.analogWrite(10, 50);  // Dim status LED
      }
    }
  });
});

PWM Frequency and Resolution

Arduino PWM operates at approximately 490 Hz (pins 5 and 6) or 980 Hz (other pins) with 8-bit resolution:

  • Resolution: 8-bit (256 discrete levels: 0-255)
  • Frequency: ~490 Hz or ~980 Hz depending on pin
  • Pins: PWM-capable pins vary by Arduino model (typically 3, 5, 6, 9, 10, 11 on UNO)

Analog Reference Voltage

Arduino analog readings are relative to the reference voltage:

  • Default: 5V on 5V Arduino boards, 3.3V on 3.3V boards
  • Resolution: 10-bit ADC provides 1024 discrete levels (0-1023)
  • Precision: ~4.9mV per step on 5V boards (5V / 1024)

Constants

// Pin modes for analog operations
ArduinoFirmata.ANALOG = 2;  // Analog input mode
ArduinoFirmata.PWM = 3;     // PWM output mode

Pin Mapping

PWM Output Pins (Arduino UNO)

  • Pin 3: PWM output (~980 Hz)
  • Pin 5: PWM output (~490 Hz)
  • Pin 6: PWM output (~490 Hz)
  • Pin 9: PWM output (~980 Hz)
  • Pin 10: PWM output (~980 Hz)
  • Pin 11: PWM output (~980 Hz)

Analog Input Pins (Arduino UNO)

  • A0 (pin 14): Analog input pin 0
  • A1 (pin 15): Analog input pin 1
  • A2 (pin 16): Analog input pin 2
  • A3 (pin 17): Analog input pin 3
  • A4 (pin 18): Analog input pin 4
  • A5 (pin 19): Analog input pin 5

Note: Analog pins can also be used as digital pins by referencing their digital pin numbers (14-19).

Common Applications

Sensor Reading

// Temperature sensor (LM35) - converts reading to Celsius
const tempReading = arduino.analogRead(0);
const voltage = (tempReading * 5.0) / 1024;
const temperature = voltage * 100; // LM35 outputs 10mV per degree C
console.log(`Temperature: ${temperature.toFixed(1)}°C`);

Motor Speed Control

// Control DC motor speed with potentiometer
const speedControl = arduino.analogRead(0);
const motorSpeed = Math.round((speedControl / 1023) * 255);
arduino.analogWrite(9, motorSpeed); // Motor connected to pin 9

LED Dimming

// Smooth LED fade effect
let brightness = 0;
let fadeDirection = 1;

setInterval(function() {
  arduino.analogWrite(9, brightness);
  brightness += fadeDirection * 2;

  if (brightness >= 255) {
    fadeDirection = -1;
  } else if (brightness <= 0) {
    fadeDirection = 1;
  }
}, 10);

Event System Integration

Analog I/O operations integrate with the event system for real-time monitoring. See Event System for complete event documentation including analog change events.

Install with Tessl CLI

npx tessl i tessl/npm-arduino-firmata

docs

analog-io.md

connection.md

digital-io.md

events.md

index.md

servo.md

sysex.md

tile.json