Import the arduino sketch for the random number generation

This commit is contained in:
Klemens Schölhorn 2017-10-28 21:14:30 +02:00
parent 6f7e173610
commit 795d87534f
6 changed files with 143 additions and 31 deletions

32
code/code.ino Normal file
View File

@ -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<uint8_t> 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);
}

12
code/debounce.h Normal file
View File

@ -0,0 +1,12 @@
enum class State : uint8_t {
Unpressed,
UnpressedDebounced,
Pressed,
PressedDebounced,
};
template<uint8_t DEBOUNCE_PRESSED, uint8_t DEBOUNCE_UNPRESSED = DEBOUNCE_PRESSED>
class Debounce {
};

14
code/lcg_rng.h Normal file
View File

@ -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;
}
};

47
code/segment.h Normal file
View File

@ -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<uint8_t PIN_SER, uint8_t PIN_SCLK, uint8_t PIN_RCLK>
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);
}
};

25
code/tests/rng.cpp Normal file
View File

@ -0,0 +1,25 @@
#include <iostream>
#include <cstdint>
#include <map>
#include "../lcg_rng.h"
#include "../uniform_int_dist.h"
int main() {
lcg_rng rng;
std::uniform_int_distribution<uint8_t> distribution(1,8);
std::map<uint8_t, size_t> 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;
}

View File

@ -31,15 +31,11 @@
#ifndef _GLIBCXX_BITS_UNIFORM_INT_DIST_H
#define _GLIBCXX_BITS_UNIFORM_INT_DIST_H
#include <type_traits>
#include <limits>
namespace std _GLIBCXX_VISIBILITY(default)
namespace std
{
namespace __detail
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/* Determine whether number is a power of 2. */
template<typename _Tp>
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<typename _IntType = int>
template<typename _IntType = uint8_t>
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<result_type>::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<result_type>::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 <bits/random.h>
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif