diff --git a/src/ofm_code_cbc_v1/new_updated_ofm .py b/src/ofm_code_cbc_v1/new_updated_ofm .py new file mode 100644 index 0000000..36d8510 --- /dev/null +++ b/src/ofm_code_cbc_v1/new_updated_ofm .py @@ -0,0 +1,256 @@ +#import matlab.engine +from PyQt5 import QtCore, QtGui, uic, QtWidgets +import sys,os +import numpy as np +import cv2 +import serial,sys +import threading, time, Queue +from datetime import datetime + + +name=raw_input("enter patient's name ") +#age=raw_input("enter age ") +today=datetime.now().date() +today1=datetime.now().time() +#t = datetime.time(datetime.now()) + +path = "./%s-" %name + str(today) +try: + os.mkdir(path) +except OSError: + print ("Creation of the directory %s failed" % path) +else: + print ("Successfully created the directory %s " % path) + + +running = False +capture_thread = None +#for i in range(3): +form_class = uic.loadUiType("simple.ui")[0] +q = Queue.Queue() +ser = serial.Serial('COM3',57600) +capture = cv2.VideoCapture(0) +capture_duration = 60*1 +q_write = Queue.Queue() + + +def grab(width, height): + global running,q,capture + #capture = cv2.VideoCapture(0) + capture.set(cv2.CAP_PROP_FRAME_WIDTH, width) + capture.set(cv2.CAP_PROP_FRAME_HEIGHT, height) + capture.set(cv2.CAP_PROP_EXPOSURE, -13) + #print (capture.get(cv2.CAP_PROP_EXPOSURE) ) + while(running): + retval, img = capture.read() + if q.qsize() < 7200: + q.put(img) + +class OwnImageWidget(QtWidgets.QWidget): + def __init__(self, parent=None): + super(OwnImageWidget, self).__init__(parent) + self.image = None + + def setImage(self, image): + self.image = image + sz = image.size() + self.setMinimumSize(sz) + self.update() + + def paintEvent(self, event): + qp = QtGui.QPainter() + qp.begin(self) + if self.image: + qp.drawImage(QtCore.QPoint(0, 0), self.image) + qp.end() + + + +class MyWindowClass(QtWidgets.QMainWindow, form_class): + location='' + def __init__(self, parent=None): + QtWidgets.QMainWindow.__init__(self, parent) + self.setupUi(self) + self.resize(730,730) + self.currzpos=0 + #btn1 = QtWidgets.QPushButton('X+', self) + #btn2 = QtWidgets.QPushButton('X-', self) + #btn1.move(200, 500) + #btn2.move(300, 500) + self.startButton.clicked.connect(self.start_clicked) + self.startButton4.clicked.connect(self.main) + self.window_width = self.ImgWidget.frameSize().width() + self.window_height = self.ImgWidget.frameSize().height() + self.ImgWidget = OwnImageWidget(self.ImgWidget) + self.startButton1.clicked.connect(self.xPos) + self.startButton2.clicked.connect(self.xNeg) + self.timer = QtCore.QTimer(self) + self.timer.timeout.connect(self.update_frame) + self.timer.start(.01) + self.startButton3.clicked.connect(self.fCapture) + self.startButton5.clicked.connect(self.home) + self.startButton6.clicked.connect(self.start) + self.startButton7.clicked.connect(self.xPoss) + self.startButton8.clicked.connect(self.xNegg) + + + def main(self): + + capture_thread2 = threading.Thread(target=self.autofocus, args = ()) + capture_thread2.start() + #capture_thread2.join() + #self.autofocus() + + def home(self): + ser.write('Q') + self.currzpos=0 + + def start(self): + self.Zpulserate = 57600 + #ser.write('S') + auto_travel=-650000 + self.gotoZ(auto_travel) + + def gotoZ(self,zValue): + zValue = int(zValue) + if self.currzpos != zValue: + zValue_str = str("%($)07d" % {"$":zValue}) + print zValue_str + ser.write('M') + ser.write(str(zValue_str)) + time.sleep(abs(self.currzpos-zValue)/self.Zpulserate) + self.currzpos = int(zValue) + + def autofocus(self): + + global q + Z_travel_for_crude = 16000; crude_step_count = 200; + crude_pulse_count = Z_travel_for_crude / crude_step_count; + crude_max_var=0; crude_loc_max_var=0; + crude_start_loc = self.currzpos -(Z_travel_for_crude/2); + self.gotoZ(crude_start_loc) + crude_curr_loc = crude_start_loc; + kernel = np.ones((5,5),np.float32)/25 + + for i in range(int(crude_pulse_count)): + img=q.get() + crude_curr_var = np.var(cv2.filter2D(img,-1,kernel)) + #cv2.imwrite("image/image_crude_auto{0}.jpg".format(i),img) + print(crude_curr_var,'||',self.currzpos) + if crude_curr_var > crude_max_var: + crude_max_var = crude_curr_var + crude_loc_max_var = crude_curr_loc + image=img + crude_curr_loc = crude_curr_loc + crude_step_count + self.gotoZ(crude_curr_loc) + time.sleep(.075) + #a="image/image_crude%d.jpg"%crude_loc_max_var + #cv2.imwrite(a ,image) + self.gotoZ(crude_loc_max_var) + + + def xPos(self): + self.currzpos=int(self.currzpos) + ser.write('G') + self.currzpos = self.currzpos + 1 + print self.currzpos + + def xNeg(self): + self.currzpos=int(self.currzpos) + ser.write('T') + print self.currzpos + + def xPoss(self): + self.currzpos=int(self.currzpos) + ser.write('D') + self.currzpos = self.currzpos + 1 + print self.currzpos + + def xNegg(self): + self.currzpos=int(self.currzpos) + ser.write('A') + self.currzpos = self.currzpos - 1 + print self.currzpos + + def start_clicked(self): + global running + running = True + capture_thread.start() + + + def update_frame(self): + global q + if not q.empty(): + img = q.get() + img_height, img_width, img_colors = img.shape + scale_w = float(self.window_width) / float(img_width) + scale_h = float(self.window_height) / float(img_height) + scale = min([scale_w, scale_h]) + + if scale == 0: + scale = 1 + + img = cv2.resize(img, None, fx=scale, fy=scale, interpolation = cv2.INTER_CUBIC) + img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) + height, width, bpc = img.shape + bpl = bpc * width + image = QtGui.QImage(img.data, width, height, bpl, QtGui.QImage.Format_RGB888) + self.ImgWidget.setImage(image) + + + def fCapture(self): + capture_thread3 = threading.Thread(target=self.fCapture_read, args = ()) + capture_thread3.start() + + def fCapture_read(self): + global capture,capture_duration + global q_write + t_end = time.time() + capture_duration + self.counter=0 + print "frame capture started" + while(capture.isOpened()): + ret, frame = capture.read() + if time.time() < t_end: + if (ret==True): + self.counter=self.counter+1 + if q_write.qsize()<120*capture_duration: + q_write.put(frame) + else: + print "frames captured" + print self.counter + self.fcapture_write() + + #cap.release() + + def fcapture_write(self): + global q_write,capture + i=0 + if not q_write.empty(): + for i in range (self.counter): + img=q_write.get() + i=i+1 + cv2.imwrite(str(path)+ "/image%d.bmp" %i,img) + + self.call_matlab() + + def call_matlab(self): + print "calling matlab" + print path + import matlab.engine as m + eng = m.start_matlab() + eng.new_whole_blood_segment_odroid(path) + #print "calling matlab" + #mlab.new_whole_blood_segment_odroid(path) + + + + +if __name__ == '__main__' : + capture_thread = threading.Thread(target=grab, args = (640,480)) + + app = QtWidgets.QApplication(sys.argv) + w = MyWindowClass() + w.setWindowTitle('OFM GUI') + w.show() + app.exec_() + \ No newline at end of file diff --git a/src/ofm_code_cbc_v1/new_whole_blood_segment_odroid.m b/src/ofm_code_cbc_v1/new_whole_blood_segment_odroid.m new file mode 100644 index 0000000..bf84c4a --- /dev/null +++ b/src/ofm_code_cbc_v1/new_whole_blood_segment_odroid.m @@ -0,0 +1,323 @@ +%% +%The code creates a feature table for the different types of cells and +%is used to create a initial training dataset for the classifier + +%% +function a=new_whole_blood_segment_odroid(path) +%path='./mahwish-2018-10-21'; +%% +disp(path); +%mkdir('G:\Experiments\odroid\S\S1\gate1'); +%mkdir('G:\Experiments\odroid\S\S1\gate2'); +mkdir(path,'/gate3'); +%mkdir('I:\ofm\im\im\gate3'); +%mkdir('C:\Users\DOIAP\Desktop\OFM\images\set8-80\gate4'); +%mkdir('G:\Experiments\odroid\S\S1\P'); +%% +% To create a circular mask to eliminate the spokes channels and perform +% processing of cells in the central imaging region +% Create a logical image of a circle with specified +% diameter, center, and image size. +% First create the image. +imageSizeX = 640; %X pixel size of the image +imageSizeY = 480; %Y pixel size of the image +[columnsInImage rowsInImage] = meshgrid(1:imageSizeX, 1:imageSizeY); +% Next create the circle in the image. +centerX = 300; %center X pixel of the circle +centerY = 240; %center y pixel of the circle +radius = 220; %Radius of the circle +circlePixels = (rowsInImage - centerY).^2 ... + + (columnsInImage - centerX).^2 <= radius.^2; % creates the circular mask + +%% Generate Background +%a = rgb2gray(imread(strcat('E:\Experiments\odroid\step1\1 (',num2str(V),').jpg'))); +%imshow(a); +%%% average ten frames to generate background. +bg = 0; V=1; +count = 100 ;% set number of frame to be averaged +N = 0; % start frame number +for i = N:N+count + bg = bg +double(rgb2gray(imread(strcat(path,'/image',num2str(V+i),'.bmp')))); +end +bg = uint8(bg /count); % Final Background generated. +%imshow(uint8(circlePixels).*bg); +%% +tic +r =0;b=0; +count = 0; +maxglcm = 0; +Cont =0;Corr=0;Homo=0;I_mean=0;I_std=0;I_cir=0;I_area =0;stain=0;Peri=0;Diameter=0;category=0; + ccount = 0; + C_Percentstained =0;StainMaxlength=0;StainMinlength=0;StainSolid=0; StainNumobj=0;Stainlength=0; + Features_table = [];F=[]; +CellFeature_table = [];cell=[]; +% Feature_table = table('VariableNames',{'Area', 'ConvexArea', 'Eccentricity', 'EquivDiameter', 'EulerNumber', 'Extent', 'FilledArea', 'MajorAxisLength', 'MinorAxisLength', 'Orientation', 'Perimeter', 'Solidity'}); + for V =1:200 + disp(V); +Shape_Features =[]; Texture_Features1 = []; +% The if condition is used to refresh the background for every 2000 frames +% This helps eliminate any debris/ struck cells in the ROI +if mod(V,2000) == 0 + %if V <19999-30 +% bg1 = bg; +bg =0; +count = 100 ;% set number of frame to be averaged +N = 1; % start frame number +for i = N:N+count + bg = bg +double(rgb2gray(imread(strcat(path,'/image',num2str(V+i),'.bmp')))); +end +bg = uint8(bg /count); % Final Background generated. + +% bg = (bg+bg1)/2.0 +end +%imshow(bg) + % The following section performs the segmentation based on histogram values + CurrFrame = (rgb2gray((imread(strcat(path,'/image',num2str(V),'.bmp'))))); + Sub = double(CurrFrame.*uint8(circlePixels))-double(bg.*uint8(circlePixels)); + + Submin = min(Sub(:)); + Submax = max(Sub(:)); + + AdjBGSub = uint8( (Sub - Submin)/(Submax-Submin) * 255); + %imshow(AdjBGSub); + Ia = AdjBGSub; + %imshow(Ia); + [A, B]=size(Ia); + %disp(B) + I = medfilt2(Ia); % To smoothen the image + %imshow(I); + I = adapthisteq(I); % to improve contrast of the image + %imshow(I); +%I1 = medfilt2(I); +%imshow(I1); +%Irgb = cat(3, I1, I1, I1); +%imshow(Irgb) +se = strel('disk',5); +Ie = imerode(AdjBGSub,se); +Iobr = imreconstruct(Ie,AdjBGSub); +Iobrd = imdilate(Iobr,se); + +Iobrcbr = imreconstruct(imcomplement(Iobrd),imcomplement(Iobr)); + +Iobrcbr = imcomplement(Iobrcbr); +%imshow(Iobrcbr) +%imwrite(Iobrcbr,strcat('C:\Users\DOIAP\Desktop\OFM\images\set8-80\image\image',num2str(V),'.jpg')); +%meanIntensityValue(V) = mean2(Iobrcbr); % Finds the mean of the intensities of the image pixels +%stdIntensityValue = std2(Iobrcbr); % Finds the standard deviation of the intensities of the image pixels +% Selection of max and minimum of intensities for the thresholding +%This multipication factor can be varied when you are optimizing the +%thresholding +%Imax = meanIntensityValue(V)+stdIntensityValue*4; % mean+ 4*standard deviation +%Imin = meanIntensityValue(V)-stdIntensityValue*4; % mean- 4*standard deviation +% Further processing of the thresholded image +%Mask = createMask(Irgb,Imax,Imin);%figure; +%imshow(Mask); +MaskInv = imbinarize(Iobrcbr); +%imshow(MaskInv); + +Maskopen =bwareaopen(MaskInv,5);%figure;imshow(Maskfinal); +%imshow(Maskopen); +% Maskdil = imdilate(Maskopen, [se90 se0]);%figure;imshow(Maskdil); +%Maskdil = imclose(Maskopen, strel('disk',5)); +%imshow(Maskopen); +Maskfill = imfill(~Maskopen, 'holes');%figure;imshow(Maskfill); +%imshow(Maskfill); +Maskclose = Maskfill; +%imshow(Maskclose); +% Maskclose = imclose(Maskfill, strel('disk',5)); +Maskclear = imclearborder(Maskclose, 4);%figure; +%imshow(Maskclear); +Maskfinal = Maskclear; +D = bwdist(~Maskfinal); +D=-D; +mask = imextendedmin(D,2); +D2 = imimposemin(D,mask); +L = watershed(D2); +L(Maskfinal==0)=0; +%imshow(L); +new_final=(L); +new_final=logical(new_final); +%imshow(new_final) +%imwrite(new_final,strcat(path '/image/image',num2str(V),'.jpg'))); +% Filter image based on image properties. +%new_final = bwpropfilt(new_final, 'Area', [20 + eps(20), Inf]); % Area greater than 20 pixels +%new_final = bwpropfilt(new_final, 'Solidity', [0.6 + eps(0.6), Inf]); % 1 is completely solid region +%new_final = bwpropfilt(new_final, 'EulerNumber', [4.94065646e-324 + eps(4.94065646e-324), Inf]); +%Extract properties of all the cells in the thresholded image +%imwrite(new_final,strcat('C:\Users\DOIAP\Desktop\OFM\images\set8-80\image1\image',num2str(V),'.jpg')); +Maskproperties = regionprops(new_final, {'Area', 'ConvexArea', 'Eccentricity', 'EquivDiameter', 'EulerNumber', 'Extent', 'FilledArea', 'MajorAxisLength', 'MinorAxisLength', 'Orientation', 'Perimeter', 'Solidity',}); +% Creates a feature table of all the above listed properties for all the +% segmented cells/regions in the image +Shape_Features = struct2table(Maskproperties); +%Plotting of 200 images to see the performance of segmetation operations +%if V<200 +%h= figure; +%subplot(2,3,1); +%subimage(Mask); +%title('Mask'); + +%subplot(2,3,2); +%subimage(Maskfill); +%title('Maskfill'); + +%subplot(2,3,3); +%subimage(Maskdil); +%title('Maskdil'); + +%subplot(2,3,4); +%subimage(uint8(MaskInv).*I1); +%title('Maskclose'); +% subplot(1,2,1); +%subplot(2,3,5); +%subimage(I1); +%title('I1'); +% subplot(1,2,2); +%subplot(2,3,6); +%subimage(uint8(Maskfinal).*I1); +%title(' Maskfinal'); +%saveas(h,strcat('C:\Users\DOIAP\Desktop\OFM\images\set8-80\gate4\FrameNumber','-',num2str(V)),'jpg'); + %close(h); +% figure;imshow(uint8(Maskfinal).*I); +% figure;imshow(I); +%end +% Generation of the traning images for the classification program +CComp = bwconncomp(new_final); +Areas = regionprops(CComp,'Area'); +Centroids1=regionprops(CComp,'Centroid'); +Perimeters=regionprops(CComp,'Perimeter'); +Texture_Features=[]; +for i = 1:CComp.NumObjects + Cent = Centroids1(i).Centroid; + HighX = round(Cent(1))+20; + if HighX>B + HighX =B; + end + HighY = round(Cent(2))+20; + if HighY>A + HighY =A; + end + LowX = round(Cent(1))-19; + if LowX<=0 + LowX =1; + end + + LowY = round(Cent(2))-19; + if LowY<=0 + LowY =1; + end + + ccount = ccount +1;%,num2str(V),'.avi' + Icrop1=Ia(LowY:HighY,LowX:HighX); + + %Icrop1=I(LowY:HighY,LowX:HighX); + %imshow(Icrop1) + Maskcrop=new_final(LowY:HighY,LowX:HighX); + imwrite(Icrop1,strcat(path,'/gate3/image',num2str(ccount),'.bmp')); + % Additional texture features for the feature table + glcm = graycomatrix(Icrop1);%gray level covariance matrix + maxglcm(ccount)=max(max(glcm)); %Feature 1 + stats(ccount) = graycoprops(glcm,{'Contrast','Correlation','homogeneity'}); + Texture_Features = struct2table(stats(ccount)); +% Cont(ccount)= stats(ccount).Contrast; %Feature 2 +% Corr(ccount) = stats(ccount).Correlation; %Feature 3 +% Homo(ccount)= stats(ccount).Homogeneity;%Feature 4 +% Ent(ccount)= stats(ccount).Entropy; + I_mean(ccount) = mean2(Icrop1); %Feature 5 + I_std(ccount)=std2(Icrop1); %Feature 6 + I_cir(ccount) = ((Shape_Features.Perimeter(i))^ 2)/ (4 * pi * Shape_Features.Area(i)); %Feature 7 + Peri(ccount) = Shape_Features.Perimeter(i)*(5.6/25.7); + Diameter(ccount) = Peri(ccount)/3.14; + %category(ccount) =0; + + % Percentage of stained area + BWthresh = imbinarize(Icrop1,0.15); + + BWthreshtemp =~(BWthresh).*Maskcrop; + + CC1 =bwconncomp(imcomplement(BWthresh).*Maskcrop); + MaxLength = regionprops(CC1,'MajorAxisLength'); + MinLength = regionprops(CC1,'MinorAxisLength'); + Solid = regionprops(CC1,'Solidity'); +% imwrite(~BWthresh,strcat('E:\Experiments\odroid\A2\A2a\gate2\FrameNumber','-',num2str(V),'_',num2str(ccount),'.jpg')); + Areas_stained = regionprops(CC1,'Area'); + StainNumobj(ccount) = CC1.NumObjects; + if CC1.NumObjects ==0 + C_Percentstained(ccount) = 0; + StainMaxlength(ccount) = 0;StainMinlength(ccount) = 0; + StainSolid(ccount) = 0; StainSolid(ccount) = 0; Stainlength(ccount)=0; + else + if (max(struct2array(MaxLength))/max(struct2array(MinLength)))<2 + F = [F; max(struct2array(MaxLength))/max(struct2array(MinLength))]; +% imwrite(Icrop,strcat('E:\Experiments\odroid\A2\A2a\P\FrameNumber','-',num2str(V),'_',num2str(ccount),'.jpg')); + end + C_Percentstained(ccount) = sum(struct2array(Areas_stained))/max((Shape_Features.Area(i)))*100; + StainMaxlength(ccount) = max(struct2array(MaxLength)); + StainMinlength(ccount) = max(struct2array(MinLength)); + Stainlength(ccount) = StainMinlength(ccount)*(5.6/25.7); + StainSolid(ccount) = max(struct2array(Solid)); + end + % Stainproperties = regionprops(BWthreshtemp, {'Area', 'ConvexArea', 'Eccentricity', 'EquivDiameter', 'EulerNumber', 'Extent', 'FilledArea', 'MajorAxisLength', 'MinorAxisLength', 'Orientation', 'Perimeter', 'Solidity'}); +% Parasite_Features = struct2table(Stainproperties); + %if (((3.5<=Diameter(ccount)) && (12>=Diameter(ccount))) &&(Stainlength(ccount)==0)) + % category(ccount) =0; + %elseif (((1<=Diameter(ccount)) && (3.5>=Diameter(ccount))) &&(Stainlength(ccount)==0)) + % category(ccount) =2; + %elseif (((5.5<=Diameter(ccount)) && (25>=Diameter(ccount))) && (Stainlength(ccount)>0)) + % category(ccount) =1; + %else + % category(ccount) =3; + %end + + + Texture_Features1 = [Texture_Features; Texture_Features1]; +end +if CComp.NumObjects>0 + Features = [Shape_Features Texture_Features1]; %Variable Addition + +Features_table = [Features_table; Features]; % Table update + end + cell = table(I_mean', I_std', I_cir', maxglcm', C_Percentstained',StainMaxlength',StainMinlength',StainSolid', StainNumobj',Stainlength', Peri', Diameter'); + cell.Properties.VariableNames = {'Mean' 'Std' 'Circularity' 'MaxGLCM' 'Percentage_Stain' 'StainMaxlength' 'StainMinlength' 'StainSolid' 'StainNumobj' 'Stainlength' 'Peri' 'Diameter'}; + CellFeature_table = [Features_table cell]; % Table update + save('test_table.mat','CellFeature_table') + end + toc + %classificationcode +load('trainedModel.mat'); +%mkdir('I:\ofm\im\im\gate3\cells\rbc'); +%mkdir('I:\ofm\im\im\gate3\cells\wbc'); +%mkdir('I:\ofm\im\im\gate3\cells\platelets'); +%% +%Classifier Function obtained after training the classifier with the +%generated training data set and the feature table +% There are 4 different catergories of classification + yfit = trainedModel.predictFcn(CellFeature_table); + rbc=0;wbc=0;platelets=0;cant_classify=0; + +for i = 1:length(yfit) + image = imread(strcat(path,'/gate3/image',num2str(i),'.bmp')); + if(yfit(i)== 0) + rbc=rbc+1; + %imwrite(image,strcat('I:\ofm\im\im\gate3\cells\rbc\image',num2str(i),'.jpg'),'jpeg'); + elseif (yfit(i)== 1) + wbc=wbc+1; + %imwrite(image,strcat('I:\ofm\im\im\gate3\cells\wbc\image',num2str(i),'.jpg'),'jpeg'); + elseif (yfit(i)== 2) + %imwrite(image,strcat('I:\ofm\im\im\gate3\cells\platelets\image',num2str(i),'.jpg'),'jpeg'); + platelets=platelets+1; + else + cant_classify=cant_classify+1; + end + +end +rows=height(CellFeature_table); +total_cells = sprintf('total count %d',rows); +disp(total_cells); +RBC = sprintf('rbc count %d',rbc); +disp(RBC); +WBC = sprintf('wbc count %d',wbc); +disp(WBC); +PLATELETS = sprintf('platelets count %d',platelets); +disp(PLATELETS); +C= sprintf('cells that cant be classified %d',cant_classify); +disp(C); \ No newline at end of file diff --git a/src/ofm_code_cbc_v1/simple.ui b/src/ofm_code_cbc_v1/simple.ui new file mode 100644 index 0000000..04dfb72 --- /dev/null +++ b/src/ofm_code_cbc_v1/simple.ui @@ -0,0 +1,184 @@ + + + MainWindow + + + + 0 + 0 + 700 + 500 + + + + MainWindow + + + + + + + + + 30 + 80 + 670 + 500 + + + + background-color: rgb(90, 90, 90); + + + + 0 + 0 + + + + + + + + + 0 + 0 + 700 + 500 + + + + + + + + 60 + 10 + 100 + 61 + + + + Start Camera + + + + + + 180 + 10 + 100 + 61 + + + + Auto Focus + + + + + + 340 + 600 + 50 + 50 + + + + X + + + + + + + 410 + 600 + 50 + 50 + + + + X - + + + + + + 300 + 10 + 100 + 61 + + + + Frame Capture + + + + + + 420 + 10 + 100 + 61 + + + + Home + + + + + + 540 + 10 + 100 + 61 + + + + Start + + + + + + 270 + 600 + 50 + 50 + + + + X++ + + + + + + 200 + 600 + 50 + 50 + + + + X-- + + + + + + + 0 + 0 + 639 + 21 + + + + + + + + diff --git a/src/ofm_code_cbc_v1/test_table.mat b/src/ofm_code_cbc_v1/test_table.mat new file mode 100644 index 0000000..6c45711 Binary files /dev/null and b/src/ofm_code_cbc_v1/test_table.mat differ diff --git a/src/ofm_code_cbc_v1/trainedModel.mat b/src/ofm_code_cbc_v1/trainedModel.mat new file mode 100644 index 0000000..a282eae Binary files /dev/null and b/src/ofm_code_cbc_v1/trainedModel.mat differ diff --git a/src/ofm_code_cbc_v1/updated_sketch_aug14a/updated_sketch_aug14a.ino b/src/ofm_code_cbc_v1/updated_sketch_aug14a/updated_sketch_aug14a.ino new file mode 100644 index 0000000..b190455 --- /dev/null +++ b/src/ofm_code_cbc_v1/updated_sketch_aug14a/updated_sketch_aug14a.ino @@ -0,0 +1,125 @@ +#define Zdir 12 +#define motorPulse 13 +#define M0 9 +#define M1 10 +#define M2 11 + +long ZcurrStep=0L; +long Ax=0L,Ay=0L,Az=0L,Bx=0L,By=0L,Bz=0L,Cx=0L,Cy=0L,Cz=0L; +long nextZstep = 0; +int needtocheckXmovement=0,needtocheckYmovement=0,needtocheckZmovement=0; +long limitTOZfocus = 20000L; + +void setup() { +// setup serial baud rate + Serial.begin(57600); + pinMode(5,OUTPUT); + pinMode(6,INPUT); + digitalWrite(5,HIGH); + pinMode(M0,OUTPUT); + pinMode(M1,OUTPUT); + pinMode(M2,OUTPUT); + +// motor dir and pulse pin set as outputs + pinMode(Zdir,OUTPUT); pinMode( motorPulse ,OUTPUT); + digitalWrite(M0, HIGH); + digitalWrite(M1, HIGH); + digitalWrite(M2, HIGH); +} + +void loop() { + + int choice = Serial.read(); + + switch(choice){ + + case('T') : digitalWrite(Zdir,LOW); delayMicroseconds(10); doZSteps(1); ZcurrStep=ZcurrStep-1; // T == Z up by 5 counts + break; + + case('G') : digitalWrite(Zdir,HIGH); delayMicroseconds(10); doZSteps(1); ZcurrStep=ZcurrStep+1; // G == Z down + break; + + case('A') : digitalWrite(Zdir,LOW); delayMicroseconds(10); doZSteps(20); + break; + + case('D') : digitalWrite(Zdir, HIGH ); delayMicroseconds(10); doZSteps(20); + break; + + case('M') : gotoZSetStep(getStep()); + break; + + case('Q') : gohome(); + break; + + } +} + +void doZSteps(long num) { + while (num > 0 ) { + digitalWrite( motorPulse ,LOW); delayMicroseconds(15); + digitalWrite( motorPulse ,HIGH); delayMicroseconds(15); + num--; + } +} + +long getStep() +{ + long index = 0, inpStep[7]={0,0,0,0,0,0,0}, invalidInput = 0; + long setStep = 0L; + + + for(index=0; index<7; index++ ) + { + while ( Serial.available() < 1 ); + inpStep[index] = Serial.read() - 48; + Serial.println(inpStep[index]); + } + + // DISCARD first byte : MATLAB sends the terminator character there. We need it since if we turn it off, MATALB won't read the Tx from this arduino + // ALSO igmore the second byte : that's the sign symbol + setStep = (inpStep[1]*100000) + (inpStep[2]*10000) + (inpStep[3]*1000) + (inpStep[4]*100) + (inpStep[5]*10) + (inpStep[6]*1) ; + //Serial.println(inpStep[index]) + // check what sign was sent. If it was anything other than a '-' then dont worry + if (inpStep[0] + 48 == '-' ) { setStep = setStep*(-1); } + Serial.println(setStep); + return setStep; +} + +void gotoZSetStep(long ZsetStep) +{ + //if(ZsetStep > ZMaxStep) {ZsetStep = ZMaxStep;} + long stepstodo = abs(ZsetStep - ZcurrStep)/5 ; + Serial.println(ZcurrStep); + Serial.println(stepstodo); + + if (ZsetStep > ZcurrStep) + { needtocheckZmovement=0 ; + Serial.println(ZcurrStep); + Serial.println("hi"); + digitalWrite(Zdir,HIGH); delayMicroseconds(10); ZcurrStep=ZsetStep; doZSteps( stepstodo ); } + + if (ZsetStep < ZcurrStep) + { + needtocheckZmovement=1 ; + Serial.println(ZcurrStep); + Serial.println("hello"); + digitalWrite(Zdir,LOW); delayMicroseconds(10); ZcurrStep=ZsetStep; doZSteps( stepstodo ); + Serial.println(ZcurrStep); + } +} + +void gohome() +{ + int v=digitalRead(6); + //Serial.println(v); + while(v<1) + { gotoZSetStep(6400); + ZcurrStep=0L; + v=digitalRead(6); + Serial.println(v); + + //gotoZSetStep(limitTOZfocus); + } + //doZSteps( 100000 ); + ZcurrStep=0L; +}