Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.08.2011, 05:58   #1
SonicBob
Форумчанин
 
Регистрация: 30.05.2011
Сообщений: 133
Сообщение Подвисает программа на Delphi, которая считывает данные с COM-порта(весы), строит график

практика горит по делфи!
для практики в унивра надо было написать программу котороя считывает данные с ком порта(весы) и по ним строит график, вдвоем с еще 1 несчастным мы смогли понять как открывать и считывать данные, преобразовывать результат в адекватнй вид, но все это только отдельно и на маленький кусках данных, когда попытались сделать это все в одну функцию либо ничего не происходит либо она вешает программу
помоги понять почему?
и как это исправить, просто не понятно почему по отдельности все работает а пачкой нет


______________
Название темы по правилам форума должно адекватно отражать суть решаемой задачи/проблемы.
на этот раз я исправил.

Модератор.
Вложения
Тип файла: rar ком порт практика.rar (270.6 Кб, 47 просмотров)

Последний раз редактировалось Serge_Bliznykov; 18.08.2011 в 20:16.
SonicBob вне форума Ответить с цитированием
Старый 18.08.2011, 02:42   #2
SonicBob
Форумчанин
 
Регистрация: 30.05.2011
Сообщений: 133
По умолчанию

и никто не знает почему это виснит?
SonicBob вне форума Ответить с цитированием
Старый 18.08.2011, 18:51   #3
Neobrat
Форумчанин
 
Регистрация: 10.12.2007
Сообщений: 124
По умолчанию

Цитата:
Сообщение от SonicBob Посмотреть сообщение
и никто не знает почему это виснит?
просто чтоб вашем коде что то обнаружить, надо для начало много выпить. ))

ComPort

подвисание возможно(скорее всего сдесь)
WaitForSingleObject(FOverRead.hEven t, INFINITE)
будет ждать до тех пор пока что нить не запишеться в ком порт оборудованием.


raise приостоновит выполнение потока!

ReadFile(FComPort.FPort, FBuf, FRead, FRead, @FOverRead)
вместо второго FRead необхожимо отправить свободную переменую, она возврашает сколько же на самом деле прочиталось


FBuf: array[0..$FF] of Byte;
и в то же время
FRead := ComStat.cbInQue;

if FRead > 0 then
if not ReadFile(FComPort.FPort, FBuf, FRead, FRead, @FOverRead) then

Буфер может принять только 255 байт, а если даных будет больше??
затрет область памяти

for i := Low(FBuf) to FRead - 1 do
arrBytes[i] := FBuf[i];

FRead вы уверены что Fread будет содержать то число которое прочиталось исходя из выше написанного, я нет.
Если уж используете Low для определения ижней границы, то используете High(вроде) для определения верхний границы
а лучше (раз знакомы с ZeroMemory) используйте CopyMemory(@arr1[0], @arr2[0], FRead - 1) будет более быстрее чем цикл for
тем более вы на это время тормозите поток из за Synchronize(DoRead);

то же самое про for i := 0 to High(ReadBytes) do



until (m > SIZE) or (found = true); //
if (found = true) then // найдя совпадение

(found = true) замените просто Found разницы не заметите



след. коментарий просто убил
// ппц я знаю, но я не знаю как сделать нормально


вместо
m := 0; //
repeat //
if simvolucs2[m] = c1 // которое ищем в массиве1 (метод "простого" перебора)
then
found := true
else
m := m + 1; //
until (m > SIZE) or (found = true); //
можно сделать
var
intPos: Integer;
intPos := Pos(c1,simvolucs2[m]);
if IntPos = 0 then
// нет совпадений
else
// есть совпадения




тоже комент убил
for e := 0 to 11 do
ListBox5.Items.Delete(0); // почему именно 0 я хз но почему то с 0 стирает нужные строки

вы скорее всего с толкнудись с проблеймой, что если написать так
ListBox5.Items.Delete(e);
то почему то происходит ошибка, верно?
Открою вам страшную тайну, когда вы удалили один элемент, то размер масивва Items стал меньше, и вы гдето на 5 шаге выйдите за границы массива


во! а здесь то почему то догодались идти с конца массива
for i := ListBox5.Items.Count - 1 downto 0 do
if Trim(ListBox5.Items[i]) = '' then
ListBox5.Items.Delete(i);


str := ListBox1.Items.Count;
Label2.caption := floattostr(str);

эм..
1. зачем это делать в цыкле
2. зачем использовать floattostr вместо IntToStr
3. можно либо в начале либо в конце
Label2.caption := IntToStr(Length(ReadBytes));


for i := Low(arrBytes) to High(arrBytes) do
arrBytes[i] := Ord(strWrite[i + 1]);

ем какую Delphi используете?
начинаея с Delphi 2006 вроде, вы получите то совсем то что хотете сделать..


а вот это пахнет утечкой памяти уже
SetLength(arrBytes, Length(strWrite));

for i := Low(arrBytes) to High(arrBytes) do
arrBytes[i] := Ord(strWrite[i + 1]);

Port.Write(arrBytes);

arrBytes := nil; - не освобождает память


application.processmessages;
раз он так вам нужен, то вставсте в цикл, вне цикла он вам не поможет


все, на больше меня не хватило )))
больно весело..
мои пожелания вам,
1. Избавиться от всех Хинтов и Варнингов
2. Дать всем переменым человеческие имена, что бы было понятно что для чего используеться
3. unit ComPort; сделать одним классом - потоком
4. выделить участки кода в отдельные процедуры и функции
5. дать компонентам на форме так же человеческие имена
6. и еще раз вдумчиво посмотреть свой код,
Русский язык не мой конёк
Neobrat вне форума Ответить с цитированием
Старый 20.08.2011, 09:55   #4
SonicBob
Форумчанин
 
Регистрация: 30.05.2011
Сообщений: 133
По умолчанию

сразу расскажу подробней про ситуацию, программу делаем ради практики с однокурсником, с ком портами не работали даже на лекциях не было а тут такое чудо, он начинал делать кусок открытия порта и получения данных(есть подозрение что на основе чего того из инета =) )

я немного не точно описал проблему тк поддался своего рода панике, программа считывает с порта данные в виде ascii, если сохранить кусок данных то можем их переводить с помощью того бреда который по ошибке называется кодом ) проблемы начинаются когда попались все загнать в одну "кнопку".

Цитата:
Сообщение от Neobrat Посмотреть сообщение
1. Избавиться от всех Хинтов и Варнингов
2. Дать всем переменым человеческие имена, что бы было понятно что для чего используеться
3. unit ComPort; сделать одним классом - потоком
4. выделить участки кода в отдельные процедуры и функции
5. дать компонентам на форме так же человеческие имена
6. и еще раз вдумчиво посмотреть свой код,

по первым 2м пунктам нет проблем понятно

а вот 3,4 проблемы - нас учили в универе что в поток и функции отдельные можно помещать только абстрактные уравнения которые работают с переменными в которых отдельно загоняются данные, вопрос как в поток загнать такую конструкцию как открытие порта,

Цитата:
Сообщение от Neobrat Посмотреть сообщение
Буфер может принять только 255 байт, а если даных будет больше??
затрет область памяти
надо увеличить буфер или сделать очистку по достижению 255 байт?

Цитата:
Сообщение от Neobrat Посмотреть сообщение
FRead вы уверены что Fread будет содержать то число которое прочиталось исходя из выше написанного, я нет.
мы ни в чем не уверены, даже в том что мы что то знаем )

Цитата:
Сообщение от Neobrat Посмотреть сообщение
во! а здесь то почему то догодались идти с конца массива
хорошо\плохо? тут как раз выскакивает вопрос а что будет если это будет работать с непрерывным поток(лавина) данных

Цитата:
Сообщение от Neobrat Посмотреть сообщение
ем какую Delphi используете?
седьмую

суть в том что надо заставить программу принимать и переводить данные в норм вид а реальном времени (что самое сложное для меня тк остался щас один человек с кем делал щас уехал оставив мне то что я сюда выложил) а дальше я уже как то сам сделаю


дайте ответы на те вопросы, пару хороших статей про потоки и функции а то я не понимаю до конца что делать а от того что мне написали я вабще испугался
SonicBob вне форума Ответить с цитированием
Старый 21.08.2011, 12:03   #5
SonicBob
Форумчанин
 
Регистрация: 30.05.2011
Сообщений: 133
По умолчанию

это добрая традиция ждать ответа на форуме 2е суток?
забыл сказать спасибо модератору за исправление названия
SonicBob вне форума Ответить с цитированием
Старый 22.08.2011, 09:39   #6
SonicBob
Форумчанин
 
Регистрация: 30.05.2011
Сообщений: 133
По умолчанию

Код:
procedure TfrmMain.Button7Click(Sender: TObject); 
var
i,m,t,r,u,e,k:integer;//куча переменных которые как буфер и для границ цикла
c1,s: string ;          //перемные буфера
found: boolean;
X,Y:double;
n: integer ;            // Здесь будет храниться индекс

begin

repeat // кусок отвечающий за перевод из 0038 0037 ... в норм вид числа 
begin
application.processmessages;
i := 0;
c1:=(listbox1.Items.strings[i]);          // в лист1 записываются данные с порта
found := FALSE;                             //масив1 и масив2 это набор символов
m:=0;                                           //
  repeat                                        //
   if simvolucs2[m] = c1                   // которое ищем в массиве1  (метод "простого" перебора)
   then found := TRUE  else m:= m+1;     // в поиске не стал ничего менять пока что пусть сначало все заработает в целом а потом уже буду менять на лучшее 
   until (m > SIZE) or (found = TRUE);    //
   if (found=true)  then                 //  найдя совпадение
       begin
       n:=m;                              //переносим индекс в переменную
       if Trim(simvol[n])<>'' then   //отсеиваем пустые строки
       listbox5.Items.Add(simvol[n]);  //переносим из масива2 используя индекс совпадения первого
       end;                                 
    if listbox5.Count>=16 then
      begin
      repeat // тут я решил таким образом объединять из набора строк с данными в одну строку 
      listbox6.items.add(trim((listbox5.Items[0]+ listbox5.Items[1]+
listbox5.Items[2]+listbox5.Items[3]+
listbox5.Items[4]+listbox5.Items[5]+listbox5.Items[6]+
listbox5.Items[7]+listbox5.Items[8]+listbox5.Items[9]+
listbox5.Items[10]+listbox5.Items[11]))) ;
      for e:=0 to 11 do
      listbox5.Items.Delete(0);
      until (listbox5.Count<12);
    for u :=0 to ListBox6.Count - 1 do
    begin
    s := ListBox6.Items.Strings[u];
    Delete(s, 9, 4);//выкидываем лишние из строки получившейся
    listbox2.Items.Add(s);//рузультат

  end;
end;
end;
помогите передлать все выше написанное что б работало вместе, а не так что если запихать на разные кнопки что б 1)переводила 2)обьединяла 3) удаляло лишние то все работает если на одну то вешает программу(нельзя выйти из неё кроме как через диспечер) и забивает одно ядро полностью


остальное работает норм вроде


вы скорее всего с толкнудись с проблеймой, что если написать так
ListBox5.Items.Delete(e);
то почему то происходит ошибка, верно?

нет нету ошибки "сообщения" просто стирались не те строки вот и все тайну ту знал а вот как сделать это симпатичней я не знаю)

и это ответь кто нить хоть что то понятное для начинающего, очень надо

Последний раз редактировалось SonicBob; 23.08.2011 в 02:51. Причина: пара ошибок в предложениях
SonicBob вне форума Ответить с цитированием
Старый 23.08.2011, 05:12   #7
SonicBob
Форумчанин
 
Регистрация: 30.05.2011
Сообщений: 133
По умолчанию

народ вы же клуб ПРОграмистов что сложного ответить новичку? просмотров почти 200 один 1 это не тема это блог какой то
SonicBob вне форума Ответить с цитированием
Старый 23.08.2011, 07:23   #8
Alar
Александр
Администратор
 
Аватар для Alar
 
Регистрация: 28.10.2006
Сообщений: 17,501
По умолчанию

Давайте вариант где не загнанов в одну кнопку и который работает.

Возможно, простой. Application.ProcessMessages между блоками разного кода вам поможет.
Alar вне форума Ответить с цитированием
Старый 23.08.2011, 10:38   #9
SonicBob
Форумчанин
 
Регистрация: 30.05.2011
Сообщений: 133
По умолчанию

откопал самый первый вариант других не осталось
Код:
procedure TfrmMain.Button9Click(Sender: TObject);// перевод из ascii в адекватный вид + выкидывание пустых строк что б не мешались
const
SIZE=160;
var
i,m,e:integer;
c1: string ; 
found: boolean;
n: integer;
begin
for m:=0 to listBox3.count-1 do 
begin
c1:=(listbox3.Items.strings[m]);  
begin
found := FALSE;                            
i:=0;                                       
repeat                                        
if simvolucs2[i] = c1                    
then found := TRUE  else i:= i+1;  
until (i > SIZE) or (found = TRUE);           
if  found  then                        
begin
n:=i;
 if Trim(simvol[n])<>'' then //Listbox5.Items.Delete(i);
listbox5.Items.Add(simvol[n]);
end;
end;
end;
Код:
procedure TfrmMain.Button10Click(Sender: TObject);//объединяем и выкидывает из строки лишние 
var
e:integer;
s:string;
begin
repeat
listbox6.items.add({trim}((listbox5.Items[0]+ listbox5.Items[1]+
listbox5.Items[2]+listbox5.Items[3]+
listbox5.Items[4]+listbox5.Items[5]+listbox5.Items[6]+
listbox5.Items[7]+listbox5.Items[8]+listbox5.Items[9]+listbox5.Items[10]+listbox5.Items[11]))) ;// про этот ужас ужи тут писали только я не понял как его заменить на нормальный вид
                   for e:=0 to 11 do
                   listbox5.Items.Delete(0);//и про это тоже писали примерно так же понятно для меня было как и верхние 
                   until (listbox5.Count<12);
                    for i :=0 to ListBox6.Count - 1 do
                    begin
                   s := ListBox6.Items.Strings[i];
Delete(s, 9, 4);
listbox2.Items.Add(s);
end;
end;
суть в том что это работает на файлах сохраненных после получения данных и все работает как задумано, но если подключить к компу устройство через ком порт или же объединить весь этот ужас в одну кнопку то программа подвисает

Application.ProcessMessages между блоками не помогло

Последний раз редактировалось SonicBob; 23.08.2011 в 10:42.
SonicBob вне форума Ответить с цитированием
Старый 23.08.2011, 18:48   #10
SonicBob
Форумчанин
 
Регистрация: 30.05.2011
Сообщений: 133
По умолчанию

есть еще идеи у кого?мои то давно закончились
SonicBob вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Разработать программу, которая строит график Функция y =Cos x. bajge Общие вопросы Delphi 2 16.06.2011 18:55
программа, которая считывает цепочку чисел и печатает наиболее длинную, монотонно возрастающую их подпосл alexb81 Помощь студентам 3 31.05.2011 14:03
Delphi, почему не строит график? xMass Помощь студентам 10 30.03.2009 20:32
Программа строит неправильный график xMass Помощь студентам 7 06.06.2008 19:04
Как считывать данные с COM,LPT порта и нарисовать график Sergiu Фриланс 2 22.12.2007 11:53