firmware  v0.1.2
Chromation Spectrometer Dev-Kit
Functions | Variables
VisCmd.h File Reference
#include <stdint.h>
#include <stdbool.h>
#include "SpiSlave.h"
#include "StatusCode.h"
#include "Queue.h"
#include "BiColorLed.h"
#include "UartSpi.h"
#include "AutoExpose.h"
#include <util/delay_basic.h>

Go to the source code of this file.

Functions

bool LedNumIsValid (bicolorled_num led_num)
 
uint8_t ReadLedState (bicolorled_num led_num)
 
bool AutoExposeConfigIsValid (uint8_t new_max_tries, uint16_t new_start_pixel, uint16_t new_stop_pixel, uint16_t new_target)
 
uint16_t GetPeak (uint16_t const, uint16_t const)
 
uint16_t AutoExpose (void)
 
void NullCommand (void)
 
void GetSensorLED (void)
 
void SetSensorLED (void)
 
void GetExposure (void)
 
void SetExposure (void)
 
static void CaptureFrame (void)
 
void AutoExposure (void)
 
void GetAutoExposeConfig (void)
 
void SetAutoExposeConfig (void)
 
void GetSensorHash (void)
 

Variables

volatile Queue_sSpiFifo
 Allocate static memory for the SPI Rx Queue.
 
uint8_t frame []
 One frame of pixel data is, at most, 1568 bytes.
 

Detailed Description

API for vis-spi-out.c

Definition in file VisCmd.h.

Function Documentation

◆ AutoExpose()

uint16_t AutoExpose ( void  )

AutoExpose behavior:

  • turns led1 red to indicate starting
  • sets min peak at target minus tolerance
  • clamps min peak at max dark if target minus tolerance is GREATER THAN target
  • clamps min peak at max dark if target minus tolerance is LESS THAN max dark
  • sets max peak at target plus tolerance
  • clamps max peak at 65535 counts if target plus tolerance is LESS THAN target
  • loops until done
  • exposes the LIS 770i pixels
  • reads pixel counts into global frame buffer
  • finds frame peak in range start pixel to stop pixel
  • is done if peak less than max dark AND exposure at max
  • scales exposure by 10 if peak less than max dark
  • clamps exposure at max exposure if 10 x exposure is GREATER THAN max exposure
  • scales exposure by half if peak ABOVE max peak
  • clamps exposure at min exposure if half exposure is LESS THAN min exposure
  • is done if peak BELOW min peak and exposure at max exposure
  • scales exposure by target div peak if peak BELOW min peak and exposure not at max
  • clamps exposure at max exposure if gain is GREATER THAN max exposure
  • is done if peak is in the target range
  • turns led1 green to indicate it hit the target range
  • gives up if it iterates for max tries

AutoExpose uses a "Take Back Half" algorithm

Find an exposure time that gets a peak within +/-5% of the target peak value. On each iteration, multiply exposure time, either by:

  • 10, if peak is below the dark background
  • 1/2, if peak is above the target range
  • gain, if peak is visible but below the target range
    • gain = target ÷ peak
      • note gain is always > 1:
        • target is the center of the target range
        • peak is below the target range, so peak < target
        • then target ÷ peak must be > 1
      • for precise division with integers:
        • multiply exposure by target BEFORE dividing by peak:
          • ( exposure_ticks x target ) ÷ peak

The algorithm gives up if:

  • exposure time hits a limit
  • or the peak fails to land in the ±5% tolerance after 10 iterations.

The large tolerance, ±5%, makes the algorithm fast. It usually settles within a few iterations.

target range

The range of target values is configured by setting target and target_tolerance. The recommended values are:

  • target: 46420 counts
  • target_tolerance: 3277 counts

AutoExpose tries to get the peak counts between min_peak and max_peak.

  • target - target_tolerance is the min_peak
  • target + target_tolerance is the max_peak

Using the recommended values, this results in:

  • min_peak: 43143 counts
  • max_peak: 49697 counts

49697 counts is the top of the guaranteed linear range of output values for the LIS-770i

  • this value is based on the dev-kit design:
    • 16-bit ADC
    • 1.8V ADC voltage reference
    • LIS-770i power supply: 3.3V
  • and based on the LIS-770i programming configuration:
    • binning on
    • gain 1x
    • all rows active

This target range, [ 43143 : 49697 ], represents 10% of the full-scale reading, 65535.

max_dark

Signal below max_dark is considered no signal because it is indistinguishable from the dark background.

  • use 4500 counts for max_dark
    • 1000 counts is the actual approximate peak in the dark background when Chromation ships the dev-kit
    • 4500 counts is well above the actual peak dark background
      • setting max_dark to 4500 ensures the algorithm calculates a gain only when necessary
      • for signal below 4500 counts, the 10x gain is sufficient
  • max_dark depends on:
    • exposure time
      • at longer exposures, peaks in the dark background are reduced because they are closer to the mean dark value
    • trim pot setting
      • trims the output offset voltage of the LIS-770i

Algorithm Setup

Initial state

AutoExpose is not done

Method to get peak value

  • expose the LIS-770i and readout one frame of data
  • return the peak value in the frame

Method to clamp exposure time

Exposure time is stored in 16-bit global exposure_ticks.

Clamp adjustments to exposure_ticks between 1 and 65535.

When multiplying exposure_ticks by:

  • 10 or gain:
    • if result > 65535, clamp exposure_ticks at 65535
  • 1/2:
    • ÷2 is a bit-shift, so result is integer truncated
    • if result < 1, clamp exposure_ticks at 1

Algorithm

while AutoExpose is not done:

  • expose LIS-770i
  • readout LIS-770i, store in global frame buffer
  • get peak from global frame buffer
  • if there is no signal: // peak <= max_dark
    • if at max exposure time:
      • AutoExpose is done
    • else:
      • 10x exposure time
  • elif peak is ABOVE target range: // peak is > max_peak
    • TAKE BACK HALF // exposure time = 1/2 exposure time
  • elif peak is BELOW target range: // peak is < min_peak
    • if at max exposure time:
      • AutoExpose is done
    • else:
      • gain = target ÷ peak
      • scale exposure time by gain // exposure time = ( target x exposure time ) ÷ peak
    • else: // signal in target range: min_peak <= peak <= max_peak
      • AutoExpose is done
    • increment iterations
    • if iterations is at max:
      • AutoExpose is done

Definition at line 81 of file VisCmd.c.

◆ CaptureFrame()

static void CaptureFrame ( void  )
inlinestatic

CaptureFrame behavior:

  • sends OK
  • checks binning to determine number of pixels in frame
  • sends num pixels MSB
  • sends num pixels LSB
  • exposes the pixels
  • does readout of num pixels into the frame buffer
  • sends the pixel readings stored in the frame buffer

Definition at line 423 of file VisCmd.h.

◆ GetExposure()

void GetExposure ( void  )
inline

GetExposure behavior:

  • sends OK
  • sends MSB of exposure ticks
  • sends LSB of exposure ticks

Definition at line 379 of file VisCmd.h.

◆ GetPeak()

uint16_t GetPeak ( uint16_t const  _start_pixel,
uint16_t const  _stop_pixel 
)

GetPeak behavior:

  • finds the peak between start pixel and stop pixel inclusive
  • ignores peaks at pixels before start pixel and after stop pixel

Algorithm

  • peak starts at 0
  • walk the global frame buffer
    • start at _start_pixel
    • stop at _stop_pixel
  • for each pixel:
    • if pixval > peak
      • peak = pixval
  • return peak

byte_index example: v----— if _start_pixel is 7 pixel: 1 2 3 4 5 6 7 8 byte: 01 23 45 67 89 AB CD EF ^----— then byte_index is 12

Definition at line 29 of file VisCmd.c.

◆ GetSensorLED()

void GetSensorLED ( void  )
inline

GetSensorLED behavior:

  • waits for byte led num
  • reads byte led num
  • sends OK and LED SETTING if led num is valid
  • sends ERROR and pads second byte if led num is invalid

Definition at line 275 of file VisCmd.h.

◆ LedNumIsValid()

bool LedNumIsValid ( bicolorled_num  led_num)
inline

LedNumIsValid behavior:

  • returns TRUE if led num is 0
  • returns TRUE if led num is 1
  • returns FALSE if led num is not 0 or 1

Definition at line 63 of file VisCmd.h.

◆ NullCommand()

void NullCommand ( void  )
inline

Do nothing.

Definition at line 271 of file VisCmd.h.

◆ ReadLedState()

uint8_t ReadLedState ( bicolorled_num  led_num)
inline

ReadLedState behavior:

  • returns OFF if LED is off
  • returns GREEN if LED is on and green
  • returns RED if LED is on and red
  • see led_state in StatusCodes.h

Definition at line 74 of file VisCmd.h.

◆ SetExposure()

void SetExposure ( void  )
inline

SetExposure behavior:

  • waits for byte exposure MSB
  • reads byte exposure MSB
  • waits for byte exposure LSB
  • reads byte exposure LSB
  • updates global exposure ticks
  • sends OK

Definition at line 392 of file VisCmd.h.

◆ SetSensorLED()

void SetSensorLED ( void  )
inline

SetSensorLED behavior:

  • waits for byte led num
  • reads byte led num
  • waits for byte led setting
  • reads byte led setting
  • sends ERROR if led num is invalid
  • sends ERROR if led setting is invalid
  • applies LED setting if valid
  • sends OK if num and setting are valid

Definition at line 304 of file VisCmd.h.