|
- // vim: noai:sw=2:tw=88
-
- #include <TimeLib.h>
- #include "NoiseSensor.h"
- //#include "NoiseSensorNode.h"
-
-
- bool NoiseSensorClass::begin() {
- _PACKET_SIZE = ( _tick_count + LORA_HEADER_LENGTH + BATTERY_FIELD_SIZE );
- _REQUEST_SIZE = ( PACKET_COUNT * _PACKET_SIZE * 2 ); // * 2, it's 16 bit.
-
- for (int i = 0; i < PACKET_COUNT; i++) {
- _nodes[i] = new NoiseSensorNode(i, _PACKET_SIZE * 2);
- }
-
- if (this->_tick_duration < 2) {
- Serial.println("--> Using a tick duration of less than two seconds. This "
- "will fail unless you've increased the MCUs SYSCLK!");
- }
-
- if (this->_tick_count >= 100) {
- Serial.println(
- "--> Using a tick count of more than 100 gets dangerously close to the "
- "LoRa transmission limitations and is not supported as of now.");
- } else if (this->_tick_count < 10) {
- Serial.println(
- "--> Using a tick count smaller than 10 might screw things up in a "
- "unpredictable manner and is not recommended.");
- }
-
-
- if (this->_tick_count >= 120) {
- Serial.println(
- "--> Increased the tick count over 120. This results in I²C packages of "
- "(tick_count + 3 ) * 2. "
- "Note that I²C packets longer than 256 bytes will need to be split into "
- "smaller chunks to allow them to transfer."
- }
-
- if (!setupNTPClient()) {
- Serial.println("!!!-------------------------!!!");
- Serial.println("NTPClient couldn't be started.");
- Serial.println("!!!-------------------------!!!");
- return false;
- }
- I2C.begin(400000);
-
- this->sendSyncBeacon();
- while (I2C.writeBusy) {
- delay(250);
- Serial.println("Writing!");
- }
- this->_first_sync = 1;
- }
-
- bool NoiseSensorClass::begin(uint8_t tick_count) {
- this->_tick_count = tick_count;
- this->begin();
- }
-
- bool NoiseSensorClass::begin(uint8_t tick_count, uint8_t tick_duration) {
- this->_tick_count = tick_count;
- this->_tick_duration = tick_duration;
- this->begin();
- }
-
- bool NoiseSensorClass::begin(uint8_t tick_count, uint8_t tick_duration,
- uint8_t tx_offset) {
- this->_tick_count = tick_count;
- this->_tick_duration = tick_duration;
- this->_tx_offset = tx_offset;
- this->begin();
- }
-
- void NoiseSensorClass::setIds(const char* sensebox_ids[], const char* sensor_ids[]) {
- for (int i = 0; i < PACKET_COUNT; i++) {
- char tmp[24] = {0};
- _nodes[i]->sensebox_id = sensebox_ids[i];
- _nodes[i]->sensor_id = sensor_ids[i];
- }
- }
-
-
- bool NoiseSensorClass::beaconReady() {
- // if (this->_time_client->getEpochTime() - this->_last_sync_time ==
- if (now() - _last_sync_time ==
- (this->_tick_count * this->_tick_duration)) {
- Serial.println("---->Beacon ready");
- return true;
- }
- return false;
- }
-
- bool NoiseSensorClass::requestReady() {
- // 1 second as tolerance
- if (!this->_first_sync &&
- //this->_time_client->getEpochTime() - this->_last_sync_time ==
- now() - _last_sync_time ==
- (5 * this->_tx_offset * this->_tick_duration + 1)) {
- Serial.println("---->Request ready");
- return true;
- }
- return false;
- }
-
- bool NoiseSensorClass::read() {
- Serial.println("Starting read");
- for (int pkt = 0; pkt < PACKET_COUNT; pkt++) {
- // Calculate the time of the sync message that triggered this packet.
- uint32_t time_offset = (_tick_count * _tick_duration) + 1; // TODO Move
- this->_nodes[pkt]->_sync_message_ts = this->_last_sync_time - time_offset;
- Serial.print("Last sync time: ");
- Serial.println(_last_sync_time);
- Serial.print("Offset: ");
- Serial.println(time_offset);
- Serial.print("TS: ");
- Serial.println(_nodes[pkt]->_sync_message_ts);
- Serial.print(minute(_nodes[pkt]->_sync_message_ts));
- Serial.print(":");
- Serial.println(second(_nodes[pkt]->_sync_message_ts));
- /*
- if (_nodes[pkt]->missing_answers > 0) {
- _nodes[pkt]->_sync_message_ts -= time_offset * _nodes[pkt]->missing_answers;
- }
- */
- I2C.readBytes(this->_i2c_address, (uint8_t *) this->_nodes[pkt]->_measurements, this->_PACKET_SIZE * 2);
- }
-
- uint32_t read_start_time = millis();
- while (I2C.readBusy) {
- Serial.println("Reading!");
- delay(1);
-
- // Restart I²C if no response for more than a second.
- if (millis() - read_start_time >= 1000) {
- Serial.println("Restarting I²C");
- I2C.end();
- I2C.begin(400000);
- return false;
- }
- }
- // Skip 0, it has no battery.
- for (int pkt = 1; pkt < PACKET_COUNT; pkt++) {
- // TODO Move this to a sane place (own function).
- if (_nodes[pkt]->_measurements[_PACKET_SIZE - 1]) {
- Serial.print("Battery low on device");
- Serial.println(pkt);
- }
- }
-
- Serial.println("Reading done.");
- return true;
- }
-
- void NoiseSensorClass::printMeasurements(uint8_t node_id) {
- uint32_t ts = this->_nodes[node_id]->_sync_message_ts;
- char printbuf[32];
- sprintf(printbuf, "- ID %u - ", node_id);
- Serial.println(printbuf);
-
- for (int i = 2; i < (this->_PACKET_SIZE - BATTERY_FIELD_SIZE); i++) {
- sprintf(printbuf, "%02i:%02i:%02i -> ", hour(ts), minute(ts), second(ts));
- Serial.print(printbuf);
-
- Serial.println(this->_nodes[node_id]->_measurements[i]);
- ts += this->_tick_duration;
-
- }
- }
-
- bool NoiseSensorClass::sendSyncBeacon() {
- //_last_sync_time = _time_client->getEpochTime();
- uint8_t setup_values[3];
-
- setup_values[0] = this->_tick_count;
- setup_values[1] = this->_tick_duration;
- setup_values[2] = this->_tx_offset;
-
- Serial.println("Sent beacon");
- I2C.writeBytes(this->_i2c_address, 0x01, (uint8_t *)setup_values,
- sizeof(setup_values));
- this->_first_sync = 0;
- _last_sync_time = now();
- Serial.println(_last_sync_time);
- Serial.print(minute(_last_sync_time));
- Serial.print(":");
- Serial.println(second(_last_sync_time));
-
- while (I2C.writeBusy) {
- delay(250);
- Serial.println("Writing!");
- }
- }
-
- String NoiseSensorClass::buildSenseBoxJSON(uint8_t device_id) {
- // _time_client->update();
- NoiseSensorNode* node = _nodes[device_id];
- uint32_t ts = node->_sync_message_ts;
-
- // Each measurement line is max. 94 chars long + 2 curly brackets.
- uint16_t bufsize = _tick_count * 94 + 2;
- char json_buf[bufsize] = {0};
- char sensor_id[25] = {0};
- node->sensor_id.toCharArray(sensor_id, 25);
-
- // Build a json string in a very comprehensible way...
- strcat(json_buf, "[\n");
-
- for (int i = 2; i < (_PACKET_SIZE - BATTERY_FIELD_SIZE); i++) {
- char tmpbuf[1024] = {0};
- char timestamp[24] = {0};
- float m = node->_measurements[i] / 10.0; // From fixed point to float.
-
- if (m >= 29 && m <= 120) {
- sprintf(timestamp, "%i-%02i-%02iT%02i:%02i:%02iZ", year(ts), month(ts),
- day(ts), hour(ts), minute(ts), second(ts));
-
- sprintf(tmpbuf, "{\"sensor\":\"%s\", \"value\":\"%.1f\", \"createdAt\":\"%s\"}", sensor_id, m, timestamp);
-
- // No trailing comma on the last entry.
- if (i != _PACKET_SIZE - BATTERY_FIELD_SIZE - 1) {
- strcat(tmpbuf, ",");
- }
- strcat(json_buf, tmpbuf);
- strcat(json_buf, "\n");
-
- }
-
- ts += this->_tick_duration;
- }
-
- /*
- if (strlen(json_buf) > 2) {
- node->missing_answers = 0;
- Serial.println("Missing answers reset.");
- } else {
- node->missing_answers++;
- Serial.print("Missing answers: ");
- Serial.println(node->missing_answers);
- }
- */
-
- strcat(json_buf, "]");
-
- return json_buf;
- }
-
- String NoiseSensorClass::buildHTTPHeader(uint8_t device_id, const char* server, uint16_t content_length) {
- char sb_id[25] = {0};
- _nodes[device_id]->sensebox_id.toCharArray(sb_id, 25);
-
- char uploadbuf[2048] = {0};
- sprintf(uploadbuf, "POST /boxes/%s/data HTTP/1.1\n"
- "Host: %s\n"
- "content-type: application/json\n"
- "Connection: close\n"
- "Content-Length: %u", sb_id, server, content_length);
-
- return String(uploadbuf);
- }
-
-
- // Private functions
-
- bool NoiseSensorClass::setupNTPClient() {
- uint32_t start_time = millis();
- while (timeStatus() != timeSet) {
- if (millis() - start_time >= 200) {
- return false;
- }
- }
- return true;
- //setSyncProvider(
-
-
- //WiFiUDP ntpUDP;
- //this->_time_client = new NTPClient(ntpUDP);
- //this->_time_client->begin();
-
- //if (this->_time_client->update()) { return true; }
-
- }
-
- NoiseSensorClass NoiseSensor;
|