Получение данных на Делфи
- Войдите на сайт для отправки комментариев
Пнд, 30/04/2012 - 00:45
Доброй ночи!
У меня возникла проблема при сравнении данных переданных с ардуино на делфи. вот собственно кусок кода:
procedure TMainForm.ReadDataClick(Sender: TObject); Var RCBuf:TBytes; //Буфер данных для приема nToRead:Cardinal; //Число байт для чтения nRead:Cardinal; //Число прочитанных байт begin nToRead:=6; //считываем число байт для чтения из структуры nToReadLabel.Caption:=IntToStr(nToRead); //выводим на форму число байт для чтения SetLength(RCBuf,nToRead+1); RCBuf[nToRead+1]:=0;// конец строки PAnsiChar ReadFile(Port,RCBuf[0],nToRead,nRead,nil); //считываем данные nReadLabel.Caption:=IntToStr(nRead); //выводим на форму число прочитанных байт if (nRead <> 0) then begin if (PAnsiChar(RCBuf) = PAnsiChar('s')) then //вот это сравнение SLabel.Caption:='S'; if (PAnsiChar(RCBuf) = PAnsiChar('a')) then //и это ALabel.Caption:='A'; Finalize(RCBuf); end; end;
что я делаю не правильно?
>что я делаю не правильно?
Плохо задаете вопросы. Совершенно упускаете из виду, что остальные не в контексте вашей проблемы.
Это ардуино.ru, а не "шоу экстрасенсов" или клуб любителй "в угадайку".
Хотя может быть и найдутся любители поперебирать варианты "что и как вы шлете, что вы ожидаете увидеть, что вы видите, как подключили и т.п."
P.S. Еще можете поиском воспользоватся, Delphi иногда встречается на форуме, не уверен, но может и найдете чего полезного.
Если проблема в коде то выкладываю полностью.
просто уже сломал голову почему они неравные
if (PAnsiChar(RCBuf) = PAnsiChar('s')) then
SLabel.Caption:='S';
просто уже сломал голову почему они неравные
if (PAnsiChar(RCBuf) = PAnsiChar('s')) then
SLabel.Caption:='S';
Есть бредовая идея, что операнды не совпадают:
a) по типам и
b) по кодировкам
Любой из этих причин достаточно для того, чтобы порушить условие, а уж двух-то...
Кроме того - расскажите нам о том, что возвращает функция (или преобразование типа?) PAnsiChar?
Есть бредовая идея...
Решили, таки, в угадайку поиграть?
>Кроме того - расскажите нам о том, что возвращает функция (или преобразование типа?) PAnsiChar?
Похоже что это, не функция, а преобразование типа. Если это так, то возможно товарищь пытается сравнить указатели, а не значения куда они указывают. Причем правый вообще указывает на какой-то случайную ячейку памяти (с адресом 's').
Я уже не говорю, что не видно что-бы он бежал по символам в цикле. То есть если попался случайный мусор (например при включении дуины она плюнула пару символов в порт), то - привет.
Да и, возможно, он должен обладать не дюженной реакцией, что-бы нажать на форме кнопку чтения из порта, ровно в тот момент когда дуина что-то послала (какого-нибудь while ожидания данных в порте - тоже не видно).
А может тупо скорости не совпадают, или вообще порт не тот (скопированный из какого-то примера).
Да еще кучу всего нафантазировать можно. Только смысл? Если сам топик-стартер не торопится сузить область поиска. Значит не шибко оно ему и нужно. Обычное "Товарищи ученые, у меня в подполье уже третий год происходит какой-то стук. Объясните отчего и почему?"
> Кроме того - расскажите нам о том, что возвращает функция (или преобразование типа?) PAnsiChar?
это не функция, я пытаюсь преобразовать тип. извиняюсь за не полноту инфрмации в этом деле я начинающий.
я попытаюсь объяснить в чем проблема.
у меня ардуино посылает сигнал о нажатии кнопки, то есть передает символ "s". и мне надо на делфи сделать действие которое бы реагировала бы на это нажатие. так что бы если пришел символ "s", то сделать одно. а если "а", тогда - другое действие. в дальнейшем планирую эту проверку сделать на таймере. в интернете нашел этот исходник который соединяется к ком-порту и выводит с нее информацию. с этим проблем нету, если сделать SLabel.Caption:=PAnsiChar(RCBuf), то выводится нормальный символ.
> Я уже не говорю, что не видно что-бы он бежал по символам в цикле.
это как? дайте направление?
> что-бы нажать на форме кнопку чтения из порта, ровно в тот момент когда дуина что-то послала
на счет этого думаю проблем нету. так как SLabel.Caption:=PAnsiChar(RCBuf) выводит все то что отправлялась в порт.
> А может тупо скорости не совпадают, или вообще порт не тот
это все настроено
если требуется могу выложить код ардуино
leshak вас таки опередил - вам необходимо сравнивать не указатели, а содержимое областей памяти, на которые указывают указатели.
Вам также необходимо быть пооисторожнее с кодировками - нен сравнивать ASCII-символ (именно такой вы скорее всего получите от микроконтроллера, c ANSI. Для латиницы это не слишком критично, а вот кириллица может доставить в этом отношении мноооого радости.
В общем - разберитесь с этими пунктами. Не поможет - будем покопаться дальше. Но на интенсивную помощь не надейтесь. Вот я, напрмер, морковкины семечки сегодня сажал, а завтра лук хоронить буду. Да и шашлык уже на шампуры просится...
спасибо! приятного вам времепровождения.
постараюсь разобраться
>у меня ардуино посылает сигнал о нажатии кнопки, то есть передает символ "s"
Может быть. А может и нет.
>если требуется могу выложить код ардуино
Ну а почему сразу этого не сделать? Тут же нет оплаты трафика. Зато сразу куча вариантов отпала бы.
Кстати, а обычным сериал монитором нормально видите посылки из ардуины?
>я попытаюсь объяснить в чем проблема.
Ну и где в стартовом посте описание проблемы? Есть указание строчек в которых вы подозреваете проблему, но описания - нет. Вообще не читаются символы, или читаются но не все, или читаются но не те... что показывает nReadLabel? И т.п. мы же не видим вашего монитора. Только то что вы написали. А причина может быть в том что вы посчитали "не важным". Поэтому чем точнее вы опишите картину - тем больше шансов на помощь (но не гарантия).
>> Я уже не говорю, что не видно что-бы он бежал по символам в цикле.
>это как? дайте направление?
Ну это вообще не ардуино вопрос, а вопрос программирования на дельфи. Я уже лет десять его не видел/трогал.
Просто вот вы вычитали 6 симвовлов, своим сравнением (PAnsiChar(RCBuf) = PAnsiChar('s') вы какой из них стравниваете с 's', первый, третий, последний?
Возможно вам нужно сделать цикл и сравнивать как-то так (PAnsiChar(RCBuf+i) = PAnsiChar('s'), где i - номер символа который хотите сравнить. Как именно точно сразвинвать - смотрите книги по дельфи. Разделы работы со строками и указателями.
Но я бы даже, не бегал по этим массивам. Зачем читать сразу все 6-ть байт? Не проще читать по одному символу вычитать из порта и сравнивать?
Еще возможные грабли: Я так понял что PAnsiChar - это указатель. То есть "адрес в памяти" где хранится значение. Возможно вы сравниваете именно адресс буффера RCBuf с адресом где хранится символ 's'. Естественно они будут разными всегда. Вам же нужно сравнивать значения, а не "где они лежат". Возможно нужно делать как-то так PAnsiChar(RCBuf+i)^='s'
Гугланите "дельфи строки сравнение символы". Не думаю что вы останетесь в неведении как это делать.
Отложите, вначле в сторону ардуину. Научитесь в строке на дельфи находить символ. Напишите функцию которая говорит если в строке символ 's' или нет.
Почитайте базовые функции работы со строками. Наверняка у них есть, какая нибуть готовая функция типа contains, которая говорит есть подстрока/символ в строке или нет.
Научитесь просто сравнивать символы, не пришедшие из ардуины, а веденные в поле формы. Сократите количество неизвестного. Раздробите задачу на части. Вначале "умею сравнивать", потом "умею принимать данные из ардуины", а уж потом "умею принять данные и сравнить их".
Следующие:
Вы уверены что кнопку на ардуине и кноку "читать даныне из порта" нажимаете обсолютно одновременно? Скорее всего вы "запустили прогу", она послушала порт - ничего не нашла. И вышла из функции ReadDataClick. Потом вы ее жмете кнопку ардуины, она что-то посылает... но ее никто уже не слушает. Или вы эту ReadDataClick вызываете по таймеру? Тогда почему click? (вообщем видите, опять гадать нужно, просто потмоу что вы не описали что-же именно вы видите на экране).
Обычно делают пустой цикл, ожидающий "пока что-нибудь не прийдет".
Примерно так:
while(!port.avaliable()){} // ждем пока в порту не появятся какие-то данные
Хотя, возможно это (ожидание) уже сделанно внутри функции ReadFile.
Но опять, таки сработает она только один раз. И выйдет. Больше не будет слушать дуину.
Значить опять-таки нужно все это обернуть в какой-то цикл бесконечный (и прерывать его какой-нибудь кнопкой типа "прекратить слушать порт").
Общий подход такой (псевдокодом).
спасибо за ответ!
попробую разобраться с вашими советами.
за не информативность прошу прощения. первый раз пишу на форуме)))) в последующем постараюсь писать по конкретней.
выкладываю код для ардуино. на обычном сериал монитре вижу все нормально.