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 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  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. #include <Arduino.h>
  39. #include "ticks.h"
  40. #include "config.h"
  41. uint16_t tick_history[HISTORY_BUFFER] = DEBUG_TICK_DATA;
  42. uint8_t tick_count = DEBUG_TICK_COUNT;
  43. void tick_new_value(uint16_t ticks) {
  44. // store new value in history buffer
  45. if (tick_count < HISTORY_BUFFER) {
  46. tick_history[tick_count] = ticks;
  47. tick_count++;
  48. } else {
  49. for (uint8_t i = 0; i < HISTORY_BUFFER - 1; i++) {
  50. tick_history[i] = tick_history[i + 1];
  51. }
  52. tick_history[HISTORY_BUFFER - 1] = ticks;
  53. }
  54. }
  55. uint16_t tick_average() {
  56. if (tick_count == 0) {
  57. return 0;
  58. }
  59. uint64_t sum = 0;
  60. for (uint8_t i = 0; i < tick_count; i++) {
  61. sum += tick_history[i];
  62. }
  63. sum /= (uint64_t)tick_count;
  64. return (uint16_t)sum;
  65. }
  66. uint16_t tick_max() {
  67. if (tick_count == 0) {
  68. return 0;
  69. }
  70. uint16_t cmp = 0;
  71. for (uint8_t i = 0; i < tick_count; i++) {
  72. if (tick_history[i] > cmp) {
  73. cmp = tick_history[i];
  74. }
  75. }
  76. return cmp;
  77. }
  78. uint16_t tick_min() {
  79. if (tick_count == 0) {
  80. return 0;
  81. }
  82. uint16_t cmp = 0xFFFF;
  83. for (uint8_t i = 0; i < tick_count; i++) {
  84. if (tick_history[i] < cmp) {
  85. cmp = tick_history[i];
  86. }
  87. }
  88. return cmp;
  89. }
  90. double tick_to_metric(uint16_t ticks) {
  91. // v = d / t
  92. double period = 1000.0 / ((double)(F_CPU));
  93. double time = period * (double)ticks;
  94. double speed = (double)SENSOR_DISTANCE / time;
  95. return speed;
  96. }
  97. double metric_to_imperial(double speed) {
  98. // convert m/s to f/s
  99. speed *= 3.28084;
  100. return speed;
  101. }
  102. double metric_to_joules(double speed, double mass) {
  103. // e = 0.5 * m * v^2
  104. double energy = 0.5 * mass * speed * speed / 1000.0;
  105. return energy;
  106. }