selan61
Member
У меня уличные датчики такой конструкции и в них стоит вентилятор. Нашел на arduinoLab скетч подсчета оборотов кулера. Вставил этот скетч в проект Виталия Коробова с GitHub и залил в ардуину. Сейчас такая конструкция с вентилятором работает на ардуине и считает обороты и вместе с показаниями датчиков отправляет на narodmon. Хочу использовать такую конструкцию корпуса метеодатчиков и для ESP
Скетч рабочий и использует прерывания.
Раскрыть Спойлер
ESP с этим скетчем тоже работает, но когда я вставляю его в скетч arduinoLab для отправки на narodmon, то ESP крахуется fatal exception(0). Поставил на IDE в инструменты EspExceptionDecoder и по данным стека определил, что ESP крахуется именно по прерываниям. Видимо ESP более капризна при работе с прерываниями, чем ардуина. Прочитал здесь на форуме, что при работе с прерываниями не надо использовать delay(), нашел скетч подсчета оборотов на millis()
Но с ним тоже, когда я вставляю его в скетч arduinoLab
для отправки на narodmon, то ESP крахуется.
Помогите, если можно, грамотно вставить в этот скетч подсчет оборотов или первый или второй вариант. Я ни разу не программист и у меня не получается, хотя до этого собирал из разных кусков различные скетчи и всё прекрасно работало.
Скетч рабочий и использует прерывания.
Раскрыть Спойлер
Код:
[LIST=1]
[*]
[*]/ volatile int val;
[*]int rpmcount = 0;
[*]void rpm(){
[*]val++;
[*]}
[*]void setup() {
[*]Serial.begin(9600);
[*]attachInterrupt(2, rpm, CHANGE);
[*]}
[*]void loop() {
[*]val = 0; // сбрасываем счетчик и ждем.
[*]delay(500); // так как прерывание CHANGE, срабатывает два раза
[*]// то и считываем каждые пол секунды.
[*]rpmcount =(val*60)/2;
[*]
[*]Serial.print(rpmcount); // количество импульсов на 60 секунд
[*]// и делим на количество импульсов на оборот
[*]Serial.print(" rpm ");
[*]Serial.print(val);
[*]Serial.println(" val");
[*]}
[*]
[/LIST]
ESP с этим скетчем тоже работает, но когда я вставляю его в скетч arduinoLab для отправки на narodmon, то ESP крахуется fatal exception(0). Поставил на IDE в инструменты EspExceptionDecoder и по данным стека определил, что ESP крахуется именно по прерываниям. Видимо ESP более капризна при работе с прерываниями, чем ардуина. Прочитал здесь на форуме, что при работе с прерываниями не надо использовать delay(), нашел скетч подсчета оборотов на millis()
Код:
// read RPM
volatile int rpmcount = 0;
int rpm = 0;
unsigned long lastmillis = 0;
void setup(){
Serial.begin(9600);
attachInterrupt(0, rpm_fan, FALLING);//interrupt cero (0) is on pin two(2).
}
void loop(){
if (millis() - lastmillis == 1000){ /*Обновляйте каждую секунду, это будет равно частоте чтения (Hz).*/
rpm = rpmcount * 60; /* Convert frecuency to RPM, note: this works for one interruption per full rotation. For two interrups per full rotation use rpmcount * 30.*/
Serial.print("RPM =\t"); //print the word "RPM" and tab.
Serial.print(rpm); // print the rpm value.
Serial.print("\t Hz=\t"); //print the word "Hz".
Serial.println(rpmcount); /*print revolutions per second or Hz. And print new line or enter.*/
rpmcount = 0; // Restart the RPM counter
lastmillis = millis(); // Uptade lasmillis
}
}
Код:
//Датчик для народного мониторинга на ESP8266
#include <ESP8266WiFi.h>
#include <OneWire.h>
OneWire ds(2); // GPIO2 (a 4.7K resistor is necessary)
const char* ssid = "******"; // название и пароль точки доступа
const char* password = "******";
const char* host = "narodmon.ru";
const int httpPort = 8283;
byte addr[8];
float temperature;
float getTemp(){
byte data[12];
if (!ds.search(addr)) {
Serial.println("No more addresses.");
while(1);
}
ds.reset_search();
if (OneWire::crc8(addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
while(1);
}
ds.reset();
ds.select(addr);
ds.write(0x44);
delay(1000);
ds.reset();
ds.select(addr);
ds.write(0xBE);
for (int i = 0; i < 9; i++) {
data[i] = ds.read();
}
int raw = (data[1] << 8) | data[0];
if (data[7] == 0x10) raw = (raw & 0xFFF0) + 12 - data[6];
return raw / 16.0;
}
void setup() {
Serial.begin(115200);
delay(10);
}
void loop() {
// забираем температуру.
temperature = getTemp();
// Подключаемся к wifi
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
Serial.print("MAC address: ");
Serial.println(WiFi.macAddress());
Serial.println();
// подключаемся к серверу
Serial.print("connecting to ");
Serial.println(host);
// Use WiFiClient class to create TCP connections
WiFiClient client;
if (!client.connect(host, httpPort)) {
Serial.println("connection failed");
return;
}
// отправляем данные
Serial.println("Sending...");
// заголовок
client.print("#");
client.print(WiFi.macAddress()); // отправляем МАС нашей ESP8266
client.print("#");
client.print("ESP8266"); // название устройства
client.println();
// отправляем данные с градусника
client.print("#");
for(int i = 0; i < 8; i++) client.print(addr[i], HEX); // номер 18b20
client.print("#");
client.print(temperature);
client.print("#temp"); // название датчика
client.println("##");
delay(10);
// читаем ответ с и отправляем его в сериал
Serial.print("Requesting: ");
while(client.available()){
String line = client.readStringUntil('\r');
Serial.print(line); // хотя это можно убрать
}
client.stop();
Serial.println();
Serial.println();
Serial.println("Closing connection");
WiFi.disconnect(); // отключаемся от сети
Serial.println("Disconnect WiFi.");
delay(1000*60*10); // перекур 10 минут
}
Помогите, если можно, грамотно вставить в этот скетч подсчет оборотов или первый или второй вариант. Я ни разу не программист и у меня не получается, хотя до этого собирал из разных кусков различные скетчи и всё прекрасно работало.
Последнее редактирование: