Recientemente lei un libro sobre números primos donde aparecía la llamada “Criba de Eratóstenes” para obtenerlos y se me ocurrió diseñar un montaje que los señalara utilizando su algoritmo más de 2000 años después. Aquí va el sencillo montaje y el código que puede ser de mayor interés. Aprovecho una esfera graduada por lo que solo se señalan los primos hasta el 360. La cantidad de números primos hasta 360 es de 72, por lo que podríamos esperar la aparición de un número primo por cada 5 números naturales (función de Gauss), cuando esto ocurre el piloto es verde, en caso contrario, rojo.

Video en acción
/* Programa que va indicando los numeros primos hasta 360
* en un dial circular a la vez que los presenta en el display.
* la vuelta entera son 200 x 8 = 1600 pasos (Driver en HHL)
* Aparecen los nos. 2,3,5,7,11,....349,353,359.
* La cantidad de nos. primos hasta 360 es de 72, por lo que
* podríamos esperar la aparición de un número primo por
* cada 5 números naturales (función de Gauss), cuando esto ocurre
* se enciende un led verde, en caso contrario uno rojo.
* JHG octubre 2016
*/
#include "MeOrion.h"
#include <SoftwareSerial.h>
#include <AccelStepper.h>
#include <Arduino.h>
#include <SoftwareSerial.h>
#include <Wire.h>
AccelStepper stepper(AccelStepper::DRIVER, 10, 11); // 10-PUL,11-DIR
// corresponde al PORT_1
Me7SegmentDisplay disp(PORT_6);
MeRGBLed led(PORT_7);
MeLightSensor luz(PORT_8);
int num =2; // el 1 no se considera primo.
int maximo =360;
int divisores;
int cont=0;
int pasos;
long tempo0, tempo1;
int pausa = 800;
int primo=2;
bool flag;
int value=0;
//===========================================================
void setup() {
Serial.begin(9600);
disp.set();
disp.init();
disp.set(BRIGHTNESS_3);
stepper.enableOutputs();
stepper.setMaxSpeed(5000);
stepper.setAcceleration(5500);
stepper.setCurrentPosition(0);
}
//===========================================================
void loop() {
espera_luz();
while (num <= maximo){
tempo1 = millis();
divisores =0;
for (int i=1; i<=int(sqrt(num)); i++){
if (num % i == 0) {divisores ++;}
}
if (divisores == 1) {//El numero solo es divisible por 1
if ((num-primo)>5) {
rojo();
flag = !flag;}
else {
verde();
flag = !flag;}
Serial.print (num);
Serial.println (", ");
disp.display(num);
tempo0 = millis();
primo =num;
pasos = int(4.44*num);
stepper.moveTo(-pasos); // cambiar
while (stepper.currentPosition() != -pasos)
//stepper.runToNewPosition(pasos);
{stepper.run();}
if (tempo1 - tempo0 < pausa) {
delay (pausa-(tempo1 - tempo0));
}
cont ++;
}
num =num +1;
}
Serial.println ("");
Serial.print ("Total= ");
Serial.println (cont);
delay(3000);
stepper.moveTo(-1600); // para cerrar el circulo y quedar en la posición inicial
while (stepper.currentPosition() != -1600)
{stepper.run();}
disp.display(0);
led.setColorAt(0, 0,0,100);
led.setColorAt(2, 0,0,100);
led.setColorAt(1, 0,0,0);
led.setColorAt(3, 0,0,0);
led.show();
stepper.disableOutputs();
}
//=================================
void espera_luz(){
value = luz.read();
while (value<960) { // espera a ser iluminado
value = luz.read();
delay(100);
}
}
void rojo(){
if (flag == true){
led.setColorAt(3, 0,0,0);
led.setColorAt(1, 200,0,0);// piloto rojo de encendido
}
else {
led.setColorAt(3, 200,0,0);
led.setColorAt(1, 0,0,0);
}
led.show();
}
void verde(){
if (flag == true){
led.setColorAt(1, 0,0,0);
led.setColorAt(3, 0,100,0);// piloto verde encendido
}
else{
led.setColorAt(1, 0,100,0);
led.setColorAt(3, 0,0,0);
}
led.show();
}

Recientemente lei un libro sobre números primos donde aparecía la llamada “Criba de Eratóstenes” para obtenerlos y se me ocurrió diseñar un montaje que los señalara utilizando su algoritmo más de 2000 años después. Aquí va el sencillo montaje y el código que puede ser de mayor interés. Aprovecho una esfera graduada por lo que solo se señalan los primos hasta el 360. La cantidad de números primos hasta 360 es de 72, por lo que podríamos esperar la aparición de un número primo por cada 5 números naturales (función de Gauss), cuando esto ocurre el piloto es verde, en caso contrario, rojo.

[Video en acción](https://vimeo.com/187307273 "Vimeo")
--
````
/* Programa que va indicando los numeros primos hasta 360
* en un dial circular a la vez que los presenta en el display.
* la vuelta entera son 200 x 8 = 1600 pasos (Driver en HHL)
* Aparecen los nos. 2,3,5,7,11,....349,353,359.
* La cantidad de nos. primos hasta 360 es de 72, por lo que
* podríamos esperar la aparición de un número primo por
* cada 5 números naturales (función de Gauss), cuando esto ocurre
* se enciende un led verde, en caso contrario uno rojo.
* JHG octubre 2016
*/
#include "MeOrion.h"
#include <SoftwareSerial.h>
#include <AccelStepper.h>
#include <Arduino.h>
#include <SoftwareSerial.h>
#include <Wire.h>
AccelStepper stepper(AccelStepper::DRIVER, 10, 11); // 10-PUL,11-DIR
// corresponde al PORT_1
Me7SegmentDisplay disp(PORT_6);
MeRGBLed led(PORT_7);
MeLightSensor luz(PORT_8);
int num =2; // el 1 no se considera primo.
int maximo =360;
int divisores;
int cont=0;
int pasos;
long tempo0, tempo1;
int pausa = 800;
int primo=2;
bool flag;
int value=0;
//===========================================================
void setup() {
Serial.begin(9600);
disp.set();
disp.init();
disp.set(BRIGHTNESS_3);
stepper.enableOutputs();
stepper.setMaxSpeed(5000);
stepper.setAcceleration(5500);
stepper.setCurrentPosition(0);
}
//===========================================================
void loop() {
espera_luz();
while (num <= maximo){
tempo1 = millis();
divisores =0;
for (int i=1; i<=int(sqrt(num)); i++){
if (num % i == 0) {divisores ++;}
}
if (divisores == 1) {//El numero solo es divisible por 1
if ((num-primo)>5) {
rojo();
flag = !flag;}
else {
verde();
flag = !flag;}
Serial.print (num);
Serial.println (", ");
disp.display(num);
tempo0 = millis();
primo =num;
pasos = int(4.44*num);
stepper.moveTo(-pasos); // cambiar
while (stepper.currentPosition() != -pasos)
//stepper.runToNewPosition(pasos);
{stepper.run();}
if (tempo1 - tempo0 < pausa) {
delay (pausa-(tempo1 - tempo0));
}
cont ++;
}
num =num +1;
}
Serial.println ("");
Serial.print ("Total= ");
Serial.println (cont);
delay(3000);
stepper.moveTo(-1600); // para cerrar el circulo y quedar en la posición inicial
while (stepper.currentPosition() != -1600)
{stepper.run();}
disp.display(0);
led.setColorAt(0, 0,0,100);
led.setColorAt(2, 0,0,100);
led.setColorAt(1, 0,0,0);
led.setColorAt(3, 0,0,0);
led.show();
stepper.disableOutputs();
}
//=================================
void espera_luz(){
value = luz.read();
while (value<960) { // espera a ser iluminado
value = luz.read();
delay(100);
}
}
void rojo(){
if (flag == true){
led.setColorAt(3, 0,0,0);
led.setColorAt(1, 200,0,0);// piloto rojo de encendido
}
else {
led.setColorAt(3, 200,0,0);
led.setColorAt(1, 0,0,0);
}
led.show();
}
void verde(){
if (flag == true){
led.setColorAt(1, 0,0,0);
led.setColorAt(3, 0,100,0);// piloto verde encendido
}
else{
led.setColorAt(1, 0,100,0);
led.setColorAt(3, 0,0,0);
}
led.show();
}````

editado 14 Oct '16 a las 1:08 pm