датчик dallas ds1820 не работает, если я использую прерывания
- Войдите на сайт для отправки комментариев
Всем привет!
я строю простую метеостанцию (анемометр + температурный датчик), использую оптический приемник и передатчик из обычной шариковой мышки и датчик температуры dallas DS1820
если я запускаю только код анемометра, то он работает
если я запускаю только код (из примеров) датчика DS1820, он тоже работает
но когда я сливаю все в один скетч, перестают работать обе части, и анемометр и температурная часть ))
на самом деле даже если я только вставляю строку "sensors.begin()" код уже перестает работать, по крайней мере на запросы веб сервер уже не отвечает ((
я использую таймер и прерывания (для анемометра) в коде. Подскажите, где собака порылась, как только ставлю sensors.being() в процедуру setup, код перестает работать ((
код ниже:
#include <SPI.h>
#include <Ethernet.h>
#include <TimerThree.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 10
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
// MAC address from Ethernet shield sticker under board
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 20, 210); // IP address, may need to change depending on network
EthernetServer server(80); // create a server at port 80
const int led = LED_BUILTIN; // the pin with a LED
unsigned long windCount = 0;
unsigned long windCountCopy = 0;
float curTemp = 0;
int ledState = LOW;
void setup()
{
Ethernet.begin(mac, ip); // initialize Ethernet device
server.begin(); // start to listen for clients
pinMode(led, OUTPUT);
attachInterrupt(1, blink, RISING);
Timer3.initialize(1000000); //1 second
Timer3.attachInterrupt(writeToPort); // blinkLED to run every 0.15 seconds
Serial.begin(9600);
sensors.begin();
}
void writeToPort(void)
{
noInterrupts();
windCountCopy = windCount;
windCount = 0;
interrupts();
//sensors.requestTemperatures();
//curTemp = sensors.getTempCByIndex(0);
Serial.print("windCount = ");
Serial.println(windCountCopy);
}
void blink(void)
{
windCount = windCount + 1;
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
digitalWrite(led, ledState);
}
void loop()
{
EthernetClient client = server.available(); // try to get client
if (client) { // got client?
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) { // client data available to read
char c = client.read(); // read 1 byte (character) from client
// last line of client request is blank and ends with \n
// respond to client only after last line received
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println();
// send web page
client.println("<!DOCTYPE html>");
client.println("<html>");
client.println("<head>");
client.println("<title>Arduino Web Page</title>");
client.println("<meta http-equiv=\"refresh\" content=\"1\" >");
client.println("</head>");
client.println("<body>");
String windCountStr = "";
// char curTempStr[15];
windCountStr += windCountCopy;
// dtostrf(curTemp, 3, 2, curTempStr);
// String curTempStr = dtostrf(curTemp, 2, 2, 10);
client.println("<p>Wind speed: " + windCountStr + "</p>");
// client.println("<p>Temperature: ");
// client.println(curTemp);
// client.println("</p>");
client.println("</body>");
client.println("</html>");
break;
}
// every line of text received from the client ends with \r\n
if (c == '\n') {
// last character on line of received text
// starting new line with next character read
currentLineIsBlank = true;
}
else if (c != '\r') {
// a text character was received from client
currentLineIsBlank = false;
}
} // end if (client.available())
} // end while (client.connected())
delay(1); // give the web browser time to receive the data
client.stop(); // close the connection
} // end if (client)
}
Мой Вам совет - уберите измерение температуры из обработчика прерывания.
1. Заведите в loop некий вызыватель некой функции (ReadTemperatures())
//////////////////// RUN EVERY 5 SEC if ( millis() < Every5SecondTimer ) { Every5SecondTimer = millis(); } // after millis() overflow if ( (millis() - Every5SecondTimer) > 5000 ) { // Read temperatures ReadTemperatures(); Every5SecondTimer = millis(); }2. Заведите некий селектор (DS18B20mode) и в функции по очереди вызывайте requestTemperatures() и функцию считывания температуры (getTempC(DS18B20_devaddr0))
void ReadTemperatures() { // Read temperatures if (DS18B20mode) { DS18B20sensors1.requestTemperatures(); } else { float tempGet; tempGet = DS18B20sensors1.getTempC(DS18B20_devaddr0); } DS18B20mode = !DS18B20mode; }спасибо, сделал как вы сказали, то же самое. У меня возникло много вопросов пока я внедрял ваш код, но я вроде самостоятельно разобрался с помощью документации и гугла.
Но, не работает почему-то. А именно, загрузил скетч, обратился по айпи адресу, получил ответ, через 10 секунд должен был быть рефреш, но страницу ардуино не отдает. Хотя я кручу колесико мыши, у меня диод моргает, значит, прерывание отрабатывает. Пинги до устройства идут. Куда смотреть? Взгляните, пожалуйста, на конечный код, может я что-то напутал? Спасибо!
#include <SPI.h> #include <Ethernet.h> #include <TimerThree.h> #include <OneWire.h> #include <DallasTemperature.h> #define ONE_WIRE_BUS 10 OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); boolean DS18B20mode = true; DeviceAddress DS18B20_devaddr0; unsigned long Every5SecondTimer; // MAC address from Ethernet shield sticker under board byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(192, 168, 1, 41); // IP address, may need to change depending on network EthernetServer server(80); // create a server at port 80 const int led = LED_BUILTIN; // the pin with a LED unsigned long windCount = 0; unsigned long windCountCopy = 0; float curTemp = 0; int ledState = LOW; void setup() { sensors.begin(); sensors.getAddress(DS18B20_devaddr0, 0); Ethernet.begin(mac, ip); // initialize Ethernet device server.begin(); // start to listen for clients pinMode(led, OUTPUT); attachInterrupt(1, blink, RISING); Timer3.initialize(10000000); //1 second Timer3.attachInterrupt(writeToPort); // blinkLED to run every 0.15 seconds //Serial.begin(9600); } void writeToPort(void) { // noInterrupts(); windCountCopy = windCount; windCount = 0; // interrupts(); // sensors.requestTemperatures(); // curTemp = sensors.getTempCByIndex(0); //Serial.print("windCount = "); //Serial.println(windCountCopy); } void blink(void) { windCount = windCount + 1; if (ledState == LOW) { ledState = HIGH; } else { ledState = LOW; } digitalWrite(led, ledState); } void ReadTemperatures() { // Read temperatures if (DS18B20mode) { sensors.requestTemperatures(); } else { curTemp = sensors.getTempC(DS18B20_devaddr0); } DS18B20mode = !DS18B20mode; } void loop() { //////////////////// RUN EVERY 5 SEC if ( millis() < Every5SecondTimer ) { Every5SecondTimer = millis(); } // after millis() overflow if ( (millis() - Every5SecondTimer) > 5000 ) { // Read temperatures ReadTemperatures(); Every5SecondTimer = millis(); } EthernetClient client = server.available(); // try to get client if (client) { // got client? boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { // client data available to read char c = client.read(); // read 1 byte (character) from client // last line of client request is blank and ends with \n // respond to client only after last line received if (c == '\n' && currentLineIsBlank) { // send a standard http response header client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html"); client.println("Connection: close"); client.println(); // send web page client.println("<!DOCTYPE html>"); client.println("<html>"); client.println("<head>"); client.println("<title>Arduino Web Page</title>"); client.println("<meta http-equiv=\"refresh\" content=\"10\" >"); client.println("</head>"); client.println("<body>"); String windCountStr = ""; // char curTempStr[15]; windCountStr += windCountCopy; // dtostrf(curTemp, 3, 2, curTempStr); // String curTempStr = dtostrf(curTemp, 2, 2, 10); client.println("<p>Wind speed: " + windCountStr + "</p>"); client.println("<p>Temperature: "); client.println(curTemp); client.println("</p>"); client.println("</body>"); client.println("</html>"); break; } // every line of text received from the client ends with \r\n if (c == '\n') { // last character on line of received text // starting new line with next character read currentLineIsBlank = true; } else if (c != '\r') { // a text character was received from client currentLineIsBlank = false; } } // end if (client.available()) } // end while (client.connected()) delay(1); // give the web browser time to receive the data client.stop(); // close the connection } // end if (client) }У меня в свое время были большие (и так и не решенные) проблемы с meta http-equiv="refresh" content="10"
Пару раз (рандомно) срабатывало и переставало отдавать контент. Убирал http-equiv="refresh" content="10", ставил автообновление страницы из браузера - та же фигня. Ничего не добился, поменял подход и ушел с TCP на UDP.
Скетч выглядит вполне рабочим и достаточно малым в плане использования памяти. Колесико мыши, моргающий диод и отрабатывающее прерывание, на мой взгляд, к проблеме с выдачей странички отношения не имеют.
ну да, опрос датчика температуры надо конечно пореже делать, он небыстро делается
я правильно понимаю, что нужно делать попеременно requestTemperatures и getTempC чтобы ускорить процесс получения температуры? в документации опять же особо ничего не расписано
ну да, опрос датчика температуры надо конечно пореже делать, он небыстро делается
я правильно понимаю, что нужно делать попеременно requestTemperatures и getTempC чтобы ускорить процесс получения температуры? в документации опять же особо ничего не расписано
Да, можно делать попеременно.
Почитайте о функциях setResolution() и setWaitForConversion() библиотеки DallasTemperature, там про "быстро" и "небыстро" как раз.
Да, можно делать попеременно.
Почитайте о функциях setResolution() и setWaitForConversion() библиотеки DallasTemperature, там про "быстро" и "небыстро" как раз.
все, нашел, в DallasTemperature.cpp ))) Получается, что если не выставить setWaitForConversion() в false, то оно будет работать "медленно". Спасибо за наводку, очень помогли, теперь понятна схема, которую вы подкинули. Осталось разобраться, почему же он все-таки зависает. Я еще на arduino.cc форуме задал вопрос, но пока ничего путнего мне там не ответили
А "нормальной" доки на dallastemperature нет? только сорцы смотреть? )
А "нормальной" доки на dallastemperature нет? только сорцы смотреть? )
DallasTemperature.h - наше все, полноценной документации не встречал, впрочем, так ли она нужна ?
Крайне не рекомендую использовать библиотеки для конкретных устройств 1wire. Лучше использовать библиотеку 1wire и отдавать команды устройствам "вручную". Сразу избавитесь от кучи проблем связанных с конфликтами библиотек.
Вот доки по "однопроводу".
http://chipenable.ru/index.php/programming-avr/item/81-1-wire-rabota-s-d...
http://owfs.sourceforge.net/family.html
http://www.maximintegrated.com/en/products/1-wire/flash/overview/
http://www.mirpu.ru/interface/87-1-wire/180--1-wire-.html?7e140644fd59b5...