ATmega328P - SteveJustin1963/Telescope-Tec1 GitHub Wiki

Example DIY Astronomy / Space Projects

  • Arduino Projects: Telescope Control with GOTO – Curdridge Observatory
  • my homemade astronomical clock! (xpost from r/arduino) – Reddit (r/Astronomy)
  • Portable Starmap by Shabaz: An Arduino-Powered Star Chart for ... – Circuit Digest
  • DIY Simple STM32 Virtual Electronic Finderscope (Stellarium ...) – PCBWay
  • Motor Controlled Telescope - How To Build – YouTube
  • rDUINOScope - Arduino Telescope Control – Electronics-Lab
  • Equatorial Telescope Mount Motorisation with ARDUNO and Stepper ... – Arduino Forum
  • Telescope Controller | Details – Hackaday.io
  • Realtime Planet Tracking System and Trajectory Prediction ... – Arduino Project Hub
  • 10 Arduino ideas (arduino, arduino projects, amateur astronomy) – Pinterest (in.pinterest.com)
  • Explore The Cosmos With This DIY Digital Telescope – Hackaday
  • Hi, I have designed DIY fully 3D printed star tracker for ... – Reddit
  • GoTo Telescope Mount – Matthew Leung
  • Arduino Projects: How to write a GOTO telescope mount controller – Curdridge Observatory
  • Control Your Telescope Using Stellarium & Arduino : 12 Steps (with ...) – Instructables
  • Arduino Star-Finder for Telescopes : 11 Steps (with Pictures ...) – Instructables
  • DIY: Telescope Maintenance, Home Observatories, & More – Sky & Telescope
  • Star Track - Arduino Powered Star Pointer and Tracker – Pinterest
  • DIY Space Globe Assembly Kit for Kids and Adults with Educational ... – BonziCart
  • Open Source Telescope Controller Puts Smart Features In Old ... – Hackaday
  • Project update: Telescope Automated Focuser – Reddit (r/arduino)
  • Stellarium Arduino Telescope Control Astronomy Stellarium ... – Bonnici Carpentry
  • Equatorial Telescope Mount Motorisation with ARDUNO and Stepper ... – Arduino Forum
  • DIY ISS Tracking Lamp – Electronics-Lab
  • DIY Telescope Power Distribution – Dave Allmon
  • DIY star tracker built using Arduino Uno – Geeky Gadgets
  • Maverick Is a DIY Rocket Flight Computer That Enables SpaceX-Style ... – Hackster.io
  • Arduino Telescope Control Harmonic Drive Mount Motorized Telescope ... – ecoparkcampogrande.com.br
  • Hacking a Motorised Telescope with Arduino – YouTube

Astronomy-Related Projects You Can Build

Telescope Automation and Control

  • Go-To Mounts
    The most common use is building a "Go-To" system for a manual telescope. By adding stepper motors and using the ATmega328P to drive them, you can automate the process of slewing (moving) the telescope to specific celestial coordinates.
    The microcontroller receives position data (often from a GPS module or a connected computer running software like Stellarium) and calculates the necessary motor movements.

  • Automated Focusers (Autofocusers)
    The ATmega328P precisely controls a small motor attached to the focuser, moving it in small, repeatable steps. This allows extremely fine focus adjustments and full integration with imaging software for automatic focusing routines (see detailed section below).

  • Star Trackers / Barn Door Mounts
    For long-exposure astrophotography, the camera needs to precisely counter the Earth's rotation.
    The ATmega328P can control a motor that slowly moves a platform (a "barn door" mount) at the sidereal rate, keeping stars as sharp points instead of streaks.


Data Acquisition and Environmental Management

  • Astrophotography Intervalometer
    You can program the microcontroller to act as a custom camera remote, taking a precise sequence of long exposures and controlling the timing, which is essential for stacking images later in post-processing.

  • Dew Heater Controller
    Telescopes and cameras often fog up due to condensation (dew).
    A project can use the chip, temperature/humidity sensors, and PWM outputs to proportionally control heating elements, keeping optics clear and conserving battery power.

  • Observatory Automation
    You can create a system to:

    • Monitor weather conditions (cloud sensors, rain sensors).
    • Control the observatory roof.
    • Alert the user if conditions become unsafe for equipment.

Display and Educational Projects

  • Star Finder Handset
    Using a digital compass and tilt sensors, a handheld device can calculate where a user is pointing in the sky and display information about constellations or planets on a small screen.

  • Astronomical Clock
    Build a clock that displays:

    • The current moon phase
    • Planetary positions
    • Local sidereal time
      using an LED ring or LCD screen.
  • Tiny Radio Telescope
    While more advanced, some amateur projects involve using microcontrollers to help process signals from simple radio antennas to observe radio sources like the Sun or Jupiter.


Automated Focuser (Autofocuser)

An autofocuser uses a small motor, controlled by the ATmega328P, to move your telescope’s focuser in tiny, repeatable steps. Instead of touching the focuser knob by hand (and shaking the image), the microcontroller drives the motor while a focusing routine or your own judgement decides which position gives the sharpest stars.

In practice, the controller:

  1. Drives a stepper motor attached to the focuser knob or drawtube.
  2. Moves in calibrated steps (e.g. X steps per millimetre of travel).
  3. Samples focus quality (manually by you, or automatically via a camera and software).
  4. Homes / references the focuser so it always knows where “zero” is.
  5. Optionally compensates for temperature so focus stays sharp as the night cools.

How It Works (Conceptual Flow)

  1. Startup / Homing

    • On power-up, the focuser moves inward or outward until it hits a limit switch (or a known mechanical stop).
    • This is set as position = 0 (home position).
    • From there, all moves are tracked in steps: current_position_steps.
  2. Commanding a Move

    • A command comes from:
      • A hand controller (buttons: IN, OUT, FAST, SLOW).
      • A PC over USB/serial (e.g. from N.I.N.A, Ekos/INDI, ASCOM client).
      • A simple menu on an LCD (preset positions, step sizes).
    • The ATmega328P converts that command into a number of steps and direction.
    • It tells the stepper driver (e.g. A4988) to step the motor with a controlled speed and acceleration (to avoid missed steps).
  3. Focusing Logic

    • Manual mode:
      You watch the live view (camera or eyepiece), press IN/OUT, and stop when stars look sharp.
    • Automatic mode:
      Imaging software runs a focus routine:
      • Move focuser in/out to several positions.
      • Measure star size / sharpness (HFR/FWHM, etc.) at each position.
      • Fit a curve and pick the best focus (minimum star size).
      • Send the final position back to the focuser, which then moves there.
  4. Temperature Compensation (Optional)

    • A temperature sensor (e.g. DS18B20) measures the scope temperature.
    • The firmware applies a focus offset per °C (pre-measured), nudging the focuser to keep stars sharp as the tube shrinks/expands.

How the Process Works with the ATmega328P (Closed-Loop Autofocus)

When you integrate the focuser with a camera and focusing software, the ATmega328P manages the mechanical movement as part of a closed-loop system:

  1. Move and Capture
    The computer software instructs the ATmega328P to move the stepper motor linked to the focuser a specific number of steps.
    A test image is captured at that position.

  2. Analyze
    The software analyzes the image and calculates its sharpness metric (e.g. an HFD/HFD-like value or similar focus metric).

  3. Repeat and Plot
    Steps 1 and 2 are repeated several times, moving the focuser through a range of positions and recording the sharpness at each one.

  4. Calculate Best Focus
    The software uses a search algorithm (like a binary search, “hill-climbing” method, or V-curve fitting) to:

    • Plot sharpness vs. focuser position.
    • Mathematically determine the exact motor position corresponding to peak sharpness.
  5. Move to Position
    The software sends a final command to the ATmega328P, which moves the focuser motor to that precise, optimal position.

By handling the precise control of the stepper motor and reporting its position, the ATmega328P enables the external software to achieve highly accurate, automated focus without manual intervention.
Some advanced systems can even use a temperature sensor connected to the ATmega328P to automatically compensate for focus shifts caused by changing ambient temperatures during the night.


What Hardware You Need

Mechanical

  • A telescope with a rack-and-pinion or Crayford focuser.
  • Stepper motor, typically:
    • NEMA 17, 200 steps/rev (or finer).
    • Enough torque to turn the focuser smoothly but not so strong it can damage it.
  • Flexible coupler or belt/gear to connect motor shaft to focuser shaft.
  • Mounting bracket:
    • 3D-printed or metal bracket that bolts to the focuser body.
    • Keeps motor aligned and rigid so there’s no slop.

Electronics

  • ATmega328P board (e.g. Arduino Uno/Nano) as the controller.
  • Stepper driver module (e.g. A4988, DRV8825, or TMC2209):
    • Connected to the ATmega328P via STEP and DIR pins.
    • Powered from a separate 12 V line (common in astro rigs).
  • Power supply:
    • 12 V DC for motors and heaters (if shared with dew heaters/power box).
    • On-board 5 V regulator for logic (or USB power).
  • Limit switch(es):
    • Micro-switch at one end of travel (or both) for homing and safety.
  • User interface (any combination of):
    • 2–4 push buttons (IN, OUT, FAST, SLOW).
    • Small OLED/LCD for position, mode, temperature.
    • Rotary encoder for fine step control.
  • Temperature sensor (optional but useful):
    • DS18B20 or NTC thermistor attached to the telescope tube or focuser.

Wiring Overview (High-Level)

  • ATmega328P digital pins → STEP, DIR, ENABLE on the stepper driver.
  • Stepper driver motor outputs → 4 wires to stepper motor coils.
  • Stepper driver VMOT & GND → 12 V supply.
  • ATmega328P 5 V & GND → logic power and common ground with VMOT.
  • Limit switch → digital input with pull-up (normally closed to ground).
  • Buttons → digital inputs with pull-ups.
  • Temperature sensor → digital or analog input (depending on sensor type).
  • Optional USB-serial → PC for control (ASCOM/INDI style protocol).

Firmware / Software Features

A typical autofocuser sketch for the ATmega328P will include:

  • Step calibration
    steps_per_mm or steps_per_focus_unit for your focuser.

  • Backlash compensation
    Always approach final focus from the same direction or add an automatic overshoot + return.

  • Speed and acceleration profiles
    Fast for big moves, slow for precise fine focus.

  • Position storage
    Save last position in EEPROM so you don’t lose focus reference on reboot.

  • PC control protocol
    Simple text commands over serial: GOTO, MOVE, HOME, GETPOS, etc.,
    or full compatibility with common focusing standards (ASCOM/INDI-style behaviour).


These projects transform the theoretical knowledge of astronomy into hands-on engineering challenges, with the ATmega328P acting as the precise, repeatable control layer that turns ideas into working hardware.

///

Yeah, fair point – I only hinted at the image processing, I didn’t spell out how the system actually decides “this frame is in focus”.

Here’s the missing piece, wired directly into the autofocuser section. You can drop this straight into your .md. I’ll only show the autofocuser part with the new image processing subsection, so you don’t have to scroll through the whole document again.

## Automated Focuser (Autofocuser)

An **autofocuser** uses a small motor, controlled by the ATmega328P, to move your telescope’s focuser in tiny, repeatable steps. Instead of touching the focuser knob by hand (and shaking the image), the microcontroller drives the motor while a focusing routine or your own judgement decides which position gives the sharpest stars.

In practice, the controller:

1. **Drives a stepper motor** attached to the focuser knob or drawtube.
2. **Moves in calibrated steps** (e.g. X steps per millimetre of travel).
3. **Samples focus quality** using **image processing** (camera + software) or your own eyes.
4. **Homes / references** the focuser so it always knows where “zero” is.
5. Optionally **compensates for temperature** so focus stays sharp as the night cools.

---

### Image Processing: How the System Knows It’s in Focus

The ATmega328P does the **precise motion**; the **focus decision** comes from image processing on the captured frames (usually on a PC, NUC, or Pi running your imaging suite).

For each trial focus position:

1. **Capture a Frame**
   - The camera takes an exposure (full frame or a cropped subframe around a star).
   - The image is sent to the focusing software.

2. **Pre-Processing**
   - Convert to **grayscale** if needed (most astro data already is).
   - **Subtract background** / estimate sky level so the algorithm sees stars, not sky glow.
   - Optionally **crop** around the brightest star or a group of stars to reduce processing time.

3. **Star Detection**
   - Find one or more stars:
     - Threshold above background.
     - Label connected bright pixels as “star blobs”.
   - Reject junk (hot pixels, cosmic rays) by size/shape filters.

4. **Focus Metric Calculation**
   Typical sharpness metrics include:

   - **FWHM (Full Width at Half Maximum)**  
     - Fit a 2D profile (often approximated as a Gaussian) to the star.
     - Measure how wide the star is at half its peak brightness.
     - **Smaller FWHM = sharper focus**.

   - **HFD / HFR (Half-Flux Diameter / Radius)**  
     - Sum the total flux from the star.
     - Find the radius where **half** the total flux is enclosed.
     - **Smaller HFD/HFR = sharper focus** and more robust to noise than a simple FWHM fit.

   - **Contrast / Edge Sharpness Metrics (alternate)**  
     - Compute gradients or Laplacian (how fast brightness changes).
     - More high-frequency content (sharper edges) → better focus.

   The software produces a **single number** for that frame:  
   `focus_metric(position) = some_value`  
   where “some_value” is FWHM, HFD, or similar. Lower is usually better.

5. **Record the Sample**
   - Store `(motor_steps, focus_metric)` for this position.
   - Repeat for multiple positions to build a curve.

The end result is a dataset like:

| Steps from start | Focus metric (HFD / FWHM) |
|------------------|---------------------------|
|  -800            | 5.2                       |
|  -400            | 3.7                       |
|     0            | 2.9 ← best                |
|  +400            | 3.6                       |
|  +800            | 5.0                       |

Plotted, this forms the classic **V-curve** or U-shaped curve: the bottom of the V is best focus.

---

### How the Process Works with the ATmega328P (Closed-Loop Autofocus)

When you integrate the focuser with a camera and focusing software, the ATmega328P manages the mechanical movement as part of a **closed-loop** system:

1. **Move and Capture**  
   The computer software instructs the ATmega328P to move the stepper motor linked to the focuser a specific number of steps.  
   A test image is captured at that position.

2. **Analyze (Image Processing)**  
   The software analyzes the image:
   - Detects star(s).
   - Computes a focus metric (HFD, FWHM, or another sharpness measure).
   - Outputs a single sharpness value for that focus position.

3. **Repeat and Plot**  
   Steps 1 and 2 are repeated several times, moving the focuser through a range of positions and recording the sharpness at each one.  
   This builds a **focus curve** (often a V-curve).

4. **Calculate Best Focus**  
   The software uses a search algorithm (binary search, hill-climbing, V-curve fitting, etc.) to:
   - Fit or approximate the curve.
   - Find the **minimum** of the focus metric (sharpest point).
   - Determine the exact motor position corresponding to peak sharpness.

5. **Move to Position**  
   The software sends a final command to the ATmega328P, which moves the focuser motor to that precise, optimal position.

By handling the precise control of the stepper motor and reporting its position, the **ATmega328P enables the external software to achieve highly accurate, automated focus** without manual intervention.  
Some advanced systems can even use a **temperature sensor connected to the ATmega328P** to automatically compensate for focus shifts caused by changing ambient temperatures during the night.

---

### What Hardware You Need (Recap)

**Mechanical**

- Telescope with a **rack-and-pinion** or **Crayford focuser**.
- **Stepper motor** (e.g. NEMA 17).
- **Flexible coupler** or belt/gear drive.
- **Rigid mounting bracket** (3D-printed or metal).

**Electronics**

- **ATmega328P board** (Arduino Uno/Nano).
- **Stepper driver** (A4988, DRV8825, TMC-series).
- **12 V power** for motors (and heaters if shared).
- **Limit switch(es)** for homing and safety.
- **Buttons / encoder + optional LCD/OLED** for manual control.
- **Temperature sensor** (DS18B20 / thermistor) for temp-comp.

**Firmware / Software**

- Step calibration, backlash compensation, speed/accel profiles.
- EEPROM storage for last position.
- Simple serial protocol (`MOVE`, `HOME`, `GOTO`, `GETPOS`) for integration with autofocus software.

That’s the bit you were yelling for: the image processing → focus metric → V-curve → best focus pipeline is now explicit and front-and-centre.

///

Good question, and this is the key architectural line in the sand:

Short answer

We do not run the image processing on the ATmega328P. We run it on a “real” computer (laptop/mini-PC/Raspberry Pi) that:

  • talks to the camera
  • talks to the ATmega328P focuser
  • does all the star detection + HFD/FWHM math

The ATmega’s job is only:

“Move the motor N steps, report where you are.”


Typical Setup (what we’re actually building)

Think of three pieces:

  1. Camera side

    • DSLR / astro-cam → connected over USB to:

      • Laptop, or
      • Mini-PC at mount, or
      • Raspberry Pi (Astroberry, Stellarmate, generic Linux).
  2. Focuser side

    • ATmega328P (Arduino) + stepper driver → connected to the same computer via USB serial (or UART/USB).
  3. Control / Image-Processing side (this is where the magic lives)

    • A program on that computer which:

      1. Tells the ATmega: MOVE to position X
      2. Triggers a camera exposure.
      3. Reads the image into RAM.
      4. Runs the focus metric algorithm (HFD/FWHM/etc).
      5. Decides where best focus is.
      6. Sends final command to ATmega: MOVE to position X_best.

So the image processing runs on:

  • A PC or laptop (Windows / Linux / macOS) running:

    • N.I.N.A / SGP / KStars+Ekos / custom Python/C++ code, etc. or
  • A Raspberry Pi / mini-PC at the mount running:

    • INDI/KStars, custom Python scripts, etc.

Why not on the ATmega328P?

Because:

  • 2 KB RAM, 32 KB flash – that’s tiny.
  • Images are megabytes; star detection and curve fitting are floating-point heavy.
  • You could hack in a toy “sharpness” measure on tiny downsampled chunks, but it’s massively easier and more powerful to just let a Pi/laptop do it.

So the division of labour is:

  • ATmega328P → “dumb but precise motor controller with position tracking + temp sensor.”
  • Host (PC/Pi) → “smart brain that sees the images, runs the algorithms, and tells the motor what to do.”

Mental Model / Data Flow

Camera  ──USB──►  PC / Pi  ◄──USB/Serial──  ATmega328P Focuser
                (image processing,          (stepper control,
                 autofocus logic)            position reporting)

If you like, next step I can sketch an actual serial command set (MOVE, HOME, GETPOS, etc.) and a tiny example of Python autofocus logic that talks to the Arduino and runs a dummy focus metric on test images.

///

Got you — this is the “host brain” side of the autofocus loop, so let’s spell out what each imaging/autofocus program is, what you need, how to set it up, and exactly how it talks to the ATmega focuser.

You can drop this into your .md under something like:

## Host Imaging & Autofocus Software

Host Imaging & Autofocus Software

The ATmega328P focuser is not doing image analysis. A PC / mini-PC / Pi runs one of these programs, which:

  • Controls the camera
  • Talks to the ATmega328P focuser
  • Runs the image processing + focus algorithm

Below are common options and how they plug into the focus loop.


1. N.I.N.A (Nighttime Imaging ‘N’ Astronomy) – Windows

What it is

N.I.N.A is a free Windows application for deep-sky imaging automation. It can:

  • Control your camera, mount, filter wheel, and focuser
  • Run autofocus routines using HFR-based metrics
  • Automate full imaging sequences (meridian flips, plate solving, etc.)

What You Need

  • Windows PC or laptop

  • ASCOM Platform installed

  • ASCOM camera driver (for DSLR/astrocam)

  • ASCOM focuser driver for your ATmega328P-based focuser

    • Often you emulate a known protocol (e.g. Moonlite / MyFocuserPro / DIY ASCOM driver)
  • USB connections:

    • Camera → PC
    • Arduino/ATmega focuser → PC (shows up as COM port via USB-serial)

Setup (High-Level)

  1. Install bits

    • Install ASCOM Platform.
    • Install N.I.N.A.
    • Install ASCOM drivers for camera and focuser.
  2. Connect hardware

    • Plug in camera and focuser via USB.
    • Confirm COM port for focuser (Device Manager).
  3. Configure in N.I.N.A

    • Open Options → Equipment.

    • Select:

      • Camera = your camera’s ASCOM driver
      • Focuser = your Arduino focuser’s ASCOM driver
    • Save as an equipment profile.

  4. Calibrate focuser in N.I.N.A

    • Set:

      • Step size (how many steps per move during autofocus)
      • Backlash compensation
      • Min/max focuser travel
    • Run a test autofocus to dial in step size.

How It Ties Into the Focus Loop

In N.I.N.A, the autofocus loop works like this:

  1. N.I.N.A tells focuser (ATmega): move to position X (via ASCOM → serial).

  2. N.I.N.A triggers camera: take an exposure.

  3. N.I.N.A:

    • Reads the FITS frame.
    • Detects stars.
    • Computes HFR (Half Flux Radius) for each trial position.
  4. It builds a focus curve (usually a V-curve or U-curve).

  5. It computes the best-focus position.

  6. It sends a final GOTO to the focuser (ATmega) to that exact step position.

The ATmega just sees “MOVE to 12345 steps” commands. N.I.N.A does all the image processing and decision-making.


2. Sequence Generator Pro (SGP) – Windows

What it is

SGP is a paid Windows imaging suite similar to N.I.N.A but older in the ecosystem. It also:

  • Controls camera, mount, filter wheel, focuser via ASCOM
  • Has built-in autofocus routines

What You Need

  • Windows PC

  • ASCOM Platform

  • ASCOM drivers for:

    • Camera
    • Focuser (again, your ATmega-based focuser presents as an ASCOM device)
  • USB connectivity to camera and focuser

Setup (High-Level)

  1. Install SGP + ASCOM + drivers.

  2. Configure Equipment Profile:

    • Choose camera ASCOM driver.
    • Choose focuser ASCOM driver.
  3. Autofocus Settings:

    • Set step size, number of data points, exposure length, binning, etc.
    • Define focus direction and backlash compensation.

How It Ties Into the Focus Loop

Loop is conceptually the same as N.I.N.A:

  1. SGP → Focuser (ATmega): move to position X.

  2. SGP → Camera: capture image.

  3. SGP:

    • Measures star size (HFR/FWHM).
    • Plots focus curve.
  4. SGP → Focuser: move to calculated best-focus position.

Again, ATmega = motor + position, SGP = brain + image processing.


3. KStars + Ekos (INDI) – Linux / Raspberry Pi / macOS / Windows

What it is

KStars is a planetarium program; Ekos is its astrophotography suite. Together, they are often used on:

  • Linux laptops/desktops
  • Raspberry Pi (Astroberry, Stellarmate, etc.)
  • They rely on INDI drivers instead of ASCOM.

What You Need

  • Linux / Pi / macOS / Windows machine running KStars+Ekos

  • INDI server installed

  • INDI drivers for:

    • Camera (e.g. ZWO, QHY, DSLR, etc.)
    • Focuser (your Arduino focuser as an INDI focuser device)
  • USB connections:

    • Camera → Pi/PC
    • Focuser (ATmega via USB-serial) → Pi/PC

Setup (High-Level)

  1. Install KStars with Ekos and INDI.

  2. Create an Ekos profile:

    • Add Camera = your INDI camera driver.
    • Add Focuser = your custom/compatible INDI focuser driver.
  3. Start INDI server from Ekos using that profile.

  4. Configure Focuser in Ekos:

    • Step size, max travel, backlash.
    • Temperature input if you wired a sensor and exposed it in the INDI driver.

How It Ties Into the Focus Loop

Ekos has a dedicated Focus Module that does:

  1. Ekos → Focuser (ATmega): move to a starting position.

  2. Ekos → Camera: capture image.

  3. Ekos:

    • Crop around a star or region.
    • Computes HFR / FWHM / other sharpness metrics.
    • Uses focus algorithms (e.g. linear, polynomial) to decide next move.
  4. Iterate until the metric is minimised.

  5. Ekos → Focuser: move to final best-focus position.

All communication runs through INDI:

  • INDI Focuser driver ↔ Serial protocol ↔ ATmega328P
  • INDI Camera driver ↔ camera hardware

ATmega just obeys “move, report position”; Ekos does the heavy math.


4. Custom Python / C++ Script (DIY Focus Controller)

What it is

Instead of using N.I.N.A / SGP / Ekos, you can write your own controller:

  • A Python script (or C++) that:

    • Talks to the camera.
    • Talks to the ATmega focuser over serial.
    • Runs your own image-processing and focusing logic.

This is maximum control, maximum pain, maximum fun.

What You Need

  • PC / laptop / Pi with:

    • Python (or C++) and libraries such as:

      • pyserial for Arduino serial comms
      • opencv-python or scikit-image for image processing
      • astropy / photutils if you want astronomy-oriented metrics
  • A way to access images:

    • From a camera SDK (ZWO, QHY, etc.)
    • Or by watching a folder where another program saves FITS files

Typical Setup

  1. Define serial protocol to ATmega:

    • e.g. text commands like:

      • MOVE 12345
      • HOME
      • GETPOS
    • ATmega firmware parses these and controls the stepper.

  2. Image capture:

    • Either call camera SDK to grab frames directly, or
    • Wait for a new FITS image to appear in a directory.
  3. Image processing:

    • Load image.
    • Find stars (threshold + connected components).
    • Compute focus metric (HFR, FWHM, Laplacian, etc.).
  4. Search algorithm:

    • Implement V-curve sampling, hill-climbing, or a simple coarse-fine sweep.
    • Store (position, metric) and pick best.
  5. Final move:

    • Send final MOVE best_position to ATmega over serial.

How It Ties Into the Focus Loop

You’re explicitly coding the loop:

for each trial position:
    send MOVE command to ATmega
    capture image
    compute focus metric
    log (position, metric)

choose best_position
send MOVE best_position to ATmega

The logic and image processing live entirely in your script; the ATmega stays a dumb but precise motor controller.


TL;DR – Division of Labour

No matter which software you pick:

  • Host imaging software (N.I.N.A / SGP / Ekos / custom script)

    • Talks to camera
    • Runs image processing (focus metric)
    • Decides best focus position
  • ATmega328P focuser

    • Knows its position in steps
    • Moves the motor on command
    • Optionally reports temperature, limit switch status, etc.

Once that line is clear, wiring in any of these programs to the loop is just a question of:

“Can this program talk to my focuser as an ASCOM/INDI/serial device, and can it read images from my camera?”

If yes → you can plug it straight into the autofocus loop we’ve already documented.

///

Yes. On Linux the clean, integrated way to do image-based focus checking + motor control is:

KStars + Ekos + INDI

Ekos (inside KStars) has a full autofocus module that:

  • talks to your camera,
  • talks to your ATmega328P focuser (via an INDI focuser driver),
  • does the image processing (HFR/FWHM) and moves the focuser automatically.

Below is a step-by-step “this is exactly how you do it” assuming Ubuntu / Ubuntu-like Linux.


1. Architecture (what runs where)

Just to lock in the mental model:

Camera  ──USB──►  Linux box (KStars/Ekos)  ◄──USB/Serial──  ATmega328P focuser
                           |
                           └── INDI drivers (camera + focuser)
  • ATmega328P focuser

    • Knows its position in steps
    • Receives commands like move to 12345
    • Optional: reports temperature, limits, etc.
  • Linux box running KStars/Ekos + INDI

    • Opens the camera via INDI.
    • Opens the focuser via INDI.
    • Captures images, measures star sharpness (HFR/FWHM).
    • Figures out the best focus position and sends the final move to the focuser.

2. Install KStars/Ekos + INDI on Ubuntu(-ish)

On most Ubuntu-style distros the recommended way (as of 24.04 era) is to use Jasem Mutlaq’s PPA, then install INDI + KStars/Ekos. ([INDI Library Documentation]1)

Open a terminal:

# 1) Add the Ekos/INDI PPA
sudo add-apt-repository ppa:mutlaqja/ppa
sudo apt update

# 2) Install INDI and KStars with Ekos
sudo apt install indi-full kstars-bleeding gsc
  • indi-full = INDI core + 3rd-party drivers.
  • kstars-bleeding = KStars including Ekos with current features.
  • gsc = Guide Star Catalog (used by plate solving & some tools).

You can confirm KStars installed by running:

kstars &

3. Make the ATmega focuser visible to INDI

You need the ATmega328P focuser to appear to Ekos as an INDI focuser device.

You’ve got two realistic routes:

Option A – Emulate an existing Arduino focuser project

Easiest path:

  • Take an existing Arduino focuser design that already has an INDI driver:

    • e.g. MyFocuserPro2, MoonLite-compatible Arduino firmware, etc.
  • Flash that firmware (or adapt it) onto your ATmega board.

  • Use the matching INDI driver (e.g. indi_moonlite_focus, indi_myfocuserpro2_focus).

Then:

  1. Plug the Arduino into USB.

  2. Check which serial port it uses:

    dmesg | grep tty
    # or
    ls /dev/ttyACM* /dev/ttyUSB* 2>/dev/null
    
  3. The INDI driver will open that port automatically (you can pick it in the driver config in Ekos).

Option B – Your own custom INDI focuser driver

If you want to roll your own:

  • Write simple firmware on the ATmega that accepts serial commands like:

    • MOVE 12345\n
    • HOME\n
    • GETPOS\n → replies POS 12345\n
    • GETTEMP\n → optional
  • Then either:

    • Hack an existing open driver (MoonLite-like) to speak your protocol, or
    • Write a small INDI focuser driver in C++ using the INDI SDK.

That’s more work, but conceptually the same: INDI driver translates Ekos focuser commands ↔ your serial protocol ↔ ATmega.


4. Create an Ekos Profile and Connect

  1. Start KStars:

    kstars &
    
  2. Open Ekos:

    • In KStars menu: Tools → Ekos.
  3. Create a new profile:

    • Click “+” to add a profile.

    • Name it something like Local-Rig.

    • Set:

      • Mode: Local
      • Mount: your INDI telescope driver (or Simulator while testing).
      • CCD: your camera’s INDI driver (e.g. ZWO CCD, GPhoto CCD for DSLR, etc.).
      • Focuser: your focuser driver (MoonLite, MyFocuserPro2, or your custom one).
    • Save the profile.

  4. Start the INDI server from Ekos:

    • In Ekos, click “Start” for that profile.
    • An INDI Control Panel will pop up with tabs for each device.
  5. Verify devices:

    • Go to the Focuser tab:

      • Confirm it’s connected.
      • Make sure the serial port is correct (/dev/ttyACM0 etc.).
    • Go to the CCD tab:

      • Confirm it can take a test exposure.

If both connect and respond, you’re ready for autofocus.


5. Calibrate the Focuser in Ekos

In the Ekos Focus module:

  1. Open Ekos → Focus.

  2. Make sure:

    • Focuser is selected.
    • Capture device is your imaging camera.
  3. Initial settings:

    • Full field / Subframe: start with Full field so it uses many stars.
    • Exposure time: 2–10s depending on target brightness.
    • Filter: choose your main imaging filter or Luminance.
    • Step size: how many focuser steps per move during AF loop (e.g. 50–200).
    • Max travel: safe range of steps so it doesn’t crash into mechanical stops.
    • Backlash: add compensation or use “always approach from one side”.
  4. Test manual moves:

    • Use the focuser IN/OUT buttons in the Focus tab.
    • Check that the focuser physically moves in the expected direction and the step count changes.

6. Run an Autofocus Pass (Image Processing + Control Loop)

With everything connected:

  1. Point the telescope at a star field (or your imaging target).

  2. In the Focus module:

    • Choose the algorithm (e.g. Polynomial / Quadratic).
    • Set the number of samples (e.g. 7–9 steps across focus).
  3. Click “Start” autofocus.

Ekos then does the full loop:

  1. Move & Capture

    • Ekos → Focuser (via INDI → ATmega): move to position X₁.
    • Ekos → Camera: capture image at X₁.
  2. Image processing / focus metric

    • Ekos reads the frame.
    • Detects stars (threshold + object detection).
    • Computes HFR (Half Flux Radius) or FWHM for stars in the frame.
    • Stores (position, HFR) for that sample.
  3. Repeat across positions

    • Ekos moves the focuser to X₂, X₃, …, Xₙ.
    • Each time: capture → analyze → record HFR.
  4. Fit the focus curve

    • It plots HFR vs focuser position (you see this graph live).
    • Finds the minimum HFR point (best focus).
    • Interpolates/extrapolates if needed to get a smooth solution.
  5. Move to best focus

    • Ekos sends a final GOTO command to the focuser driver.
    • INDI driver converts that to serial (e.g. MOVE 12345\n).
    • ATmega moves the stepper to that best-focus step and reports done.

If the HFR curve makes sense (nice V/U-shape), you’re locked in. You can then tick options like:

  • “Autofocus on temperature change” (if driver exposes temperature).
  • “Autofocus on filter change” (different filters can have different focus offsets).

7. Optional: Run Everything Headless on a Pi / Mini-PC

Exactly the same stack runs on:

  • Raspberry Pi
  • NUC / small form-factor PC

Using the same install pattern (Ubuntu or Ubuntu-like + PPA + indi-full kstars-bleeding). ([Astro What?]2)

You can:

  • Run KStars/Ekos on the Pi and remote-desktop into it, or
  • Run just INDI server on the Pi and connect to it over the network from KStars/Ekos on your main laptop.

Either way, the autofocus loop is identical.


8. If You Want Ultra-Minimal CLI Instead

If you ever decide you don’t want UI at all, the ultra-minimal Linux option is:

  • Use INDI camera driver + INDI focuser driver.

  • Write a Python script that:

    • Uses an INDI client library (or just your own serial protocol).
    • Captures test images.
    • Runs HFR/FWHM with astropy / photutils / opencv.
    • Does the same V-curve logic and sends MOVE commands to the ATmega.

That’s basically re-implementing the Ekos “Focus” module yourself – good for full control, but more work.


TL;DR

Yes: on Linux you can use KStars + Ekos + INDI to do exactly what you want:

  • Image-based focus checking (HFR/FWHM)
  • Automatic control of your ATmega328P focuser
  • Entire loop is configurable and repeatable, and can run on your existing Ubuntu box or a small Pi at the mount.

If you tell me which camera you’re using and whether you want to emulate a MoonLite / MyFocuserPro2 or do your own protocol, I can sketch the exact INDI driver + Arduino serial commands to match it.

///

Yes, we absolutely can. Think of it as:

Canon M100 + gphoto2 + Octave (image package) + Arduino/Uno + instrument-control all glued together into your own autofocus brain.

I’ll lay it out step-by-step so you can actually build it.


0. Big Picture Architecture

On Linux (your Ubuntu box):

Canon M100  ─USB─►  Linux (Octave)
                         │
                         ├─ calls gphoto2 to take images
                         │
                         └─ serial over USB to Arduino/Uno (focuser)
  • Canon M100 – controlled via gphoto2 / libgphoto2 (capture frames, maybe liveview). The M100 is supported for image capture and preview in libgphoto2.

  • Octave – runs your autofocus logic:

    • calls gphoto2 to grab an image,
    • uses the image package to compute a focus metric (HFR/FWHM-ish or simpler)
    • talks to your Uno over serial using the instrument-control package
  • Arduino Uno – drives the stepper motor on the focuser, exposes a simple serial command set: HOME, GOTO N, GETPOS, etc.


1. Install the Linux Pieces

1.1 Install gphoto2 (Canon control)

sudo apt update
sudo apt install gphoto2

Check that the M100 is seen:

gphoto2 --auto-detect

You should see something like:

Model            Port
----------------------------------------------------------
Canon EOS M100   usb:00x,00y

Confirm you can capture a test image:

gphoto2 --capture-image-and-download --filename test.jpg

If that works, you’ve got USB remote capture from the M100 via libgphoto2.

Note: The M100 has had some quirks (e.g. SD card too full, some config options not exposed), but basic capture/preview is supported and used by people for automation.


1.2 Install Octave + image + instrument-control

Install Octave and dev packages if you haven’t:

sudo apt install octave octave-communications octave-control octave-signal

Install the image and instrument-control packages from Octave Forge:

Start Octave:

octave

Inside Octave:

pkg install -forge image
pkg install -forge instrument-control

Then in your scripts:

pkg load image
pkg load instrument-control
  • image gives you imread, rgb2gray, imfilter, etc.
  • instrument-control gives you serial() functions to talk to the Uno over USB.

(If your distro already has octave-image and octave-instrument-control packages, you can install those instead of pkg install -forge.)


2. Arduino/Uno Focuser Firmware

On the Uno, you want:

  • A stepper driver (A4988 / DRV8825 / TMC) wired to:

    • STEP, DIR, ENABLE pins
  • A limit switch for homing (optional but recommended)

  • Simple serial protocol like:

HOME\n         -> homes towards switch, sets position = 0, then replies "OK"
GOTO 12345\n   -> move to step 12345, then reply "OK"
GETPOS\n       -> reply "POS 12345"

Skeleton Arduino sketch (idea, not full code):

#include <AccelStepper.h>

AccelStepper stepper(AccelStepper::DRIVER, 2, 3); // STEP=2, DIR=3
long currentPos = 0;

void setup() {
  Serial.begin(115200);
  stepper.setMaxSpeed(2000);
  stepper.setAcceleration(1000);
  // setup limit switch pinMode...
}

void loop() {
  if (Serial.available()) {
    String cmd = Serial.readStringUntil('\n');
    cmd.trim();

    if (cmd == "HOME") {
      // move inward until limit switch triggers
      stepper.setSpeed(-500);
      while (digitalRead(LIMIT_PIN) == HIGH) {
        stepper.runSpeed();
      }
      stepper.setCurrentPosition(0);
      currentPos = 0;
      Serial.println("OK");
    }
    else if (cmd.startsWith("GOTO")) {
      long target = cmd.substring(5).toInt(); // after "GOTO "
      stepper.moveTo(target);
      while (stepper.distanceToGo() != 0) {
        stepper.run();
      }
      currentPos = target;
      Serial.println("OK");
    }
    else if (cmd == "GETPOS") {
      Serial.print("POS ");
      Serial.println(currentPos);
    }
  }
}

That’s enough for Octave to treat the Uno as a dumb, precise motor slave.


3. Talking to the Uno from Octave (USB Serial)

Find your Uno’s device:

ls /dev/ttyACM* /dev/ttyUSB* 2>/dev/null

Suppose it’s /dev/ttyACM0.

In Octave:

pkg load instrument-control

if (exist("serial") ~= 3)
  error("Instrument-control package (serial) not available");
endif

port = "/dev/ttyACM0";
baud = 115200;

s = serial(port, baud);
fopen(s);          % Open serial port (Arduino resets here)

% optional small pause for Uno to reboot
pause(2);

% Flush any junk
while (s.BytesAvailable > 0)
  fread(s, s.BytesAvailable);
endwhile

Helper to send a command and wait for "OK":

function ok = send_cmd_and_wait(s, cmd)
  fprintf(s, "%s\n", cmd);
  ok = false;
  t0 = time();
  buf = "";
  while (time() - t0 < 5)    % 5s timeout
    if (s.BytesAvailable > 0)
      buf = [buf, char(fread(s, s.BytesAvailable)')];
      if (strfind(buf, "OK"))
        ok = true;
        break;
      endif
    endif
    pause(0.05);
  endwhile
  if (!ok)
    warning("No OK from focuser for command: %s (buffer: %s)", cmd, buf);
  endif
endfunction

Home the focuser:

send_cmd_and_wait(s, "HOME");

4. Capturing Images from the M100 into Octave

We’ll use gphoto2 from inside Octave:

function fname = capture_frame(index)
  fname = sprintf("frame_%03d.jpg", index);
  cmd = sprintf("gphoto2 --capture-image-and-download --filename %s --force-overwrite", fname);
  status = system(cmd);
  if (status != 0)
    error("gphoto2 capture failed with status %d", status);
  endif
endfunction

Now read the image and convert to grayscale:

pkg load image

function Igray = load_gray(fname)
  I = imread(fname);        % RGB matrix
  if (ndims(I) == 3)
    Igray = rgb2gray(I);    % from image package
  else
    Igray = I;
  endif
endfunction

5. A Simple Focus Metric in Octave

Fancy star-fitting (HFR, FWHM) is doable but a bit of work. A quick and surprisingly effective metric is variance of the Laplacian:

  • Sharper image → stronger high-frequency edges → larger Laplacian variance.
function m = focus_metric_laplacian(Igray)
  % ensure double
  I = im2double(Igray);

  % simple Laplacian kernel
  h = [0  -1  0;
      -1   4 -1;
       0  -1  0];

  L = imfilter(I, h, "replicate");
  m = var(L(:));   % bigger = sharper
endfunction

You can later switch this out for a proper star-based HFR metric if you want.


6. Putting It Together: Octave Autofocus Loop

Now we combine:

  • Move focuser → capture frame → compute metric
  • Repeat across several positions → pick the best → move back there

Example:

pkg load image
pkg load instrument-control

% --- serial setup (from above) ---
port = "/dev/ttyACM0"; baud = 115200;
s = serial(port, baud);
fopen(s);
pause(2);
while (s.BytesAvailable > 0); fread(s, s.BytesAvailable); endwhile

send_cmd_and_wait(s, "HOME");   % home focuser

% --- focus sweep parameters ---
center   =  0;        % start around home (you can offset this later)
step_sz  = 200;       % focuser steps between samples
n_steps  = 7;         % number of positions (must be odd for symmetric sweep)

positions = center + step_sz * (-(n_steps-1)/2 : (n_steps-1)/2);

metrics = zeros(size(positions));

for k = 1:numel(positions)
  pos = positions(k);

  % move focuser
  cmd = sprintf("GOTO %d", pos);
  send_cmd_and_wait(s, cmd);

  % capture image from Canon
  fname = capture_frame(k);

  % load and compute focus metric
  Ig = load_gray(fname);
  metrics(k) = focus_metric_laplacian(Ig);

  printf("Position %d: metric = %f\n", pos, metrics(k));
  fflush(stdout);
endfor

% find best focus (max metric for Laplacian-variance)
[best_metric, idx_best] = max(metrics);
best_pos = positions(idx_best);

printf("Best metric %f at position %d\n", best_metric, best_pos);

% move to best focus
send_cmd_and_wait(s, sprintf("GOTO %d", best_pos));

% optionally close port
fclose(s);
delete(s);
clear s;

That is a fully working conceptual autofocus loop:

  1. Octave → Uno: move focuser with GOTO.
  2. Octave → gphoto2 → M100: capture image file.
  3. Octave → image package: compute focus metric.
  4. Octave: picks best position.
  5. Octave → Uno: move focuser to best position.

7. Libraries / Extras You Can Exploit

  • Octave image package – all sorts of goodies:

    • imread, imwrite, imshow, imfilter, edge, imgaussfilt, bwlabel, etc.
    • Lets you implement more advanced focus metrics (star detection, centroiding, radial profiles).
  • instrument-control – serial/UDP/GPIB; we only care about serial here.

  • Arduino-Octave (Firmata) – alternative approach: upload Firmata to the Uno and control pins directly from Octave using an Arduino class. Could be used if you ever want to bypass your own text protocol.

  • gphoto2/libgphoto2 – you can call the CLI (as above) or, if you feel masochistic later, use the C API and call it from an Octave .oct function, but CLI is plenty for now.


8. Reality Checks / Gotchas

  • Speed – this will be slower than KStars/Ekos autofocus because:

    • We’re spawning gphoto2 for each frame.
    • Octave is not super-optimised for realtime loops.
    • But for a few test positions per focus run, it’s fine.
  • M100 quirks – keep SD card relatively clean (<10k files) and make sure USB is in the right mode; some users have hit connection issues with large card contents.

  • Focusing metric tuning – you may need to adjust:

    • exposure time,
    • ISO,
    • ROI (crop a bright star region),
    • and the metric itself, to get a nice “V”/“U” shape.

If you want, next step I can help you:

  • swap the Laplacian metric for a proper star HFR/HFD implementation in Octave, or
  • tighten up the Arduino serial protocol and Octave error handling so it’s rock-solid for all-night runs.

///////