Processing-Software für den Zufallsgenerator
Programm-Bedienung und Princeton-Experiment
Wichtiger Hinweis zum "Download der folgenden Software":
Das folgende Listing kann direkt per Copy and Paste in einen geöffneten Processing (2) Editor kopiert werden und ist danach sofort lauffähig, wenn ein Arduino-Uno mit der auf der nächsten Seite vorgestellten Software an den PC angeschlossen ist und die im Gerätemanager angegebene Portnummer in der ersten Zeile der setup-Funktion eingetragen ist:
Beispiel:
serport = new Serial(this, "COM4", 115200);
Die durcheinander geratenen ###-Zeichen der Kommentare müssen nicht geändert werden, da sie nach dem Kopieren in den Editor automatisch wieder an der richtigen Stelle sitzen.
Ab hier bitte kopieren --->
//programmed by kurt diedrich
//Nov. 2016
import processing.serial.*;
int[] array1 = new int[50000]; // mode 1
int[] array2 = new int[50000]; // mode 2
int[] array3 = new int[50000]; // Memory for a loaded file
byte[] container = new byte [4]; //int to byte
byte [] array6 = new byte[100000];
int x_max = 1050; // Total screen size
int y_max = 800; // Total screen size
Serial serport; // Getting Arduiono-Values
int linefeed = 10; // Getting Arduiono-Values
float valFloat; // Getting Arduiono-Values
float valnoise; // Integer value of the sampled values of Arduino
int mousedown; // Mouse operation
int x_pos = 0; // x-Position in upper Window
int x; // Draw Grid-Lines
int y; // Draw Grid-Lines
float val_princeton; // Values calculated from Random curve (mode 1)
float val2_princeton; // Values calculated from Random curve (mode 1)
float limit = 153; // Horizontal line to separate positive from negative values
int endwert; // Scaled version of Princetonw values displayed in diagram // mode 1
int endwert2; // Scaled version of Princetonw values displayed in diagram // mode 2
int x_pr; // X-Position in lower window
int x_save; // Array-Pointer for saving Princeton data
int savecntr; // Determines the time intervalls that a file will be autosaved
int savetime = 180; // File will be saved regulary each 10 * savetime seconds. Default = 180 = 1800 seconds = 30 minutes
int cnt_screen; // selecting the right "array-page" to display array values in princeton window
int divider = 32; // Dividing val_princeton values to fit in lower window
int divider2 = 64; // Dividing val_princeton values to fit in lower window
int n; // general for-next loop-counter
int m; // general for-next loop-counter
int i; // general for-next loop-counter
int ee; // Changes Byte to int in function Lade
int zz; // Changes Byte to int in function Lade
int filestop; // Function Lade
int filelength; // Function Lade
int y1; // amplitude first princeton curve
int y2; // amplitude second princeton curve
int stop; // End of program;
int aktuell=1; // flag to display current data or loaded data
int page; // page counter for looking at looaded file
int xx; // Compressed reading of saved file
int zoomfaktor = 10; // Compress factor
String filename; // = "2016_03_28_21-34_noise.dat";
// Data to create filename
String Jahr; String Monat; String Tag; String Stunde; String Endstunde; String Minute;
String Endminute; String Datumstart; String Datumstop;
String Akt_stunde; String Akt_min;
// ##################################################################
// ###### ######
// ###### To do one time before the program starts ######
// ###### ######
// ##################################################################
void setup ()
{
serport = new Serial(this, "COM4", 115200); // Enter individual port number
background(40,65,80);
size(x_max, y_max);
fill(60,90,120); rect(525,18,220,305);
// Draw graphic windows ############################################
// Draw Time Signal Window
fill(0,0,0);
rect(20,20,500,300); // Print time signal window
draw_grid();
// Draw Princeton Window
fill(0,0,0); stroke(255,255,255);
rect(20,340,1000,401); // Print time signal window
draw_princeton_grid();
// Draw Textboxes ##################################################
// TextBox for Princeton Values
// Mode 1 (left window)
stroke(0,0,0);
fill (255,255,255); rect(580,25,40,20);
// Mode 2 (right window)
rect(640,25,40,20);
// TextBox for limit display (Calibration)
// TextBox for limit value (y-position of horizontal
//line in upper graphics window)
rect(580,50,100,20);
fill(0,0,0); text(limit, 582,64);
// TextBox for divider value
fill (255,255,255); rect(580,80,100,20);
fill(0,0,0); text(divider, 582,94);
// TextBox for divider2 value
fill (255,255,255); rect(580,110,100,20);
fill(0,0,0); text(divider2, 582,124);
// TextBox for page value
fill (255,255,255); rect(580,220,100,20);
fill(0,0,0); text(page, 583,234);
// TextBox for zoomfactor
fill (255,255,255); rect(580,280,100,20);
fill(0,0,0); text(zoomfaktor, 583,294);
fill (255,255,255); rect(900,300,100,20);
fill(0,0,0) ; text (mouseX,902,314 ); text(mouseY,940,314 );
// Writing on user interface Background ##################################
fill(255,255,255);
text("Calibration (limit value for Mode 1)", 750,64);
text("Actual princeton value - Mode 1 / Mode 2", 750,34);
text("Divider value Mode 1 ", 750,94);
text("Divider value Mode 2 ", 750,124);
text("page up/down in loaded file", 750,234);
text("zoomfactor for file overview ", 750,294);
text("Mouse coordinates x, y", 750,314);
// Draw Buttons ############################################################
fill(170,170,140);
rect(530,50,40,20); rect(690,50,40,20); // Limit value
rect(530,80,40,20); rect(690,80,40,20); // Divider value
rect(530,110,40,20); rect(690,110,40,20); // Divider2 value
rect(530,135,200,20); // Load File
rect(530,165,200,20); // Actual Data or loaded file
rect(530,195,200,20); // Actual Data or loaded file
rect(530,220,40,20); rect(690,220,40,20); // page
rect(530,250,200,20); // View loaded file / Compressed mode
rect(530,280,40,20); rect(690,280,40,20); // zoomfactor
fill(0,60,0); rect(710,195,20,20); // Signal LEDs to display activated Button: actual data
fill(0,255,0); rect(710,165,20,20); // Signal LEDs to display activated Button: loaded file
fill(0,0,0);
text("<",548,64);
text(">",708,64);
text("<",548,94);
text(">",708,94);
text("<",548,124);
text(">",708,124);
text("<",548,234);
text(">",708,234);
text("<",548,294);
text(">",708,294);
text(" LOAD FILE ", 590, 149);
text(" Display current Data ", 575, 179);
text(" Display loaded file ", 575, 209);
text(" Loaded file overview ", 575,264);
fill(255,255,255);
text("30",200,760);
text("60",382,760);
text("90",560,760);
text("120",740,760);
text("120",740,760);
text("150",920,760);
// Find time and date ##################################################
int d = day(); // Values from 1 - 31
int mo = month(); // Values from 1 - 12
int y = year(); // 2003, 2004, 2005, etc.
int h = hour();
int mi = minute();
Jahr = String.valueOf(y);
Monat = String.valueOf(mo);
Tag = String.valueOf(d);
Stunde = String.valueOf(h);
Minute = String.valueOf(mi);
// Vorstehende Nullen einsetzen
if(d < 10) {Tag = "0" + Tag;}
if(mo < 10) {Monat = "0" + Monat;}
if(h < 10) {Stunde = "0" + Stunde;}
if(mi < 10) {Minute = "0" + Minute;}
Datumstart = (Jahr +"_" + Monat + "_" + Tag + "_" + Stunde + "-" + Minute);
}
// What happens if the mouse gets released #######################################
void mouseReleased()
{
mousedown=0;
}
// Same as "mousePressed" but calling the fileselect Box only works with this ####
void mouseClicked()
{
// File Select Function only works if called from this function: Clicking on LOAD button
if ((mouseX> 530) & (mouseX<730) & (mouseY >135) & (mouseY < 155))
{
selectInput("Select a file to process:", "fileSelected");
}
}
void draw()
{
// ###########################################################################
// ###### ######
// ###### Endless loop for mouse control ######
// ###### ######
// ###########################################################################
if (mousePressed)
{ stroke(0,0,0);
// TextBox for mouse coordinates
fill (255,255,255); rect(900,300,100,20);
fill(0,0,0) ; text (mouseX,902,314 ); text(mouseY,940,314 );
// ##########################################################################
// ###### Check Buttons ######
// ##########################################################################
// Lower Limit
if ((mouseX > 530) & (mouseX <570) & (mouseY >50) & (mouseY <70))
{
if (mousedown==0)
{
limit=limit-0.1; if (limit<100) {limit = 100;}
// TextBox for limit display (Calibration)
stroke(0,0,0);
fill (255,255,255); rect(580,50,100,20);
fill(0,0,0); text(limit, 582,64);
fill(0,0,0);
rect(20,20,500,300); // Print time signal window
draw_grid();
mousedown=1;
}
}
// Higher Limit
if ((mouseX > 690) & (mouseX <730) & (mouseY >50) & (mouseY <70))
{
if (mousedown==0)
{
limit=limit+0.1; if (limit>200) {limit = 200;}
// TextBox for limit display (Calibration)
stroke(0,0,0);
fill (255,255,255); rect(580,50,100,20);
fill(0,0,0); text(limit, 582,64);
fill(0,0,0);
rect(20,20,500,300); // Print time signal window
draw_grid();
mousedown=1;
}
}
// Divider down
if ((mouseX > 530) & (mouseX <570) & (mouseY >80) & (mouseY <100))
{
if (mousedown==0)
{
divider = divider/2; if (divider<2) {divider=2;}
// TextBox for limit display (Calibration)
stroke(0,0,0);
fill (255,255,255); rect(580,80,100,20);
fill(0,0,0); text(divider, 582,94);
if (aktuell==1) {auslese();}
if (aktuell==0) {display_loaded_file();}
mousedown=1;
}
}
// Divider up
if ((mouseX > 690) & (mouseX <730) & (mouseY >80) & (mouseY <100))
{
if (mousedown==0)
{
divider = divider*2; if (divider>128) {divider=128;}
// TextBox for limit display (Calibration)
stroke(0,0,0);
fill (255,255,255); rect(580,80,100,20);
fill(0,0,0); text(divider, 582,94);
if (aktuell==1) {auslese();}
if (aktuell==0) {display_loaded_file();}
mousedown=1;
}
}
// Divider2 down
if ((mouseX > 530) & (mouseX <570) & (mouseY >110) & (mouseY <130))
{
if (mousedown==0)
{
divider2 = divider2/2; if (divider2<2) {divider2=2;}
// TextBox for limit display (Calibration)
stroke(0,0,0);
fill (255,255,255); rect(580,110,100,20);
fill(0,0,0); text(divider2, 582,124);
auslese();
mousedown=1;
}
}
// Divider2 up
if ((mouseX > 690) & (mouseX <730) & (mouseY >110) & (mouseY <130))
{
if (mousedown==0)
{
divider2 = divider2*2; if (divider2>128) {divider2=128;}
// TextBox for limit display (Calibration)
stroke(0,0,0);
fill (255,255,255); rect(580,110,100,20);
fill(0,0,0); text(divider2, 582,124);
auslese();
mousedown=1;
}
}
// Show actual Data
if ((mouseX> 530) & (mouseX<730) & (mouseY >165) & (mouseY < 185))
{
aktuell=1;
fill(0,60,0); rect(710,195,20,20); fill(0,255,0); rect(710,165,20,20);
}
// Show loaded file
if ((mouseX> 530) & (mouseX<730) & (mouseY >195) & (mouseY <215))
{
aktuell=0;
fill(0,255,0); rect(710,195,20,20); fill(0,60,0); rect(710,165,20,20); display_loaded_file();
}
// Page counter
if ((mouseX > 530) & (mouseX <570) & (mouseY >220) & (mouseY <240))
{
if (mousedown==0)
{
page=page-1; if (page<0) {page=0;}
// TextBox for page display
stroke(0,0,0);
fill (255,255,255); rect(580,220,100,20);
fill(0,0,0); text(page, 582,234);
if (aktuell==1) {auslese();}
if (aktuell==0) {display_loaded_file();}
mousedown=1;
}
}
// Divider up
if ((mouseX > 690) & (mouseX <730) & (mouseY >220) & (mouseY <240))
{
if (mousedown==0)
{
page=page+1; if (page>35) {page=35;}
// TextBox for page display
stroke(0,0,0);
fill (255,255,255); rect(580,220,100,20);
fill(0,0,0); text(page, 582,234);
if (aktuell==1) {auslese();}
if (aktuell==0) {display_loaded_file();}
mousedown=1;
}
}
if ((mouseX > 530) & (mouseX <730) & (mouseY >250) & (mouseY <270))
{
if (mousedown==0)
{
display_loaded_file2();
mousedown=1;
}
}
// Zoomfactor
if ((mouseX > 530) & (mouseX <570) & (mouseY >280) & (mouseY <300))
{
if (mousedown==0)
{
zoomfaktor = zoomfaktor-2; if (zoomfaktor<2) {zoomfaktor=2;}
// TextBox for zoomfactor
stroke(0,0,0);
fill (255,255,255); rect(580,280,100,20);
fill(0,0,0); text(zoomfaktor, 582,294);
display_loaded_file2();
mousedown=1;
}
}
if ((mouseX > 690) & (mouseX <730) & (mouseY >280) & (mouseY <300))
{
if (mousedown==0)
{
zoomfaktor = zoomfaktor+2; if (zoomfaktor>34) {zoomfaktor=34;}
// TextBox for zoomfactor
stroke(0,0,0);
fill (255,255,255); rect(580,280,100,20);
fill(0,0,0); text(zoomfaktor, 582,294);
display_loaded_file2();
mousedown=1;
}
}
}
// ################################################################
// ###### ######
// ###### End of "Check Buttons" ######
// ###### ######
// ################################################################
// ################################################################
// ###### ######
// ###### Read Data from Port and define as valnoise ######
// ###### ######
// ################################################################
while ((serport.available() > 0) & (stop==0))
{
String valString = serport.readStringUntil(linefeed);
if (valString != null)
{ // print(valString);
valFloat=float(valString);
// valnoise=int(valFloat);
valnoise=valFloat;
}
}
// Display data as timesignal in upper graphics window ###############
stroke(0,255,0);
fill(0,255,0);
if(valnoise/2 < 398)
{
//point(x_pos + 20, 21+int(valnoise/2));
// Change between: Small dots
if (x_pos <=498) {ellipse( x_pos + 21, 21+int(valnoise/2), 2,2); }
// and larger dots.
}
x_pos = x_pos+1;
// the following only happens one time if the noise-timesignal has reached the right margin
if (x_pos == 500)
{
x_pos =0; // Back to left margin of times signal window
fill(0,0,0);
// Clear Screen
stroke(255,255,255);
rect(20,20,500,300);
draw_grid();
// display actual numerical princeton-value in text window for Mode 1 and Mode 2
stroke(0,0,0);
fill (255,255,255); rect(580,25,40,20);
fill(0,0,0) ; text (-endwert,582,39 );
fill (255,255,255); rect(640,25,40,20);
fill(0,0,0) ; text (-endwert2,642,39 );
// increment x-coordinates lower window
x_pr = x_pr +1;
if (x_pr>999) // if screen is full
{
x_pr =1;
cnt_screen=cnt_screen+1000;
if (cnt_screen > 49000) {stop=1;} // Stop after approx. 150 hours recording
stroke(255,255,255); // Clear Screen and draw grid
fill(0,0,0); rect(20,340,1000,400);
draw_princeton_grid();
}
// increment array-pointer for saving princeton data
x_save = x_save+1;
stroke(0,255,0);
// write princeton values into array1 and 2
array1[x_save] = endwert;
array3[x_save] = endwert; // The array where a loaded file can be storend and displayed page by page
array2[x_save] = endwert2;
// change Integers to Bytes to be saved as file (Processing only saves bytes)
container [2] = (byte) (endwert >> 8);
container [3] = (byte) (endwert);
array6[2*x_save] = container[3]; // array6 will be saved on harddisk
array6[2*x_save+1] = container[2];
// Display new value of Princeton-Data by reading the complete array
auslese();
// Save file automatically after each 30 minutes
/*
if (x_pr == 180) { autosave();} // Alternative method for individual Saving times by
if (x_pr == 360) { autosave();} // referring to x_pr
*/
// Saves a file each "savetime" * 10 seconds
// savetime can be set above in the variable declaration
savecntr= savecntr+1;
if (savecntr > savetime) { autosave(); savecntr=0; }
}
// End of: only if time signal has reached right margin ##########
// #######################################################
// ###### ######
// ###### Calculate Princeton Values ######
// ###### ######
// #######################################################
// mode 1
if ((valnoise/2) > limit){val_princeton = val_princeton+1;}
if ((valnoise/2) < limit) {val_princeton = val_princeton-1;}
endwert=int(val_princeton);
// mode 2
if (valnoise % 2 ==0) {val2_princeton = val2_princeton+0.96;}
// increment: 1 - correction factor of 0.xx to get horizontal mode2-curve / Reason: Unknown.
if (valnoise % 2 !=0) {val2_princeton = val2_princeton-1;}
endwert2=int(val2_princeton);
}
// #################################################################
// ###### ######
// ###### Display Princeton Values (lower window) ######
// ###### ######
// #################################################################
void auslese()
{
if(aktuell==1)
{
stroke(255,255,255); // Clear Screen
fill(0,0,0); rect(20,340,1000,400);
draw_princeton_grid();
stroke(0,255,0); // Color curve1
for (n=1; n<=x_pr; n++)
{
y1= int(array1[n-1+cnt_screen]/divider);
y2=int(array1[n+cnt_screen]/divider);
if ((y1<200) & (y1 > -200)& (y2 < 200) & (y1 > -200)) // amplitude limitation
{line (n+21-1, 540 + y1,n+21, 540 + y2);}
// draw princeton curve by reading array content after changing divider
}
stroke(255,0,255); // Color curve2
for (n=1; n<=x_pr; n++)
{
y1= int(array2[n-1+cnt_screen]/divider2);
y2=int(array2[n+cnt_screen]/divider2);
if ((y1<200) & (y1 > -200)& (y2 < 200) & (y1 > -200)) // the same for curve 2 (mode 2)
{line (n+21-1, 540 + y1,n+21, 540 + y2);}
}
}
}
// #################################################################
// ###### ######
// ###### Draw Grid in Time Signal window ) ######
// ###### ######
// #################################################################
void draw_grid()
{
fill(0,0,0);
stroke(200,0,0);
for (x=20 ; x<=520; x+=50)
{ line (x ,20,x,320);}
for (int y=20; y<=320; y+=50)
{ line (20,y,520,y);}
stroke(0,200,200);
line (20,20+limit, 520, 20+limit);
}
// #################################################################
// ###### ######
// ###### Draw Grid in Princeton value window ######
// ###### ######
// #################################################################
void draw_princeton_grid()
{
fill(0,0,0);
stroke(80,80,80);
for (x=20 ; x<=1020; x+=60)
{ line (x ,340,x,740);}
for (y=340; y<=740; y+=50)
{ line (20,y,1020,y);}
stroke(255,0,0);
line(20, 540, 1019,540);
}
// #################################################################
// ###### ######
// ###### Call FileselectBox ######
// ###### ######
// #################################################################
void fileSelected(File selection)
{
if (selection == null)
{
noStroke();
fill(255,255,255);
rect(100,990,1000,20);
fill(0,0,0);
text("Window was closed or the user hit cancel.", 102,1004);
}
else
{
noStroke();
fill(255,255,255);
rect(100,990,1000,20);
fill(0,0,0);
filename=selection.getAbsolutePath();
text(filename, 102,1004);
lade();
}
}
// #################################################################
// ###### ######
// ###### Load a file from Harddisk ######
// ###### ######
// #################################################################
void lade()
{
int ee; int zz;
// Load file into array6
byte array6[] = loadBytes(filename) ;
// Ckeck filesize
// Check filelength
for(i=0; i<=36000; i++)
{
if ((array6[i]==0) & (array6[i+1]==0) &(array6[i+2]==0)&(array6[i+3]==0)& (array6[i+4]==0))
{
filestop=i; filelength=int(filestop/2);
// i=36000;
}
}
// Copy file into array3 and change back to integers at the same time
for(i=0; i<=filestop; i+=2)
{
ee = (array6[i]);
zz = (array6[i+1]);
if (ee <0) {ee = ee+255;}
println(ee);
array3[m]= ee + 256 * zz;
m++;
}
m=0;
}
// #################################################################
// ###### ######
// ###### Save file automatically ######
// ###### ######
// #################################################################
void autosave()
{
saveBytes(Datumstart + "_noise.dat", array6);
}
// #################################################################
// ###### ######
// ###### Display loaded file ######
// ###### ######
// #################################################################
void display_loaded_file()
{
stroke(255,255,255); // Clear Screen
fill(0,0,0); rect(20,340,1000,400);
draw_princeton_grid();
stroke(0,255,0); // Color curve1
for (n=1; n<=999; n++)
{
y1= int(array3[n-1+(1000*page)]/divider);
y2=int(array3[n+(1000*page)]/divider);
if ((y1<200) & (y1 > -200)& (y2 < 200) & (y2 > -200)) // amplitude limitation
{line (n+21-1, 540 + y1,n+21, 540 + y2);}
// draw princeton curve by reading array content after changing divider
}
}
// #################################################################
// ###### ######
// ###### Display compressed loaded file ######
// ###### ######
// #################################################################
void display_loaded_file2()
{
stroke(255,255,255); // Clear Screen
fill(0,0,0); rect(20,340,1000,400);
draw_princeton_grid();
stroke(0,255,0); // Color curve1
for (n=1; n<=9999; n+= zoomfaktor)
{
if (n>10) {y1= int(array3[n-zoomfaktor]/divider);}
y2=int(array3[n]/divider);
xx = xx+1;
if ((y1<200) & (y1 > -200)& (y2 < 200) & (y2 > -200)) // amplitude limitation
{line (xx+21-1, 540 + y1,xx+21, 540 + y2);} // draw princeton curve by reading array content after changing divider
}
xx=0;
}