-
Notifications
You must be signed in to change notification settings - Fork 37
/
UNO_Prime_Integer_32MHz.ino
129 lines (108 loc) · 3.2 KB
/
UNO_Prime_Integer_32MHz.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
/*
* This sketch is for the 32MHz version of the LGT8F328P (ATMEGA328P upgrade)
*
* It should calculate 10,000 prime numbers in 59 seconds. If it takes longer the setup for
* the board is not correct.
*
* See https://github.com/RalphBacon/LGT8F328P-Arduino-Clone-Chip-ATMega328P
*/
// Must include this to be able change the prescaler frequency
#include <avr/power.h>
long start = 0;
long max_primes = 10000;
long i = 2; // Start at 2
long found = 0; // Number of primes we've found
long lastPrime = 0;
long lastfound = found;
//#define DISPLAY_OUTPUT 1
void setup() {
// This runs MCU at full speed. See comment below.
clock_prescale_set(clock_div_1);
// Wait for serial to initialise
Serial.begin(9600);
while (!Serial) { }
// In case the serial output is corrupt let's beep the start
pinMode(PE5, OUTPUT);
beep(2);
// the MCU Frequency is described in ~\Arduino Sketches\hardware\LGT\avr\boards.txt
// on this line: lardu_328x.build.f_cpu=32000000L
Serial.print("F_CPU value: "); Serial.println(F_CPU);
Serial.print("Clock cycles per µsecond: "); Serial.println(clockCyclesPerMicrosecond());
uint32_t guid = *(uint32_t*)&GUID0 ;
Serial.print("GUID of this device: "); Serial.println(guid, HEX);
// Go!
Serial.println("Prime calculation starting.");
#ifdef DISPLAY_OUTPUT
Serial.print("0: ");
#endif
start = millis();
}
void loop() {
int prime = is_prime(i); // Check if the number we're on is prime
if (prime == 1) {
#ifdef DISPLAY_OUTPUT
Serial.print(i); Serial.print(" ");
#endif
lastPrime = i;
found++;
}
int running_seconds = (millis() - start) / 1000;
if (found >= max_primes) {
Serial.print("\nFound ");
Serial.print(found);
Serial.print(" primes in ");
Serial.print(running_seconds);
Serial.println(" seconds");
Serial.print("Highest prime found was: ");
Serial.println(lastPrime);
//beep(3);
delay(60000);
i = 2;
found = 0;
lastPrime = 0;
Serial.println("Prime calculation starting (again)");
start = millis();
}
else {
i++;
#ifdef DISPLAY_OUTPUT
if (found != lastfound && found % 10 == 0) {
Serial.println(""); Serial.print(found); Serial.print(": ");
lastfound = found;
}
#endif
}
}
int is_prime(long num) {
// Only have to check for divisible for the sqrt(number)
int upper = sqrt(num);
// Check if the number is evenly divisible (start at 2 going up)
for (long cnum = 2; cnum <= upper; cnum++) {
long mod = num % cnum; // Remainder
if (mod == 0) {
return 0;
} // If the remainder is 0 it's evenly divisible
}
return 1; // If you get this far it's prime
}
void beep(int count) {
for (auto cnt = 0; cnt < count; cnt++) {
digitalWrite(D5, HIGH);
delay(200);
digitalWrite(D5, LOW);
delay(200);
}
}
// Delay: count 1000 milliseconds and decrement amount of time (in ms) to wait
//void delay(double ms)
//{
// uint32_t start = micros();
//
// while (ms > 0) {
// yield();
// while ( ms > 0 && (micros() - start) >= 1000) {
// ms--;
// start += 1000;
// }
// }
//}