Simple Latency Measurement Application for Head Mounted Display. This project handles LED and light sensor to measure the latency from blinking to showing on the display.

Dependencies:   mbed-dsp mbed

Committer:
mfurukawa
Date:
Tue Sep 23 08:55:58 2014 +0000
Revision:
2:4ec0fc856963
Parent:
0:f6d58666cdc3
typo corected

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mfurukawa 0:f6d58666cdc3 1 //
mfurukawa 0:f6d58666cdc3 2 // Latency Checker rev 0.1
mfurukawa 0:f6d58666cdc3 3 //
mfurukawa 0:f6d58666cdc3 4 // Author : Masahiro Furukawa
mfurukawa 0:f6d58666cdc3 5 // Mail : m.furukawa@ist.osaka-u.ac.jp
mfurukawa 0:f6d58666cdc3 6 // Created : Sept 22, 2014
mfurukawa 0:f6d58666cdc3 7 // Updated : Sept 23, 2014
mfurukawa 0:f6d58666cdc3 8 //
mfurukawa 0:f6d58666cdc3 9 // Purpose : Latency Measurement between Camera and Display (HMD)
mfurukawa 0:f6d58666cdc3 10 // Requirement : Serial Terminal to show result
mfurukawa 0:f6d58666cdc3 11 //
mfurukawa 0:f6d58666cdc3 12 // Pin Assign : P16 --- LED Anode
mfurukawa 0:f6d58666cdc3 13 // P18 --- Cross point btwn AD in (PT600T) and register
mfurukawa 0:f6d58666cdc3 14
mfurukawa 0:f6d58666cdc3 15 #include "mbed.h"
mfurukawa 0:f6d58666cdc3 16 #include "dsp.h"
mfurukawa 0:f6d58666cdc3 17
mfurukawa 0:f6d58666cdc3 18 #define BUF_SIZE 2000
mfurukawa 0:f6d58666cdc3 19 #define H_TO_L 1
mfurukawa 0:f6d58666cdc3 20 #define L_TO_H -1
mfurukawa 0:f6d58666cdc3 21
mfurukawa 0:f6d58666cdc3 22 InterruptIn button(p5);
mfurukawa 0:f6d58666cdc3 23 AnalogIn adc_in(p18);
mfurukawa 0:f6d58666cdc3 24 DigitalOut led(LED1);
mfurukawa 0:f6d58666cdc3 25 DigitalOut flash(p16);
mfurukawa 0:f6d58666cdc3 26
mfurukawa 0:f6d58666cdc3 27 float32_t threshold = 0.0;
mfurukawa 0:f6d58666cdc3 28 float32_t ad[BUF_SIZE];
mfurukawa 0:f6d58666cdc3 29 int cycle = 0;
mfurukawa 0:f6d58666cdc3 30
mfurukawa 0:f6d58666cdc3 31 Ticker adc_grabber;
mfurukawa 0:f6d58666cdc3 32
mfurukawa 0:f6d58666cdc3 33 void show_credit()
mfurukawa 0:f6d58666cdc3 34 {
mfurukawa 0:f6d58666cdc3 35 printf("\n\r Latency Checker rev 0.1\n\r\n\r");
mfurukawa 0:f6d58666cdc3 36 printf(" Author : Masahiro Furukawa\n\r");
mfurukawa 0:f6d58666cdc3 37 printf(" Mail : m.furukawa@ist.osaka-u.ac.jp\n\r");
mfurukawa 0:f6d58666cdc3 38 printf(" Created : Sept 22, 2014\n\r");
mfurukawa 0:f6d58666cdc3 39 printf(" Updated : \n\r\n\r");
mfurukawa 0:f6d58666cdc3 40 }
mfurukawa 0:f6d58666cdc3 41
mfurukawa 0:f6d58666cdc3 42 void show_menu()
mfurukawa 0:f6d58666cdc3 43 {
mfurukawa 0:f6d58666cdc3 44 printf("[a] start AUTO mode\n\r");
mfurukawa 0:f6d58666cdc3 45 //printf("[s] start\n\r");
mfurukawa 0:f6d58666cdc3 46
mfurukawa 0:f6d58666cdc3 47 //printf("\n\r");
mfurukawa 0:f6d58666cdc3 48 //printf("\n\r");
mfurukawa 0:f6d58666cdc3 49 }
mfurukawa 0:f6d58666cdc3 50
mfurukawa 0:f6d58666cdc3 51 void init_cnt()
mfurukawa 0:f6d58666cdc3 52 {
mfurukawa 0:f6d58666cdc3 53 cycle = 0;
mfurukawa 0:f6d58666cdc3 54 }
mfurukawa 0:f6d58666cdc3 55 void init()
mfurukawa 0:f6d58666cdc3 56 {
mfurukawa 0:f6d58666cdc3 57 threshold = 0.0;
mfurukawa 0:f6d58666cdc3 58 init_cnt();
mfurukawa 0:f6d58666cdc3 59 }
mfurukawa 0:f6d58666cdc3 60 void get_ad()
mfurukawa 0:f6d58666cdc3 61 {
mfurukawa 0:f6d58666cdc3 62 ad[cycle] = 0;
mfurukawa 0:f6d58666cdc3 63 ad[cycle] = adc_in.read();
mfurukawa 0:f6d58666cdc3 64 cycle ++;
mfurukawa 0:f6d58666cdc3 65 }
mfurukawa 0:f6d58666cdc3 66 void get_mean_stdev(float32_t *mean, float32_t *stdev)
mfurukawa 0:f6d58666cdc3 67 {
mfurukawa 0:f6d58666cdc3 68 // clear counter : cycle
mfurukawa 0:f6d58666cdc3 69 init_cnt();
mfurukawa 0:f6d58666cdc3 70
mfurukawa 0:f6d58666cdc3 71 // blocking sequence to grab adc result per 500 micro-second
mfurukawa 0:f6d58666cdc3 72 adc_grabber.attach_us(&get_ad, 500); // 500 us
mfurukawa 0:f6d58666cdc3 73 wait(0.5); // = 500 ms = 500,000 us = 1000 cycle
mfurukawa 0:f6d58666cdc3 74 adc_grabber.detach();
mfurukawa 0:f6d58666cdc3 75
mfurukawa 0:f6d58666cdc3 76 arm_mean_f32( ad , cycle , mean );
mfurukawa 0:f6d58666cdc3 77 arm_std_f32 ( ad , cycle , stdev );
mfurukawa 0:f6d58666cdc3 78 }
mfurukawa 0:f6d58666cdc3 79
mfurukawa 0:f6d58666cdc3 80 void count_up()
mfurukawa 0:f6d58666cdc3 81 {
mfurukawa 0:f6d58666cdc3 82 cycle ++;
mfurukawa 0:f6d58666cdc3 83 }
mfurukawa 0:f6d58666cdc3 84 void get_edge_us(float32_t *edge_us, int direction)
mfurukawa 0:f6d58666cdc3 85 {
mfurukawa 0:f6d58666cdc3 86 // clear counter : cycle
mfurukawa 0:f6d58666cdc3 87 init_cnt();
mfurukawa 0:f6d58666cdc3 88
mfurukawa 0:f6d58666cdc3 89 // toggle LED
mfurukawa 0:f6d58666cdc3 90 if(direction == H_TO_L){ flash = 1; wait(1); flash = 0; }
mfurukawa 0:f6d58666cdc3 91 else
mfurukawa 0:f6d58666cdc3 92 if(direction == L_TO_H){ flash = 0; wait(1); flash = 1; }
mfurukawa 0:f6d58666cdc3 93
mfurukawa 0:f6d58666cdc3 94 // start grabbing adc result per 500 micro-second
mfurukawa 0:f6d58666cdc3 95 adc_grabber.attach_us(&count_up, 500); // 500 us
mfurukawa 0:f6d58666cdc3 96
mfurukawa 0:f6d58666cdc3 97 // wait for over threshold
mfurukawa 0:f6d58666cdc3 98 if(direction == H_TO_L) while( adc_in.read() > threshold ){}
mfurukawa 0:f6d58666cdc3 99 else
mfurukawa 0:f6d58666cdc3 100 if(direction == L_TO_H) while( adc_in.read() < threshold ){}
mfurukawa 0:f6d58666cdc3 101
mfurukawa 0:f6d58666cdc3 102 // stop timer
mfurukawa 0:f6d58666cdc3 103 adc_grabber.detach();
mfurukawa 0:f6d58666cdc3 104
mfurukawa 0:f6d58666cdc3 105 *edge_us = cycle * 500.0;
mfurukawa 0:f6d58666cdc3 106 // printf("cycle (%d)",cycle);
mfurukawa 0:f6d58666cdc3 107 }
mfurukawa 0:f6d58666cdc3 108
mfurukawa 0:f6d58666cdc3 109 struct result{
mfurukawa 0:f6d58666cdc3 110 float32_t mean;
mfurukawa 0:f6d58666cdc3 111 float32_t stdev;
mfurukawa 0:f6d58666cdc3 112 } ;
mfurukawa 0:f6d58666cdc3 113
mfurukawa 0:f6d58666cdc3 114 int get_threshold()
mfurukawa 0:f6d58666cdc3 115 {
mfurukawa 2:4ec0fc856963 116 struct result dark, bright;
mfurukawa 0:f6d58666cdc3 117 int ret;
mfurukawa 0:f6d58666cdc3 118
mfurukawa 0:f6d58666cdc3 119 // LED OFF
mfurukawa 0:f6d58666cdc3 120 flash = 0;
mfurukawa 0:f6d58666cdc3 121 wait(1);
mfurukawa 0:f6d58666cdc3 122
mfurukawa 0:f6d58666cdc3 123 // get adc
mfurukawa 0:f6d58666cdc3 124 get_mean_stdev( &dark.mean, &dark.stdev );
mfurukawa 0:f6d58666cdc3 125
mfurukawa 0:f6d58666cdc3 126 // LED ON
mfurukawa 0:f6d58666cdc3 127 flash = 1;
mfurukawa 0:f6d58666cdc3 128 wait(1);
mfurukawa 0:f6d58666cdc3 129
mfurukawa 0:f6d58666cdc3 130 // get adc
mfurukawa 2:4ec0fc856963 131 get_mean_stdev( &bright.mean, &bright.stdev );
mfurukawa 0:f6d58666cdc3 132
mfurukawa 0:f6d58666cdc3 133 // show fractuation notice
mfurukawa 2:4ec0fc856963 134 if(dark.stdev * 3.3 > 0.1 || bright.stdev * 3.3 > 0.1 )
mfurukawa 0:f6d58666cdc3 135 {
mfurukawa 2:4ec0fc856963 136 printf("*** CAUTION *** : LCD Backlight Flicker Detected(stdev > 0.1V). brightness shuold be max. \n\r");
mfurukawa 0:f6d58666cdc3 137 ret = -2;
mfurukawa 0:f6d58666cdc3 138 threshold = -1;
mfurukawa 0:f6d58666cdc3 139 }
mfurukawa 2:4ec0fc856963 140 else if(dark.stdev * 3.3 > 0.01 || bright.stdev * 3.3 > 0.01 )
mfurukawa 0:f6d58666cdc3 141 {
mfurukawa 2:4ec0fc856963 142 printf("(NOTICE) : LCD Backlight Flicker Detected (stdev > 0.01V). brightness shuold be max.\n\r");
mfurukawa 0:f6d58666cdc3 143 ret = -1;
mfurukawa 0:f6d58666cdc3 144 threshold = -1;
mfurukawa 0:f6d58666cdc3 145 }else
mfurukawa 0:f6d58666cdc3 146 {
mfurukawa 0:f6d58666cdc3 147 printf(" great! ");
mfurukawa 0:f6d58666cdc3 148 ret = 0;
mfurukawa 0:f6d58666cdc3 149
mfurukawa 0:f6d58666cdc3 150 // 50% threshold
mfurukawa 2:4ec0fc856963 151 threshold = (bright.mean - dark.mean) / 2.0 ;
mfurukawa 0:f6d58666cdc3 152 }
mfurukawa 0:f6d58666cdc3 153
mfurukawa 0:f6d58666cdc3 154 // show result
mfurukawa 0:f6d58666cdc3 155 printf("Drk avg %1.5lf (SD %1.5lf) / ", dark.mean * 3.3 , dark.stdev * 3.3);
mfurukawa 2:4ec0fc856963 156 printf("Brght avg %1.5lf (SD %1.5lf)\r\n", bright.mean * 3.3 , bright.stdev * 3.3);
mfurukawa 0:f6d58666cdc3 157
mfurukawa 0:f6d58666cdc3 158 return ret;
mfurukawa 0:f6d58666cdc3 159 }
mfurukawa 0:f6d58666cdc3 160
mfurukawa 0:f6d58666cdc3 161 #define CHECK_TIMES 5
mfurukawa 0:f6d58666cdc3 162 void get_latency()
mfurukawa 0:f6d58666cdc3 163 {
mfurukawa 0:f6d58666cdc3 164 float32_t latency_us_up[CHECK_TIMES], latency_us_down[CHECK_TIMES];
mfurukawa 0:f6d58666cdc3 165 struct result up, down;
mfurukawa 0:f6d58666cdc3 166
mfurukawa 0:f6d58666cdc3 167 if( threshold == -1 )
mfurukawa 0:f6d58666cdc3 168 {
mfurukawa 0:f6d58666cdc3 169 printf(" Thredhold value error(-1). Latency measurement fault. \n\r ");
mfurukawa 0:f6d58666cdc3 170 }else
mfurukawa 0:f6d58666cdc3 171 {
mfurukawa 0:f6d58666cdc3 172 //printf(" latency check started ! wait a while ");wait(0.5);
mfurukawa 0:f6d58666cdc3 173 }
mfurukawa 0:f6d58666cdc3 174
mfurukawa 0:f6d58666cdc3 175 // measure latency
mfurukawa 0:f6d58666cdc3 176 for(int i=0; i<CHECK_TIMES; i++)
mfurukawa 0:f6d58666cdc3 177 {
mfurukawa 0:f6d58666cdc3 178 //printf(".");
mfurukawa 0:f6d58666cdc3 179 get_edge_us(&latency_us_down[i], H_TO_L );
mfurukawa 0:f6d58666cdc3 180 get_edge_us(&latency_us_up[i], L_TO_H );
mfurukawa 0:f6d58666cdc3 181 }
mfurukawa 0:f6d58666cdc3 182
mfurukawa 0:f6d58666cdc3 183 arm_mean_f32( latency_us_down , CHECK_TIMES , &down.mean );
mfurukawa 0:f6d58666cdc3 184 arm_mean_f32( latency_us_up , CHECK_TIMES , &up.mean );
mfurukawa 0:f6d58666cdc3 185 arm_std_f32 ( latency_us_down , CHECK_TIMES , &down.stdev );
mfurukawa 0:f6d58666cdc3 186 arm_std_f32 ( latency_us_up , CHECK_TIMES , &up.stdev );
mfurukawa 0:f6d58666cdc3 187
mfurukawa 0:f6d58666cdc3 188 // show result
mfurukawa 0:f6d58666cdc3 189 printf("\n\r\n\r [RESULT] ");
mfurukawa 0:f6d58666cdc3 190 printf("H to L avg %3.2lf ms (SD %3.2lf) / ", down.mean / 1000.0, down.stdev / 1000.0);
mfurukawa 0:f6d58666cdc3 191 printf("L to H avg %3.2lf ms (SD %3.2lf)", up.mean / 1000.0, up.stdev / 1000.0);
mfurukawa 0:f6d58666cdc3 192 printf(" / Threshold %1.5lf V\r\n\r\n", threshold * 3.3 );
mfurukawa 0:f6d58666cdc3 193 }
mfurukawa 0:f6d58666cdc3 194
mfurukawa 0:f6d58666cdc3 195
mfurukawa 0:f6d58666cdc3 196 int main()
mfurukawa 0:f6d58666cdc3 197 {
mfurukawa 0:f6d58666cdc3 198 show_credit();
mfurukawa 0:f6d58666cdc3 199 get_threshold();
mfurukawa 0:f6d58666cdc3 200
mfurukawa 0:f6d58666cdc3 201 while(1)
mfurukawa 0:f6d58666cdc3 202 {
mfurukawa 0:f6d58666cdc3 203 while( get_threshold() != 0 ){}
mfurukawa 0:f6d58666cdc3 204
mfurukawa 0:f6d58666cdc3 205 get_latency();
mfurukawa 0:f6d58666cdc3 206
mfurukawa 0:f6d58666cdc3 207 }
mfurukawa 0:f6d58666cdc3 208 }