3D printed Arduino Airsoft Chronograph
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ticks.cpp 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /*
  2. * ticks.cpp
  3. *
  4. * OpenChrono BB speed measurement device.
  5. *
  6. * Copyright (c) 2022 Thomas Buck <thomas@xythobuz.de>
  7. *
  8. * Some notes about time calculations:
  9. * We have Timer1 running with 16MHz
  10. * which gives us a tick period of 62.5ns.
  11. *
  12. * The distance of the sensors is given in mm
  13. * in SENSOR_DISTANCE (eg. 70mm).
  14. *
  15. * period_in_s = 1 / F_CPU
  16. * period_in_s = 62.5 / 1000 / 1000 / 1000;
  17. * dist_in_m = SENSOR_DISTANCE * 0.1 * 0.01
  18. * travel_time_in_s = ticks * period_in_s;
  19. * speed = dist_in_m / travel_time_in_s;
  20. *
  21. * period_in_s = 0.0000000625
  22. * dist_in_m = 0.07m
  23. * ticks = 2000
  24. * travel_time_in_s = 0.000125
  25. * speed = 560 m/s
  26. *
  27. * speed = (SENSOR_DISTANCE / 1000) / (ticks * 62.5 / 1000 / 1000 / 1000)
  28. * speed = SENSOR_DISTANCE / (ticks * 62.5 / 1000 / 1000)
  29. * speed = SENSOR_DISTANCE / (ticks * 1000 / F_CPU)
  30. *
  31. * Because we can at max measure 0xFFFF ticks
  32. * this gives us a slowest speed we can measure.
  33. * 0xFFFF = 65535 ticks
  34. * speed = SENSOR_DISTANCE / (65535 * 1000 / F_CPU)
  35. * so we can measure from 17m/s (61km/h, approx. 0.03J @ 0.2g)
  36. * up to ridulous 1120000m/s (4032000km/h)
  37. *
  38. * with a prescaler of 8, we can measure from 2.14m/s to 140000m/s
  39. * with a prescaler of 64, we can measure from 0.27m/s to 17500m/s
  40. */
  41. #include <Arduino.h>
  42. #include "ticks.h"
  43. #include "config.h"
  44. uint16_t tick_history[HISTORY_BUFFER] = DEBUG_TICK_DATA;
  45. uint8_t tick_count = DEBUG_TICK_COUNT;
  46. void tick_new_value(uint16_t ticks) {
  47. // store new value in history buffer
  48. if (tick_count < HISTORY_BUFFER) {
  49. tick_history[tick_count] = ticks;
  50. tick_count++;
  51. } else {
  52. for (uint8_t i = 0; i < HISTORY_BUFFER - 1; i++) {
  53. tick_history[i] = tick_history[i + 1];
  54. }
  55. tick_history[HISTORY_BUFFER - 1] = ticks;
  56. }
  57. }
  58. uint16_t tick_average() {
  59. if (tick_count == 0) {
  60. return 0;
  61. }
  62. uint64_t sum = 0;
  63. for (uint8_t i = 0; i < tick_count; i++) {
  64. sum += tick_history[i];
  65. }
  66. sum /= (uint64_t)tick_count;
  67. return (uint16_t)sum;
  68. }
  69. uint16_t tick_max() {
  70. if (tick_count == 0) {
  71. return 0;
  72. }
  73. uint16_t cmp = 0;
  74. for (uint8_t i = 0; i < tick_count; i++) {
  75. if (tick_history[i] > cmp) {
  76. cmp = tick_history[i];
  77. }
  78. }
  79. return cmp;
  80. }
  81. uint16_t tick_min() {
  82. if (tick_count == 0) {
  83. return 0;
  84. }
  85. uint16_t cmp = 0xFFFF;
  86. for (uint8_t i = 0; i < tick_count; i++) {
  87. if (tick_history[i] < cmp) {
  88. cmp = tick_history[i];
  89. }
  90. }
  91. return cmp;
  92. }
  93. double tick_to_metric(uint16_t ticks) {
  94. // v = d / t
  95. double period = 1000.0 / ((double)(F_CPU / TIMER_PRESCALER));
  96. double time = period * (double)ticks;
  97. double speed = (double)SENSOR_DISTANCE / time;
  98. return speed;
  99. }
  100. double metric_to_imperial(double speed) {
  101. // convert m/s to f/s
  102. speed *= 3.28084;
  103. return speed;
  104. }
  105. double metric_to_joules(double speed, double mass) {
  106. // e = 0.5 * m * v^2
  107. double energy = 0.5 * mass * speed * speed / 1000.0;
  108. return energy;
  109. }