// Plik testapp.cpp, część 1. z 7
#include "testApp.h"
void testApp::setup(){
  printf ("Start \n");
  serial.setup("/dev/ttyUSB0", 115200); // zmień parametry, aby odpowiadały podłączeniu Arduino
  for (int i = 0; i < 256; i++){
    graph[i] = 127 + (100 * sin((1*(PI/127))*(i-0))); // funkcje sinusoidalne
    graph1[i] = 127 + (75 * sin((2*(PI/127))*(i-10)));  // znormalizowane w przedziale wartości 256×256
    graph2[i] = 127 + (50 * sin((3*(PI/127))*(i-40)));
  } // koniec wypełniania danymi
  for (int i = 0; i < 10; i++){
    destADR[i] = 0x00;  // ustawienie 64-bitowego adresu rozgłoszeniowego
  } // koniec wypełniania adresami
  destADR[6] = 0xFF; // ustawienie sieciowego adresu rozgłoszeniowego
  destADR[7] = 0xFF;
  destADR[8] = 0xFF;
  destADR[9] = 0xFE;
  point = 0; // wskaźnik zerowego punktu danych
  counts = 0; // zmienna do opóźnienia wysyłania pakietu
  SensorsSent [0] = false; // flagi pakietów
  SensorsSent [1] = false;
  SensorsSent [2] = false;
  FirstPacketsent = false;
} // koniec testApp::setup()
// Plik testapp.cpp, część 2. z 7
void testApp::update(){
  unsigned char DatatoSend[3] ;
  if (counts == 500){
    printf ("czujnik 1 \n");
    DatatoSend[0] = 'S';
    DatatoSend[1] = '1';
    DatatoSend[2] =  point;
    DatatoSend[3] = graph[point];
    CreatePacket(DatatoSend, 4);
    WaitForReply();
    SensorsSent [0] = true;
  }
  if (counts == 1000){
    printf ("czujnik 2 \n");
    DatatoSend[0] = 'S' ;
    DatatoSend[1] = '2' ;
    DatatoSend[2] =  point;
    DatatoSend[3] = graph1[point] ;
    CreatePacket(DatatoSend , 4 );
    WaitForReply();
    SensorsSent [1] = true;
  }
  if (counts == 1500){
    printf ("czujnik 3 \n");
    DatatoSend[0] = 'S';
    DatatoSend[1] = '3';
    DatatoSend[2] =  point;
    DatatoSend[3] = graph2[point] ;
    CreatePacket(DatatoSend , 4 );
    WaitForReply();
    SensorsSent [2] = true;
  }
  if (SensorsSent [0] == true && SensorsSent [1] == true && SensorsSent [2] == true){
    printf ("reset licznika punktów \n");
    counts = 0;
    point++;
    SensorsSent [0] = false;
    SensorsSent [1] = false;
    SensorsSent [2] = false;
  }
  counts++;
  CheckForIncoming();
} // koniec testApp::update()
// Plik testapp.cpp, część 3. z 7
void testApp::CheckForIncoming(){
  incomingPacketChecksum = 0;
  incomingByteLen = 0;
  if (serial.available() && 0x7E == (incomingBuffer[0] = serial.readByte())){
    printf ("Odebrany pakiet \n");
    incomingBuffer[1] = serial.readByte(); // odczyt długości pakietu
    incomingBuffer[2] = serial.readByte();
    incomingByteLen = incomingBuffer[1] + incomingBuffer[2];
    for (int i  = 3; i <= incomingByteLen + 3; i++){  // odebranie pozostałych danych pakietu
      incomingBuffer[i]  = serial.readByte();
      incomingPacketChecksum += incomingBuffer[i]; // dodanie bajtu do wyliczenia sumy kontrolnej
    }
    incomingPacketChecksum = (0xFF - incomingPacketChecksum);
    incomingByteLen += 3;
    if (incomingByteLen > 0 &&
      incomingPacketChecksum == incomingBuffer[incomingByteLen + 1 ] ){
      printf ("Suma kontrolna poprawna \n");
      ReadPacket();
      serial.flush(true,true); // wyczyszczenie buforów szeregowych wejściowego i wyjściowego
    }
    else {
      printf ("Błąd sumy kontrolnej\n");
      serial.flush(true,true);
      incomingByteLen = 0;
      incomingPacketChecksum = 0;
      for (int i = 0; i <= 80; i++){
       incomingBuffer[i] = 0;
      }
    } // koniec instrukcji else
  } // koniec if (serial.available() && 0x7E ==...
} // koniec testApp::CheckForIncoming()
// Plik testapp.cpp, część 4. z 7
void testApp::ReadPacket() {
  switch (incomingBuffer[3]) {  // sprawdzenie typu pakietu i wysłanie odpowiedzi
    case 0x90:
      dataLength = incomingByteLen - 15;  // zmniejszenie do długości danych w celu ich pobrania
      for (int i = 0; i <= dataLength; i++){
        incomeData [i] = incomingBuffer[i+15]; // wyodrębnienie danych z pakietu
      }
      if (dataLength == 2 && incomeData[0] == 'O' && incomeData[1] == 'K'){
        printf ("OK\n");    // ustawienie flagi, jeżeli odebrano dobrą odpowiedź
        ReplyOK = true;
     }
      if (dataLength == 3 && incomeData[0] == 'B' && incomeData[1] == 'A' &&
        incomeData[2]  == 'D' && FirstPacketsent){
        ReplyOK = false;  // upewnienie się, że flaga jest ustawiona na false, jeżeli odebrana jest ZŁA odpowiedź
        printf ("BAD\n");
        serial.writeBytes (packetBuffer, lastPacketLength); // wysłanie ostatniego znanego pakietu
        WaitForReply();  // następne oczekiwanie na dobrą odpowiedź
      }
      break;
    case 0x8B:
      printf ("Status transmisji\n");
      break;
    case 0x88:
      printf ("Odpowiedź na polecenie %X%X \n", incomingBuffer[8] , incomingBuffer[9]);
      break;
      default: // informacja o pakiecie nieznanego typu
      printf ("błąd: nieznany typ pakietu\n" );
  } // koniec switch
} // koniec testApp::ReadPacket()
// Plik testapp.cpp, część 5. z 7
void testApp::WaitForReply(){
  printf ("Oczekiwanie na odpowiedź \n");
  ReplyOK = false;
    while (ReplyOK != true){
    CheckForIncoming();
  }
} // koniec testApp::WaitForReply()
// Plik testapp.cpp, część 6. z 7
void testApp::CreatePacket(unsigned char *Outdata, int length){
  printf ("tworzenie pakietu\n");
  packetBuffer[17+ length] = 0;
  packetBuffer[0] = 0x7E;    // bajt początkowy
  packetBuffer[1] = 0;       // pierwszy bajt jest równy 0
  packetBuffer[3] = 0x10;    // typ ramki
  packetBuffer[4] =  0;         // identyfikator ramki
  for (int i = 5; i <= 14; i++){     // dodanie adresu
    packetBuffer[i] = destADR[i-5];
  }
  packetBuffer[15] = 0;  // ustawienie obu opcji
  packetBuffer[16] = 0;
  for (int i = 0; i < length; i++){
    packetBuffer[i + 17] =  Outdata [i];  // dodanie danych do pakietu
    printf ("wykres: %X\n",packetBuffer[i+17]); // wyświetlenie wysłanych danych na konsolę debugującą
  }
  packetBuffer[2] = 14 + length;      // ustawienie młodszego bajtu długości
  for (int i = 0; i <  packetBuffer[2]; i++){ // obliczenie sumy kontrolnej
    packetBuffer[17+ length] =  packetBuffer[17+ length] + packetBuffer[i+3];
  }
  // umieszczenie sumy kontrolnej na ostatniej pozycji i ukończenie pakietu
  packetBuffer[17+ length]= 0xFF - packetBuffer[17+ length];
  serial.writeBytes (packetBuffer, (18 + length)); // wysłanie pakietu
  lastPacketLength = 18 + length;  // zapisanie długości ostatniego pakietu
  FirstPacketsent = true;  // flaga informująca, że przynajmniej jeden pakiet został wysłany
} // koniec testApp::CreatePacket
// Plik testapp.cpp, część 7. z 7
void testApp::draw(){
  ofBackground (50,50,50);
  ofSetLineWidth (1);
  ofSetColor(0,0,0);
  for (int i = 266; i > 9; i -=32){  // narysowanie siatki
    ofLine(10,i,266,i);
    ofLine(i,10,i,266);
  }
  for (int i = 0; i < 255; i++){ // narysowanie danych
    ofSetLineWidth (2);
    ofSetColor(0,255,0);
    ofLine (i+10,(266 - graph[i]) , i+11 , (266 -graph [i+1]));
    ofSetColor(255,255,0);
    ofLine (i+10,(266 - graph1[i]) , i+11 , (266 -graph1 [i+1]));
    ofSetColor(0,0,255);
    ofLine (i+10,(266 - graph2[i]) , i+11 , (266 -graph2 [i+1]));
  }
  ofSetColor(255,0,0);
  ofLine (10 + point, 10, 10 + point, 266); // narysowanie linii pozycji
  ofSetLineWidth (1);
} // koniec testApp::draw()
