-
Notifications
You must be signed in to change notification settings - Fork 0
/
arduino_random_gen.ino
130 lines (110 loc) · 3.18 KB
/
arduino_random_gen.ino
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
const int analogPin = 4;
long millisec,contat;
const bool fastADC=true;//http://forum.arduino.cc/index.php?topic=6549.0
const bool printPerformances=true;//Every 10Kbits,I print the time
const bool outputASCII=true;//true->output with '0' '1' ASCII characters,otherwise pure binary oupput
// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
void setup() {
Serial.begin(115200);
//pinMode(5,INPUT);
//analogReference(EXTERNAL);
pinMode(A4,INPUT);
millisec=millis();
if(fastADC){
// set prescale to 16
sbi(ADCSRA,ADPS2) ;
cbi(ADCSRA,ADPS1) ;
cbi(ADCSRA,ADPS0) ;
}
}
void loop() {
// put your main code here, to run repeatedly:
//Serial.print(digitalRead(5));
//Serial.println(analogRead(analogPin));
//while(1){
int val1,val2;
delayMicroseconds(3);
val1=getInt();
delayMicroseconds(2);
val2=getInt();
/*
* Usually lower bits has an higher variancy. At the same time, I don't want to waste completly highest bits, so I've merged two nibbles using xor
*/
val1=(val1>>4)^(val1&15);
val2=(val2>>4)^(val2&15);
int xo=val1^val2;//there are variation across two reads
xo=xo&255;
if(xo>0 && !( (val1&256)^(val2&512))){//Insteadd of completly throw away the two highest bits,I use the to flip the outcome
int temp=val1;//a NOT over val1 would be sufficient
val1=val2;
val2=temp;
}
//if(xo){Serial.print(xo);Serial.print(" ");Serial.println(val1&15);contat++;}
while(xo>0){//I print bits which differ across two reads
if(xo&1){
if(outputASCII){
Serial.print(val1&1);
}else{
writeBitToBuffer(val1&1);
}
contat++;
}
xo>>=1;
val1>>=1;
}
if(!outputASCII){ eventuallySendBuffer();}
if(printPerformances){
if(contat>=10000){
Serial.println("");
Serial.print(contat);
Serial.print(" ");
Serial.println(millis()-millisec);
millisec=millis();
contat=0;
}
}
/*
It increases a bit the noise. Is mandatory to test if this trick compromises the quality of randomness
*/
analogWrite(9, (contat%16)*16);
//}
}
const int lenBuffer=32;
byte bufferSend[lenBuffer+2];
int bufferIndex=0;
void writeBitToBuffer(char _bit){
_bit&=1;
int offsBit=bufferIndex&7;//I get the bit position inside the byte
int offsByte=bufferIndex>>3;//I get the n° of the byte
bitWrite(bufferSend[offsByte],offsBit,_bit);
bufferIndex++;
}
void eventuallySendBuffer(){
const int threeshold=(lenBuffer-2)*8;
if((bufferIndex>=threeshold && ((bufferIndex&7)==0))||(bufferIndex>=lenBuffer*8)){
Serial.write(bufferSend,bufferIndex>>3);//I send the buffer.if there are more than lenBuffer*8 bits,I simply discard addiitonal bits
bufferIndex=0;
}
}
/*inline byte getInt(){
int val;
do{
val=analogRead(analogPin)>>1;
}while(val>=385 ||val<=127);
//return val;
return val-128;
}*/
inline int getInt(){
int val;
do{
val=analogRead(analogPin);
}while(val>=1020 ||val<=3);
// return val;
return val-4;
}