unit device_thread; interface uses Classes, Windows, SysUtils, D2xxUnit, Dialogs, IzmUnit, DateUtils, user_types, Forms, class_measure; type TIzmResult = IzmUnit.TIzmResult; type TDevice_thread = class(TThread) public points_amount, repeat_amount, params_amount : integer; destructor Destroy; override; constructor Create (suspended:boolean); virtual; private measure: TRDMeasure; decoded_message: params_record; procedure Get_current_measure; { Private declarations } protected procedure Execute; override; procedure Get_message; procedure Update; procedure Update_dev_cond_string_getdata; procedure Update_dev_cond_string_ready; procedure Update_dev_cond_string_decode; procedure Update_message_count; procedure Check_and_load_data; procedure Check_errors; end; Var num: integer; point,povtor: integer; izm_result: TIzmResult; message_: message_Array; execute_t: boolean; implementation uses MainUnit, ConstUnit, DataUnit; { Important: Methods and properties of objects in visual components can only be used in a method called using Synchronize, for example, Synchronize(UpdateCaption); and UpdateCaption could look like, procedure device_thread.UpdateCaption; begin Form1.Caption := 'Updated in a thread'; end; } { device_thread } constructor TDevice_thread.Create(suspended:boolean); begin inherited Create ( suspended ); self.OnTerminate := nil; self.Priority := tpLowest; end; destructor TDevice_thread.Destroy; begin //Suspend; //inherited; //здесь выполняй все действия, что должны выполниться при разрушении потока, // например пошли sendmessage "родительскому" окну //что поток закончил свою работу (при этом Synchronize не нужна) end; procedure TDevice_thread.Execute; begin Get_current_measure; Get_message; end; procedure TDevice_thread.Get_current_measure; begin if Assigned( IzmForm.measure ) then begin self.measure := IzmForm.measure; end; end; procedure TDevice_thread.Get_message; var i, j, k,m: integer; message_begin: boolean; begin points_amount:=24; repeat_amount:=5; params_amount:=7; //устанавливаем длину массива результатов измерений SetLength(izm_result,points_amount+1,repeat_amount+1); //инициализируем массив результатов измерений for i:=1 to points_amount do for j:=1 to repeat_amount do begin izm_result[i,j].R_calc:=0; izm_result[i,j].g0_calc:=0; izm_result[i,j].g1_calc:=0; izm_result[i,j].g2_calc:=0; izm_result[i,j].g3_calc:=0; izm_result[i,j].C_calc:=0; izm_result[i,j].Usm_calc:=0; izm_result[i,j].R_device:=0; izm_result[i,j].g0_device:=0; izm_result[i,j].g1_device:=0; izm_result[i,j].g2_device:=0; izm_result[i,j].g3_device:=0; izm_result[i,j].C_device:=0; izm_result[i,j].Usm_device:=0; for k:= 0 to 2400 do begin izm_result[i,j].U_izm[k]:=0; izm_result[i,j].I_izm[k]:=0; end; end; j:=0; num:=0; povtor:=0; point:=1; message_begin:=false; for i:=0 to length(message_)-1 do message_[i]:=0; execute_t:=true; //ждем сообщение Purge_USB_Device_In; Purge_USB_Device_Out; if IzmForm.Visible then while execute_t do begin repeat Application.ProcessMessages; Get_USB_Device_Status; //проверяем буфер устройства //в этом месте идет загрузка на 100%. Вопрос в том как справится!!! until FT_Q_Bytes > 0; Read_USB_Device_Buffer(1); //читаем буфер устройства i:=FT_In_Buffer[0]; //читаем первое число if i=240 then begin for m:=0 to length(message_)-1 do message_[m]:=0; message_begin:=true;//посылка пошла //Выводим сообщение о получении данных //прогресс бар измерения в 0 Synchronize(Update_dev_cond_string_getdata); end; if message_begin then begin //запоминаем число из посылки message_[j]:=i; inc(j); end; if i=255 then begin //посылка закончилась j:=0; message_begin:=false; Purge_USB_Device_In; Purge_USB_Device_Out; //Вывод сообщения о декодировании посылки Synchronize(Update_dev_cond_string_decode); /// Обрабатываем посылку /// Выводим результаты в лист /// Выводим сообщения об ошибках Synchronize(Update); //Вывод сообщения о готовности прибора к измерению Synchronize(Update_dev_cond_string_ready); // Уведичиваем порядковый номер замера inc(num); //Увеличиваем значение повтора inc(povtor); //Загружаем информацию в базу данных Synchronize(Check_and_load_data); //проверяем условие перехода на новую точку Synchronize(Update_message_count); for i:=0 to length(message_)-1 do message_[i]:=0; Purge_USB_Device_Out;//очищаем буфер end; end; //Suspend; end; procedure TDevice_thread.Update; begin end; procedure TDevice_thread.Update_dev_cond_string_getdata; begin //Выводим сообщение о получении данных end; procedure TDevice_thread.Update_dev_cond_string_ready; begin end; procedure TDevice_thread.Update_dev_cond_string_decode; begin end; procedure TDevice_thread.Update_message_count; begin end; procedure TDevice_thread.Check_and_load_data; var list:TStringList; //i,j, k: Integer; str, y1, y2:string; tmp:array of extended; begin setLength(tmp,params_amount+1); //Проверяем значения на ошибки Check_errors; //в массив результатов записываем декодированное сообщение izm_result[point,povtor]:=decoded_message; //создаем запись об измерении with SQL_DM.mysql_query4 do begin Connection:=SQL_DM.mysql_con; SQL.Clear; //Создаем запись об измерении. SQL.Add('SELECT * FROM `rd`.`rd_izmerenia` WHERE'); SQL.Add(' `id`='+IzmForm.Izm_gen_num.Caption+';'); try Active:=true; except // end; if SQL_DM.mysql_DSQ4.DataSet.IsEmpty then begin SQL.Clear; //Создаем запись об измерении. SQL.Add('INSERT INTO `rd`.`rd_izmerenia` ('); SQL.Add('`id` ,'); SQL.Add('`date` ,'); SQL.Add('`patient_num` ,'); SQL.Add('`opisanie`'); SQL.Add(')'); SQL.Add('VALUES ('); SQL.Add(' '''+IzmForm.Izm_gen_num.Caption+''' , NOW() , ''' + MainForm.patient.Get_current_patient_ID + ''', ' ); SQL.Add(' '''+IzmForm.izm_opisanie_edit.Text+''');'); try Execute; except // end; end; end; //проверяем не было ли уже записано в базу параметры текущей точки: with SQL_DM.mysql_query4 do begin Connection:=SQL_DM.mysql_con; SQL.Clear; SQL.Add('SELECT * FROM `rd`.`'+table_znacheniya_name+'` WHERE ('); SQL.Add(' (`izm_num`='+IzmForm.Izm_gen_num.Caption+') AND ('+ ' `param_num`='+inttostr(3)+') AND ('+ ' `povtor_num`='+inttostr(povtor)+') AND ('+ ' `point_num`='+inttostr(point)+'));'); //showmessage(SQL.Text); try Active:=true; except // end; end; //берем информацию с прибора tmp[1]:=decoded_message.R_device; tmp[2]:=decoded_message.g0_device; tmp[3]:=decoded_message.g1_device; tmp[4]:=decoded_message.g2_device; tmp[5]:=decoded_message.g3_device; tmp[6]:=decoded_message.C_device; tmp[7]:=decoded_message.Usm_device; //y1:=IzmForm.get_string(decoded_message.U_izm); //y2:=IzmForm.get_string(decoded_message.I_izm); //showmessage (inttostr(SQL_DM.mysql_DSQ4.DataSet.RecordCount)); if not (SQL_DM.mysql_DSQ4.DataSet.RecordCount=0) then //в случае если апдейт begin //создаем стринглист для загрузки в него запроса к базе list:=TStringList.Create; list.Clear; for k:=1 to params_amount do begin list.Add('UPDATE `rd`.`'+table_znacheniya_name+'` SET `znach`='); DecimalSeparator:='.'; str:=floattostrf(tmp[k],ffExponent, 6, 2); list.Add(''''+str+''''+' WHERE ((`param_num`='+inttostr(k+2)+ ') AND (`izm_num`='+IzmForm.Izm_gen_num.Caption+ ') AND (`point_num`='+inttostr(point)+ ') AND (`povtor_num`='+inttostr(povtor)+')); '); //list.Add(str); end; //showmessage(list.Text); list.SaveToFile('znachzapros.txt'); end else //в случае если надо записать ///////////////////////////////// /// /// Здесь остановились чтобы сделать Usm /// /// /// ////////////////////// begin //создаем стринглист для загрузки в него запроса к базе list:=TStringList.Create; with list do begin Clear; Add('INSERT INTO `rd`.`'+table_znacheniya_name+'` ('); Add('`id` ,'); Add('`izm_num` ,'); Add('`param_num` ,'); Add('`point_num` ,'); Add('`povtor_num` ,'); Add('`znach` ,'); Add('`znach_UI`'); Add(')'); Add('VALUES'); end; for k:=1 to params_amount do begin DecimalSeparator:='.'; str:='(NULL , '''+ IzmForm.Izm_gen_num.Caption+''', '''+ inttostr(k+2)+''', '''+ inttostr(point)+''', '''+ inttostr(povtor)+''', '''; str:=str+floattostrf(tmp[k],ffExponent, 6, 2)+''',' +'NULL'; if (k=params_amount) and not(MainForm.izm_write_ui.Checked) then str:=str+')' else str:=str+'),'; list.Add(str); end; list.SaveToFile('znachzapros.txt'); end; //непосредственная запись в базу with SQL_DM.mysql_query4 do begin Connection:=SQL_DM.mysql_con; SQL.Clear; SQL.AddStrings(list); try Execute; except // end; end; list.Destroy; {//запись текущего измерения в виде sql запросов в текстовый файл AssignFile(file_record, 'last_measute.dat'); Assigns the Filename if (point=1) and (povtor=1) then ReWrite(file_record) else Append(file_record); Writeln(file_record, izm_result[i,j].R+#9+ izm_result[point,povtor].G0+#9+ izm_result[point,povtor].G1+#9+ izm_result[point,povtor].G2+#9+ izm_result[point,povtor].G3+#9+ izm_result[point,povtor].C;); Closefile(file_record); //Closes file F} //если пришли к концу всего измерения: 24 точки по 5 повторов if (point=points_amount) and (povtor=repeat_amount) then //выводим сообщение о законченности измерения if MessageBox(0, PChar(izm_izm_end), PChar(izm_caption_message), MB_ICONQUESTION or MB_OKCANCEL )=id_OK then //если пользователь выбрал загрузку begin IzmForm.Izm_stop_btn.Caption:=izm_unit_end_measurment_btn_label; Suspend; IzmForm.Close; MainForm.GoToLookResults.Execute; { //проходим по каждой точке, каждому повтору по точке, и каждому параметру for i:=1 to points_amount do begin //запись полученных значений for j:=1 to repeat_amount do begin // во временный файл заносим результаты для данной точки и повтора tmp[1]:=izm_result[i,j].R; tmp[2]:=izm_result[i,j].G0; tmp[3]:=izm_result[i,j].G1; tmp[4]:=izm_result[i,j].G2; tmp[5]:=izm_result[i,j].G3; tmp[6]:=izm_result[i,j].C; y1:=IzmForm.get_string(izm_result[i,j].U_izm); y2:=IzmForm.get_string(izm_result[i,j].I_izm); //по параметрам, и сразу же формируем строку для записи for k:=1 to params_amount do begin DecimalSeparator:='.'; str:='(NULL , '''+ IzmForm.Izm_gen_num.Caption+''', '''+ inttostr(k+2)+''', '''+ inttostr(i)+''', '''+ inttostr(j)+''', '''; str:=str+floattostrf(tmp[k],ffExponent, 6, 2)+''',' +'NULL'; if (i=points_amount) and (j=repeat_amount) and (k=params_amount) and not(IzmForm.izm_write_ui.Checked) then str:=str+')' else str:=str+'),'; list.Add(str); end; //если необходимо также записывать значения тока и напряжения if IzmForm.izm_write_ui.Checked then begin str:='(NULL , '''+ IzmForm.Izm_gen_num.Caption+''', '''+ inttostr(1)+''', '''+ inttostr(i)+''', '''+ inttostr(j)+''', '''+floattostr(0)+''',' +y1+'),'; list.Add(str); str:='(NULL , '''+ IzmForm.Izm_gen_num.Caption+''', '''+ inttostr(2)+''', '''+ inttostr(i)+''', '''+ inttostr(j)+''', '''+floattostr(0)+''',' +y2+')'; if not((i=points_amount) and (j=repeat_amount) and (k=6)) then str:=str+','; list.Add(str); end; end; end; list.SaveToFile('znachzapros.txt'); //формируем время измерения GetSystemTime(s); date:=inttostr(s.wYear)+'-'+inttostr(s.wMonth)+'-'+inttostr(s.wDay)+' '+ inttostr(s.wHour+4)+':'+inttostr(s.wMinute)+':'+inttostr(s.wSecond); //непосредственная запись в базу with SQL_DM.mysql_query4 do begin Connection:=SQL_DM.mysql_con; SQL.Clear; //Создаем запись об измерении. Почему только здесь??? SQL.Add('INSERT INTO `rd`.`rd_izmerenia` ('); SQL.Add('`id` ,'); SQL.Add('`date` ,'); SQL.Add('`patient_num` ,'); SQL.Add('`opisanie`'); SQL.Add(')'); SQL.Add('VALUES ('); SQL.Add(' '''+IzmForm.Izm_gen_num.Caption+''' , '''+date+ ''', '''+IzmForm.Izm_pat_id.Caption+''', '); SQL.Add(' '''+IzmForm.izm_opisanie_edit.Text+''');'); Execute; Active:=false; SQL.Clear; SQL.AddStrings(list); try Execute; except // end; end; list.Destroy; //запись в файл токов и напряжений {list:=Tstringlist.Create; str:=''; for i:=1 to 24 do for j:=1 to 5 do begin ///формируем следующим образом: /// создаем табулированный файл для последующего экспорта в эксель /// в первой строчке номер точки, номер повтора /// потом столбец значений str:=str+'точка: '+inttostr(i)+'повтор: '+inttostr(j)+'U'+#9+ 'точка: '+inttostr(i)+'повтор: '+inttostr(j)+'I'+#9; end; list.Add(str); str:=''; for i:=1 to 24 do for j:=1 to 5 do for k:=0 to 2400 do begin begin str:=str+inttostr(izm_result[i,j].U_izm[k])+#9+inttostr(izm_result[i,j].I_izm[k])+#9; list.Add(str); end; list.SaveToFile(IzmForm.izm_opisanie_edit.Text+'номер пациента: '+IzmForm.Izm_pat_id.Caption+'точка №:'+inttostr(i)); end; end; showmessage('Токи и напряжения записаны'); list.Destroy;} end; // IzmForm.load_data_to_database(izm_result); end; procedure TDevice_thread.Check_errors; begin ///////////////////////////////// //Обработка ошибок в измерении // ///////////////////////////////// if decoded_message.U_mis then begin //если была ошибка, то обнуляем результаты if MainForm.Izm_null_result_CB.Checked then begin decoded_message.R_calc:=0; decoded_message.C_calc:=0; decoded_message.g0_calc:=0; decoded_message.g1_calc:=0; decoded_message.g2_calc:=0; decoded_message.g3_calc:=0; decoded_message.Usm_calc:=0; decoded_message.R_device:=0; decoded_message.C_device:=0; decoded_message.g0_device:=0; decoded_message.g1_device:=0; decoded_message.g2_device:=0; decoded_message.g3_device:=0; decoded_message.Usm_device:=0; end; end; if decoded_message.I_mis then begin //если была ошибка, то обнуляем результаты if MainForm.Izm_null_result_CB.Checked then begin decoded_message.R_calc:=0; decoded_message.C_calc:=0; decoded_message.g0_calc:=0; decoded_message.g1_calc:=0; decoded_message.g2_calc:=0; decoded_message.g3_calc:=0; decoded_message.Usm_calc:=0; decoded_message.R_device:=0; decoded_message.C_device:=0; decoded_message.g0_device:=0; decoded_message.g1_device:=0; decoded_message.g2_device:=0; decoded_message.g3_device:=0; decoded_message.Usm_device:=0; end; end; end; end.