@@ -46,8 +46,8 @@ static struct camera_auto_last_values
46
46
double shutter ;
47
47
double gain ;
48
48
} last = {
49
- .shutter = 3000 ,
50
- .gain = 0 ,
49
+ .shutter = 500.0f ,
50
+ .gain = 1.0f ,
51
51
};
52
52
53
53
static lua_Integer camera_quality_factor = 50 ;
@@ -327,10 +327,9 @@ static int lua_camera_auto(lua_State *L)
327
327
}
328
328
329
329
camera_metering_mode_t metering = AVERAGE ;
330
- double exposure = 0.0 ;
331
- double shutter_kp = 0.1 ;
332
- double shutter_limit = 6000.0 ;
333
- double gain_kp = 1.0 ;
330
+ double target_exposure = 0.18 ;
331
+ double exposure_speed = 0.50 ;
332
+ double shutter_limit = 800.0 ; // TODO fix this value
334
333
double gain_limit = 248.0 ;
335
334
336
335
if (lua_istable (L , 1 ))
@@ -362,21 +361,21 @@ static int lua_camera_auto(lua_State *L)
362
361
363
362
if (lua_getfield (L , 1 , "exposure" ) != LUA_TNIL )
364
363
{
365
- exposure = luaL_checknumber (L , -1 );
366
- if (exposure < -2 .0 || exposure > 2 .0 )
364
+ target_exposure = luaL_checknumber (L , -1 );
365
+ if (target_exposure < 0 .0 || target_exposure > 1 .0 )
367
366
{
368
- luaL_error (L , "exposure must be between -2 and 2 " );
367
+ luaL_error (L , "exposure must be between 0 and 1 " );
369
368
}
370
369
371
370
lua_pop (L , 1 );
372
371
}
373
372
374
- if (lua_getfield (L , 1 , "shutter_kp " ) != LUA_TNIL )
373
+ if (lua_getfield (L , 1 , "exposure_speed " ) != LUA_TNIL )
375
374
{
376
- shutter_kp = luaL_checknumber (L , -1 );
377
- if (shutter_kp < 0.0 )
375
+ exposure_speed = luaL_checknumber (L , -1 );
376
+ if (exposure_speed < 0.0 || exposure_speed > 1 .0 )
378
377
{
379
- luaL_error (L , "shutter_kp must be greater than 0 " );
378
+ luaL_error (L , "exposure_speed must be between 0 and 1 " );
380
379
}
381
380
382
381
lua_pop (L , 1 );
@@ -393,17 +392,6 @@ static int lua_camera_auto(lua_State *L)
393
392
lua_pop (L , 1 );
394
393
}
395
394
396
- if (lua_getfield (L , 1 , "gain_kp" ) != LUA_TNIL )
397
- {
398
- gain_kp = luaL_checknumber (L , -1 );
399
- if (gain_kp < 0.0 )
400
- {
401
- luaL_error (L , "gain_kp must be greater than 0" );
402
- }
403
-
404
- lua_pop (L , 1 );
405
- }
406
-
407
395
if (lua_getfield (L , 1 , "gain_limit" ) != LUA_TNIL )
408
396
{
409
397
gain_limit = luaL_checknumber (L , -1 );
@@ -420,12 +408,12 @@ static int lua_camera_auto(lua_State *L)
420
408
volatile uint8_t metering_data [6 ];
421
409
spi_read (FPGA , 0x25 , (uint8_t * )metering_data , sizeof (metering_data ));
422
410
423
- double spot_r = metering_data [0 ] / 64.0 - 2 ;
424
- double spot_g = metering_data [1 ] / 64.0 - 2 ;
425
- double spot_b = metering_data [2 ] / 64.0 - 2 ;
426
- double matrix_r = metering_data [3 ] / 64.0 - 2 ;
427
- double matrix_g = metering_data [4 ] / 64.0 - 2 ;
428
- double matrix_b = metering_data [5 ] / 64.0 - 2 ;
411
+ double spot_r = metering_data [0 ] / 255.0f ;
412
+ double spot_g = metering_data [1 ] / 255.0f ;
413
+ double spot_b = metering_data [2 ] / 255.0f ;
414
+ double matrix_r = metering_data [3 ] / 255.0f ;
415
+ double matrix_g = metering_data [4 ] / 255.0f ;
416
+ double matrix_b = metering_data [5 ] / 255.0f ;
429
417
430
418
double spot_average = (spot_r + spot_g + spot_b ) / 3.0 ;
431
419
double matrix_average = (matrix_r + matrix_g + matrix_b ) / 3.0 ;
@@ -436,40 +424,66 @@ static int lua_camera_auto(lua_State *L)
436
424
437
425
// Choose error
438
426
double error ;
427
+
439
428
switch (metering )
440
429
{
441
430
case SPOT :
442
- error = exposure - spot_average ;
431
+ error = exposure_speed * (( target_exposure / spot_average ) - 1 ) + 1 ;
443
432
break ;
444
433
445
434
case CENTER_WEIGHTED :
446
- error = exposure - center_weighted_average ;
435
+ error = exposure_speed * (( target_exposure / center_weighted_average ) - 1 ) + 1 ;
447
436
break ;
448
437
449
- default : // AVERAGE
450
- error = exposure - matrix_average ;
438
+ case AVERAGE :
439
+ error = exposure_speed * (( target_exposure / matrix_average ) - 1 ) + 1 ;
451
440
break ;
452
441
}
453
442
454
- // Run the loop iteration
455
- if (error > 0 )
443
+ if (error > 1 )
456
444
{
457
- last . shutter += ( shutter_kp * last .shutter ) * error ;
445
+ double shutter = last .shutter ;
458
446
459
- // Prioritize shutter over gain when image is too dark
460
- if (last .shutter >= shutter_limit )
447
+ last .shutter *= error ;
448
+
449
+ if (last .shutter > shutter_limit )
461
450
{
462
- last .gain += gain_kp * error ;
451
+ last .shutter = shutter_limit ;
452
+ }
453
+
454
+ error *= shutter / last .shutter ;
455
+
456
+ if (error > 1 )
457
+ {
458
+ last .gain *= error ;
459
+
460
+ if (last .gain > gain_limit )
461
+ {
462
+ last .gain = gain_limit ;
463
+ }
463
464
}
464
465
}
465
466
else
466
467
{
467
- // When image is too bright, reduce gain first
468
- last .gain += gain_kp * error ;
468
+ double gain = last .gain ;
469
+
470
+ last .gain *= error ;
469
471
470
- if (last .gain <= 0 )
472
+ if (last .gain < 1. 0 )
471
473
{
472
- last .shutter += (shutter_kp * last .shutter ) * error ;
474
+ last .gain = 1.0 ;
475
+ }
476
+
477
+ error *= gain / last .gain ;
478
+
479
+ if (error < 1 )
480
+ {
481
+ last .shutter *= error ;
482
+
483
+ if (last .shutter > shutter_limit )
484
+ {
485
+ last .shutter = shutter_limit ;
486
+ }
473
487
}
474
488
}
475
489
@@ -497,18 +511,6 @@ static int lua_camera_auto(lua_State *L)
497
511
uint16_t shutter = (uint16_t )last .shutter ;
498
512
uint8_t gain = (uint8_t )last .gain ;
499
513
500
- // If shutter is longer than frame length (VTS register)
501
- if (shutter > 0x32A )
502
- {
503
- check_error (i2c_write (CAMERA , 0x380E , 0xFF , shutter >> 8 ).fail );
504
- check_error (i2c_write (CAMERA , 0x380F , 0xFF , shutter ).fail );
505
- }
506
- else
507
- {
508
- check_error (i2c_write (CAMERA , 0x380E , 0xFF , 0x03 ).fail );
509
- check_error (i2c_write (CAMERA , 0x380F , 0xFF , 0x22 ).fail );
510
- }
511
-
512
514
check_error (i2c_write (CAMERA , 0x3500 , 0x03 , shutter >> 12 ).fail );
513
515
check_error (i2c_write (CAMERA , 0x3501 , 0xFF , shutter >> 4 ).fail );
514
516
check_error (i2c_write (CAMERA , 0x3502 , 0xF0 , shutter << 4 ).fail );
@@ -599,18 +601,6 @@ static int lua_camera_set_shutter(lua_State *L)
599
601
return luaL_error (L , "shutter must be between 4 and 16383" );
600
602
}
601
603
602
- // If shutter is longer than frame length (VTS register)
603
- if (shutter > 0x32A )
604
- {
605
- check_error (i2c_write (CAMERA , 0x380E , 0xFF , shutter >> 8 ).fail );
606
- check_error (i2c_write (CAMERA , 0x380F , 0xFF , shutter ).fail );
607
- }
608
- else
609
- {
610
- check_error (i2c_write (CAMERA , 0x380E , 0xFF , 0x03 ).fail );
611
- check_error (i2c_write (CAMERA , 0x380F , 0xFF , 0x22 ).fail );
612
- }
613
-
614
604
check_error (i2c_write (CAMERA , 0x3500 , 0x03 , shutter >> 12 ).fail );
615
605
check_error (i2c_write (CAMERA , 0x3501 , 0xFF , shutter >> 4 ).fail );
616
606
check_error (i2c_write (CAMERA , 0x3502 , 0xF0 , shutter << 4 ).fail );
@@ -697,6 +687,32 @@ static int lua_camera_set_register(lua_State *L)
697
687
return 0 ;
698
688
}
699
689
690
+ static int lua_camera_get_register (lua_State * L )
691
+ {
692
+ if (nrf_gpio_pin_out_read (CAMERA_SLEEP_PIN ) == false)
693
+ {
694
+ luaL_error (L , "camera is asleep" );
695
+ }
696
+
697
+ lua_Integer address = luaL_checkinteger (L , 1 );
698
+
699
+ if (address < 0 || address > 0xFFFF )
700
+ {
701
+ luaL_error (L , "address must be a 16 bit unsigned number" );
702
+ }
703
+
704
+ i2c_response_t response = i2c_read (CAMERA , (uint16_t )address , 0xFF );
705
+
706
+ if (response .fail )
707
+ {
708
+ error ();
709
+ }
710
+
711
+ lua_pushinteger (L , response .value );
712
+
713
+ return 1 ;
714
+ }
715
+
700
716
void lua_open_camera_library (lua_State * L )
701
717
{
702
718
// Wake up camera in case it was asleep
@@ -740,6 +756,9 @@ void lua_open_camera_library(lua_State *L)
740
756
lua_pushcfunction (L , lua_camera_set_register );
741
757
lua_setfield (L , -2 , "set_register" );
742
758
759
+ lua_pushcfunction (L , lua_camera_get_register );
760
+ lua_setfield (L , -2 , "get_register" );
761
+
743
762
lua_setfield (L , -2 , "camera" );
744
763
745
764
lua_pop (L , 1 );
0 commit comments