Запись и обработка номеров DS18b20 в его EEPROM
- Войдите на сайт для отправки комментариев
Пт, 24/03/2017 - 12:12
#include <OneWire.h> #define NumPin 70 //колличество пинов на используемой плате ардуино (для примера - MEGA)(Uno=20) #define NumConfigPin 69 //(A15)//выделенный пин для программирования номеров датчиков(Uno=19-(A5)) int NumSens;//колличество обнаруженых датчиков boolean PinNumSens[NumPin - 3];//массив задействованных(true) или нет(false) пинов для датчиков(не включая пин 0 и 1 UART и выделенный пин) unsigned long timeSens;//время события int diftime = 0;//разница времени между двумя событиями boolean ReadSens = false;//признак чтения\записи датчика void setup() { Serial.begin(9600); Serial.println(F("Start Search for Sensors:")); SearchNumSens(); } void loop() { if (Serial.available()) { String SerialRead = Serial.readString(); if (SerialRead == "s") {//поиск числа датчиков и задействованных пинов SearchNumSens(); } else {//запись номера датчика в его EEPROM на выделенном пине NumConfigPin int Num = SerialRead.toInt(); Serial.print(F("Sensors Number Recording: #")); Serial.print(Num); if (Num < 1) { Serial.println(F(" Number Error")); } else if (NumConfigSens(Num)) { Serial.println(F(" OK")); } else { Serial.println(F(" Error")); } } } //что-бы не мешало переполнение millis if (timeSens > millis()) { diftime = int(4294967295 - timeSens + millis()); } else { diftime = int(millis() - timeSens); } if (ReadSens == false) { for (byte i = 2; i < NumConfigPin; i++) { if (PinNumSens[i - 2] == true) { OneWire ds(i); // обращение ко всем датчикам шины сразу: ds.reset();//сброс шины ds.write(0xCC);//Игнорировать адрес ds.write(0x44);//начать преобразование температуры(без паразитного питания) } } ReadSens = true; timeSens = millis(); } else if (ReadSens == true && diftime >= 1000) {//1000ms(с запасом)-т.к. время преобразования =750ms для // default value of Config = 0x7F (user byte 3) int Sensor[NumSens][3];//значения опроса датчиков int N = 0;//число корректно ответивших датчиков for (byte n = 2; n < NumConfigPin; n++) { if (PinNumSens[n - 2] == true) { OneWire ds(n); byte addr[8]; while (N <= NumSens) { if ( !ds.search(addr)) { break; } for (byte c = 0; c < 2; c++) { byte present = ds.reset();//признак готовности датчика к ответу ds.select(addr); ds.write(0xBE);//Чтение памяти byte data[9]; for (byte d = 0; d < 9; d++) { data[d] = ds.read(); } byte CRC = OneWire::crc8(data, 8); if (CRC == data[8] && present == 1 && CRC != 0) {//ответ корректный if (N < NumSens) { Sensor[N][0] = data[0]; Sensor[N][1] = data[1]; Sensor[N][2] = data[3] * 10 + data[2];//номер датчика } N++; break; } else if (c == 0) {//датчик отсутсвует или мусор Serial.println(F("CRC!")); delay(100); } else { Serial.println(F("Sensors CRC Error")); } } } if (N > NumSens) { break; } } } // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // просто пример обработки показаний датчиков, // если их нумерация непрерывная с первого номера, // хотя не обязательно - тогда каждый отдельно, // а номера должны быть любые неповторяющиеся for (int SensorN = 1; SensorN <= NumSens; SensorN++) { int16_t DataT = DataSens(SensorN, Sensor); if (DataT == -1000) { Serial.print(F("Error")); } else { double SensT = (double)DataT / 16.0;//для библиотеки PID например Serial.print(SensT); Serial.print(F("*C")); } Serial.print(F(" Sensor #")); Serial.println(SensorN); } Serial.println(); // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> if (N > NumSens) { Serial.println(F("Find New Sensor. Start Search:")); SearchNumSens(); } ReadSens = false; } } //========================================================= //поиск нужного значения температуры в массиве по номеру датчика int16_t DataSens(int SensorN, int Sensor[][3]) { int16_t rawData = -1000;//любое нереальное значение for (byte i = 0; i < NumSens; i++) { if (Sensor[i][2] == SensorN) { rawData = (Sensor[i][1] << 8) | Sensor[i][0]; break; } } return rawData; } //========================================================= //запись номера датчика в его EEPROM boolean NumConfigSens(int NumConfig) { byte v1 = NumConfig % 10; byte v2 = (NumConfig - v1) / 10; OneWire ds(NumConfigPin); ds.reset();//сброс шины ds.write(0xCC);//Игнорировать адрес ds.write(0x4E);//разрешение записать конфиг //write scratchpad (starts at byte 2) ds.write(v1);//value of user byte 1 ds.write(v2);//value of user byte 2 ds.write(0x7F);//default value of Config = 0x7F (user byte 3)//точность преобразования ds.reset();//сброс шины - обязательно до задания следующей комманды копирования в EEPROM ds.write(0xCC);//Игнорировать адрес ds.write(0x48);// копируем три байта в EEPROM DS18B20, чтобы сохранить постоянно delay(20);//ждём, пока закончит запись ds.reset();//сброс шины - обязательно до задания следующей комманды копирования в ОЗУ ds.write(0xCC);//Игнорировать адрес ds.write(0xB8);//Данные перезагружены из EEPROM в ОЗУ ds.reset();//сброс шины - обязательно до задания следующей комманды чтения из ОЗУ ds.write(0xCC);//Игнорировать адрес ds.write(0xBE);//Чтение памяти - нам нужны только байт 2,3 ds.read();//нам не нужен(0) ds.read();//нам не нужен(1) if (ds.read() == v1 && ds.read() == v2) { return true; } else { return false; } } //========================================================= //поиск числа датчиков и задействованных пинов void SearchNumSens() { NumSens = 0; byte addr[8]; for (byte n = 2; n < NumConfigPin; n++) { PinNumSens[n - 2] = false; OneWire ds(n); while (true) { if ( !ds.search(addr)) { break; } Serial.print(F("Pin #")); Serial.print(n); Serial.print(F(":\r\nROM = ")); for (byte i = 0; i < 8; i++) { Serial.print(addr[i], HEX); Serial.print(' '); } if (OneWire::crc8(addr, 7) == addr[7]) { ds.reset();//сброс шины - обязательно до задания следующей комманды чтения из ОЗУ ds.select(addr); ds.write(0xBE);//Чтение памяти - нам нужны только байт 2,3 ds.read();//нам не нужен(0) ds.read();//нам не нужен(1) Serial.print(F("Sensor #")); Serial.println(ds.read() + ds.read() * 10); NumSens++; PinNumSens[n - 2] = true; } else { Serial.println(F("Sensors ID Error!")); } } } Serial.print(F("\r\nNumber of Sensors = ")); Serial.println(NumSens); Serial.println(); }
думаю хорошей идеей будет записать в Eeprom датчика его номер
и уже по нему обрабатывать его показания:
1.подключаем датчик к выделенному пину
2.программой записываем в датчик нужный номер
3.помечаем биркой его номер
4.забываем про ID датчиков
пользуемся любым колличеством, на любом пине, в любом порядке...
что вы думаете по этому поводу?
начинайте критиковать...
А это что за плод сумрачных мыслей?
Зачем искать пины, к которым подключены ds18b20? Вы забыли куда их подключали - дак посмотрите. По хорошему, должна быть схема, где это видно невооруженным глазом,
А чего спросить то хотели?
У датчика уже есть "врожденный" номер. Его адрес, зачем второй в него писать?
ПС. стр39-45 Это чё нафиг такое? Опять переполнение миллиса?! Да сколько ж можна то...
поеееехали..
представте себе наладчика.который подготовил датчики(ну сто, например) по номерам,
программу обработки, кабели на проэкте , воткнув их в любой пин...
что осталось? : подключить физически датчики по списку номеров совместив их с местом на проекте...
а поменять датчик? : вписал номер и всё...
а поменять местами, если ошибся?...
или по ID сверять?
а для дома с парой датчиков и городить нечего: записал на бумажке и в прорамму ID и всё...
а по поводу миллиса моооожно поподробней? только без обычных грубостей...
Опять переполнение миллиса?! Да сколько ж можна то...
А вдруг переполнится? Ужасть-же!
или по ID сверять?
А чем Ваш номер в епроме лучше его родного номера/адреса? Вот просто - какие выгоды Вы от этого получаете?
Вы собрались приклеивать бирки с номерами, так что мешает приклеивать бирки с адресами?
а по поводу миллиса моооожно поподробней? только без обычных грубостей...
Дак без грубостей первую полсотню раз было ))) Не помогает, поищите по форуму, оно пару раз в месяц всплывает с завидной регулярностью.
Опять переполнение миллиса?! Да сколько ж можна то...
А вдруг переполнится? Ужасть-же!
да просто раз в 50 дней будет сбой верности чтения датчика, или я что-то не так понимаю?
а если не критично ,то можно и упростить...
да просто раз в 50 дней будет сбой верности чтения датчика, или я что-то не так понимаю?
Что-то не так понимаете.
или по ID сверять?
А чем Ваш номер в епроме лучше его родного номера/адреса? Вот просто - какие выгоды Вы от этого получаете?
Вы собрались приклеивать бирки с номерами, так что мешает приклеивать бирки с адресами?
можно теоретически и в бинарном виде номер дома обозначать, только почту перестанете получать...
номер как-то человечней для наладчика...
а по поводу миллиса моооожно поподробней? только без обычных грубостей...
Дак без грубостей первую полсотню раз было ))) Не помогает, поищите по форуму, оно пару раз в месяц всплывает с завидной регулярностью.
учту,пороюсь...
номер как-то человечней для наладчика...
А адрес (число от 8 до 127) как-то бесчеловечно? :) Понял.
Предлагаю ещё более человечный вариант: футбольные карточки: на одном датчике Пеле, на другом Кака, на третьем Ахахауи. Ну, или, если наладчики - мужики, то можно фото порнозвёзд использовать. Всяко лучше, чем безликое число :))))
Да. Колода порнокарт - просто идеально и картон крепкий и идентификаторы какие хочеш, хоть чирва девятка, хоть блондинка в раскаряку.
номер как-то человечней для наладчика...
А адрес (число от 8 до 127) как-то бесчеловечно? :) Понял.
Предлагаю ещё более человечный вариант: футбольные карточки: на одном датчике Пеле, на другом Кака, на третьем Ахахауи. Ну, или, если наладчики - мужики, то можно фото порнозвёзд использовать. Всяко лучше, чем безликое число :))))
а число действительно безликое. т,к ID произвольный, а номер - контролируемый...
и заодно сходите на проект...
и попросите наладчика найти датчик по ID...да даже в списке.
куда он пошлёт?
Неважно куда пощлет, важно куда пойдет. Выдете ему датчик с порнокартой "блондинка в раскаряку" а в коде, лучше в отдельном файле ашнике, пишете
с реальным адресом этого датчика.
Когда вернется - скажет куда дел датчик, "на трубе весит" снова прямо в код.
#define BLONDINKA_IN_RASCARYAKA_POSITION "На трубе"
Потом все такие дефайники собираете в массив структур из которого всегда можна узнать адрес датчика на трубе. Если надо то и идентификатор бирки, можна хранить. А можна и в код глянуть когда надо узнать соответствие между биркой расположением и адресом.
вот нашёл объяснение:
UPD1:
Раз в коментариях возник вопрос, попробую объяснить "почему тут не будет переполнения".
Оно будет. Но будет "два раза". После того как millis() перепрыгнет границу и начнет опять отсчет с нуля можно заподозрить что выражение if(millis()-lastDoTime>inteval) больше никогда не сработает. Так как разница (millis()-lastDoTime) - будет отрицательной (пока millis() опять не станет боьлше lastDoTime). И соответственно всегда меньше любого интервала.
Но.... это в математике. А тут нам нужно еще помнить про типы. И то что время мы храним в unsigned long. Следовательно отрицательных чисел - у нас просто не бывает. Попытка сохранить отрицательное числов в беззнаковую переменную, опять вызовет переполнение-переход. Только "в обратную сторону". И интервал (millis()-lastDoTime) - все-таки будет правильным. Несмотря на переполнение.
исправлюсь...
а насчёт трубы...
а вы соберите макет на несколько датчиков, потасуйте, поменяйте ,
увидите как удобно, само всё находится автоматически,
наладчику надо минимум навыков(не нужен програмист) - в этом и была цель.
Я делал такое 2-я приложениями одно чисто для такой процедуры и сохраняет в EEPROM, а второе основное рабочее просто использует готовіе данные. Так размер основного приложения сокращается.