график в реальном времени с использованием canvasjs - PullRequest
1 голос
/ 25 февраля 2020

Я пытаюсь сделать график почти в реальном времени, используя canvas js. Я использую Raspberry Pi для измерения данных и отправки их в базу данных внешнего виртуального сервера MariaDB.

С помощью RPI я отправляю n (считать от 1 до бесконечности), напать ie (напряжение, значение от SPI ), cas (время). Это довольно медленно, потому что я посылаю только 1000 образцов в секунду. Просто записав в .txt файл, не отправляя в базу данных, я получаю около 30 тыс. Сэмплов как таковых c. КОД от RPI:

#include <wiringPi.h>
#include <stdio.h>
#include <string.h>
#include <wiringPiSPI.h>
#include <iostream>
#include <stdint.h>
#include <stdlib.h>
#include <mariadb/mysql.h>
#include <string>
#include <ctime>
#include <date.h>
using namespace std;

int main(){

using namespace date;
using namespace std::Chrono;

time_t raw time;
  struct tm * timeinfo;
  char buffer [80];

//CONNECT TO DB

MYSQL *conn;

  if ((conn = mysql_init(NULL)) == NULL)
  {
    fprintf(stderr, "Could not init DB\n");
    return EXIT_FAILURE;
  }
  if (mysql_real_connect(conn, "IP", "name", "pass", "dbname", 0, NULL, 0) == NULL)
  {
    fprintf(stderr, "DB Connection Error\n");
    return EXIT_FAILURE;
  }

//READ FROM SPI
wiringPiSPISetup(0,2000000);
int i=1;
wiringPiSetup();
std::time_t now = std::time(0);

while (1){
uint8_t spiData [2] ;
wiringPiSPIDataRW (0, spiData, 2) ;
int MSB_1 = spiData[1];
MSB_1 = MSB_1 >> 1;
int MSB_0 = spiData[0] & 0b00011111;
MSB_0 = MSB_0 << 7;
int a = MSB_1 + MSB_0;
float b = ((5.0 *(float)a)/ 4096.0);

time (&rawtime);
timeinfo = localtime (&rawtime);
strftime (buffer, 80,"%Y-%m-%d %H:%M:%S",timeinfo);

//INSERT TO DB
string query = "INSERT INTO tabulka (n, napatie,cas) VALUES ("+to_string(i)+","+to_string(b)+",'"+buffer+"')";

i++;

if ( mysql_query(conn, query.c_str()) !=0)
 {
  fprintf(stderr, "Query Failure\n");
  return EXIT_FAILURE;
 }
delayMicroseconds(10);
}
mysql_close(conn);
return 0;
}

СТОРОНА ВИРТУАЛЬНОГО СЕРВЕРА:

Чтобы обновить страницу sh, я использую простой <meta http-equiv="refresh" content="1" >

КОД для создания графика на виртуальном сервере:

<?php

//CONNECT TO DB AND READ
$dataPoints = array();

$conn = mysqli_connect('127.0.0.1', 'name', 'pass', 'dbname');
if ($conn->connect_error) {
        die("Connection error: " . $conn->connect_error);
}

$result = $conn->query("select n, napatie from hodnoty.tabulka");

if ($result->num_rows > 0) {
        while ($row = $result->fetch_assoc()) {
            //$dataPoints[] = $row;
            array_push($dataPoints, array("x"=> $row['n'], "y"=> $row['napatie']));


    }
}


//MAKE GRAPH

?>
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="refresh" content="1" >
<script>
window.onload = function() {

var dataPoints = <?php echo json_encode($dataPoints, JSON_NUMERIC_CHECK); ?>;
var dataLength = 1000; 
var chart = new CanvasJS.Chart("chartContainer", {
    theme: "light2",
    title: {
        text: "NAPATIE NA VSTUPE DO RPI"
    },
    axisX:{
        title: "n [/-]"
    },
    axisY:{
        includeZero: false,
        suffix: "U [V]"
    },
    data: [{
        type: "line",
        yValueFormatString: "#,##0.0#",
        toolTipContent: "{y} Mbps",
        dataPoints: dataPoints 
    }]
});

    if (dataPoints.length > dataLength) {       // i think this dont work
        dataPoints.shift();
    }



chart.render();

}
</script>
</head>
<body>
<div id="chartContainer" style="height: 370px; width: 100%;"></div>
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
</body>
</html>

Для удаления старых данных я использую MariaDB EVENT, например:

CREATE EVENT mazanie ON SCHEDULE EVERY 1 SECOND ENABLE DO DELETE FROM tabulka WHERE 'cas' < CURRENT_TIMESTAMP - INTERVAL 5 SECOND; Столбец cas имеет метку времени типа данных.

И, наконец, проблема в том, что я хочу всегда видеть хотя бы одно и то же число значений на графике, созданное событие странным образом удаляет строки, как только у меня получается около 150 значений, а иногда около 1500 Допустим, я хочу всегда видеть около 1000 образцов.

ЗДЕСЬ ВЫ МОЖЕТЕ УВИДЕТЬ: http://147.232.175.92/info_1.php

1 Ответ

0 голосов
/ 03 марта 2020

Измените код, чтобы собрать 10 значений, создав пакетную вставку (INSERT ... VALUES (...), (...), ... (...);), а затем отправив этот запрос. Это может увеличить вашу емкость с 1К до 5К строк в секунду.

Конкурирует ли EVENT со сценарием вставки? То есть они касаются одного стола? Вместо этого, сделайте, чтобы скрипт выполнил DELETE и добавил LIMIT 1000.

Если вы можете допустить задержку пакетирования 10 значений, попробуйте 100; это будет работать еще быстрее. Также настройте LIMIT.

. DELETE может заменить каждый 10-й delayMicroseconds(10);. Это добавляет еще одну особенность к настройке.

Больше обоснования:

  • Из-за накладных расходов и транзакционной ATOMicity вставка 100 строк за раз примерно в 10 раз быстрее, чем 1 за раз. (Выход за 100 означает «убывающую отдачу».)
  • DELETE удаляет различное количество строк. Когда он удаляет много строк, он оказывает большее влияние на INSERTs и SELECTs, , возможно , приводя к очевидным пробелам в данных.
  • 10us задержка намного быстрее чем человеческое восприятие, которое кажется неоправданным для go этого минимума.
  • Опять же, для людей, рассмотрите возможность замораживания графика на уровне +/- 10 единиц, тем самым упрощая пользователю сравнение одной страницы с другой. .
  • И отправьте фактическое время, чтобы ось X была правильно разложена, а не равномерно разложена. Таким образом, вы сможете увидеть пробелы и, возможно, узнать, по какому шаблону они следуют.

Выполните большую часть этого, а затем вернитесь для дополнительной критики и настройки.

...