Arduino SIM800 двойной пост данных - PullRequest
0 голосов
/ 01 апреля 2019

У меня есть метеостанция, которая каждые несколько минут отправляет данные на мой сервер. Частота обновления в настоящее время установлена ​​на 170 секунд, и большую часть времени она работает, но время от времени данные отправляются два раза подряд в течение нескольких секунд (30-60), даже если сценарий должен это предотвратить. Мой проект настроен так, что при запуске arduino он отправляет данные после первого измерения, а затем после 10 измерений (около 3 минут). Похоже, что второй пост (обычно) содержит только одно измерение, так как измеренный порыв ветра и скорость обычно одинаковы, что обычно не имеет место. Я думал, что эта проблема может быть вызвана ошибкой последовательного буфера печати, и время от времени arduino сбрасывается, поэтому я отключил последовательную печать, но ошибка все еще сохраняется. Я попытался сделать несколько дополнительных блокировок, которые могли бы предотвратить отправку данных, когда отправка уже выполняется, но пока безуспешно.

Вот пример из json post

171 {"dir": "176", "speed": "2.2", "gust": "4.8", "tmp": "21.5", "wat": "", "btt": "66"}
172 {"dir": "0", "speed": "0.9", "gust": "1.9", "tmp": "21.1", "wat": "", "btt": "66"}
170 {"dir": "110", "speed": "1.3", "gust": "1.9", "tmp": "20.7", "wat": "", "btt": "65"}
171 {"dir": "132", "speed": "2.7", "gust": "3.9", "tmp": "20.4", "wat": "", "btt": "67"}
172 {"dir": "198", "speed": "2.9", "gust": "3.9", "tmp": "20.0", "wat": "", "btt": "65"}
171 {"dir": "286", "speed": "16.6", "gust": "16.6", "tmp": "19.8", "wat": "", "btt": "68"}
42 {"dir": "198", "speed": "2.7", "gust": "3.9", "tmp": "19.5", "wat": "", "btt": "68"}
171 {"dir": "220", "speed": "2.0", "gust": "2.9", "tmp": "19.2", "wat": "", "btt": "65"}
169 {"dir": "176", "speed": "2.1", "gust": "3.9", "tmp": "18.8", "wat": "", "btt": "65"}

Вот мой код

#include <Http.h> // send data
#include <ArduinoJson.h> //parse server response
#include <Sleep_n0m1.h> // put arduino to sleep
#include <math.h> // wind speed calculations
#include <OneWire.h> // water Temperature sensor
#include <DallasTemperature.h> // water Temperature sensor
#include <DHT.h> // Temperature sensor
#include <DHT_U.h>
#include "config.h"
#define WindSensorPin (3) // The pin location of the anemometer sensor 
#define WindVanePin (A3)       // The pin the wind vane sensor is connected to
#define DHTPIN 4     // what pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302)
#define ONE_WIRE_BUS 2
#define DEBUG FALSE

Sleep sleep;
DHT dht(DHTPIN, DHTTYPE); //// Initialize DHT sensor
OneWire oneWire(ONE_WIRE_BUS); // water semperature
DallasTemperature sensors(&oneWire);

const char *bearer="internet.bob.si"; // APN address
const char *id=API_PASSWORD;  // get this unique ID in order to send data to vetercek.com
const char *webpage="vetercek.com/xml/post.php";  // where POST request is made
unsigned int RX_PIN = 9; //RX pin for sim800
unsigned int TX_PIN = 8; //TX pin for sim800
unsigned int RST_PIN = 12; //RST pin for sim800 - not in use
volatile unsigned long Rotations; // cup rotation counter used in interrupt routine 
volatile unsigned long ContactBounceTime; // Timer to avoid contact bounce in interrupt routine 
int WindSpeed; // speed  
long WindAvr=0; //sum of all wind speed between update
int WindGust=0;
int avrDir[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; // array where wind direction are saved and later one with highest value is selected as dominant
int measure_count=0; // count each mesurement
float Water; // water Temperature
char wat[6]; // Water char value
float Temp; //Stores Temperature value
char tmp[6]; // Temperature char value
int VaneValue;       // raw analog value from wind vane
int Direction;       // translated 0 - 360 direction
int VaneOffset=0;        // define the anemometer offset from magnetic north
int CalDirection;    // converted value with offset applied
int wind_dir;  //calculated wind direction
int wind_speed;  //calculated wind speed
int wind_gust;   //calculated wind gusts
char voltage[2]; //battery percentage
char gps[20]; //gps location
char response[100];
char body[200]; 
const int SleepTime=10000;       // delay between each masurement
int WhenSend=1;       // after how many measurements to send data to server
Result result;

HTTP http(9600, RX_PIN, TX_PIN, RST_PIN);
#define BODY_FORMAT "{\"id\": \"%s\", \"dir\": \"%d\", \"speed\": \"%d.%d\", \"gust\": \"%d.%d\", \"tmp\": \"%s\", \"wat\": \"%s\",  \"btt\": \"%s\",  \"loc\": \"%s\"}"


// the setup routine runs once when you press reset:
void setup() {
  if (DEBUG){
    Serial.begin(9600);
    while(!Serial);
      Serial.println("Starting!");
  }

  dht.begin();
  attachInterrupt(digitalPinToInterrupt(WindSensorPin), isr_rotation, FALLING); // interupt for anemometer
}

// the loop routine runs over and over again forever:
void loop() {

  Rotations = 0; // Set Rotations count to 0 ready for calculations 
  sei(); // Enables interrupts 
  delay (2000); // Wait 2 second to average 
  cli(); // Disable interrupts 
  sleep.pwrDownMode(); //set sleep mode
  sleep.sleepDelay(10000); //sleep for: sleepTime

  WindSpeed = Rotations * 1.125 * 0.868976242 * 10 ;  // convert to mp/h using the formula V=P(2.25/Time);    *0.868976242 to get knots 
  ++measure_count; // add +1 to counter
  WindAvr += WindSpeed; // add to sum of average wind values

  if (WindSpeed > WindGust) { // check if > than old gust of wind
    WindGust=WindSpeed;
  } 
  getWindDirection();

  if (DEBUG){
    Serial.println(CalDirection); 
    Serial.println(WindSpeed); 
    Serial.println(WindGust); 
    Serial.println(Temp); 
    Serial.println(Water); 
    Serial.println(WhenSend-measure_count); 
    Serial.println("");
  }   


  if (measure_count >= WhenSend) { // check if is time to send data online
    Temp= dht.readTemperature(); //read temperature...
    sensors.requestTemperatures(); // get water Temperature
    Water=sensors.getTempCByIndex(0);

    http.wakeUp();
    sendData();
    http.sleep();
  } 
}


void isr_rotation () {  // This is the function that the interrupt calls to increment the rotation count 
  if ((millis() - ContactBounceTime) > 15 ) { // debounce the switch contact. 
    Rotations++; 
    ContactBounceTime = millis(); 
  } 
}

int dominantDirection(int* array, int size){ // get dominant wind direction
  int maxIndex = 0;
  int max = array[maxIndex];
  for (int i=1; i<size; i++){
    if (max<array[i]){
      max = array[i];
      maxIndex = i*22; //this is just approximate calculation so server can return the right char value
    }
  }
  return maxIndex;
}


// Get Wind Direction, and split it in 16 parts and save it to array
void getWindDirection() {
  VaneValue = analogRead(WindVanePin);
  Direction = map(VaneValue, 0, 1023, 0, 360);
  CalDirection = Direction + VaneOffset;

  if(CalDirection > 360)
    CalDirection = CalDirection - 360;

  if(CalDirection < 0)
    CalDirection = CalDirection + 360;

  CalDirection=(CalDirection+11.25)/22.5;
    if(CalDirection < 16) { ++avrDir[CalDirection]; }
    else { ++avrDir[0]; }
}



// send data to server
void sendData(){
  wind_dir=dominantDirection(avrDir,16);
  wind_speed=WindAvr/measure_count; 
  dtostrf(Temp, 4, 1, tmp); //float Tmp to char
  dtostrf(Water, 4, 1, wat); //water to char

  http.configureBearer(bearer);
  result = http.connect();
  http.batteryState(voltage); //battery percentage
  http.gpsLocation(gps); // GPS location

  sprintf(body, BODY_FORMAT, id,wind_dir,wind_speed/10,wind_speed%10,WindGust/10,WindGust%10,tmp,wat,voltage,gps);

  if (DEBUG){
    Serial.println(body);
  }  

  result = http.post(webpage, body, response);
  if (result == SUCCESS) {

    measure_count=0;
    WindAvr=0; 
    WindGust=0;
    Water=0;
    Temp=0;
    memset(avrDir,0,sizeof(avrDir)); // empty direction array

    StaticJsonDocument<200> doc;
    deserializeJson(doc, response);
    JsonObject root = doc.as<JsonObject>();
    const char* idd = root["id"];
    int WhenSend2 = root["whensend"];
    int Offset = root["offset"];

    if (WhenSend2 > 0){  // server response to when to do next update 
      WhenSend=WhenSend2;
    }

    if (Offset > -999){  // server response to when to do next update 
      VaneOffset=Offset;
    }
  }

  http.disconnect();
}

Проект и более подробная информация доступны на https://github.com/jaka87/vetercek_WS/

Помощь приветствуется

...