Отправка данных на thingspeak
- Войдите на сайт для отправки комментариев
Сб, 17/08/2019 - 17:01
Здравствуйте.
Мне необходимо отслеживать состояние 2х датчиков и при срабатывании отправлять время срабокти на thingspeak.
Но записать данные получается очень редко. На 30 попыток может произойти 1 передача.
Передача данных проивзодится по GPRS используя GPRS-shield от Амперки, на борту которого SIM800C.
При запуск модуль включается, получает IP сети. Настройки интернета выставлены верно.
Прошу подсказать где я допустил ошибку.
Мучаюсь уже 2й день, буду признателен за любой совет.
Код прилогаю ниже:
Moderator : пожалуйста, вставьте код правильно - http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukommentarii
Вставьте код по правилам форума, чтобы можно было указать номер строки с ошибкой. А пока просто - проверьте условия, в одном из них в логическом операторе потеряли символ
#include <TroykaRTC.h> #include <GPRS_Shield_Arduino.h> #include <SoftwareSerial.h> #include <Wire.h> #define SIM900_TX_PIN 4 #define SIM900_RX_PIN 5 #define SIM900_POWER_PIN 9 #define SIM900_BAND 9600 #define SENSOR_1_PIN 2 #define SENSOR_2_PIN 8 #define MIN_SEND_INTERVAL 22 // Максимальная частота отправки запросов на сайт (ограничение thingspeak) #define SENSOR_ACTIVE_STATE HIGH //Состояние выхода датчика при сработке #define H08M00_H19M30 15 // Интервал 08:00-19:30 #define H19M30_H22M30 15 // Интервал 19:31-22:30 #define H22M30_H06M00 60 // Интервал 22:31-06:00 #define H06M00_H08M00 15 // Интервал 06:01-07:59 RTC clock; String time; String date; String weekDay; // Адрес сайта (не менять) char gprs_server[] = "api.thingspeak.com"; // Ключ для записи на сайт String API = "***KWQ1DU3A5KBJE"; // ВАШ НОМЕР ТЕЛЕФОНА ДЛЯ ЗВОНКОВ char phone[] = "+79****"; //Служебные флаги bool vypis = 0; bool need_send_info_1 = false; bool need_send_info_2 = false; bool check1 = false; bool check2 = false; bool Sensor1State = false; bool lastSensor1State = false; int SensorCounter1 = 0; bool Sensor2State = false; bool lastSensor2State = false; int SensorCounter2 = 0; // Переменная, которая хранит максимальное время между сработками (если за это время датчик не сработал, будет звонок) unsigned long max_send_interval = 900; // Временная метка последнего звонка unsigned long timestamp_call = 0; // Служебные флаги bool need_calling = false; bool block_calling = false; GPRS sim900(SIM900_TX_PIN, SIM900_RX_PIN, SIM900_BAND); void send_info() { static unsigned long send_timestamp = millis(); // Проверка, что шлем не слишком часто и что надо отправлять if ((millis() - send_timestamp > MIN_SEND_INTERVAL * 1000) & (need_send_info_1 || need_send_info_2)) { Serial.print("TIMESTAMP "); Serial.println(send_timestamp); if (!sim900.connect(TCP, gprs_server, 80)) { Serial.println("Connect to server error"); delay(5000); } else { Serial.print("-> Connect to "); Serial.print(gprs_server); Serial.println(" OK!"); String url = "GET /update?api_key="; Serial.println(url); url += API; if (need_send_info_1 && need_send_info_2) { url += "&field1=1"; url += "&field2=1"; } else if (need_send_info_1) { url += "&field1=1"; } else if (need_send_info_2) { url += "&field2=1"; } else { return; } url += " HTTP/1.0\r\n\r\n"; char urlChar[url.length() + 1]; url.toCharArray(urlChar, url.length() + 1); sim900.send(urlChar, url.length()); char odpoved[512]; while (true) { int znaky = sim900.recv(odpoved, sizeof(odpoved) - 1); if (znaky <= 0) { if (vypis) { Serial.println("-> End answer."); } break; } odpoved[znaky] = '\0'; if (vypis) { Serial.print("Get: "); Serial.print(znaky); Serial.print(" byte: "); Serial.println(odpoved); } } sim900.close(); sim900.disconnect(); if (need_send_info_1 && need_send_info_2) { need_send_info_1 = false; need_send_info_2 = false; timestamp_call = millis(); block_calling = false; } else if (need_send_info_1) { need_send_info_1 = false; timestamp_call = millis(); block_calling = false; } else if (need_send_info_2) { need_send_info_2 = false; } send_timestamp = millis(); Serial.println("-> Disconnect"); } } } // Звонок на телефон void calling() { static unsigned long timestamp = 0; static bool is_calling = false; if (need_calling) { if (millis() - timestamp > 20000 && !is_calling && !sim900.isCallActive(phone) && !block_calling) { sim900.callUp(phone); is_calling = true; timestamp = millis(); } else if (millis() - timestamp > 20000 && is_calling && !sim900.isCallActive(phone)) { block_calling = true; timestamp = millis(); is_calling = false; } else if (millis() - timestamp > 20000 && is_calling && sim900.isCallActive(phone)) { timestamp = millis(); is_calling = false; sim900.hangup(); } } } // Проверка времени void check_time() { clock.read(); clock.getTimeStamp(time, date, weekDay); int hours = 0; int minutes = 0; hours = time.substring(0,2).toInt(); Serial.println(time.substring(0,2)); Serial.println(time.substring(3,5)); Serial.println(time.substring(6,8)); minutes = time.substring(3,5).toInt(); // Интервал 08:00-19:30 if (hours >= 8 && hours <= 19) // Сначала смотрим, что попали по часам { if (hours == 19 && minutes <=30) // Проверяем верхний предел по минутам { max_send_interval = H08M00_H19M30*60; } else if (hours >= 8 && hours < 19) // Смотрим широкий интервал { max_send_interval = H08M00_H19M30*60; } } // Интервал 19:31-22:30 if (hours >= 19 && hours <= 22) // Сначала смотрим, что попали по часам { if (hours == 19 && minutes > 30) // Проверяем в нижний предел по минутам { max_send_interval = H19M30_H22M30*60; } else if (hours == 22 && minutes <=30) // Проверяем верхний предел по минутам { max_send_interval = H19M30_H22M30*60; } else if (hours > 19 && hours < 22) // Смотрим широкий интервал { max_send_interval = H19M30_H22M30*60; } } // Интервал 22:31-6:00 if (hours >= 22 || hours <= 6) { if (hours == 22 && minutes > 30) { max_send_interval = H22M30_H06M00*60; } else if (hours == 6 && minutes == 00) { max_send_interval = H22M30_H06M00*60; } else if (hours >= 22 || hours <= 6) { max_send_interval = H22M30_H06M00*60; } } // Интервал 6:01-8:00 if (hours >= 6 && hours <= 8) { if (hours == 6 && minutes > 1) { max_send_interval = H06M00_H08M00*60; } else if (hours == 8 && minutes == 00) { max_send_interval = H06M00_H08M00*60; } else if (hours > 6 && hours < 8) { max_send_interval = H06M00_H08M00*60; } } Serial.print("h="); Serial.print(hours);Serial.print("m=");Serial.print(minutes);Serial.print("max_send_interval");Serial.println(max_send_interval); } void setup() { Serial.begin(9600); // Скорость обмена данными с компьютером clock.begin(); // clock.set(__TIMESTAMP__); pinMode(SENSOR_1_PIN, INPUT_PULLUP); pinMode(SENSOR_2_PIN, INPUT_PULLUP); if (!sim900.checkPowerUp()) { sim900.powerUpDown(SIM900_POWER_PIN); } Serial.print("SIM900 INIT"); while (!sim900.init()) { Serial.print("."); delay(1000); } delay(5000); Serial.println("OK"); Serial.print("Setting GPRS"); // Настройки интернета while (!sim900.join(F("beeline.internet.ru"), F("beeline"), F("beeline"))) { Serial.print("."); delay(2000); } Serial.print("OK"); Serial.print("IP Adress: "); Serial.println(sim900.getIPAddress()); check_time(); } void loop() { static unsigned long time_update_stamp = 0; //датчик 1// Sensor1State = digitalRead(SENSOR_1_PIN); if (Sensor1State != lastSensor1State) { if (Sensor1State == LOW) { check1 = HIGH; Serial.println("on sens1"); delay(25); } else { check1 = LOW; } delay(25); Serial.println(check1); } lastSensor1State = Sensor1State; if (check1 == HIGH) { need_send_info_1 = true; Serial.println("Сработал датчик 1"); Serial.println(need_send_info_1); delay(50); } else //датчик 2// Sensor2State = digitalRead(SENSOR_2_PIN); if (Sensor2State != lastSensor2State) { if (Sensor2State == LOW) { check2 = HIGH; Serial.println("on sens2"); delay(50); } else { check2 = LOW; } delay(50); Serial.println(check2); } lastSensor2State = Sensor2State; if (check2 == HIGH) { need_send_info_2 = true; Serial.println("Сработал датчик 2"); Serial.println(need_send_info_2); } // Проверяем и если надо отправляем данные send_info(); // Если превышен предел максимального времени сработки ставим флаг, что надо звонить if (millis() - timestamp_call > max_send_interval * 1000 && !block_calling) { need_calling = true; } else { need_calling = false; } // Делаем звонок calling(); // Обновляем данные о значении максимального времени сработки каждую минуту в зависимости от времени if (millis() - time_update_stamp > 60000) { check_time(); time_update_stamp = millis(); } // Чтобы дать время подумать delay(300); }неужели даже после подсказки не нашли? - строка 61
Ошибку нашел, исправил. Но проблема не делать.
Диагностируя состояние переменных через Serial обнаружил, что операции объединения строк в функции "send_info" не производятся. В чем может быть проблема?
может не ту ошибку исправили?
Если не формируется url, то выведите на экран переменные в условиях, и посмотрите какие условия у вас сработают.
В условии нехватало одного "&". Верно ?
Так и делаю. Условия срабатывают верно, но url не формируется.
Если объявить url без контактенации, то он отобразиться, но дальнейшие манипуляции с ним ни к чему не приводят
if((millis() - send_timestamp > MIN_SEND_INTERVAL * 1000) & (need_send_info_1 || need_send_info_2))Вы сдесь проверяете три разных условия или пытаетесь произвести булевую операцию?Условия срабатывают верно, но url не формируется.
Так не бывает.
вставьте вывод url в Сериал после каждой конкатеации и покажите результат
Проблема решена. Использовал макрос F() для вывода диагностических сообщений в порт и перенес объявление переменной в основной цикл.
Видимо происходило переполнение памяти и неверная запись.