-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathanalog_in_cyclo_converger3.ino
117 lines (86 loc) · 4.61 KB
/
analog_in_cyclo_converger3.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
// define the analog input pin
#define ANALOG_IN A0
// define the PWM output pin
#define PWM_OUT 9
// define the sampling frequency in Hz
#define SAMPLING_FREQ 1000
// define the buffer size proportional to the sampling frequency
#define BUFFER_SIZE SAMPLING_FREQ
// define the cyclotomic polynomial coefficients
#define CYCLO_DEGREE 16
const int cyclo_coef[CYCLO_DEGREE + 1] = {1, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 1};
// define the LFSR polynomials coefficients
#define LFSR_DEGREE 8
const int lfsr1_coef[LFSR_DEGREE + 1] = {1, 1, 0, 1, 1, 0, 0, 0, 1}; // x^8 + x^7 + x^4 + x^3 + x + 1
const int lfsr2_coef[LFSR_DEGREE + 1] = {1, 0, 1, 1, 0, 1, 0, 0, 1}; // x^8 + x^6 + x^5 + x^3 + x + 1
// declare the buffer array to store the input samples
int buffer[BUFFER_SIZE];
// declare the index variable to keep track of the buffer position
int index = 0;
// declare the timer variable to keep track of the sampling interval
unsigned long timer = 0;
// declare the function variable to store the function candidate
int function[LFSR_DEGREE * CYCLO_DEGREE];
// declare the error variable to store the error between the input and the function
long error = LONG_MAX;
// declare the lfsr variables to store the current state and output of the LFSRs
int lfsr1_state = random(256); // initialize with a random value
int lfsr2_state = random(256); // initialize with a random value
int lfsr1_out = lfsr1_state & 1; // get the least significant bit as output
int lfsr2_out = lfsr2_state & 1; // get the least significant bit as output
void setup() {
// set the PWM output pin as an output
pinMode(PWM_OUT, OUTPUT);
// initialize the timer variable with the current time in microseconds
timer = micros();
}
void loop() {
// check if the timer variable has reached the sampling interval in microseconds
if (micros() - timer >= (1000000 / SAMPLING_FREQ)) {
// read the analog input value and map it to a range of 0 to 255
int input = map(analogRead(ANALOG_IN), 0, 1023, 0, 255);
// store the input value in the buffer array at the current index position
buffer[index] = input;
// increment the index variable and wrap it around if it reaches the buffer size
index = (index + 1) % BUFFER_SIZE;
// reset the timer variable with the current time in microseconds
timer = micros();
// generate a new function candidate by multiplying two LFSR polynomials and evaluating them at the cyclotomic polynomial roots
// shift both LFSR states to the right by one bit and calculate the new least significant bit by XORing the previous state with the polynomial coefficients
int new_bit1 = ((lfsr1_state >> 7) & 1) ^ ((lfsr1_state >> 6) & 1) ^ ((lfsr1_state >> 3) & 1) ^ ((lfsr1_state >> 2) & 1) ^ (lfsr1_state & 1);
int new_bit2 = ((lfsr2_state >> 7) & 1) ^ ((lfsr2_state >> 6) & 1) ^ ((lfsr2_state >> 5) & 1) ^ ((lfsr2_state >> 3) & 1) ^ (lfsr2_state & 1);
// update the LFSR states with the new bits
lfsr1_state = (lfsr1_state >> 1) | (new_bit1 << 7);
lfsr2_state = (lfsr2_state >> 1) | (new_bit2 << 7);
// update the LFSR outputs by getting the new least significant bits
lfsr1_out = lfsr1_state & 1;
lfsr2_out = lfsr2_state & 1;
// multiply the two LFSR outputs and store them in a temporary variable
int temp = lfsr1_out * lfsr2_out;
// loop through the function array and update each element by multiplying it with the temporary variable and adding it to the previous element
for (int i = LFSR_DEGREE * CYCLO_DEGREE - 1; i > 0; i--) {
function[i] = function[i] * temp + function[i - 1];
}
function[0] = function[0] * temp;
// loop through the function array again and evaluate each element at the cyclotomic polynomial roots by substituting x with 2^i mod 256
for (int i = 0; i < LFSR_DEGREE * CYCLO_DEGREE; i++) {
int x = pow(2, i) % 256;
int y = 0;
for (int j = CYCLO_DEGREE; j >= 0; j--) {
y = y * x + cyclo_coef[j];
}
function[i] = function[i] * y;
}
// calculate the error between the input and the function by looping through the buffer array and subtracting each input value from the corresponding function value and squaring the difference
long new_error = 0;
for (int i = 0; i < BUFFER_SIZE; i++) {
int diff = buffer[i] - function[i];
new_error += diff * diff;
}
// if the new error is smaller than the previous error, update the error variable with the new error and output the corresponding function value to the PWM pin
if (new_error < error) {
error = new_error;
analogWrite(PWM_OUT, function[index]);
}
}
}