не могу найти ошибку в синтаксисе
- Войдите на сайт для отправки комментариев
Доброго времени суток всем
Пробую подключить датчик температуры DS18B20 к ардуине меге
пример взял вот отсюда: _http://arduino.net.ua/Arduino_articles/Arduino_proekty/Podkljuchaem%20datchik%20temperatury%20DS18S20%20ili%20DS18B20%20k%20Arduino/
определить датчик по первому куску кода смог, только кавычки в коде все ухеали (там, в примере) и пробел лишний был. Ну да бог с ним, разобрался.
А вот получить данные от датчика никак не могу, ошибка на ошибке.
Вот код, который пытаюсь скомпилировать:
#include <OneWire.h> //init the one wire interface on pin 12 OneWire ow (12); //write here the address you receive from the other program byte sensor[8] = {0x28, 0xc, 0x47, 0xb5, 0x00, 0x00, 0x00, 0xcb}; void setup (void) { Serial.begin (9600); } void writeTimeToScratchpad (byte* address){ //reset the bus ow.reset (); //select our sensor ow.select (address); //CONVERT T function call (44h) which puts the temperature into the scratchpad ow.write (0x44,1); //sleep a second for the write to take place delay (1000); } void readTimeFromScratchpad (byte* address, byte* data){ //reset the bus ow.reset (); //select our sensor ow.select (address); //read the scratchpad (BEh) ow.write (0xBE); for (byte i=0;i<9;i++){ data[i] = ow.read (); } } float getTemperature (byte* address){ int tr; byte data[12]; writeTimeToScratchpad (address); readTimeFromScratchpad (address,data); //put in temp all the 8 bits of LSB (least significant byte) tr = data[0]; //check for negative temperature if (data[1] > 0x80){ tr =! tr + 1; //two's complement adjustment tr = tr * -1; //flip value negative. } //COUNT PER Celsius degree (10h) int cpc = data[7]; //COUNT REMAIN (0Ch) int cr = data[6]; //drop bit 0 tr = tr >> 1; //calculate the temperature based on this formula: //TEMPERATURE = TEMP READ — 0.25 + (COUNT PER Celsius Degree — COUNT REMAIN)/ (COUNT PER Celsius Degree) return tr—(float)0.25+(cpc — cr)/(float)cpc; } //fahrenheit to celsius conversion float f2c (float val){ float aux = val — 32; return (aux * 5 / 9); } //celsius to fahrenheit conversion float c2f (float val){ float aux = (val * 9 / 5); return (aux + 32); } void loop (void) { float temp; float tmp2; tmp2 = getTemperature (sensor); temp = c2f (tmp2); Serial.print ( "Temperature ="); Serial.print (temp); Serial.print (" F or"); Serial.print (tmp2); Serial.println (" C"); //wait 30 seconds delay (30000); }
а вот ошибки, которые выдает Arduino IDE:
in_Dallas:62: error: stray '\' in program in_Dallas:62: error: stray '\' in program in_Dallas:67: error: stray '\' in program in_Dallas.cpp: In function 'float getTemperature(byte*)': in_Dallas:62: error: expected ';' before 'u2014' in_Dallas:62: error: expected primary-expression before 'float' in_Dallas:62: error: 'u2014' was not declared in this scope in_Dallas:62: error: expected `;' before numeric constant in_Dallas.cpp: In function 'float f2c(float)': in_Dallas:67: error: expected ',' or ';' before 'u2014'
никак не пойму, где он находит эту '\' и откуда вылезли 'u2014'
на СИ раньше не программировал, это первый опыт подобного рода, так что я весь потерялся
направьте на путь истинный, где копать? :)
В каталоге, в котором установлена ваша Arduino IDE, найдите подкатклог libraries, а в нем - OneWire. Там, по идее, должен быть файл in_Dallas.cpp (какая-то хрень для поддержки микросхем от Dallas Semiconductor??), в котором компиллятор находит ошибки.
Кстати, может быть, у вас библиотека OneWire какая-то левая? Откуда брали?
ЗЫ: OneWire.zip по вышеприведенной ссылке? 2008 года выпечки? Возьмите что-нибудь посвежее. Отсюда, например (ссылка для скачки на словах "The latest version of the library is ")
неа, in_Dallas - это имя скетча, другого с этим именем ничего нет, но и в папке со скетчем собсно файл in_Dallas.ino
а вот in_Dallas.cpp нигде не вижу, может этот файл при компиляции где-то создается?
Arduino IDE вроде использует компилятор от СИ (могу и ошибаться)
понять бы на что конкретно ругается
первая ошибка возникает на 62 строке, а там комментарий, ни хрена не понимаю
ежели закомментировать строку после комментария (return tr—(float)0.25+(cpc — cr)/(float)cpc;), то первая ошибка уходит, такое ощущение, что ругается именно на это сложное выражение.
А библиотеку OneWire я брал с разных мест, в частности с той страницы, откуда пример взят, в поведении скетча при этом ничего не менялось.
По Вашей ссылке версию тоже забирал, она щас и стоит. Версия Arduino IDE кстати, стоит 1.000
На более ранних версиях IDE (0022, 0023) не пробовали?
ЗЫ: загрузил-таки этот скетч к себе. Получил ту же хрень. Пришлось присмотреться поближе. Выяснилось - у вас в некоторых местах дефисы вместо минусов стоят (в редакторе IDE они сужественно - арза в полтора - длиннее минусов).
Перепишите "гнилые" символы
твою ж налево, вот никак не мог подумать на такую разницу, все-таки гнилой пример, ох гнилой
спасибо, пойду переправлять
а из ранних пробовал 0017, то же самое
такс, получилось, теперь надо разобраться в полученных данных, как-то он мне неправильно кажет (40 градусов, а если взяться за датчик пальцами, то все 90)
може конечно с подключением датчика чой-то не то, надо поглядеть
за подсказку спасибо, эту гниль я не разглядел
мне вот непонятно что это за арифметические действия такие :
tr =! tr + 1;
и
tr = tr >> 1;
в описании языка не нашел, что это
мне вот интересно, а расчет температуры хоть верный?
//calculate the temperature based on this formula:
//TEMPERATURE = TEMP READ — 0.25 + (COUNT PER Celsius Degree — COUNT REMAIN)/ (COUNT PER Celsius Degree)
return tr-(float)0.25+(cpc - cr)/(float)cpc;
не блин, я шизею
при комнатной температуре данные выходят:
почти как у автора в статье
пойду искать ошибку в формуле
мне вот непонятно что это за арифметические действия такие :
tr =! tr + 1;
Читаем arduino.ru/Reference/Boolean про ! (логическое отрицание)
При этом держим в уме, что в ардуино нет отдельного типа Boolean. Любое числовое значение отличное от нуля будет интерпретироватся как "Истина", а ноль как "Ложь". Точно так же и любой логический оператор можно рассматривать как числовую функцию, которая возвращает либо 0, либо единицу.
Поэтому эту срочку можно интепретировать так: !tr вернет ноль, если tr не равно нулю, и единицу если tr равно нулю. Потом к ней прибавится единица и все это сохранится опять в tr. В итоге в tr будет 1, если изначально было 0, и будет 2 если изначально было не ноль.
А еще лучше, напишите скетчик, который который будет возвращать значения tr, !tr, !tr+1 для разных значений tr, поиграйтесь, поймете.
tr = tr >> 1;
в описании языка не нашел, что это
Плохо искали. Arudino.ru это не единственное место где описана ардуина. Есть еще первоисточник http://arduino.cc/en/Reference/Bitshift
А еще можно вспомнить, что ардуино это "такой упрощенный C/C++" и почитать его справочники по ним. Погуглите что-то типа "операторы сдвига в C C++". Вот, например www.softsvet.ru/2007/08/07/operatory_sdviga_v_s_i_s.html
Многие "зубодробительные" вещи типа работы с указателями можно подсмотреть "там". Плюс это пригодится если прийдется разбиратся в каких-то примерах/объяснениях которые пишут "настоящие" микроконтрольщики.
мне вот непонятно что это за арифметические действия такие :
tr =! tr + 1;
и
tr = tr >> 1;
в описании языка не нашел, что это
! - инвертирование. Например, tr=85 (0x55, b01010101) !tr=-86 (0xAA, b10101010) - каждый бит текущего значения меняется на противоположный.
>> - смещение значения переменной на n бит вправо. Например, tr=85 (0x55,b01010101) tr>>1=42 (0x2A, b00101010)
пойду искать ошибку в формуле
Я бы вам посоветовал приглядеться к примеру DS18x20_Temperature из библиотеки OneWire. Он точно работоспособный и отталкиваясь от него вполне можно расширить функциональность в нужную сторону.
А на заборах скетчи срисовывать- занятие весьма нерациональное.
не блин, я шизею
Вот главврачиха - женщина -
пусть тихо, но помешана, -
Я говорю: "Сойду с ума!" - она мне: "Подожди!"
А зачем так сложно?
http://milesburton.com/Dallas_Temperature_Control_Library
В вся кухня работы с датчиком уже "упрятанна под капот". Сразу умеет возвращать как в цельсиях, так и в фаренгейтах (в примере, как раз, работа с цельсиями).
! - инвертирование. Например, tr=85 (0x55, b01010101) !tr=-86 (0xAA, b10101010)
Может вы и правы (поэтому конечно лучше написать демо-скетч и проверить "как оно взаправду"), но я опирался, в своем ответе на http://arduino.cc/en/Reference/HomePage где ! находится в разделе логических операторов, поэтому логично предположить именно поведения "логического" оператора.
А вот то что вы описали больше похоже на оператор Bitwise NOT (~) operator из раздела "bitwise Operators"
http://arduino.cc/en/Reference/BitwiseXorNot
http://arduino.cc/en/Reference/Boolean
В разделе warning (предупреждение, внимание) упоминается что не стоит путать ! и ~. Они хоть и похожи, но... нужно знать какой когда. В переводе, к сожалению, это предупреждение уже отсутсвует. Как и, по большому счету весь раздел "Bitwise Operators"
Честно говоря, шевелился червячок сомнения при написании, но я его героически растоптал. Ибо - лень!
Спасибо за поправку, leshak.
У меня тоже. Поэтому и делал оговорку про "напишите проверочный скетч". Даже сейчас, не смотря на все свои доводы, я не уверен что я прав (нет ардуины под рукой что-бы проверить).
Но, по как минимум в одном случае мы будем правы оба: если "входящий tr будет 0 или 1". Тогда оба "наши" оператора будут работать идентично ;)
спасибо за разбор
со сдвигом понял, просто в ардуиновских учебниках не нашел сего момента, а про "=!" смутило, что в учебниках последовательность другая.
скетч из примеров, шедших вместе с библиотекой, залил, но температуту почему-то кажет 85 градусов, на нагрев от руки не реагирует
датчика три штуки, проверял все.
Ладно, завтра вечером проверю подключение, может тут где накосячил. Щас мозг спит ужо.
Тут возможно магическим словом будет слово "питание" для татчика. Подлючать его так как нарисованно в стартовой статье - испытывать судьбу. Либо заработает, либо порт сгорит, либо ему не хватит питания для измерения. Вот официальный даташит на этот даташит на этот датчик http://datasheets.maxim-ic.com/en/ds/DS18B20.pdf
Схему подключения смотрите лучше в нем, а не в какой-то статье.
Схем подключения существует две. Страница 6, Figure 4 и 5.
Figure 4 это подключение "на паразитном питании". Когда необходимая энергия берется с линии данных, запасается во встроенный внутри конденсатор и "расходуется" в момент измерения. Похоже что автор той статьи и пытался использовать эту схему (и судя по скриншотам с отрицательной температурой у него тоже не получилось). Но... в момент "зарядки конденсатора" с линии данных может забиратся довольно большой ток. Что-бы "не натварить караула", производитель вносит в схему дополнительный "подпитывающий транзистор". Что-бы большой ток забирался не с пина, а все-таки из +5v. Автор статьи решил это дело "упростить". Вернее, думаю, брал где-то переводную. В англоязычных статьях тоже, почему-то, зачастую показано именно такое подключение.
Кстати не уверен, но где-то встречал что эти DS1820 бывают которые поддерживают паразитное питание, а бывают что и "нет".
Что-бы не морочится с транзюком, можно дать датчику питания "в явном виде". На третью его ногу. Это и есть Figure 5 (Внешнее Питание/ External Supply).
Подключение по этой схеме (питание заведено отдельно) и этой библиотекой лично у меня заработало "без танцев с бубном".
со сдвигом понял, просто в ардуиновских учебниках не нашел сего момента, а про "=!" смутило, что в учебниках последовательность другая.
tr =! tr + 1; это то же самое, что и tr = !tr + 1; то есть в такой форме записи оператор ! относится к переменной, стоящей справа от него. Кстати, прогнал это выражение в цикле - результат всегда равен единице, то есть это выражение либо бесполезно и тогда его стоит выбросить, либо ошибочно - и тогда неудивительно, что программа не делает то, что от неее ожидают.
А "!=" в приведенном контексте вообще не имеет смысла, хоть и не является синтаксической ошибкой. Это оператор сравнения, он возвращает значение ЛОЖЬ или ИСТИНА, не меняя при этом значений используемых в выражении переменных. В выражении if(), while() и т.п. это возвращаемое значение используется, а вот в "tr != tr+1;" уходит в никуда.
Возможно вы путаете с конструкцией "|=", которую часто используют для установки определенных битов в байте. Например, установка третьего бита (отсчет начинаем с нуля, т.е. в "лбычной жизни" это четвертый справа бит) в переменной v:
v |= 1<<3; или более наглядно
v = v | (1<<3);
"Подлючать его так как нарисованно в стартовой статье - испытывать судьбу. "
Подключал обоими способами, подключение сравнивал с разными источниками, вроде все верно. Сейчас подключено с полноценным питанием.
Про знак "|=" я понял, там точно не он, но попробую вечером подставить, поглядеть на результат. Хотя я код заменил на код с официального примера с самой библиотеки
Кстати, прогнал это выражение в цикле - результат всегда равен единице
Плохо "гнали" :)
Вот скетч:
А вот его вывод
!tr+1=1 where tr=1
!tr+1=1 where tr=2
!tr+1=1 where tr=3
!tr+1=1 where tr=4
!tr+1=1 where tr=5
!tr+1=1 where tr=6
!tr+1=1 where tr=7
!tr+1=1 where tr=8
!tr+1=1 where tr=9
Кстати, прогнал это выражение в цикле - результат всегда равен единице
Плохо "гнали" :)
Не совсем. В этом кусочке кода неизвестный герой, судя по комментариям, похоже, пытается преобразовать отрицательное целое (семь первых бит второго байта - мантисса, восьмой бит - знак числа, 1 - отрицательное) в соответствующее ему положительное (т.е. найти модуль отрицательного числа):
Пытается вычислить дополнение до двух, а вместо этого всегда получает единичку (особый случай "0" не пропускается условием if(data[1]>0x80) - в переводе на русский - "если целое, сохраненное в нулевой и первой ячейках массива data, отрицательное"). В результате из 32 с лишком тысяч возможных значений на входе получает одно значение на выходе.
если бы здесь стояло
tr = ~tr+1;
то two's complement получился бы.
Кстати, того же результата он бы добился и простым рабоче-крестьянским методом:
tr = -tr;
ЗЫ: сильно похоже, что этот самый неизвестный герой переводил ассемблерную программу в сишную - уж больно специфические манипуляции с памятью присутствуют в этом коде.
>Не совсем. В этом кусочке кода неизвестный герой
Ну тут похоже мы оба правы. Просто я рассмотрел ваше высказывание "вне контекста", зацепившись за слова " это выражение в цикле - результат всегда равен единице". Ну и доказал, что "это выражение" таки, иногда бывает двойкой.
Вы же видимо, имели ввиду "эта строчка" не имеет смысл. В контексте данного скетча. И тогда правы вы.
В результате, я уверен, что по крайней мере мы двое, никогда ~ и ! не перепутаем ;)
В результате, я уверен, что по крайней мере мы двое, никогда ~ и ! не перепутаем ;)
Ну да - только ! и | ;)
все, добил, работает
блин, ну как вот у людей совести хватает писать статьи практически для учебника и так дико лажать в них
пример скетча взял из самой библиотеки + пример подключения из даташита = все работает
в том уроке практически все неправильно
кому интересно, пример рабочего скетча кидаю сюда
подключение
левая нога - земля
средняя нога - на пин ардуино (в моем случае 10)
правая нога - питание 5 вольт
между средней и правой ногой резистор 4,7 килоома
(датчик маркировкой к себе, ногами вниз)
всем спасибо за науку и не дай бог никому напороться на такую откровенную лажу
тему можно закрывать
И все же, думаю, польза от таких лажовых примеров есть - человек, напоровшийся на них, узнает о микроконтроллере и его программировании гораздо больше, чем тот, кто десяток правильных скетчей залил и прогнал, даже не вникая в принципы их работы. ;)
согласен, а еще сколько много узнать предстоит, по уши влезу в это дело :)
а у меня к знатокам следующий вопрос:
я хочу подключить к ардуине три термодатчика (акваконтроллер собираю), так вот, как лучше поступить, все три на один пин повесить и определять их по серийнику или развесить на разные пины? (пинов хватает, у меня мега)
и как тогда организовывать работу скетча? вернее как различать работу с разными датчиками?
Подключайте все на одну веревочку, если датчики находятся, так сказать, на одной линии.
Подключайте по одному на отдельный вход, если Ардуинко в центре, а датчики в разных направлениях от нее понаставлены.
Здесь не и не может быть однозначного ответа.
Ну а как работу с разными датчиками различать, вы уже сами ответили:
для случая "все на одной ножке" - по сер. номерам,
для отдельных выводов - по номеру этого самого вывода.
Ну и опрашивайте их в цикле последовательно
просто как опрашивать по серийным номерам, я еще не разобрался
а для отдельных выводов интересует вот эта строчка
это привязка пина 10 к переменной ds я так понимаю?
значит для трех датчиков я могу сделать например так
это будет правильно? Я к сожалению не могу щас проверить, кабель отдать пришлось, не мой был, а до магазина добежать никак не соберусь
>просто как опрашивать по серийным номерам, я еще не разобрался
На "Dallas Temperature Control Library" вообще элементарно, разбиратся не с чем (на "одной веревочке").
Но это если цель "просто работать с градустником", если же цель "разобратся как oneWire работает (а это может пригодится много где, кроме градусника), то....
ну пока цель-минимум - именно поработать с градусником, но никто не говорил, что продолжения не будет :)
я ж говорю, даже с СИ дела до сих пор не имел, все еще впереди
ох, как дохрена ж впереди.....
>ну пока цель-минимум - именно поработать с градусником
Ну тогда не понятно, почему-же вы отмахиваетесь от библиотеки написанной специально для этого датчика(ссылку я давал в сообщение #12).
У меня минут 10-ть заняло от "вынуть датчик из пакетика" (первый раз в жизни), до "увидеть температуру в сериал" (погреть пальцами датчик, увидить изменения). Минут 5-ть на поиск библиотеки и чтение даташита (как подлючать, где какая нога), минуты 4-ре на подключение. Даже скетч не писал, тупо запустил пример идущий с библиотекой.
Даже если "библиотека почему-то не запускается", то, помоему, за то время, что вы потрали на рабирательство с неравильным чужим примером вы бы библиотеку "полюбому запустили". Ну разве что, свои навыки конкретно прокачали :)
>ох, как дохрена ж впереди.....
Вы полагаете когда впереди уже "нихрена" оно веселей? ;)
Кстати, возможно вы не вкурсе, но ваш итоговый скетч это есть пример который вам советовал посмотреть step962, из библиотеки one-wire. (на всяк случай, а я говорил про Dallas_Temperature_Control_Library это еще более высоуровневая обертка над one-wire).
Когда вы ставите любую библиотеку, то вас сразу, в IDE появляются ее примеры. Их можно сразу открывать в меню File/Examples/Имя Библиотеки/Имя примера
http://screencast.com/t/ffaUBUQau - вот пример про который говорил step962
http://screencast.com/t/YSIva1hI - а вот примеры про которые говорил я (с одним датчиком там вообще получает "три строчки работы". Одна begin, одна запросить измерение и одна получить результат). Там же есть, судя по названию, и готовый пример работы с несколькими датчиками.
я не отмахиваюсь от этой библиотеки, просто я коего-то хрена ее так и не смог запустить, могу выкинуть сюда, на что она ругается
а то, что мой итоговый скетч это есть пример из библиотеки, я собственно и говорил, я только вывод лишней для меня информации убрал
> Когда вы ставите любую библиотеку, то вас сразу, в IDE появляются ее примеры. Их можно сразу открывать в меню File/Examples/Имя Библиотеки/Имя примера
а вот этого момента не заметил, буду знать
вот еще бы кто точно сказал, как ПРАВИЛЬНО подключать библиотеки к Arduino IDE 1.000, а то везде пишут что нужно ложить в папку Hardware\Librares, а у меня такой нет, есть просто Librares. Ну я, короче, везде и понапихал, может в этом косяк и есть.
>могу выкинуть сюда, на что она ругается
Да. Я думаю потратить время на "разобратся с библиотекой", это более продуктивно, чем "воспроизвести ее самому".
Возможно вы библиотеку качнули откуда-то устаревшю? Возмите по ссылке что я дал. Там "последняя" имеется. В том числе и под Arduino IDE 1.0
>а вот этого момента не заметил, буду знать
Я это и предположил, поэтому и дал скриншоты :)
>вот еще бы кто точно сказал, как ПРАВИЛЬНО подключать библиотеки
"Как точно правильно" - я не знаю, но могу рассказать как я делаю. Из принципа "работает - не трогает" я 1.0 еще не ставил. Использую 0.22. Куда нужно ложить - тоже не читал. Просто посмотрел где лежат те библиотеки что идут "в комплекте" и "положил тудаже и также" , а это папка "Librares/[Имя новой библиотеки]". Дальше выходим/заходим из IDE и "вуаля..." :)
Вообщем попробовал с Arduino IDE 1.0 - тоже все нормально (по крайней мере компилируется без воплей).
Мои действия:
И еще две вещи:
На http://www.pjrc.com/teensy/td_libs_OneWire.html есть интерестное примечание "The DS18x20_Temperature has a known bug. Remove "unsigned" from the raw variable on line 88, for correct results below zero degrees Celsius!". Это про пример идущий с OneWire (и свой скетч, я так понял, вы с него делали). Перевести это можно так: "Пример DS18x20_Temperature имеет известную ошибку. Уберите слово "unsigned" в объявлении переменной row в строке 88, для корректного результата в цельсиях, при значениях меньше нуля). В вашем скетче, как я понял, это строчка 43.
Для "чистоты эксперемента" и что-бы "новые библиотеки не конфликтовали со старыми" (не известно что и куда вы раньше накидали). Можно скачать и поставить еще один "комплект" Arduino IDE просто где-то рядом в соседнюю папку по отношению к той что у вас уже стоит. Они спокойно могут "сосуществовать рядом". Просто будете запускать "либо ту", "либо ту".
да, все проверил, все работает.
а вот библиотека с названием папки "DallasTemperature" и примером "GetTemperature" выдает следующее:
вот код примера
для чистоты эксперимента комментарии не удалял, из замеченного мной отсутствует вызов и использование OneWire.h
может в этом причина? или просто с новой версией Arduino IDE он уже не работает?
щас вот тока не вспомню точно, где брал эту библиотеку, но она по-моему ни разу не левая
Хм, что-то я не понимаю. У вас "все работает", но выхотите разобратся почему у вас не работает пример из библиотеки "взятой неизвестно когда, неизвестно где"? Она имеет какие-то дополнительные плюшки? Чем вас не устраивает последния, официальная, рабочая версия библиотеки?
Из этой ошибки видно, что нет библиотеки OneWire. Вторая строчка ошибок. Где можно взять эту библиотеку - я давал ссылку выше.
Правда я не знаю подойдет ли ее версия к вашей "неизвестной библиотеке".
Думаю, можно конечно, произвести археологический изыскания, найти "откуда взялась эта библиотке", откатится на старые версии ардуино тех времен, найти соотвевествующу версию OneWire... но это без меня. Смысл этих действий от меня ускользает.
Если вам интересен именно этот пример, то подправте его на использование DallasTemperatureControl . Тем более что это на две минуты работы.
смысл только разобраться в ситуации, чтоб приобрести опыт, не более, практическая ценность приобретена выше, далее только теоретические изыскания на тему "а что если....."
так что все путем, появится время - буду двигаться дальше
А как реализовать такую схему: LCD HD44780 + Arduino Uno+датчик температуры DS18B20?
Наверное нагуглить библиотеку на LCD HD44780 научится выводить на него текст.
Ну а потом взять пример на DS1820 и Serila.print заменить выводом на LCD.