Skip to content

achydenius/voltage

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

79 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Voltage

An oscillographics programming library for Teensy 3.6. The goal of the library is to provide a simple to use API for creating three-dimensional vector graphics similar to classic arcade games such as Battlezone or Star Wars.

The project depends on raylib's header-only math library. An external DAC can be used to control the brightness of individual lines.

An oscilloscope running a Voltage example

Setting up

  1. Connect Teensy's DAC0, DAC1 and GND pins to oscilloscope's X and Y inputs
  2. Download raymath.h header file and copy it under Voltage/src directory
  3. Install the library by copying the Voltage directory to Arduino libraries folder (e.g. ~/Documents/Arduino/libraries/ on macOS)

How to use

The rendering loop consists of three phases:

  1. Clear Renderer's internal buffers with clear method call
  2. Add geometry to be rendered with the overloaded add method
  3. Render all the added geometry with render method call

Voltage's rendering resolution is 12 bits, which is Teensy's maximum resolution. By default, every value along the line being drawn is being lit, yielding a smooth result, but requiring significant amount of CPU power and potentially causing flickering. The rendering can be made more performant by drawing only every nth pixel, which can be configured by setting a larger increment argument (default being one) when instantiating the renderer. For example, increment value of two usually improves the performance quite a lot without any significant visual changes.

Importing 3D meshes from third-party software

3D meshes in .obj file format can be imported to Voltage with parse-obj.py Python script in utils directory. The script takes two command line arguments: the name of the obj file to be imported, and a name for a variable, which can be then accessed in Voltage code.

For example, running ./parse-obj.py example.obj mesh outputs code with the mesh definition in voltage::Mesh* mesh variable, which can be then pasted to the sketch. See import.ino for an example.

Alternatively, the mesh can be imported by first redirecting the output of the parser to a file (e.g. with ./parse-obj.py example.obj > example.h), copying the file to the sketch's directory, and then including the file in the sketch with #include "example.h.

Setting up external DAC for brightness control

An external Microchip MCP4922 DAC can be used for setting the brightness of individual lines. MCP4922 can be used with Teensy 3.6 by using the following connections:

MCP4922 Teensy 3.6
Pin 1 (VDD) 3.3V
Pin 3 (CS) Pin 10 (CS0)
Pin 4 (SCK) Pin 13 (SCK0)
Pin 5 (SDI) Pin 11 (MOSI0)
Pin 8 (LDAC) GND
Pin 9 (SHDN) 3.3V
Pin 12 (VSS) GND
Pin 13 (VREFA) 3.3V

The DAC output voltage is in pin 14 (VOUTA).

Code examples

More examples can be found in examples directory.

Draw a rotating line by passing a Line to add method:

#include <Voltage.h>

voltage::Renderer renderer;

void setup() {}

float phase = 0;
void loop() {
  renderer.clear();
  renderer.add({
    { cosf(phase), sinf(phase) },
    { cosf(PI + phase), sinf(PI + phase) }
  });
  renderer.render();

  phase -= 0.001;
}

Draw an animated 3D cube using Object and FreeCamera:

#include <Voltage.h>

using namespace voltage;

Renderer renderer;
Mesh *mesh = MeshBuilder::createCube(1.0);
Object *object = new Object(mesh);
FreeCamera camera;

void setup() {}

float phase = 0;
void loop() {
  camera.setTranslation(0, 0, sin(phase) * 5.0);
  object->setRotation(phase, phase, 0);

  renderer.clear();
  renderer.add(object, camera);
  renderer.render();
  phase += 0.001;
}

Initializing a MCP4922 DAC and enabling shading

Initialize the Renderer class as follows:

MCP4922Writer *brightnessWriter = new MCP4922Writer();
BrightnessTransform *brightnessTransform = new LinearBrightnessTransform(brightnessWriter);
Renderer renderer(brightnessWriter, brightnessTransform);

Enable hidden line shading and set the hidden line brightness:

void setup() {
  object->shading = Shading::Hidden;
  object->hiddenBrightness = 0.5;
}

The rest of the code works just as in previous examples.

Running without oscilloscope and Teensy on MacOS (experimental)

Voltage can also be used without oscilloscope and Teensy. This can be useful for a bit more convenient testing and development. The oscilloscope/Teensy emulator can be found in emulator directory. main.cpp file includes the cube example above and contains further instructions how to modify/use the code.

  1. Install SDL2 with brew install sdl2
  2. Build emulator with make
  3. Run the emulator with ./main

About

An oscillographics programming library for Arduino-compatible microcontrollers

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published