Остался вопрос, что будет, если их не запрещать. Но, чувствую, узнать опытным путем будет быстрее.
Если прервёте хоть сколько-нибудь надолго - сломается нахрен. Вы почитайте описание протокола OneWire - там всё построено на микросекунднных таймингах. Сигал должен быть определённой длительности. Будет длинее/короче - приплыли. Запасы там не очень большие. Хотя, может Вы в них и уложитесь. Смотрите сами. Протокол достаточно подробно описан в даташитре на датчик
Камрады, такой вопрос... Опрос датчиков тормозит прерывания. Как избавится? Можно это как-то обойти? Если более конкретно, то есть программный диммер, который, используя датчик перехода через 0, повешенный на прерывание, управляет семистором. Как только к этому коду добавляется одна строка ds.write(0x??), появляется еле заметное мерцание, 2 строки - мерцание оч заметно.. и т д, в итоге мигание с частотой опроса. Временно решил проблему отправкой команд датчикам раз в секунду по одной, но мерцание все равно есть. Коллега с телевизором в середине темы испытывал схожие проблемы, скорее всего по той же причине.
Это напоминает мне анекдот: Почему когда я стучу головой об стену, у меня болит голова. Может я заболел. Вы можете опрашивать датчики после преравания. Или у вас прерывания занимают всю работу ЦПУ.
Не спец в прерываниях, но терзают смутные сомненья, на выше означенном TV сигнале (те же 50Гц) срывало синхронизацию при полном опросе двух датчиков, при разделении опроса по одному все стабилизировалось. Здесь мигает при полной расчлененке опроса одного датчика, может что то с алгоритмом обработки прерывания не так?
Зачем датчик перехода через 0 вешать на прерывание?
На пик контроллере тау тела цикла хватало обрабатывать этот датчик с лихвой, не думаю, что здесь хуже
Тут другое. Мне за него стыдно. Это как к доктору с грязными труселсями.
bwn пишет:
Не спец в прерываниях, но терзают смутные сомненья, на выше означенном TV сигнале (те же 50Гц) срывало синхронизацию при полном опросе двух датчиков, при разделении опроса по одному все стабилизировалось. Здесь мигает при полной расчлененке опроса одного датчика, может что то с алгоритмом обработки прерывания не так?
Да я не скажу, что вот прям мигает. С такой расчлененкой (это ты метко подметил ) иногда может быть скачечек на малых яркостях - чуть позже закроется или откроется, вот и разовое изменение яркости. Мне просто костыли такие напрягают. А алгоритм весь я написал выше. Сейчас еще отдельно ds.reset() выделил - в нем, оказывается, тоже noInterrupts() - Interrupts(); присутствует, даже трижды. И delayMicroseconds. С тв там проблема тоже не полностью с одним датчиком ушла - частичное подергивание оставалось.
Так то костыль есть, результат вроде пока не раздражает... Единственная альтернатива, которую вижу на данный момент - править библиотеку с вероятность рандомно получать мусор от датчика. Но это требует изрядно времени на отладку.
На отдельном перрывании, потому, что, если я правильно считаю, переход переменного тока через 0 дважды за период, итого 100гц при частоте переменки в 50. Я ж не тэном управляю, там период можно в неск сек выставлять...
На отдельном перрывании, потому, что, если я правильно считаю, переход переменного тока через 0 дважды за период, итого 100гц при частоте переменки в 50. Я ж не тэном управляю, там период можно в неск сек выставлять...
Я как понял. Переход через 0 вызывает перерывание и вы держите это прерывание, пока нужная мощность не выставится. Так что выходит на 100% мощьности идет 100% прерывания и мощности процессора. Но так как полная мощность не всегда нужна , то вы на остатках ресурса ЦП опрашиваете датчики. Диковато-такое решение.
Я готов к конструктивной критике, но другого решения тупо не вижу - чтоб не моргало, резаться должен каждый полупериод. А почему думаешь, что проц то на всю загружен? Ну срабатывает прерывание, пускает таймер... Таймер это таймер, он отдельным потоком работает. millis тоже на таймере висит, все время работает. Я не знаю, тут ссылки на сторонние ресурсы можно, или нет, если что, тапками не пинать. Первое , что дельное попалось http://robotosha.ru/arduino/multitasking-and-interrupts-arduino.html
Ну к многозадачности я банально подошел с другой стороны. С моей точки зрения надо при прерывании нужно сделать отметку по millis() или micros() и отпустить процессор на другие задачи, периодически отлавливая время отключения.
Судя по сообщениям на амперике, идея управлять триаком у тебя крутится. Реализуй. С лампочкой, через тело программы. Потом расскажешь. А я тебе и так скажу: получишь рандомный стробоскоп. Потому, что если цикл не совпадет с таймером даже на 1 мкс - такт будет пропущен. В итоге лампа вовремя или не загорится, или не погаснет. В итоге скачки яркости. Причем таймер значение должен уметь менять, иначе яркость будет фиксированной. Подогнать "цикличность цикла" можно только через delay, но разрешение оного никак не соответствует задачам. Да и смысл мероприятия теряется. ИМХО.
А для управления каим либо нагревателем вполне себе вариант. Если считаешь возможным помеху в сеть гнать.
Трабл то не в том, что прерывание проц дергает, а в том, что onewire дергает даже прерывания.
Я делал с этой библиотекой, но не освещение, а нагрев четырьмя прожекторами, соответственно о мигании что то сложно сказать, не присматривался.
Если мощность не очень большая, может есть смысл перейти на MOSFET и ШИМ?
attachInterrupt(0, detect_up, LOW); // настроить срабатывание прерывания interrupt0 на pin 2 на низкий уровень
StartTimer1(halfcycle, 40); //время для одного разряда ШИМ
StopTimer1(); //остановить таймер
в твоей ссылке тебя не смущают? Точно тоже, что у меня, только без левой библиотеки. Детектор 0 на прерывании запускает таймер отсчета. Судя по схожим названиям и коментариям, даже исходный код у нас из одинакового источника.
WarIock, вам нужно из прерываний detectUp/Down вызывать специальную функцию, которая будет при каждом вызове контролировать текущий ход опроса датчиков, и отдавать новые команды по мере необходимости и возможности. Таким образом всё всегда будет крутится в прерываниях, и никто никому мешать не будет. Но функция должна запускать команды строго порционно, с расчётом что бы точно успеть отработать "порцию" до наступления следующего прерывания. Это довольно сложная задача, не для начинающих.
Прошу прощения, я таки не очень понимаю... Т е Вы предлагаете отказаться от onewire, а тот же reset вынести в отдельную функцию или, точнее, несколько функций, делеи между которыми будут завязаны на такты прерывания. Так?
WarIock, если у Вас пошла такая пьянка, Вам нужно просто выбросить эту библиотеку написать всё ручками на прерываниях от таймера, так чтобы не было никаких задержек вовсе.
Вы поймите, протоколу не мешают как таковые прерывания. Он их запрещает только для того, чтобы соблюсти правильные тайминги. Так это делается и без задержек с запрешёнными прерываниями.
Определяете список состояний в которых может находиться Ваш протокол (на бумажку выписываете). Вместо задержки, заводите таймер на нужное количество микросекунд, а сами занимаетесь своими делами. По прерыванию таймера выполняете действие (в зависимости от текущего состояния), меняете состояние и, если нужна ещё задержка, опять заводите таймер на нужное количество микросекунд. При таком подходе у Вас вообще не будет задержек. Вы получите неблокирующую версию библиотеки для работы с датчиком.
// снять все ремарки если нужно поменять разрешение
// ds.reset(); // сброс шины
// ds.select(addr); //выставить адрес
// ds.write(0x4E); // разрешение записать конфиг
// ds.write(0x7F); // Th контроль температуры макс 128грд
// ds.write(0xFF); //Tl контроль температуры мин -128грд
// ds.write(0x60); // 0x60 12-бит разрешение, 0x00 -9бит разрешение
А я решил, что будет достаточно для всех датчиков скопом
Объявляете глобально массив адресов датчиков: byte addr[3][8] = {{.......},{......},{.....}}; Массив температур: float Temp[3]; и переменную времени обработки: byte flagDallRead;
Вставляете функцию в скетч и вызываете через: dallRead(flagDallRead*1000) значения температуры будут в массиве Temp[]. Количество датчиков изменяется размерами массивов адресов и температур и значением for в функции. Время повторного измерения выставляется в 23 строке. Если нужны более точные, чем секундные, интервалы - flagDallRead объявляем как unsigned long и выставляем задержки в миллисекудах, соответственно при вызове на 1000 не перемножать.
Блин, ну писал же, давайте полное сообщение об ошибке. Там ведь и номер строки был, а теперь мне его самому искать. Сейчас поищу, но впредь, имейте совесть. Сейчас посмотрю.
Про эту ошибку всё понятно, у Вас функция dallRead описана в 42 строке как не возвращающая никакого значения.
А в 32 строке Вы пытаетесь возвращённое ею значение передать функции dispFloat.
Вы уж определитесь. Если она что-то должна возвращать, так опишите её соответсвующим типом и пусть возвращает. А если она ничего не возвращает (как сейчас), так что именно Вы собрались передавать dispFloat?
Но там есть ещё оибка. В 58 строке Вы передаёте функции select один байт, а она ждёт массива из 8 байтов.
Sanyaba, ведь написал же, что за что отвечает. Функция сделана на несколько датчиков, у Вас один. Соответственно адресный массив стал одномерным, зачем его крутить в форе? Для температуры массив стал не нужен.
Убираете for, в 58 строке ds.select(addr); , 61 строка Temp = ....., 13-я float Temp; и передавайте значение из Temp, температура там хранится, она глобальная.
Парни, я новичек в этом всем и для меня очень сложно, на практике применяю куски кода которые есть в сети и свои наработки, но бывают ситуации как сейчас что не могу разобраться и ВАМ за это огромное человеческое спасибо!
Жуто извиняюсь за дикий оффтоп, но беда - не отписаться никак от уведомлениях на почту о новых коментариях в этой теме. Писать в другую тему просто опасаюсь, чтобы спамом не завалило. При переходе по ссылке из письма "Отключить уведомления" пишет "отключено", но реально не отключает. В профиле в "Следить" значится эта тема, но там можно только перейти сюда, кнопки удалить нет. В "изменить" в "уведомления по e-mail " стоит "не уведомлять"... Даже где удалиться найти не могу...
да хоть 1 хоть 10000 поставь, это интервал опроса.. смотри 24 строку
Ну спасибо, отец родной, открыл истину. Я то когда эту функцию писал, весь извелся, какую мне цифирку там поставить. А ты вона как быстро.
Прежде, чем разъяснять, сам разберись как работает.
Факт, что работает корректно при любых значениях, не значит, что ты понимаешь как это происходит.
в схемах с подключением через диод-конденсатор указывают кондер 1...10 мкФ.
я правильно понимаю, что кашу маслом не испортишь, и можно постаивть хоть 100 - хуже не будет?
или я о чем-то не догадываюсь?
и еще - имеет смысл для 5 датчиков при очень плохой линии (экран+ 2 жилы, длина 20 м., несколько "лучей", причем сходящихся в разных точках) повесить керамические кондеры или они уже включены внутрь?
Здавствуйте, помогите плиз наченающему ученику в ардуино.
Использовал скетч с 4 сообщения для щитывания 3 датчиков DS18B20 и вывод их на LCd, пока все работает но не могу избавиться от лишнего символа, на фото посредине, точнее не пойму от куда он береться. спс.
ХЗ как код сгорнуть...
#include <OneWire.h>
OneWire ds(5); //пин для датчиков
byte addr1[8]={0x28,0xFF,0xC8,0x8A,0xC2,0x15,0x01,0xC7}; //двигатель
byte addr2[8]={0x28,0xFF,0x66,0x18,0xC2,0x15,0x02,0x52}; //салон
byte addr3[8]={0x28, 0xFF, 0xAA, 0xDB, 0xA2, 0x16, 0x04, 0xCD}; //
volatile int temp1,temp2,temp3;
#include "RTClib.h"
RTC_DS1307 RTC;
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3f, 16, 2);
#if defined(ARDUINO) && ARDUINO >= 100
#define printByte(args) write(args);
#else
#define printByte(args) print(args,BYTE);
#endif
int analog = A0; //пульт руль
int Gabarit = 2; //вход lsd
int LedLsd = 6; //выход lsd
int inPin = 3; //газ
int analogInput = A6; //вход для вольтметра
float vin = 0; // ВХОДНОЕ ЕАПРЯЖЕНИЕ
//Символ градуса
byte grad[8] = {
0b01100,
0b10010,
0b10010,
0b01100,
0b00000,
0b00000,
0b00000,
0b00000
};
void setup(void) {
Serial.begin(9600);
WDTCSR=(1<<WDCE)|(1<<WDE); //установить биты WDCE WDE (что б разрешить запись в другие биты
WDTCSR=(1<<WDIE)| (1<<WDP2)|(1<<WDP1); // разрешение прерывания + выдержка 1 секунда
// снять все ремарки если нужно поменять разрешение
// ds.reset(); // сброс шины
// ds.select(addr2); //выставить адрес
// ds.write(0x4E); // разрешение записать конфиг
// ds.write(0x7F); // Th контроль температуры макс 128грд
// ds.write(0xFF); //Tl контроль температуры мин -128грд
// ds.write(0x60); // 0x60 12-бит разрешение, 0x00 -9бит разрешение
pinMode(8, INPUT);
pinMode(9, INPUT);
pinMode(10, INPUT);
pinMode(11, INPUT);
pinMode(12, INPUT);
pinMode(analogInput, INPUT); //пин А6 как вход
pinMode(LedLsd, OUTPUT); //пин 6 как выход для LSD
pinMode(Gabarit, INPUT); //пин 2 как вход от габаритов для LSD
lcd.init(); // Инициализация lcd
lcd.backlight(); // Включаем подсветку
lcd.createChar(0, grad); //Символ градуса
lcd.setCursor(4, 0); //курсор
lcd.print("Hello :)"); //надпись при включении
lcd.setCursor(3, 1); //курсор
lcd.print("Good day."); //надпись при включении
delay(1500); //задержка
lcd.clear(); //очистить екран
if (! RTC.isrunning())
{
// строка ниже используется для настройки даты и времени часов
RTC.adjust(DateTime(__DATE__, __TIME__));
}
}
void loop() {
Serial.print("Temp1= ");
Serial.print(temp1/16.0);
Serial.print(" ");
Serial.print("Temp2= ");
Serial.println(temp2/16.0);
//часы
DateTime now = RTC.now();
DateTime future (now.unixtime() + 7 * 86400L + 30);
lcd.setCursor(11, 0);
lcd.print(future.hour(), DEC);
lcd.print(':');
lcd.print(future.minute(), DEC);
//газ
if (digitalRead(inPin))
{
lcd.setCursor(5, 0);
lcd.print("GAZ");
}
else
{
lcd.setCursor(5, 0);
lcd.print(" - ");
}
lcd.setCursor(0, 0); //темп улица
lcd.print("");
lcd.print(temp3/16);
lcd.printByte(0);
lcd.setCursor(0, 1); //темп салон
lcd.print("");
lcd.print(temp1/16);
lcd.printByte(0);
lcd.setCursor(5, 1); //темп двигатель
lcd.print("");
lcd.println(temp2/16);
lcd.printByte(0);
//вольтметр
vin = float(analogRead(analogInput))/18.3; //подстроичное число для показа вольтметра
lcd.setCursor(11, 1);
lcd.print("");
lcd.print(vin, 1);
lcd.print("V");
analog=analogRead(14); //считываем сигнал с пина АЦП
if(analog>750&&analog<820) // k1 - up
{
pinMode(8, OUTPUT);
digitalWrite(8,LOW);
delay(50);
pinMode(8, INPUT);
delay(150);
}
if(analog>300&&analog<400) //k2 - right
{
pinMode(9, OUTPUT);
digitalWrite(9,LOW);
delay(50);
pinMode(9, INPUT);
delay(70);
}
if(analog>200&&analog<290) //k3 down
{
pinMode(10, OUTPUT);
digitalWrite(10,LOW);
delay(50);
pinMode(10, INPUT);
delay(70);
}
if(analog>100&&analog<190) //k4 vol+
{
// для енкодера
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
digitalWrite(11, HIGH);
delay(25);
digitalWrite(12, HIGH);
delay(25);
digitalWrite(11,LOW);
delay(25);
digitalWrite(12,LOW);
delay(25);
pinMode(11, INPUT);
pinMode(12, INPUT);
}
if(analog>=0&&analog<80) //k5 vol-
{
// для енкодера
pinMode(12, OUTPUT);
pinMode(11, OUTPUT);
digitalWrite(12, HIGH);
delay(25);
digitalWrite(11, HIGH);
delay(25);
digitalWrite(12,LOW);
delay(25);
digitalWrite(11,LOW);
delay(25);
pinMode(12, INPUT);
pinMode(11, INPUT);
}
}
ISR (WDT_vect){ //вектор прерывания WD
static boolean n=0; // флаг работы: запрос температуры или её чтение
n=!n;
if (n) {ds.reset(); // сброс шины
ds.write(0xCC);//обращение ко всем датчикам
ds.write(0x44);// начать преобразование (без паразитного питания)
}
else {ds.reset();
ds.select(addr1);
ds.write(0xBE); // Read Scratchpad (чтение регистров)
temp1 = ds.read() | (ds.read()<<8); //прочитаны 2 байта
// получение с 2-го датчика
ds.reset();
ds.select(addr2);
ds.write(0xBE); // Read Scratchpad (чтение регистров)
temp2 = ds.read() | (ds.read()<<8); //прочитаны 2 байта
ds.reset();
ds.select(addr3);
ds.write(0xBE); // Read Scratchpad (чтение регистров)
temp3 = ds.read() | (ds.read()<<8); //прочитаны 2 байта
}
}
#include <OneWire.h>
OneWire ds(2);
// подключение датчика №2 ds18b20 к 2 контакту
void setup() {
//ds.reset();
//ds.write(0x4E);
//ds.write(0x7F); не работает
// установка скорости обмена Serial port. По умолчанию 9600
Serial.begin(9600);
}
void loop()
{
byte data[2];
ds.reset();
ds.write(0xCC);
ds.write(0x44);
delay(1000);
ds.reset();
ds.write(0xCC);
ds.write(0xBE);
for (byte i = 0; i < 9; i++) // можно увеличить точность измерения до 0.0625 *С (от 9 до 12 байт) НИЧЕГО НЕ ИЗМЕНЯЕТ
{ // we need 9 bytes
data[i] = ds.read ();
}
float raw = (data[1] << 8) | data[0];//=======Пересчитываем в температуру
float Temp = raw / 16.0;
Serial.print("TEMP 1: ");
Serial.println(Temp);
}
Но не получется вывести с погрешность 0,0625 . Выводит до 100.
// снять все ремарки если нужно поменять разрешение
// ds.reset(); // сброс шины
// ds.select(addr); //выставить адрес
// ds.write(0x4E); // разрешение записать конфиг
// ds.write(0x7F); // Th контроль температуры макс 128грд
// ds.write(0xFF); //Tl контроль температуры мин -128грд
// ds.write(0x60); // 0x60 12-бит разрешение, 0x00 -9бит разрешение
Не помню, воспримет ли без адреса. Настройка делается один раз.
Ваша 26 строка разрешение не изменяет, это 8 байт данных от датчика.
Остался вопрос, что будет, если их не запрещать. Но, чувствую, узнать опытным путем будет быстрее.
Если прервёте хоть сколько-нибудь надолго - сломается нахрен. Вы почитайте описание протокола OneWire - там всё построено на микросекунднных таймингах. Сигал должен быть определённой длительности. Будет длинее/короче - приплыли. Запасы там не очень большие. Хотя, может Вы в них и уложитесь. Смотрите сами. Протокол достаточно подробно описан в даташитре на датчик
Камрады, такой вопрос... Опрос датчиков тормозит прерывания. Как избавится? Можно это как-то обойти? Если более конкретно, то есть программный диммер, который, используя датчик перехода через 0, повешенный на прерывание, управляет семистором. Как только к этому коду добавляется одна строка ds.write(0x??), появляется еле заметное мерцание, 2 строки - мерцание оч заметно.. и т д, в итоге мигание с частотой опроса. Временно решил проблему отправкой команд датчикам раз в секунду по одной, но мерцание все равно есть. Коллега с телевизором в середине темы испытывал схожие проблемы, скорее всего по той же причине.
Это напоминает мне анекдот: Почему когда я стучу головой об стену, у меня болит голова. Может я заболел. Вы можете опрашивать датчики после преравания. Или у вас прерывания занимают всю работу ЦПУ.
Не спец в прерываниях, но терзают смутные сомненья, на выше означенном TV сигнале (те же 50Гц) срывало синхронизацию при полном опросе двух датчиков, при разделении опроса по одному все стабилизировалось. Здесь мигает при полной расчлененке опроса одного датчика, может что то с алгоритмом обработки прерывания не так?
Зачем датчик перехода через 0 вешать на прерывание?
На пик контроллере тау тела цикла хватало обрабатывать этот датчик с лихвой, не думаю, что здесь хуже
но при этом боятся, что их ценнейший код украдут)
Тут другое. Мне за него стыдно. Это как к доктору с грязными труселсями.
Не спец в прерываниях, но терзают смутные сомненья, на выше означенном TV сигнале (те же 50Гц) срывало синхронизацию при полном опросе двух датчиков, при разделении опроса по одному все стабилизировалось. Здесь мигает при полной расчлененке опроса одного датчика, может что то с алгоритмом обработки прерывания не так?
Да я не скажу, что вот прям мигает. С такой расчлененкой (это ты метко подметил ) иногда может быть скачечек на малых яркостях - чуть позже закроется или откроется, вот и разовое изменение яркости. Мне просто костыли такие напрягают. А алгоритм весь я написал выше. Сейчас еще отдельно ds.reset() выделил - в нем, оказывается, тоже noInterrupts() - Interrupts(); присутствует, даже трижды. И delayMicroseconds. С тв там проблема тоже не полностью с одним датчиком ушла - частичное подергивание оставалось.
Так то костыль есть, результат вроде пока не раздражает... Единственная альтернатива, которую вижу на данный момент - править библиотеку с вероятность рандомно получать мусор от датчика. Но это требует изрядно времени на отладку.
На отдельном перрывании, потому, что, если я правильно считаю, переход переменного тока через 0 дважды за период, итого 100гц при частоте переменки в 50. Я ж не тэном управляю, там период можно в неск сек выставлять...
На отдельном перрывании, потому, что, если я правильно считаю, переход переменного тока через 0 дважды за период, итого 100гц при частоте переменки в 50. Я ж не тэном управляю, там период можно в неск сек выставлять...
Я как понял. Переход через 0 вызывает перерывание и вы держите это прерывание, пока нужная мощность не выставится. Так что выходит на 100% мощьности идет 100% прерывания и мощности процессора. Но так как полная мощность не всегда нужна , то вы на остатках ресурса ЦП опрашиваете датчики. Диковато-такое решение.
Я готов к конструктивной критике, но другого решения тупо не вижу - чтоб не моргало, резаться должен каждый полупериод. А почему думаешь, что проц то на всю загружен? Ну срабатывает прерывание, пускает таймер... Таймер это таймер, он отдельным потоком работает. millis тоже на таймере висит, все время работает. Я не знаю, тут ссылки на сторонние ресурсы можно, или нет, если что, тапками не пинать. Первое , что дельное попалось http://robotosha.ru/arduino/multitasking-and-interrupts-arduino.html
Ну к многозадачности я банально подошел с другой стороны. С моей точки зрения надо при прерывании нужно сделать отметку по millis() или micros() и отпустить процессор на другие задачи, периодически отлавливая время отключения.
Судя по сообщениям на амперике, идея управлять триаком у тебя крутится. Реализуй. С лампочкой, через тело программы. Потом расскажешь. А я тебе и так скажу: получишь рандомный стробоскоп. Потому, что если цикл не совпадет с таймером даже на 1 мкс - такт будет пропущен. В итоге лампа вовремя или не загорится, или не погаснет. В итоге скачки яркости. Причем таймер значение должен уметь менять, иначе яркость будет фиксированной. Подогнать "цикличность цикла" можно только через delay, но разрешение оного никак не соответствует задачам. Да и смысл мероприятия теряется. ИМХО.
А для управления каим либо нагревателем вполне себе вариант. Если считаешь возможным помеху в сеть гнать.
Трабл то не в том, что прерывание проц дергает, а в том, что onewire дергает даже прерывания.
Я делал с этой библиотекой, но не освещение, а нагрев четырьмя прожекторами, соответственно о мигании что то сложно сказать, не присматривался.
Если мощность не очень большая, может есть смысл перейти на MOSFET и ШИМ?
Ну что такое у меня было реализовано. Но только для управления сервой
bwn, а сторки типа
в твоей ссылке тебя не смущают? Точно тоже, что у меня, только без левой библиотеки. Детектор 0 на прерывании запускает таймер отсчета. Судя по схожим названиям и коментариям, даже исходный код у нас из одинакового источника.
qwone, просто сделай, ок? Я не знаю как еще объяснить тебе, что работать это не будет. С рисунками почитай. http://avrproject.ru/publ/poleznaja_informacija/setevoj_dimmer_220v_na_mikrokontrollere/4-1-0-140
WarIock, вам нужно из прерываний detectUp/Down вызывать специальную функцию, которая будет при каждом вызове контролировать текущий ход опроса датчиков, и отдавать новые команды по мере необходимости и возможности. Таким образом всё всегда будет крутится в прерываниях, и никто никому мешать не будет. Но функция должна запускать команды строго порционно, с расчётом что бы точно успеть отработать "порцию" до наступления следующего прерывания. Это довольно сложная задача, не для начинающих.
Друзья, пошу прощения, не знал, что тут принято на Вы, на форумах это редкость, исправлюсь.
Если я верно понял мысль, то Вы предлагаете связать этапы опроса датчиков с тактами прерывания.
Так то это вроде не сложно, но тут какая канитель... такт перывания 200 мкс. А в onewire тот же reset
Имеет 3 delayMicroseconds между noInterrupts(). Тут, похоже, не попасть будет.
Эти делэи некритичны, а функцию можно разорвать на части и выполнять по частям. Я же Вам советовал прочитать описание протокола OneWire - почитайте.
Прошу прощения, я таки не очень понимаю... Т е Вы предлагаете отказаться от onewire, а тот же reset вынести в отдельную функцию или, точнее, несколько функций, делеи между которыми будут завязаны на такты прерывания. Так?
WarIock, если у Вас пошла такая пьянка, Вам нужно просто выбросить эту библиотеку написать всё ручками на прерываниях от таймера, так чтобы не было никаких задержек вовсе.
Вы поймите, протоколу не мешают как таковые прерывания. Он их запрещает только для того, чтобы соблюсти правильные тайминги. Так это делается и без задержек с запрешёнными прерываниями.
Определяете список состояний в которых может находиться Ваш протокол (на бумажку выписываете). Вместо задержки, заводите таймер на нужное количество микросекунд, а сами занимаетесь своими делами. По прерыванию таймера выполняете действие (в зависимости от текущего состояния), меняете состояние и, если нужна ещё задержка, опять заводите таймер на нужное количество микросекунд. При таком подходе у Вас вообще не будет задержек. Вы получите неблокирующую версию библиотеки для работы с датчиком.
Dimax, подскажите, чтоб сделать опрос датчиков не каждую секунду а раз в 8 секунд , где нужно это изменить?
WDTCSR=(1<<WDIE)| (1<<WDP2)|(1<<WDP1); // разрешение прерывания + выдержка 1 секунда
Serg1, вот так: WDTCSR=(1<<WDIE)| (1<<WDP3)|(1<<WDP0);
Что я делаю не так? Из этой темы взят пример.
Переменные Double.
Резолюция 12 бит
Все работает четко. Захотелось выводить температуру с десятыми. Выдает с шагом 0,5. Сделал так...
(t*10)>>4 = (t*10)/16 - получаем целое число равное температуре в десятых градуса, сотые отбрасываются: число 214 соответствует температуре 21,4 *С
выдает с шагом 5 (760, 765,770) а хотелось бы (760, 761, 762....)
temp_kot = (float)temp / 16.0; Вроде так.
Разобрался. Недочитал и схитрож...ил.
Написано ведь снять ВСЕ ремарки:
А я решил, что будет достаточно для всех датчиков скопом
Вот оно и в дефолтном 9-бит режиме и работало.
подскажите пожалуйста как использовать код из 47 коммента
http://arduino.ru/forum/programmirovanie/pochistil-sketch-primera-raboty-s-ds18b20-iz-bibly-oneware#comment-174443
Вызов из loop - dallRead(flagDallRead*1000);
Объявляете глобально массив адресов датчиков: byte addr[3][8] = {{.......},{......},{.....}}; Массив температур: float Temp[3]; и переменную времени обработки: byte flagDallRead;
Вставляете функцию в скетч и вызываете через: dallRead(flagDallRead*1000) значения температуры будут в массиве Temp[]. Количество датчиков изменяется размерами массивов адресов и температур и значением for в функции. Время повторного измерения выставляется в 23 строке. Если нужны более точные, чем секундные, интервалы - flagDallRead объявляем как unsigned long и выставляем задержки в миллисекудах, соответственно при вызове на 1000 не перемножать.
2 часа промаялся, так и не запустил код, ошбки invalid use of void expression...
Давайте полную ошибку и текущую версию кода. Чего так-то гадать?
Блин, ну писал же, давайте полное сообщение об ошибке. Там ведь и номер строки был, а теперь мне его самому искать. Сейчас поищу, но впредь, имейте совесть. Сейчас посмотрю.
Про эту ошибку всё понятно, у Вас функция dallRead описана в 42 строке как не возвращающая никакого значения.
А в 32 строке Вы пытаетесь возвращённое ею значение передать функции dispFloat.
Вы уж определитесь. Если она что-то должна возвращать, так опишите её соответсвующим типом и пусть возвращает. А если она ничего не возвращает (как сейчас), так что именно Вы собрались передавать dispFloat?
Но там есть ещё оибка. В 58 строке Вы передаёте функции select один байт, а она ждёт массива из 8 байтов.
Sanyaba, ведь написал же, что за что отвечает. Функция сделана на несколько датчиков, у Вас один. Соответственно адресный массив стал одномерным, зачем его крутить в форе? Для температуры массив стал не нужен.
Убираете for, в 58 строке ds.select(addr); , 61 строка Temp = ....., 13-я float Temp; и передавайте значение из Temp, температура там хранится, она глобальная.
Парни, я новичек в этом всем и для меня очень сложно, на практике применяю куски кода которые есть в сети и свои наработки, но бывают ситуации как сейчас что не могу разобраться и ВАМ за это огромное человеческое спасибо!
добавлено позже: Спасибо заработало.
Жуто извиняюсь за дикий оффтоп, но беда - не отписаться никак от уведомлениях на почту о новых коментариях в этой теме. Писать в другую тему просто опасаюсь, чтобы спамом не завалило. При переходе по ссылке из письма "Отключить уведомления" пишет "отключено", но реально не отключает. В профиле в "Следить" значится эта тема, но там можно только перейти сюда, кнопки удалить нет. В "изменить" в "уведомления по e-mail " стоит "не уведомлять"... Даже где удалиться найти не могу...
Сайта подглючивает, я от кнопок новичку уже года полтора отписаться не могу. Либо ручками уведомления удалять, либо сразу все в спам. Так то.
Dimax, здравствуйте.
Успешно использую ваш метод с датчиками DS18.
Возможно ли его применить для датчикиков DHT22?
И как?
Димах и всем в этой теме - спасбио большое за классный код!
очень долго мучался и неработой сериал порта при считывании датчиков.
Этот код все решил!
Выложу код того что получилось для одного датчика DS18b20, может кому пригодится ;)
Я запитывал по 2-м проводам вот так.
*конденсатор желательно с низким ESR
Выложу код того что получилось для одного датчика DS18b20, может кому пригодится ;)
В 19 строке ошибка, должно быть ......*1000.
да хоть 1 хоть 10000 поставь, это интервал опроса.. смотри 24 строку
да хоть 1 хоть 10000 поставь, это интервал опроса.. смотри 24 строку
Ну спасибо, отец родной, открыл истину. Я то когда эту функцию писал, весь извелся, какую мне цифирку там поставить. А ты вона как быстро.
Прежде, чем разъяснять, сам разберись как работает.
Факт, что работает корректно при любых значениях, не значит, что ты понимаешь как это происходит.
Спасибо за функцию.
А может человеку просто стыдно показать свой говнокод? ))) Не в обиду никому, я по себе сужу ))
коллеги, а скажите:
в схемах с подключением через диод-конденсатор указывают кондер 1...10 мкФ.
я правильно понимаю, что кашу маслом не испортишь, и можно постаивть хоть 100 - хуже не будет?
или я о чем-то не догадываюсь?
и еще - имеет смысл для 5 датчиков при очень плохой линии (экран+ 2 жилы, длина 20 м., несколько "лучей", причем сходящихся в разных точках) повесить керамические кондеры или они уже включены внутрь?
спасибо!
Здавствуйте, помогите плиз наченающему ученику в ардуино.
Использовал скетч с 4 сообщения для щитывания 3 датчиков DS18B20 и вывод их на LCd, пока все работает но не могу избавиться от лишнего символа, на фото посредине, точнее не пойму от куда он береться. спс.
ХЗ как код сгорнуть...
в 126 строчке "lcd.println(temp2/16)" точно уверены?
Да, это было оно, 3 дня искал в чем проблема, спасибо))
Давно собрал такой код
Но не получется вывести с погрешность 0,0625 . Выводит до 100.
HELP PLZ. Где косячу??
датчик без адреса, так и задуманно
Не помню, воспримет ли без адреса. Настройка делается один раз.
Ваша 26 строка разрешение не изменяет, это 8 байт данных от датчика.
Чтобы избавиться от задержек, можно ds.read() делать не разом, а в отдельных прерываниях.
Можно даже читать побитово read_bit.
Я вообще дорабатывал эту функцию, вынеся её из класса и удалив внутри задержку в 53мкс перед return.
Такая доработка практически убрала задержки при опросе датчиков.
Вот кусок кода побайтной обработки. Тут идёт опрос множества датчиков, расположенных на разных пинах.
Может кому пригодиться.