#include <cvirte.h>
#include <userint.h>
#include <utility.h>
#include <ansi_c.h>
#include <rs232.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "motor.h"
#include <analysis.h>
#include <math.h>
//stepping motor busheng --> declaration 1step=1.8degrees
//experimantally: full rotation = 3200 steps (on setting 1step/mm ($100))
// PORTS
int pCOM1
= 6;
int pCOM2
= 7;
char GRBL
[10] = "COM8"; //BE CAREFUL, IT'S IMPORTANT TO KNOW THE NAME OF THE PORTS
char ADC
[10] = "COM7";
int run
, graph
, chart
, ji
, vi
, run1
;
int left_1
, right_1
;
static int panel
, tfID
, tfID1
;
static int poolHandle
= 0;
#define TEXT_LENGTH 2000
#define MAX_THREADS 10
double volt_g
[TEXT_LENGTH
], volt_g1
[TEXT_LENGTH
*200];
int bytes_read0
;
int bytes_read1
;
char read_data0
[TEXT_LENGTH
];
char read_data1
[TEXT_LENGTH
];
void initialize
()
{
// Open grbl serial port //("COM6",115200)
OpenComConfig
(pCOM1
, GRBL
, 115200, 0, 8, 1, 512, 512);
/* Turn off Hardware handshaking (loopback test will not function with it on) */
SetCTSMode
(pCOM1
, LWRS_HWHANDSHAKE_OFF
);
ComWrt
(pCOM1
, "\r\n\r\n", 5); //Writing on Port
Delay
(2); //Wait for grbl to initialize
int strLen0
= GetInQLen
(pCOM1
); //Reading from Port
bytes_read0
= ComRd
(pCOM1
, read_data0
, strLen0
);
printf("%s\n", read_data0
);
//Left in this form - can have more initializing commands if needeed
char init
[1][10] = {"$RST=$\n"};//, "$100=20\n","$$\n","$100=100\n"
char *cmd
;
for(int i
=0; i
<1; i
++)
{
cmd
= init
+ i
; //Takes init[i]
int len
= strlen(cmd
);
ComWrt
(pCOM1
, cmd
, len
);
printf("%s", cmd
);
Delay
(0.01); //Give it a little time to respond...
int strLen1
= GetInQLen
(pCOM1
);
bytes_read1
= ComRd
(pCOM1
, read_data1
, strLen1
);
printf(" : %s\n", read_data1
);
//printf("bytes_read = %d\n\n", bytes_read1);
}
FlushOutQ
(pCOM1
);
}
void asking_position
()
{
while (1)
{
FlushInQ
(pCOM1
);
FlushOutQ
(pCOM1
);
ComWrt
(pCOM1
, "?\n", 2); //asks grbl his position
Delay
(0.01);
int strLen0
= GetInQLen
(pCOM1
);
bytes_read0
= ComRd
(pCOM1
, read_data0
, strLen0
);
//printf(" : %s", read_data0);
//printf("bytes_read = %d\n\n", bytes_read0);
//taking subtring of a string to first appernace of character
char *read_data_0
= strtok(read_data0
, "\n");
//printf(" : %s\n", read_data_0);
//finding substring in string
char *substr
= strstr(read_data_0
,"Idle");
//printf("\n%s\n", substr);
if(substr
>0) break;
if (!run
)
{
ComWrt
(pCOM1
, "!\n", 2); //stops grbl
Delay
(0.01);
ComWrt
(pCOM1
, "~\n", 2); //releases grbl
Delay
(0.01);
int strLen
= GetInQLen
(pCOM1
);
bytes_read0
= ComRd
(pCOM1
, read_data0
, strLen
);
//printf(" : %s", read_data0);
break;
}
}
}
void initialize_voltage
()
{
// Open serial port for ADC & photodetector - reading is on chanel A1
OpenComConfig
(pCOM2
, ADC
, 115200, 0, 8, 1, 512, 512);
SetCTSMode
(pCOM2
, LWRS_HWHANDSHAKE_OFF
);
Delay
(0.5);
FlushInQ
(pCOM2
);
FlushOutQ
(pCOM2
);
}
int bytes_read2
;
char read_data2
[TEXT_LENGTH
];
double read_voltage
()
{
//int strLen2 = GetInQLen (pCOM2);
bytes_read2
= ComRdTerm
(pCOM2
, read_data2
, 11, 10);
//IMPORTANT: 11 bytes is the size of one line
printf("Voltage: \n%s\n", read_data2
);
//printf("bytes_read = %d\n\n", bytes_read2);
//Delay(0.1);
double Volt
;
sscanf(read_data2
, "%lf", &Volt
);
//printf("Volt = %lf\n", Volt);
return Volt
;
}
int bytes_read3
;
char read_data3
[TEXT_LENGTH
];
void movement
(int steps
)
{
//Move on the steps
char str
[10], move
[20] = "$J=X";
sprintf(str
,"%d",steps
);
strcat(move
,str
);
strcat(move
,"F600\n");
//Command must look like "X200\n" or "$J=X200F600"
int len0
= strlen(move
);
//printf("len0 is %d ", len0);
printf("Moving on point %d\n", steps
);
ComWrt
(pCOM1
, move
, len0
);
Delay
(0.01);
int strLen3
= GetInQLen
(pCOM1
);
bytes_read3
= ComRd
(pCOM1
, read_data3
, strLen3
);
//printf(" :\n%s", read_data3);
//printf("bytes_read = %d\n\n", bytes_read3);
FlushInQ
(pCOM1
);
}
static int CVICALLBACK daq_run
(void *functionData
)
{
int num_points
;
int waittime
;
double volt
;
int j
= 0; //for graph
GetCtrlVal
(panel
, p1_NUM_POINTS
, &num_points
);
GetCtrlVal
(panel
, p1_WAIT_TIME
, &waittime
);
//double wait = waittime/1000.0; //Wait time between each step
//printf("wait: %lf", wait);
movement
(0);
Delay
(0.1);
asking_position
();
initialize_voltage
();
if (!run
) return 0;
FlushInQ
(pCOM1
);
FlushOutQ
(pCOM1
);
Delay
(0.1);
movement
(num_points
);
while (1) // Continious reading
{
volt
= read_voltage
();
FlushInQ
(pCOM2
);
SetCtrlVal
(panel
, p1_VOLTAGE
, volt
);
//writing in tabel for graph
volt_g1
[j
] = volt
;
if (volt
>6) volt_g1
[j
]=volt_g1
[j
-1];
if (volt
<-0.1) volt_g1
[j
]=volt_g1
[j
-1];
j
++;
if (!run
) // Stopping grbl if pressed STOP
{
ComWrt
(pCOM1
, "!\n", 2); //stops grbl
Delay
(0.01);
ComWrt
(pCOM1
, "~\n", 2); //releases grbl
Delay
(0.01);
int strLen
= GetInQLen
(pCOM1
);
bytes_read0
= ComRd
(pCOM1
, read_data0
, strLen
);
//printf(" : %s", read_data0);
break;
}
FlushInQ
(pCOM1
);
FlushOutQ
(pCOM1
);
ComWrt
(pCOM1
, "?\n", 2); //asks grbl his position
Delay
(0.01);
int strLen5
= GetInQLen
(pCOM1
);
bytes_read0
= ComRd
(pCOM1
, read_data0
, strLen5
);
char *read_data_0
= strtok(read_data0
, "\n");
char *substr2
= strstr(read_data_0
,"Idle");
//printf("\n%d\n", substr);
if(substr2
>0) break;
}
if (run
)
{
// Choosing 2^n points
int j_j
= j
- 500; //cut off first 300 and last - 200 - points
int j_jj
= j_j
/num_points
;
//printf("j_j = %d, j_jj = %d\n",j_j,j_jj);
//IMPORTANT! On graph must be only num_points of points
for (int i
=0; i
<num_points
; i
++)
{
volt_g
[i
] = volt_g1
[300+i
*j_jj
];
}
}
// Moving by steps
/*for(int i=(-num_points/2); i<(num_points/2); i++)
{
//printf("i is: %d\n", i);
movement(i);
asking_position();
Delay(0.01); // Little time has to be in between so that grbl can respond
volt = read_voltage();
Delay(wait);
FlushInQ (pCOM1);
FlushInQ (pCOM2);
SetCtrlVal(panel, p1_VOLTAGE, volt);
//writing in tabel for graph
volt_g[j] = volt;
j++;
if (!run) break;
}*/
if (run
) //IMPORTANT!! SAME NUM. of POINTS FOR FOURIER
{
//for(int i=0;i<j;i++) printf("volt_g[%d] = %lf\n",i,volt_g[i]);
if (graph
>0) DeleteGraphPlot
(panel
, p1_VOLTAGE_GRAPH
, graph
, VAL_DELAYED_DRAW
);
graph
= PlotY
(panel
, p1_VOLTAGE_GRAPH
, &volt_g
[0], num_points
, VAL_DOUBLE
,
VAL_CONNECTED_POINTS
, VAL_SIMPLE_DOT
, VAL_SOLID
, 1, VAL_WHITE
);
ji
= num_points
;
}
FlushInQ
(pCOM1
);
FlushOutQ
(pCOM1
);
FlushInQ
(pCOM2
);
FlushOutQ
(pCOM2
);
run
= 0;
return 0;
}
static int CVICALLBACK voltage_run
(void *functionData
)
{
double voltA
;
initialize_voltage
();
chart
= NewCtrl
(panel
, CTRL_STRIP_CHART_LS
, "RUN VOLTAGE", 100, 15);
SetCtrlAttribute
(panel
, chart
, ATTR_HEIGHT
, 600);
SetCtrlAttribute
(panel
, chart
, ATTR_WIDTH
, 1300);
SetAxisRange
(panel
, chart
, VAL_NO_CHANGE
, 0, 0, VAL_AUTOSCALE
, 0, 0);
while(1)
{
voltA
= read_voltage
();
PlotStripChartPoint
(panel
, chart
, voltA
);
SetCtrlVal
(panel
, p1_VOLTAGE
, voltA
);
Delay
(0.05);
FlushInQ
(pCOM2
);
if (vi
== 0) break;
}
DiscardCtrl
(panel
, chart
);
chart
= 0;
return 0;
}
static int CVICALLBACK free_run
(void *functionData
)
{
if (run
== 1) return 0;
run1
= 1;
if (left_1
) movement
(-10000);
if (right_1
) movement
(10000);
left_1
= 0;
right_1
= 0;
while (1)
{
if (run1
== 0)
{
ComWrt
(pCOM1
, "!\n", 2); //stops grbl
Delay
(0.01);
ComWrt
(pCOM1
, "~\n", 2); //releases grbl
Delay
(0.01);
int strLen
= GetInQLen
(pCOM1
);
bytes_read0
= ComRd
(pCOM1
, read_data0
, strLen
);
//printf(" : %s", read_data0);
//printf("Stop run1\n");
break;
}
}
return 0;
}
int main
()
{
SetStdioPort
(HOST_SYSTEM_STDIO
);
SetStdioWindowOptions
(1000000, 0, 0);
SetStdioWindowVisibility
(1);
initialize
();
CmtNewThreadPool
(MAX_THREADS
, &poolHandle
);
DisplayPanel
(panel
= LoadPanel
(0, "motor.uir", p1
));
RunUserInterface
();
CmtDiscardThreadPool
(poolHandle
);
return 0;
}
int CVICALLBACK StartCB
(int panel
, int control
, int event
,
void *callbackData
, int eventData1
, int eventData2
)
{
int dummy
;
switch (event
)
{
case EVENT_COMMIT
:
if (run
== 1) break;
run
= 1;
CmtScheduleThreadPoolFunction
(poolHandle
, daq_run
, (void *)&dummy
, &tfID
);
}
return 0;
}
int CVICALLBACK StopCB
(int panel
, int control
, int event
,
void *callbackData
, int eventData1
, int eventData2
)
{
switch (event
)
{
case EVENT_COMMIT
:
if (run
== 0) break;
run
= 0;
CmtWaitForThreadPoolFunctionCompletion
(poolHandle
, tfID
,
OPT_TP_PROCESS_EVENTS_WHILE_WAITING
);
CmtReleaseThreadPoolFunctionID
(poolHandle
, tfID
);
printf("Stop\n");
break;
}
return 0;
}
int CVICALLBACK ExitCB
(int panel
, int control
, int event
,
void *callbackData
, int eventData1
, int eventData2
)
{
switch (event
)
{
case EVENT_COMMIT
:
QuitUserInterface
(0);
CloseCom
(pCOM1
);
CloseCom
(pCOM2
);
break;
}
return 0;
}
int CVICALLBACK Fourier_TransCB
(int panel
, int control
, int event
,
void *callbackData
, int eventData1
, int eventData2
)
{
if (!ji
) return 0;
const int ii
= ji
;
double fourier_t
[ii
], fourier_ti
[ii
];
char window_fun
;
double voltmax
=0, voltmin
=5, voltavg
;
switch (event
)
{
case EVENT_COMMIT
:
for(int i
=0; i
<ii
; i
++)
{
fourier_t
[i
] = volt_g
[i
];
fourier_ti
[i
] = 0;
if (fourier_t
[i
]>voltmax
) voltmax
= fourier_t
[i
];
if (fourier_t
[i
]<voltmin
) voltmin
= fourier_t
[i
];
}
voltavg
= (voltmin
+voltmax
)/2.0;
GetCtrlVal
(panel
, p1_WIN_FUN
, &window_fun
);
//printf("window_fun = %d\n", window_fun);
//printf("max %f, min %f, avg %f\n", voltmax, voltmin, voltavg);
if (window_fun
!=0)
{
//do something with window functions (N=ii)
if(window_fun
==1) for(int i
=0; i
<ii
; i
++) fourier_t
[i
] = (fourier_t
[i
] - voltavg
)*(1 - fabs((i
-(ii
/2.0))/(ii
/2))) + voltavg
; //Bartlett
if(window_fun
==2) for(int i
=0; i
<ii
; i
++) fourier_t
[i
] = (fourier_t
[i
] - voltavg
)*(1 - ((i
-(ii
/2.0))/(ii
/2))*((i
-(ii
/2.0))/(ii
/2))) + voltavg
; //Welch
if(window_fun
==3) for(int i
=0; i
<ii
; i
++) fourier_t
[i
] = (fourier_t
[i
] - voltavg
)*(0.5*(1 - cos(2*3.14159265359*i
/ii
))) + voltavg
; //Hann
YGraphPopup
("HOW voltage LOOKS NOW", fourier_t
, ii
, VAL_DOUBLE
);
}
FFT
(fourier_t
, fourier_ti
, ii
);
for (int i
=0; i
<ii
; i
++) fourier_t
[i
] = fabs(fourier_t
[i
]);
fourier_t
[0]=0;
YGraphPopup
("FOURIER", fourier_t
, ii
/2+1, VAL_DOUBLE
);
FILE
*fp
,*fp1
;
//file name has to have file extension
char fname
[50];
GetCtrlVal
(panel
, p1_F_NAME
, fname
);
char fname0
[100] = "C:/Users/";
char *name
;
name
= getenv("USERNAME");
strcat(fname0
,name
);
strcat(fname0
,"/Desktop/");
//char fname0[100] = "C:/Users/Student/Desktop/"; //Alternative way
strcat(fname0
,fname
);
fp
= fopen(fname0
, "w");
char fname1
[50];
GetCtrlVal
(panel
, p1_F_NAME1
, fname1
);
char fname10
[100] = "C:/Users/";
strcat(fname10
,name
);
strcat(fname10
,"/Desktop/");
strcat(fname10
,fname1
);
fp1
= fopen(fname10
, "w");
fprintf(fp
, "step\tvoltage\n");
for(int i
=0; i
<ii
; i
++)
{
fprintf(fp
, "%d\t%lf\n", i
+1, volt_g
[i
]);
}
fprintf(fp1
, "step\tfourier\n");
for(int i
=0; i
<ii
/2+1; i
++)
{
fprintf(fp1
, "%d\t%lf\n", i
, fourier_t
[i
]); //0th component is from DC - background? YES
}
fclose(fp
);
fclose(fp1
);
printf("Files %s and %s created.\n", fname
, fname1
);
break;
}
return 0;
}
int CVICALLBACK ExamplesCB
(int panel
, int control
, int event
,
void *callbackData
, int eventData1
, int eventData2
)
{
const int ki
=1024;
double ret
[ki
], ret1
[ki
];
double val
= 3.14159265/180;
int x1
, x2
, a1
, a2
;
char window_fun
;
switch (event
)
{
case EVENT_COMMIT
:
GetCtrlVal
(panel
, p1_FREQ1
, &x1
);
GetCtrlVal
(panel
, p1_FREQ2
, &x2
);
GetCtrlVal
(panel
, p1_AMPL1
, &a1
);
GetCtrlVal
(panel
, p1_AMPL2
, &a2
);
GetCtrlVal
(panel
, p1_WIN_FUN
, &window_fun
);
//printf("window_fun = %d\n", window_fun);
for (int i
=0; i
<ki
; i
++)
{
ret
[i
] = a1
*sin(x1
*i
*val
)+a2
*sin(x2
*i
*val
);
ret1
[i
] = 0;
}
if (window_fun
!=0)
{
//do something with window functions (N=ki)
if(window_fun
==1) for(int i
=0; i
<ki
; i
++) ret
[i
] = ret
[i
]*(1 - fabs((i
-(ki
/2.0))/(ki
/2))); //Bartlett
if(window_fun
==2) for(int i
=0; i
<ki
; i
++) ret
[i
] = ret
[i
]*(1 - ((i
-(ki
/2.0))/(ki
/2))*((i
-(ki
/2.0))/(ki
/2))); //Welch
if(window_fun
==3) for(int i
=0; i
<ki
; i
++) ret
[i
] = ret
[i
]*(0.5*(1 - cos(2*3.14159265359*i
/ki
))); //Hann
}
YGraphPopup
("example graph", ret
, ki
, VAL_DOUBLE
);
FFT
(ret
, ret1
, ki
);
for (int i
=0; i
<ki
; i
++) ret
[i
] = fabs(ret
[i
]);
//for (int i=0;i<ki;i++) printf("basic: %lf, fourier: %lf\n", ret1[i], ret[i]);
YGraphPopup
("example fourier", ret
, ki
/2+1, VAL_DOUBLE
);
break;
}
return 0;
}
int CVICALLBACK Only_voltageCB
(int panel
, int control
, int event
,
void *callbackData
, int eventData1
, int eventData2
)
{
int dummy
, volt_run
;
switch (event
)
{
case EVENT_COMMIT
:
GetCtrlVal
(panel
, p1_VOLT_GRAPH
, &volt_run
);
if(volt_run
)
{
vi
= 1;
CmtScheduleThreadPoolFunction
(poolHandle
, voltage_run
, (void *)&dummy
, &tfID
);
}
else
{
vi
= 0;
CmtWaitForThreadPoolFunctionCompletion
(poolHandle
, tfID
,
OPT_TP_PROCESS_EVENTS_WHILE_WAITING
);
CmtReleaseThreadPoolFunctionID
(poolHandle
, tfID
);
}
break;
}
return 0;
}
int CVICALLBACK RangeCB
(int panel
, int control
, int event
,
void *callbackData
, int eventData1
, int eventData2
)
{
int fix_range
;
double ymin
,ymax
,xmin
,xmax
;
switch (event
)
{
case EVENT_COMMIT
:
GetCtrlVal
(panel
, p1_RANGE
, &fix_range
);
if(chart
)
{
if(fix_range
)
{
GetAxisRange
(panel
, chart
, VAL_MANUAL
, &xmin
, &xmax
, VAL_MANUAL
, &ymin
, &ymax
);
if (ymax
<=2) SetAxisRange
(panel
, chart
, VAL_NO_CHANGE
, 0, 0, VAL_MANUAL
, 0, 2);
else SetAxisRange
(panel
, chart
, VAL_NO_CHANGE
, 0, 0, VAL_MANUAL
, 0, 5);
}
else SetAxisRange
(panel
, chart
, VAL_NO_CHANGE
, 0, 0, VAL_AUTOSCALE
, 0, 0);
}
if(fix_range
)
{
GetAxisRange
(panel
, p1_VOLTAGE_GRAPH
, VAL_MANUAL
, &xmin
, &xmax
, VAL_MANUAL
, &ymin
, &ymax
);
if (ymax
<=2) SetAxisRange
(panel
, p1_VOLTAGE_GRAPH
, VAL_NO_CHANGE
, 0, 0, VAL_MANUAL
, 0, 2);
else SetAxisRange
(panel
, p1_VOLTAGE_GRAPH
, VAL_NO_CHANGE
, 0, 0, VAL_MANUAL
, 0, 5);
}
else SetAxisRange
(panel
, p1_VOLTAGE_GRAPH
, VAL_NO_CHANGE
, 0, 0, VAL_AUTOSCALE
, 0, 0);
break;
}
return 0;
}
int CVICALLBACK FreeMoveCB
(int panel
, int control
, int event
,
void *callbackData
, int eventData1
, int eventData2
)
{
int dummy
;
switch (event
)
{
case EVENT_COMMIT
:
if (run
== 1) break;
if (run1
== 1) break;
right_1
= 1;
CmtScheduleThreadPoolFunction
(poolHandle
, free_run
, (void *)&dummy
, &tfID1
);
break;
}
return 0;
}
int CVICALLBACK FreeMove1CB
(int panel
, int control
, int event
,
void *callbackData
, int eventData1
, int eventData2
)
{
int dummy
;
switch (event
)
{
case EVENT_COMMIT
:
if (run
== 1) break;
if (run1
== 1) break;
left_1
= 1;
CmtScheduleThreadPoolFunction
(poolHandle
, free_run
, (void *)&dummy
, &tfID1
);
break;
}
return 0;
}
int CVICALLBACK FreeMoveStopCB
(int panel
, int control
, int event
,
void *callbackData
, int eventData1
, int eventData2
)
{
switch (event
)
{
case EVENT_COMMIT
:
if (run
== 1) break;
if (run1
== 0) break;
run1
= 0;
if (run1
== 0) //Additionally here just to be sure
{
ComWrt
(pCOM1
, "!\n", 2); //stops grbl
Delay
(0.01);
ComWrt
(pCOM1
, "~\n", 2); //releases grbl
Delay
(0.01);
int strLen
= GetInQLen
(pCOM1
);
bytes_read0
= ComRd
(pCOM1
, read_data0
, strLen
);
//printf(" : %s", read_data0);
printf("Stop run1\n");
}
CmtWaitForThreadPoolFunctionCompletion
(poolHandle
, tfID1
,
OPT_TP_PROCESS_EVENTS_WHILE_WAITING
);
CmtReleaseThreadPoolFunctionID
(poolHandle
, tfID1
);
break;
}
return 0;
}
int CVICALLBACK Pos0CB
(int panel
, int control
, int event
,
void *callbackData
, int eventData1
, int eventData2
)
{
switch (event
)
{
case EVENT_COMMIT
:
if (run
== 1) break;
if (run1
== 1) break;
FlushInQ
(pCOM1
);
FlushOutQ
(pCOM1
);
CloseCom
(pCOM1
);
initialize
();
break;
}
return 0;
}