diff --git a/code/code.ino b/code/code.ino new file mode 100644 index 0000000..1178d19 --- /dev/null +++ b/code/code.ino @@ -0,0 +1,32 @@ +// Conflicts with std c++ headers +#undef min +#undef max + +#include "debounce.h" +#include "lcg_rng.h" +#include "segment.h" +#include "uniform_int_dist.h" + + +#define PIN1 1 + +lcg_rng rng; +std::uniform_int_distribution distribution(1,16); + +SegmentDisplay<4, 2, 0> display; + +void setup() { + pinMode(PIN1, INPUT_PULLUP); + pinMode(3, OUTPUT); + digitalWrite(3, 0); + digitalWrite(0, 0); +} + +void loop() { + if(!digitalRead(PIN1)) { + display.set(distribution(rng)); + display.write(); + } + delay(16); +} + diff --git a/code/debounce.h b/code/debounce.h new file mode 100644 index 0000000..857860f --- /dev/null +++ b/code/debounce.h @@ -0,0 +1,12 @@ +enum class State : uint8_t { + Unpressed, + UnpressedDebounced, + Pressed, + PressedDebounced, +}; + +template +class Debounce { + +}; + diff --git a/code/lcg_rng.h b/code/lcg_rng.h new file mode 100644 index 0000000..48d0315 --- /dev/null +++ b/code/lcg_rng.h @@ -0,0 +1,14 @@ +#undef min +#undef max + +class lcg_rng { + uint8_t x = 33, a = 69, c = 85; + + public: + uint8_t min() const { return 0; } + uint8_t max() const { return 255; } + uint8_t operator()() { + x = a * x + c; + return x; + } +}; diff --git a/code/segment.h b/code/segment.h new file mode 100644 index 0000000..7114b72 --- /dev/null +++ b/code/segment.h @@ -0,0 +1,47 @@ +const static PROGMEM uint8_t DECODER[] = { + 0b10000001, // 0 + 0b11001111, // 1 + 0b10010010, // 2 + 0b10000110, // 3 + 0b11001100, // 4 + 0b10100100, // 5 + 0b10100000, // 6 + 0b10001111, // 7 + 0b10000000, // 8 + 0b10000100, // 9 + 0b11111111, // off + 0b11111110, // - +}; + +template +class SegmentDisplay { + uint8_t number[2]; + +public: + SegmentDisplay() { + pinMode(PIN_SER, OUTPUT); + pinMode(PIN_SCLK, OUTPUT); + pinMode(PIN_RCLK, OUTPUT); + setOff(); + } + + void set(uint8_t number) { + uint8_t num = constrain(number, 0, 99); + this->number[0] = pgm_read_byte_near(DECODER + num % 10); + this->number[1] = pgm_read_byte_near(DECODER + num / 10); + } + + void setOff() { + number[0] = 0xFF; + number[1] = 0xFF; + } + + void write() { + shiftOut(PIN_SER, PIN_SCLK, LSBFIRST, number[0]); + shiftOut(PIN_SER, PIN_SCLK, LSBFIRST, number[1]); + digitalWrite(PIN_RCLK, HIGH); + delay(1); + digitalWrite(PIN_RCLK, LOW); + } +}; + diff --git a/code/tests/rng.cpp b/code/tests/rng.cpp new file mode 100644 index 0000000..bf383ee --- /dev/null +++ b/code/tests/rng.cpp @@ -0,0 +1,25 @@ +#include +#include +#include + +#include "../lcg_rng.h" +#include "../uniform_int_dist.h" + + +int main() { + lcg_rng rng; + std::uniform_int_distribution distribution(1,8); + + std::map map; + for(int i=0;i<=25500000;++i) { + uint8_t x = distribution(rng); + map[x] += 1; + //std::cout << (int) x << std::endl; + } + + for(auto x : map) { + std::cout << (int) x.first << ", " << x.second << std::endl; + } + + return 0; +} diff --git a/code/uniform_int_dist.h b/code/uniform_int_dist.h index af7ac14..b9755c7 100644 --- a/code/uniform_int_dist.h +++ b/code/uniform_int_dist.h @@ -31,15 +31,11 @@ #ifndef _GLIBCXX_BITS_UNIFORM_INT_DIST_H #define _GLIBCXX_BITS_UNIFORM_INT_DIST_H -#include -#include - -namespace std _GLIBCXX_VISIBILITY(default) +namespace std { namespace __detail { -_GLIBCXX_BEGIN_NAMESPACE_VERSION /* Determine whether number is a power of 2. */ template inline bool @@ -47,21 +43,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return ((__x - 1) & __x) == 0; }; -_GLIBCXX_END_NAMESPACE_VERSION } -_GLIBCXX_BEGIN_NAMESPACE_VERSION - /** * @brief Uniform discrete distribution for random numbers. * A discrete random distribution on the range @f$[min, max]@f$ with equal * probability throughout the range. */ - template + template class uniform_int_distribution { - static_assert(std::is_integral<_IntType>::value, - "template argument must be an integral type"); public: /** The type of the range of the distribution. */ @@ -72,12 +63,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef uniform_int_distribution<_IntType> distribution_type; explicit - param_type(_IntType __a = 0, - _IntType __b = std::numeric_limits<_IntType>::max()) + param_type(_IntType __a, + _IntType __b) : _M_a(__a), _M_b(__b) - { - __glibcxx_assert(_M_a <= _M_b); - } + {} result_type a() const @@ -105,8 +94,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @brief Constructs a uniform distribution object. */ explicit - uniform_int_distribution(_IntType __a = 0, - _IntType __b = std::numeric_limits<_IntType>::max()) + uniform_int_distribution(_IntType __a, + _IntType __b) : _M_param(__a, __b) { } @@ -222,11 +211,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION operator()(_UniformRandomNumberGenerator& __urng, const param_type& __param) { - typedef typename _UniformRandomNumberGenerator::result_type - _Gresult_type; - typedef typename std::make_unsigned::type __utype; - typedef typename std::common_type<_Gresult_type, __utype>::type - __uctype; + typedef uint8_t _Gresult_type; + typedef uint8_t __utype; + typedef uint8_t __uctype; const __uctype __urngmin = __urng.min(); const __uctype __urngmax = __urng.max(); @@ -290,12 +277,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _UniformRandomNumberGenerator& __urng, const param_type& __param) { - __glibcxx_function_requires(_ForwardIteratorConcept<_ForwardIterator>) - typedef typename _UniformRandomNumberGenerator::result_type - _Gresult_type; - typedef typename std::make_unsigned::type __utype; - typedef typename std::common_type<_Gresult_type, __utype>::type - __uctype; + typedef uint8_t _Gresult_type; + typedef uint8_t __utype; + typedef uint8_t __uctype; const __uctype __urngmin = __urng.min(); const __uctype __urngmax = __urng.max(); @@ -368,8 +352,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } // operator!= and operator<< and operator>> are defined in - -_GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif