Duomenų srautas

Netikėtai nutrūko mobilaus interneto paslauga. Iškilo klausimas, kokį srautą generuoja duomenų grafiko perpiešimas. Suinstaliuotas iptraf paketas į Rpi.
parodytas srautas su iptraf paslauga ir grafiko atvaizdavimas viename įrenginyje generavo 38kbit/sek. srautą. Pridėjus dar vieną įrenginį su grafiko srauto vaizdavimu gavosi 52 kbit/sek. Atjungus įrenginius srautas sumažėjo iki 28kbit/sek. nedidelės matematinės manipuliacijos rodo

(52-27)/2=12,5kbit/sek duomenų srautas vieno grafiko dinaminiam atvaizdavimui

.

TODO: Gerai būtų automatiškai stabdyti duomenų perdavimą – reikia mygtuko grafiko vaizdavimo puslapyje.

Ką daryti, jei neveikia?

Prijungti USB kabelį – įsitikinti ar detektuoja Arduino Procesorių – įrenginių tvarkytuvėje turi atsirasti COM prievadas.
Pajungti LAN kabelį – Rpi turi atsakyti į ping paketą ir jungtis 192.168.2.177 fiksuotu LAN adresu su SSH protokolu (naudoju Putty programą).
Patikrinti megabaitų likutį http://mano.tele2.lt svetainėje. 2018.01.15 nustojo veikti valdiklio registracija MySQL į centrinį serverį. Per 15 dienų išnaudota 3GB duomenų.

Rpi programos kodas

Kompiliavimo eilutė

gcc -o test3.o -lmysqlclient -I/usr/local/include -L/usr/local/lib -lwiringPi test2.c

Programos kodas:

/*****Configures an Raspberry Pi as an SPI master and demonstrates bidirectional communication with an***/
#include <mysql/mysql.h>        //used by mysql
#include              //used by mysql
#include 
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
#include 
#include 
#include              //used by string
//#include 
/*******Declare Global Variables*****************************/
unsigned short int spiTxRx(char txDat);
int fd;
unsigned char AR_command[]={0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
//AR_command antras baitas nurodo siunciamos komandos ilgi be pirmo ir antro baitu jis uzpildomas siunciant seka
unsigned char AR_Komanda[512];
unsigned int AR_Komanda_Size;
unsigned char AR_command1[] = {0x20, 0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12};
unsigned char spi_bitsPerWord;
unsigned char spi_mode;
struct connection_details{char *server;char *user;char *password;char *database;};
MYSQL* mysql_connection_setup(struct connection_details mysql_details){// first of all create a mysql instance and initialize the variables within
        MYSQL *connection = mysql_init(NULL); // connect to the database with the details attached.
        if (!mysql_real_connect(connection,mysql_details.server, mysql_details.user, mysql_details.password, mysql_details.database, 0, NULL, 0)) {
                printf("Conection error : %s\n", mysql_error(connection));exit(1);
        }
        return connection;
}
MYSQL_RES* mysql_perform_query(MYSQL *connection, char *sql_query){
        if (mysql_query(connection, sql_query)) {// send the query to the database
                printf("MySQL query error : %s\n", mysql_error(connection));
                exit(1);
        }
        return mysql_use_result(connection);
}
struct connection_details mysqlD;
MYSQL *conn;                            // the connection
MYSQL_RES *res;                         // the results
MYSQL_ROW row;                          // the results row (line by line)
/**********************************************************
Main
    Setup SPI
    Open file spidev0.0 (chip enable 0) for read/write access with the file descriptor "fd"
    Configure transfer speed(1MHz)
***********************************************************/
unsigned short int resu[512];
int main (void){
    mysqlD.server = "localhost";                // where the mysql database is
    mysqlD.user = "vejojegaines";               // the root user of mysql
    mysqlD.password = "vejojegaines";           // the password of the root user in mysql
    mysqlD.database = "vejojegaines";           // the databse to pick
    conn = mysql_connection_setup(mysqlD);      // connect to the mysql database
    unsigned char result[20];
    unsigned char buffH[1];
    unsigned char buffL[1];
    fd = open("/dev/spidev0.0", O_RDWR);
    unsigned int speed =100000;
    ioctl (fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
    unsigned short int i;
    unsigned short int j=0;
    unsigned short int jmax=30;
    unsigned short int TS=100;
    unsigned short int TS_Prev=100;
    unsigned short int *TSa2Point;
    unsigned char qu[255];
    char *lai;
    unsigned int retx;
    unsigned int iii;
    unsigned int iiii;
    unsigned short int DisableWork=0;
    unsigned short int DisableWorkPrevious=0;
    unsigned char Komanda;
    void KomandosVykdymas();
    void LokalusDarbas();
    unsigned int id;
    char *pChar;
    while (1) {
        res = mysql_perform_query(conn, "select id, Komanda, Atlikta from komandos where Atlikta=0 order by ModData asc limit 1");
        while ((row = mysql_fetch_row(res))!=NULL) {
            for (iiii=0; iiii<strlen(row[1]); iiii=iiii+2) {
                AR_Komanda[iiii/2]=hex_char_to_bin(row[1][iiii])*16+hex_char_to_bin(row[1][iiii+1]);
            }
            AR_Komanda_Size=strlen(row[1])/2;
            if (atoi(row[2])==0) {DisableWork=1;} else {DisableWork=0;}
            if (DisableWork!=DisableWorkPrevious) {
                //printf("Darbo rezimas: %d\n", DisableWork);
                DisableWorkPrevious=DisableWork;
            }
            id=atoi(row[0]);
        }
        mysql_free_result(res);
        if (DisableWork==1) {
            KomandosVykdymas();
            sprintf(qu, "update komandos set Atlikta=1 where id=%d", id);
            res = mysql_perform_query(conn, qu);
            mysql_free_result(res);
            DisableWork=0;
          } else {
            //LokalusDarbas();
        }
        LokalusDarbas();        //testavimui
        usleep(1000000);//sekundes uzdelsimas tarp duomenu uzklausu
    }
    exit(1);
}
void KomandosVykdymas() {
    unsigned int i, pakartojimas;
    printf("(ilgis=%d) vykdymas\n", AR_Komanda_Size);
    SR_packet(AR_Komanda, AR_Komanda_Size);
    while (SR_packet(AR_Komanda, AR_Komanda_Size)==0){
        for (i=0; i<AR_Komanda_Size; i++) {printf("%02X ", AR_Komanda[i]);} printf("Kartojimas Komandos (%d baitu ilgis) vykdymas (%u kartas)\n", AR_Komanda_Size, pakartojimas); if (pakartojimas++>100) {
            printf("Pasiektas limitas kartojimui: %d. Vykdymas nesekmingas\n");
            break;
        }
    }
}
void LokalusDarbas() {
    unsigned int A0, A1, A2, A3, A4, A5, TS1, TS2, VGRA, VGRB, GenHzA, GenHzB;
    unsigned int i, pakartojimas;
    unsigned char qu[255];
    while (SR_packet(AR_command, sizeof(AR_command))==0){
        for (i=0; i<sizeof(AR_command); i++) {printf("%02X ", AR_command[i]);} SR_packet(AR_command, sizeof(AR_command)); printf("Kartojimas Komandos (%d baitu ilgis) vykdymas (%u kartas)\n", sizeof(AR_command), pakartojimas); if (pakartojimas++>100) {
            printf("Pasiektas limitas kartojimui (LokalusDarbas): %d. Vykdymas nesekmingas\n");
            return ;
            break;
        }
    }
    printf("Uzklausa(lokali):");
    for (i=0; i<sizeof(AR_command); i++) {printf("%02X ", AR_command[i]);}
    printf("Rezultatas:");
    for (i=0; i<sizeof(AR_command); i++) {printf("%02X ", resu[i]);}
    printf("\n ");
        A0=resu[3] + resu[4]*256;
        A1=resu[5] + resu[6]*256;
        A2=resu[7] + resu[8]*256;
        A3=resu[9] + resu[10]*256;
        A4=resu[11] + resu[12]*256;
        A5=resu[13] + resu[14]*256;
        VGRA=resu[15] + resu[16]*256;
        VGRB=resu[17] + resu[18]*256;
        GenHzA=resu[19] + resu[20]*256;
        GenHzB=resu[21] + resu[22]*256;
        TS1=resu[23] + resu[24]*256;
        TS2=resu[25] + resu[26]*256;
        //TSa2Point=&TSa2[0];
        //TS=AtmestiKrastinesReikmes(TSa2Point, jmax);
        //int A0min=0xFFFF;int A0max=0;for (j=0; j<jmax; j++) {if (A0a[j]>A0max) A0max=A0a[j];if (A0a[j]<A0min) A0min=A0a[j];}
        //int A1min=0xFFFF;int A1max=0;for (j=0; j<jmax; j++) {if (A1a[j]>A1max) A1max=A1a[j];if (A1a[j]<A1min) A1min=A1a[j];}
        //int A2min=0xFFFF;int A2max=0;for (j=0; j<jmax; j++) {if (A2a[j]>A2max) A2max=A2a[j];if (A2a[j]<A2min) A2min=A2a[j];}
        //int A3min=0xFFFF;int A3max=0;for (j=0; j<jmax; j++) {if (A3a[j]>A3max) A3max=A3a[j];if (A3a[j]<A3min) A3min=A3a[j];}
        //int A4min=0xFFFF;int A4max=0;for (j=0; j<jmax; j++) {if (A4a[j]>A4max) A4max=A4a[j];if (A4a[j]<A4min) A4min=A4a[j];}
        //int A5min=0xFFFF;int A5max=0;for (j=0; j<jmax; j++) {if (A5a[j]>A5max) A5max=A5a[j];if (A5a[j]<A5min) A5min=A5a[j];}
        sprintf(qu, "insert into vejojegaines.spi values (\"\",%i,%i,%i,%i,%i,%i,%i,%i,%i,null)",A0,A1,A2,A3,A4,A5, VGRA+VGRB*256*256, GenHzA+GenHzB*256*256, TS1+TS2*256*256);
        //printf("qu=%s\n", qu);
        res=mysql_perform_query(conn, qu);      // assign the results return to the MYSQL_RES pointer
        mysql_free_result(res);                 //clean up the database result set
}
int SR_packet(char AR[], int KKiek) {
    unsigned short int cs, css, i;
    cs=spiTxRx(0x81);//pradinis sekos baitas
    cs=0;//pirmas baitas dummy - jis neapskaitomas issiunciamojoje kontrolineje sumoje
    css=0x81;   //pirmas baitas ir pradeda kontrolin▒ siun▒iamos bait▒ sekos sum▒
    for (i=0; i<KKiek; i++) { if (i==1) {AR[i]=KKiek-2;}//siunciamu baitu kiekis irasomas i seka, kad priimantis irenginys zinotu ilgi resu[i] = spiTxRx(AR[i]); cs+=resu[i];if(cs>255) {cs=cs-256;}
        css+=AR[i];if(css>255) {css=css-256;}
    }
    resu[i]=spiTxRx(255-css);//kontrolin▒ siunciam▒ bait▒ sekos suma
    cs+=resu[i++];if(cs>255) {cs=cs-256;}
    resu[i]=spiTxRx(0x00);//finalinis baitas 'dymmy' skirtas nuskaityti paskutin▒ gaunam▒ bait▒
    cs+=resu[i];if(cs>255) {cs=cs-256;}
    if (cs!=0xff){
        printf("Bloga kontroline suma (checksum send) sc=%x\n", cs);return 0;
        } else {
        return 1;
    }
}
/**********************************************************
spiTxRx
    Transmits one byte via the SPI device, and returns one byte as the result.
    Establishes a data structure, spi_ioc_transfer as defined by spidev.h and loads the various members to pass the data
    and configuration parameters to the SPI device via IOCTL
    Local variables txDat and rxDat are defined and passed by reference.
***********************************************************/
unsigned short int spiTxRx(char txDat){
    unsigned char rxDat;
    struct spi_ioc_transfer spi;
    memset (&spi, 0, sizeof (spi));
    spi.tx_buf        = (unsigned long)&txDat;
    spi.rx_buf        = (unsigned long)&rxDat;
    spi.len           = 1;
    ioctl (fd, SPI_IOC_MESSAGE(1), &spi);
    return rxDat;
}
void ToMySQL(char qu[]) {
        res=mysql_perform_query(conn, qu);      // assign the results return to the MYSQL_RES pointer
        mysql_free_result(res);                 //clean up the database result set
}
int AtmestiKrastinesReikmes(unsigned short int *ar_ptr, int jmax) {
    unsigned short int i;
    unsigned short int max=0;
    unsigned short int min=1024;
    unsigned int res=0;
    unsigned long int res1=55555555;
    unsigned short int ct=0;
    for (i=0;i<jmax; i++) { if (*(ar_ptr+i)>max) max=*(ar_ptr+i);
        if (*(ar_ptr+i)<min) min=*(ar_ptr+i);
        //printf("%hu,", *(ar_ptr+i));
    }
    for (i=0;i<jmax; i++) {
        if (*(ar_ptr+i)!=max && *(ar_ptr+i)!=min) {
            res+=*(ar_ptr+i);
            ct++;
        }
    }
    if (ct==0) {
        //printf(".max:%hu, min: %hu, ct: %hu, res1: %li,--------\n", max, min, ct, max);
        return max;
      } else {
        res1=(double)res/(double)ct;
        res=res1;
        //printf(".max:%hu, min: %hu, ct: %hu, res1: %li,--------\n", max, min, ct, res);
        return res;
    }
}
int hex_char_to_bin(unsigned char *c){// TODO handle default / error
    switch(toupper(c)) {
        case '0': return 0;
        case '1': return 1;
        case '2': return 2;
        case '3': return 3;
        case '4': return 4;
        case '5': return 5;
        case '6': return 6;
        case '7': return 7;
        case '8': return 8;
        case '9': return 9;
        case 'A': return 10;
        case 'B': return 11;
        case 'C': return 12;
        case 'D': return 13;
        case 'E': return 14;
        case 'F': return 15;
    }
}

Arduino programos kodas

#include <SPI.h>
const int markeris=8;
const int klaida=4;
const int VejoPin=3;
const int Power1=5;
const int Power2=6;
const int VGROUT=2;//sukeiciau 2 ir 7 vietomis, kad tur42iau pertraukima, kurie galimi 2 ir 3 pin'uose UNO versijai
const int TempCL=7;
byte buf[256];
byte BETZ[256]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x03,0x03,0x03,0x03,0x03,0x03,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x06,0x06,0x06,0x06,0x07,0x07,0x07,0x08,0x08,0x08,0x08,0x09,0x09,0x09,0x0A,0x0A,0x0A,0x0A,0x0B,0x0B,0x0B,0x0C,0x0C,0x0C,0x0D,0x0D,0x0D,0x0E,0x0E,0x0E,0x0F,0x10,0x11,0x11,0x12,0x12,0x13,0x14,0x14,0x15,0x15,0x16,0x17,0x17,0x18,0x18,0x19,0x1A,0x1A,0x1B,0x1B,0x1C,0x1C,0x1D,0x1E,0x1F,0x1F,0x20,0x20,0x21,0x22,0x23,0x24,0x25,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x48,0x49,0x4B,0x4D,0x4E,0x4F,0x52,0x53,0x55,0x57,0x58,0x5A,0x5C,0x5D,0x5F,0x60,0x62,0x64,0x65,0x66,0x67,0x69,0x6A,0x6C,0x6E,0x6F,0x71,0x72,0x73,0x74,0x76,0x78,0x7B,0x7D,0x80,0x83,0x85,0x88,0x8A,0x8D,0x8F,0x92,0x94,0x97,0x9A,0x9C,0x9D,0x9F,0xA1,0xA4,0xA6,0xA9,0xAC,0xAE,0xB1,0xB4,0xB6,0xB9,0xBB,0xBF,0xC1,0xC2,0xC3,0xC5,0xC6,0xC8,0xCA,0xCC,0xCE,0xD0,0xD2,0xD4,0xD6,0xD8,0xDA,0xDC,0xDE,0xE0,0xE1,0xE3,0xE5,0xE7,0xE9,0xEB,0xED,0xEF,0xF1,0xF3,0xF4,0xF7,0xF9,0xFB,0xFD,0xFF};
byte dat[256];//={0x82,0xA9,0x0f,0x12,0x55,0x66,0x77,0x88,0x99,0x0A,0x19,0x28,0x37,0x46,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
byte checksumreal,komanda,clr;
int komilgis;
boolean beginas=false;
boolean process_error=false;
byte checksumsend=0;
int ctklaida=0;
volatile boolean doprint=false;
volatile byte pos;
signed long GenDaznis_us, prev_time_GenD, VejoGreitis_us, prev_time_us;
volatile boolean process_it;
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))    //Speedup the analogRead() function
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))      //Speedup the analogRead() function
void setup (void){
  Serial.begin (115200);         // debugging
  pinMode(markeris, OUTPUT);
  pinMode(klaida, OUTPUT);
  pinMode(VGROUT, INPUT);
  pinMode(Power1, OUTPUT);
  pinMode(Power2, OUTPUT);
  pinMode(MISO, OUTPUT);         // have to send on master in, *slave out*
  SPCR |= _BV(SPE);              // turn on SPI in slave mode, get ready for an interrupt 
  clr=SPSR;
  clr=SPDR;
  delay(10);
  ctklaida=0;
  pos = 0;                       // buffer empty
  checksumsend=0;
  process_it = false;
  SPI.attachInterrupt();         // now turn on interrupts
  sbi(ADCSRA, ADPS2);    //Speedup the analogRead() functionSS
  cbi(ADCSRA, ADPS1);
  cbi(ADCSRA, ADPS0);
  digitalWrite(klaida, LOW);
  attachInterrupt(digitalPinToInterrupt(VejoPin), rising, RISING);
  attachInterrupt(digitalPinToInterrupt(VGROUT), rising1, RISING);
  //pinMode(TempCL, OUTPUT);
  //setPwmFrequency(TempCL,1);
  //analogWrite(TempCL, 127);
} 
ISR (SPI_STC_vect){              // SPI interrupt routine
  digitalWrite(markeris, HIGH);
  byte c = SPDR;                 // grab byte from SPI Data Register
  byte z = 0;
  if (c==0x81 and beginas==false) {//0X81 hex'E - PAKETO PIRMAS BAITAS
    beginas=true;checksumreal=0;komilgis=0;pos=0;checksumsend=0; 
  }  
  if (beginas==true) {
    buf[pos]=c;
    checksumreal+=c; 
    switch (pos) {
      case 0:     z=dat[pos];
                  checksumsend+=dat[pos]; 
                  break;
      case 1:     z=dat[pos];
                  checksumsend+=dat[pos]; 
                  komanda=c;
                  break;
      case 2:     z=dat[pos];
                  checksumsend+=dat[pos]; 
                  komilgis=c; 
                  break;
      default: 
                if ((komanda & 0xF8)==0x30) {
                  if (pos<(komilgis+3)) {
                    BETZ[(komanda & 0x07)* 32 + pos-3]=c;    //Komandos A8-AF apraso, kuris is astuoniu paketas bus irasytas i BETZ masyva. Viename pakete 32 baitai. A8: 0-32 masyvo baitai AF - 224-256 baitai
                  }
                } else if ((komanda & 0xF8)==0x40) {
                   z=BETZ[(komanda & 0x07)* 32 + pos-3];
                } else {
                  //Serial.println("Komanda kita ");
                   z=dat[pos];
                } 
                if (pos==(komilgis+3)) {
                   dat[pos]=255-checksumsend;
                   z=dat[pos];
                  } else if (pos==(komilgis+4)) {
                   z=0x55;
                   process_it=true;
                   checksumsend=0;
                   pos=0;
                   beginas=false;
                   if (checksumreal==0xFF) {
                       process_error=false;
                      } else {
                       process_error=true;
                      digitalWrite(klaida, HIGH);
                   }
                } else {
                   checksumsend+=z; 
                }  
    }
    SPDR=z;  
    if (pos < sizeof(buf)) pos++; else { pos=0;beginas=false; } } digitalWrite(markeris, LOW); } void loop (void){ byte apkr; unsigned long TPM; unsigned int VGRmpers, x, CL, CH, GL, GH, TPL, TPH;//unsigned int - 0...256, signed int, -127...+127 reiksmes if (process_it) {process_it = false;} x=analogRead(A0); dat[3]=lowByte(x); dat[4]=highByte(x); x=analogRead(A1); dat[5]=lowByte(x); dat[6]=highByte(x); x=analogRead(A2); dat[7]=lowByte(x); dat[8]=highByte(x); x=analogRead(A3); dat[9]=lowByte(x); dat[10]=highByte(x); x=analogRead(A4); dat[11]=lowByte(x); dat[12]=highByte(x); x=analogRead(A5); dat[13]=lowByte(x); dat[14]=highByte(x); CH=VejoGreitis_us>>16; CL=VejoGreitis_us;
  dat[15]=lowByte(CL); dat[16]=highByte(CL); dat[17]=lowByte(CH); dat[18]=highByte(CH);//vejo greicio perdavimas 4 baitai
  GH=GenDaznis_us>>16; GL=GenDaznis_us;
  dat[19]=lowByte(GL); dat[20]=highByte(GL); dat[21]=lowByte(GH); dat[22]=highByte(GH);//generatoriaus daznio perdavimas 4 baitai
  TPM=millis(); TPH=TPM>>16; TPL=TPM;
  dat[23]=lowByte(TPL); dat[24]=highByte(TPL); dat[25]=lowByte(TPH); dat[26]=highByte(TPH);//TPL //TPH
  //paruosiame apkrovai vejo greitį padaugintą iš 16 (užpildysime 0-16m/s kiekvieną iš 16 vėjo greicio 16 tarpinių reiksmiu - viso 256 reiksmes)
  VGRmpers=1000000*16/12/VejoGreitis_us;//VGRmpers reiškia vėjo greitį padaugintą is 16, 12 - vėjo daviklio charakteristika tiek mimpulsų per sekundę esant 1m/sek vėjo greičiui
  analogWrite(Power1, BETZ[VGRmpers]);
  analogWrite(Power2, BETZ[VGRmpers]);
}
void SePrHe(int x) {
if (x<16) {
    Serial.print("0");
    Serial.print(x, HEX);
  } else {
    Serial.print(x, HEX);
  }
  Serial.print(" ");
  return;
}
void rising() {
  attachInterrupt(digitalPinToInterrupt(VejoPin), falling, FALLING);
  GenDaznis_us=micros()-prev_time_GenD;
  prev_time_GenD = micros();
}
void falling() {
  attachInterrupt(digitalPinToInterrupt(VejoPin), rising, RISING);
}
void rising1() {
  attachInterrupt(digitalPinToInterrupt(VGROUT), falling1, FALLING);
  VejoGreitis_us=micros()-prev_time_us;
  prev_time_us = micros();
}
void falling1() {
  attachInterrupt(digitalPinToInterrupt(VGROUT), rising1, RISING);
}
void setPwmFrequency(int pin, int divisor) {
  byte mode;
  if(pin == 5 || pin == 6 || pin == 9 || pin == 10) {
    switch(divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 64: mode = 0x03; break;
      case 256: mode = 0x04; break;
      case 1024: mode = 0x05; break;
      default: return;
    }
    if(pin == 5 || pin == 6) {
      TCCR0B = TCCR0B & 0b11111000 | mode;
    } else {
      TCCR1B = TCCR1B & 0b11111000 | mode;
    }
  } else if(pin == 3 || pin == 11) {
    switch(divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 32: mode = 0x03; break;
      case 64: mode = 0x04; break;
      case 128: mode = 0x05; break;
      case 256: mode = 0x06; break;
      case 1024: mode = 0x07; break;
      default: return;
  }
  TCCR2B = TCCR2B & 0b11111000 | mode;
}
}

Analoginių parametrų atvaizdavimas internetinėje svetainėje

Analoginiai duomenys randasi duomenų bazėje. Užduotis vaizdžiai atvaizduoti dinaminį parametrų pokytį interneto naršyklėje. Šią užduotį sudaro dvi dalys: duomenų nuskaitymas ir atvaizdavimas. Žemiau aprašysiu abu procesus.

A. Duomenų nuskaitymas iš duomenų bazės.

Šis etapas apima duomenų periodinį užklausos formavimą, rezultato gavimą, rezultato išvedimą. Interneto svetainėje aktyvuojame JavaScript procedūrą vgrrefresh().

HTML kalba tai atrodys:

body onload="vgrrefresh();"

Procedūrą sudaro viena eilutė:

function vgrrefresh() { 
	setInterval(function() {vgrrefresh1();},1000); 
}

Ši funkcija iškviečia periodinį kreipimąsi į sekančia funkciją vgrrefresh1(). Ji patalpnta faile vejas.js, kurio turinys pateiktas žemiau:

var ct=0;
var ve=0;
var ctmax=50;
var ctx;
var myChart;
var DuplRec=0;//užklausa grąžina tokį pat įrašą, kaip ir praeita užklausa
var vgrss;//start stop kintamasis
var vgrid=0;//užklausiamų duomenų id kintamasis
var ooo="";//outut isvedimo kintamasis
var vgrgo=false;//užklausai startuoti
var vgrctreset=false;//ctreset - naujausi duomenys
var tik=5;//tik - priodas
function vgrrefresh() {
    ctx = document.getElementById('myChart1').getContext('2d');
    myChart = new Chart(ctx, {
        type: 'line',
        data: {
            labels: [],
            datasets: [{
                label: 'Vėjo greitis',
                data: [],
                backgroundColor: "rgba(153,255,51,0.4)"
              }, {
                label: 'Generatoriaus dažnis',
                data: [],
                backgroundColor: "rgba(127,153,0,0.4)"
              }, {
                label: 'Srovė',
                data: [],
                backgroundColor: "rgba(255,153,0,0.4)"
              }, {
                label: 'Įtampa',
                data: [],
                backgroundColor: "rgba(73,153,0,0.4)"
              }, {
                label: 'Apkrova',
                data: [],
                backgroundColor: "rgba(73,153,127,0.4)"
              }]
        },
        options: {
            animation: false,
            animation: {duration: 0}
        }    
    });
    realtime=false;
    vgrstartstop();
}
function vgrrefresh1() {//Send a http request with AJAX http://api.jquery.com/jQuery.ajax/
    Toggle_color();
    if (vgrctreset==true) {vgrid=0; vgrctreset=false;}
    if (realtime==true) {vgrid=0;}
    var uzklausa="host=vejas001&id=" + vgrid;
    $.ajax({
        type: "POST",
        cache: true,
        url: 'http://uzsakymai.defas.lt/vgreitis.php',             //the script to call to get data          
        data: "host=vejas001&id=" + vgrid,           //you can insert url argumnets here to pass to api.php for example "id=5&parent=6"
        dataType: 'json',                //data format      
        success: function(data) {        //on recieve of reply
            if (data!=null) {
                var out="";
                for (i=0;i<11;i++) {out=out+" " + data[i];}//alert(JSON.stringify(data));
                vgrid=parseInt(data[0])+tik; //užklausos parametras
                    if (data[7]==0) {ve=0;} else {ve=(1000000/12/(data[7])).toFixed(2);}//data[7] - meandro periodas mikrosekundėmis. 1m/s - 12 impulsų!
                    if (data[8]==0) {ge=0;} else {ge=(1000000/12/(data[8])).toFixed(2);}//data[7] - generatoriaus signalo periodas mikrosekundėmis. rpm
                    ooo="ct=" + ct + " data=" + out;
                    ooo+="<br>Vėjo greitis:" + ve+ " m/s<br>";
                    ooo+="Apkrova=" + ((data[9] & 255)/256*100).toFixed(2) + "%<br>";
                    ooo+="Apkrovos indeksas=" + (data[9]>>>8) + "<br>";
                    document.getElementById('output22').innerHTML=ooo;
                    document.getElementById('DL').value=data[11].substring(0,10);
                    // recommend reading http://api.jquery.com/category/selectors/
                    if (ct==ctmax) {shiftarray();} else {ct++;} 
                    myChart.data.labels[ct]=data[11].substring(11,16);
                    myChart.data.datasets[0].data[ct]=ve;
                    myChart.data.datasets[1].data[ct]=ge;
                    myChart.data.datasets[2].data[ct]=data[1];
                    myChart.data.datasets[3].data[ct]=data[4];
                    myChart.data.datasets[4].data[ct]=((data[9] & 255)/256*100).toFixed(2);
                    myChart.update();
            }
            vgrgo=true;
        },
        error: function(xhr, status, error) {
            document.getElementById('output22').innerHTML+=". Kaida:" + error;
            vgrgo=true;
        }
    });
    vgrgo=true;
}
function shiftarray() {
    for (i=0;i<ctmax;i++) {
        myChart.data.labels[i]=myChart.data.labels[i+1];
        myChart.data.datasets[0].data[i]=myChart.data.datasets[0].data[i+1];
        myChart.data.datasets[1].data[i]=myChart.data.datasets[1].data[i+1];
        myChart.data.datasets[2].data[i]=myChart.data.datasets[2].data[i+1];
        myChart.data.datasets[3].data[i]=myChart.data.datasets[3].data[i+1];
        myChart.data.datasets[4].data[i]=myChart.data.datasets[4].data[i+1];
        //myChart.data.datasets[5].data[i]=myChart.data.datasets[5].data[i+1];
    }
    //myChart.options: {animation: false,animation: {duration: 0}};    
}
function vgrstartstop() {
    if (document.getElementById('vgrstartstop').value=="Stop") {
        document.getElementById('vgrstartstop').value="Start";
        clearTimeout(vgrss);
    } else {
        document.getElementById('vgrstartstop').value="Stop";
        vgrgo=true;       
        vgrss=setInterval(function() {vgrgocheck();},1000);
    }   
}
function vgrgocheck() {
    if (vgrgo==true) {
        vgrrefresh1();
        vgrgo=false;
    }  
}
function Resetct() {
    vgrctreset=true;
}
function Toggle_color() {
    if (document.getElementById('vgrstartstop').style.border=="2px solid red") {
        document.getElementById('vgrstartstop').style.border="2px solid green";    
      } else {
        document.getElementById('vgrstartstop').style.border="2px solid red";    
    }
}
function Toggle_realtime() {
    if (realtime==false) {
        document.getElementById('realtime').value="Įrašas"; 
        realtime=true;           
      } else {
        document.getElementById('realtime').value="Realiu laiku";  
        realtime=false;      
    }
}
function setid() {
    vgrid=parseInt(document.getElementById('setid').value);
}
function settik() {
    tik=parseInt(document.getElementById('settik').value);
}

Šioje funkcijoje formuojama AJAX užklausa į vgreitis.php failą su parametru host=vejas001, identifikuojančiu jėgainę. Sistema kuriama keletos jėgainių valdymui. Taigi JavaScript procedūra formuoja http užklausą:

http://uzsakymai.defas.lt/vgreitis.php?host=vejas001

Failo vgreitis.php turinys:

<?
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST, GET, OPTIONS");
header("Access-Control-Allow-Headers: X-PINGOTHER");
header("Access-Control-Max-Age: 3600");
if(($dbh=mysqli_connect("localhost", "vejas", "dvejasD1", "VJserver", 3306)) > 0 ){
  if(isset($_REQUEST['host'])) {
    $q="Select * from VJserver.hostai where host='".$_REQUEST['host']."' order by id desc limit 1";
    if (!$res = mysqli_query($dbh, $q)) {
		echo $q."<br>".mysqli_error($dbh);
	  } else {
        $row = mysqli_fetch_array($res);
        if(($dbh=mysqli_connect($row["IP"], "vejojegaines", "vejojegaines", "vejojegaines", 3306)) > 0 ){
            if ($_REQUEST['id']!=0) {
                $id=$_REQUEST['id'];
              } else {
                $q="Select id from vejojegaines.spi order by id desc limit 1";//TSL
                if (!$res = mysqli_query($dbh, $q)) {
                    echo $q."<br>".mysqli_error($dbh);
                  } else {
                    $row = mysqli_fetch_assoc($res);
                    $id=$row['id'];
                }
            }
            $q="Select * from vejojegaines.spi where id=".$id." order by id asc limit 1";//TSL
            if (!$res = mysqli_query($dbh, $q)) {
                echo $q."<br>".mysqli_error($dbh);
              } else {
                while($row = mysqli_fetch_row($res)) {echo json_encode($row);}
            }
        } else echo "Klaida 2-ame connecte: ".mysqli_error($dbh); 
    }
  } else echo "Naudoti: <a href=\"http://uzsakymai.defas.lt/vgreitis.php?host=vejas001&id=0\">Nuoroda</a>";
} else echo mysqli_error($dbh);
?>

Kaip tipinį atsakymą gauname pagal DB užklausos ‘Select * from vejojegaines.spi order by id desc limit 1’ formatą. Atkreipkite dėmesį, kad užklausa formuojama į valdiklio DB, kuris randamas pagal įrašą centriniame serveryje: „Select * from VJserver.hostai where host='”.$_REQUEST[‘host’].”‘ order by id desc limit 1″. Čia $_REQUEST[‘host’] yra tas pats parametras iš http užklausos. Tai galima remiantis strategine nuostata, pagal kurią kiekviena jėgainė kas 15 min registruojasi centriniame serveryje pranešdama savo IP adresą. To galima būtų išvengti naudojant statinius IP adresus. Taigi atsakymo formatas:

["909795","13","11","8","10","11","9","27700","224480","12291","237762269","2018-11-16 05:50:10"]

Čia duomenų formatas atitinka duomenų bazės lentelės struktūrą, kur 12 parametrų atskirtų kableliu reiškia: identifikatorių (DB įrašo eilės numeris), A0-A5 – analoginės Arduino matavimo reikšmės, vėjo ir generatoriaus greičius mikrosekundėmis, apkrovos indeksą (aukštsnis baitas) ir koeficientą (žemesnis baitas) patalpintus viename žodyje, TimeStamp reikšmė – gautas iš Arduino laiko parametras ir data su laiku, DB įrašo (Rpi) data ir laikas. DB lentelės struktūra:

DROP TABLE IF EXISTS `vejojegaines`.`spi`;
CREATE TABLE  `vejojegaines`.`spi` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `A1` smallint(5) unsigned NOT NULL,
  `A2` smallint(5) unsigned NOT NULL,
  `A3` smallint(5) unsigned NOT NULL,
  `A4` smallint(5) unsigned NOT NULL,
  `A5` smallint(5) unsigned NOT NULL,
  `A6` smallint(5) unsigned NOT NULL,
  `VGRusvid` int(10) unsigned NOT NULL,
  `GDAusvid` int(10) unsigned NOT NULL,
  `Apkrova` int(10) unsigned NOT NULL,
  `TS` int(10) unsigned NOT NULL,
  `Data` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;

B. Duomenų atvaizdavimas interneto naršyklės lange.