#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include WINDOW *header, *connections, *packages; uint32_t counter = 0; timer_t gTimerid; WINDOW *create_newwin(int height, int width, int starty, int startx); void destroy_win(WINDOW *local_win); char *server = "localhost"; /* server host (default=localhost) */ char *user = "root"; /* username (default=login name) */ char *password = "raspberry"; /* password (default=none) */ char *database = "adatok"; /* database name (default=none) */ /*static*/ static MYSQL *conn; struct buf_struct { //packed start uint16_t start_header; //fix 0xFB55 csak a csomag elejének azonosításához kell //innentől kerülnének az adatbázisba mind külön öszlopba uint8_t chamber_id; //fix 0x00 felsőbb egység állítsa be uint8_t ch_id; //jumper configurable lsb module ch0-1 select next 4 bit 16 modul select next 1 bit xy board select int32_t inte_data; //integrated curve uint16_t peak_amp; uint16_t width; uint32_t time_sec; uint32_t time_ns; uint16_t cmp_level; uint16_t reserved; //ez mehetne valami tömbbszerüségbe ha van ilyen #ifdef debug_buf uint16_t buff[raw_buff_size]; #endif //crc-t lehetne ellenőrízni amikor megérkezik a csomag, nem kell az adatbázisba uint16_t crc32; uint16_t end_header; //fix 0xFEAA //csomag vége ez se kell! }; #define raw_buff_size 64 #ifdef debug_buf #define packet_size (28 + (2*raw_buff_size)) #else #define packet_size 28 #endif WINDOW *create_newwin(int height, int width, int starty, int startx) { WINDOW *local_win; local_win = newwin(height, width, starty, startx); //box(local_win, 0 , 0); /* 0, 0 gives default characters // * for the vertical and horizontal // * lines */ wborder(local_win, '|', '|', '-', '-', '+', '+', '+', '+'); wrefresh(local_win); /* Show that box */ return local_win; } int redrawborder(WINDOW *local_win) { //box(local_win, 0 , 0); /* 0, 0 gives default characters // * for the vertical and horizontal // * lines */ wborder(local_win, '|', '|', '-', '-', '+', '+', '+', '+'); wrefresh(local_win); } void destroy_win(WINDOW *local_win) { /* box(local_win, ' ', ' '); : This won't produce the desired * result of erasing the window. It will leave it's four corners * and so an ugly remnant of window. */ wborder(local_win, ' ', ' ', ' ',' ',' ',' ',' ',' '); /* The parameters taken are * 1. win: the window on which to operate * 2. ls: character to be used for the left side of the window * 3. rs: character to be used for the right side of the window * 4. ts: character to be used for the top side of the window * 5. bs: character to be used for the bottom side of the window * 6. tl: character to be used for the top left corner of the window * 7. tr: character to be used for the top right corner of the window * 8. bl: character to be used for the bottom left corner of the window * 9. br: character to be used for the bottom right corner of the window */ wrefresh(local_win); delwin(local_win); } /* * serialOpen: * Open and initialise the serial port, setting all the right * port parameters - or as many as are required - hopefully! ********************************************************************************* */ int serialOpen (const char *device, const int baud) { struct termios options ; speed_t myBaud ; int status, fd ; switch (baud) { case 50: myBaud = B50 ; break ; case 75: myBaud = B75 ; break ; case 110: myBaud = B110 ; break ; case 134: myBaud = B134 ; break ; case 150: myBaud = B150 ; break ; case 200: myBaud = B200 ; break ; case 300: myBaud = B300 ; break ; case 600: myBaud = B600 ; break ; case 1200: myBaud = B1200 ; break ; case 1800: myBaud = B1800 ; break ; case 2400: myBaud = B2400 ; break ; case 4800: myBaud = B4800 ; break ; case 9600: myBaud = B9600 ; break ; case 19200: myBaud = B19200 ; break ; case 38400: myBaud = B38400 ; break ; case 57600: myBaud = B57600 ; break ; case 115200: myBaud = B115200 ; break ; case 230400: myBaud = B230400 ; break ; case 460800: myBaud = B460800 ; break ; default: return -2 ; } if ((fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1) return -1 ; fcntl (fd, F_SETFL, O_RDWR) ; // Get and modify current options: tcgetattr (fd, &options) ; cfmakeraw (&options) ; cfsetispeed (&options, myBaud) ; cfsetospeed (&options, myBaud) ; options.c_cflag |= (CLOCAL | CREAD) ; options.c_cflag &= ~PARENB ; options.c_cflag &= ~CSTOPB ; options.c_cflag &= ~CSIZE ; options.c_cflag |= CS8 ; options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG) ; options.c_oflag &= ~OPOST ; options.c_cc [VMIN] = 0 ; options.c_cc [VTIME] = 100 ; // Ten seconds (100 deciseconds) tcsetattr (fd, TCSANOW | TCSAFLUSH, &options) ; ioctl (fd, TIOCMGET, &status); status |= TIOCM_DTR ; status |= TIOCM_RTS ; ioctl (fd, TIOCMSET, &status); usleep (10000) ; // 10mS return fd ; } /* * serialFlush: * Flush the serial buffers (both tx & rx) ********************************************************************************* */ void serialFlush (const int fd) { tcflush (fd, TCIOFLUSH) ; } /* * serialClose: * Release the serial port ********************************************************************************* */ void serialClose (const int fd) { close (fd) ; } /* * serialPutchar: * Send a single character to the serial port ********************************************************************************* */ void serialPutchar (const int fd, const unsigned char c) { write (fd, &c, 1) ; } /* * serialPuts: * Send a string to the serial port ********************************************************************************* */ void serialPuts (const int fd, const char *s) { write (fd, s, strlen (s)) ; } /* * serialPrintf: * Printf over Serial ********************************************************************************* */ void serialPrintf (const int fd, const char *message, ...) { va_list argp ; char buffer [1024] ; va_start (argp, message) ; vsnprintf (buffer, 1023, message, argp) ; va_end (argp) ; serialPuts (fd, buffer) ; } /* * serialDataAvail: * Return the number of bytes of data avalable to be read in the serial port ********************************************************************************* */ int serialDataAvail (const int fd) { int result ; if (ioctl (fd, FIONREAD, &result) == -1) return -1 ; return result ; } /* * serialGetchar: * Get a single character from the serial device. * Note: Zero is a valid character and this function will time-out after * 10 seconds. ********************************************************************************* */ int serialGetchar (const int fd) { uint8_t x ; if (read (fd, &x, 1) != 1) return -1 ; return ((int)x) & 0xFF ; } /*************************************************************************************************************************************************************************************************/ /*************************************************************************************************************************************************************************************************/ /*************************************************************************************************************************************************************************************************/ /*************************************************************************************************************************************************************************************************/ /*************************************************************************************************************************************************************************************************/ /*************************************************************************************************************************************************************************************************/ int serialGetarray(const int fd, uint8_t out[], unsigned int size) { int i; uint8_t x; if((out == 0) | (fd == 0)) return -1; if(size == 0) return -1; for(i=0;i 0)) //vár amíg nincs adat { usleep(200); } buff[0] = serialGetchar (fd); }while(buff[0] != 0x55); //ha start header eleje akkro tovább while(! (serialDataAvail(fd) > 0)) //vár amíg nincs adat { //thread sleep? kelhet } buff[1] = serialGetchar (fd); if(buff[1] != 0xFB) //nem start header return error return -1; //ha igen akkor beolvassa a maradék 22 bájtot while(! (serialDataAvail(fd) >= (size-2))) //vár amíg nincs adat { usleep(1); } if(serialGetarray(fd, &buff[2], (size-2)) == -1) //beolvas 22 bájtott a bufferbe a header utánra { return -1; //uart hiba } if(buff[size-2] != 0xAA | buff[size-1] != 0xFE) //ha az end header nem passzol error return -1; //todo crc check return 1; //adat beolvasva } int mysql_connect(WINDOW *local_win) { conn = mysql_init(NULL); //printf("Mysql: Connecting to %s@%s as %s\n",database,server,user); if (!mysql_real_connect(conn, server, user, password, database, 0, NULL, 0)) { wattron(local_win,COLOR_PAIR(1)); mvwprintw(local_win,2,1,"MySQL Error"); wattroff(local_win,COLOR_PAIR(1)); wrefresh(local_win); /*fprintf(stderr, "%s\n", mysql_error(conn)); exit(1);*/ } else { wattron(local_win,COLOR_PAIR(2)); mvwprintw(local_win,2,1,"MySQL OK"); wattroff(local_win,COLOR_PAIR(2)); wrefresh(local_win); } //printf("Mysql: Connected succesfully!\n"); } int mysql_write(struct buf_struct adatok, WINDOW *local_win) { char data[300]; //printf("MySQL: Adatok beírása...\n"); //snprintf(data,300,"INSERT INTO fb55(chamber_id,ch_id,inte_data,peak_amp,width,time_sec,time_ns,cmp_lvl) VALUES(%d,%d,%d,%d,%d,%ld,%ld,%d)",adatok.chamber_id,adatok.ch_id,adatok.inte_data,adatok.peak_amp,adatok.width,adatok.time_sec,adatok.time_ns, adatok.cmp_level); snprintf(data,300,"INSERT INTO fb55(chamber_id,ch_id,inte_data,peak_amp,width,time_sec,time_ns,cmp_lvl) VALUES(%hhu,%hhu,%d,%hu,%hu,%u,%u,%hu)" ,adatok.chamber_id,adatok.ch_id,adatok.inte_data,adatok.peak_amp,adatok.width,adatok.time_sec,adatok.time_ns, adatok.cmp_level); if (!mysql_query(conn,data)) { wattron(local_win,COLOR_PAIR(2)); mvwprintw(local_win,4,1,"Database OK"); wattroff(local_win,COLOR_PAIR(2)); wrefresh(local_win); return 1; } else { wattron(local_win,COLOR_PAIR(1)); mvwprintw(local_win,4,1,"Database Error"); wattroff(local_win,COLOR_PAIR(1)); wrefresh(local_win); } } int droptablecontent(char *tablename, WINDOW *local_win) { char data[100]; //printf("MySQL: Tábla ürítése...\n"); if (tablename==NULL) { snprintf(data,100,"truncate fb55"); } else snprintf(data,100,"truncate %s",tablename); if(mysql_query(conn,data)==0) { //printf("Sikeres ürítés!\n"); wattron(local_win,COLOR_PAIR(2)); mvwprintw(local_win,5,1,"Truncate OK"); wattroff(local_win,COLOR_PAIR(2)); wrefresh(local_win); return 1; } else return -1; } void sigintHandler(int sig_num) { signal(SIGINT, sigintHandler); mysql_close(conn); clear(); char msg[]="Exiting..."; int row,col; getmaxyx(stdscr,row,col); mvprintw(row/2,(col-strlen(msg))/2,"%s",msg); refresh(); //sleep(1); endwin(); //printf("\nExiting... \n"); exit(1); } int init() { if ( (initscr()) == NULL ) { fprintf(stderr, "Error initialising ncurses.\n"); exit(EXIT_FAILURE); } curs_set(0); cbreak(); refresh(); if(has_colors() == FALSE) { endwin(); printf("Your terminal does not support color\n"); exit(1); } start_color(); /* Start color */ init_pair(1, COLOR_RED, COLOR_BLACK); init_pair(2, COLOR_GREEN, COLOR_BLACK); } int printheader(WINDOW *header) { int width_max = COLS; mvwprintw(header, 1, (width_max-58)/2, " ___ _ _ ___ __ __ ___ ___ _ "); mvwprintw(header, 2, (width_max-58)/2, "/ __| ___ _ _(_)__ _| | |_ ) | \\/ |_ _/ __|/ _ \\| | "); mvwprintw(header, 3, (width_max-58)/2, "\\__ \\/ -_) '_| / _` | | / / | |\\/| | || \\__ \\ (_) | |__ "); mvwprintw(header, 4, (width_max-58)/2, "|___/\\___|_| |_\\__,_|_| /___| |_| |_|\\_, |___/\\__\\_\\____|"); mvwprintw(header, 5, (width_max-58)/2, " |__/"); wrefresh(header); } int printdatas(WINDOW *datas, struct buf_struct packet, int height, int width) { //ch_id:%d, inte:%ld, peak:%d, width:%d, time_sec:%ld, time_ns:%ld, , , , , , , mvwprintw(datas,height-2,1,"comp_lvl: "); wclrtoeol(datas); mvwprintw(datas,height-2,(width-floor((log10(packet.cmp_level+1) + 2))), "%d",packet.cmp_level); mvwprintw(datas,height-4,1,"time_ns: "); wclrtoeol(datas); mvwprintw(datas,height-4,(width-floor((log10(packet.time_ns+1) + 2))), "%d",packet.time_ns); mvwprintw(datas,height-6,1,"time_sec: "); wclrtoeol(datas); mvwprintw(datas,height-6,(width-floor((log10(packet.time_sec+1) + 2))), "%d",packet.time_sec); mvwprintw(datas,height-8,1,"width: "); wclrtoeol(datas); mvwprintw(datas,height-8,(width-floor((log10(packet.width+1) + 2))), "%d",packet.width); mvwprintw(datas,height-10,1,"peak_amp: "); wclrtoeol(datas); mvwprintw(datas,height-10,(width-floor((log10(packet.peak_amp+1) + 2))), "%d",packet.peak_amp); mvwprintw(datas,height-12,1,"inte_data: "); wclrtoeol(datas); mvwprintw(datas,height-12,(width-floor((log10(abs(packet.inte_data+1)) + 2))), "%d",packet.inte_data); mvwprintw(datas,height-14,1,"ch_id: "); wclrtoeol(datas); mvwprintw(datas,height-14,(width-floor((log10(packet.ch_id+1) + 2))), "%d",packet.ch_id); redrawborder(datas); wrefresh(datas); } void start_timer(void) { struct itimerspec value; value.it_value.tv_sec = 1;//waits for 5 seconds before sending timer signal value.it_value.tv_nsec = 0; value.it_interval.tv_sec = 1; //sends timer signal every 5 seconds value.it_interval.tv_nsec = 0; timer_create (CLOCK_REALTIME, NULL, &gTimerid); timer_settime (gTimerid, 0, &value, NULL); } void stop_timer(void) { struct itimerspec value; value.it_value.tv_sec = 0; value.it_value.tv_nsec = 0; value.it_interval.tv_sec = 0; value.it_interval.tv_nsec = 0; timer_settime (gTimerid, 0, &value, NULL); } void timer_callback(int sig) { int height, width; getmaxyx(connections,height,width); mvwprintw(connections,height-7,1,"Received/Sec:"); wmove(connections,height-6,1); wclrtoeol(connections); mvwprintw(connections,height-6,(width-floor((log10(abs(counter)) + 2))),"%d", counter); wrefresh(connections); counter=0; } int main(int argc,char* argv[]) { init(); int startx, starty, width_max, height_max, width, height, serialstatus, packages_maxx, packages_maxy; uint8_t raw_buff[packet_size + 10]; //packet_size + egy kis tartalék, ha nincs hiba sehol akkor nem kell uint16_t i; uint32_t received = 0, writed = 0, count_x=0, count_y=0; struct buf_struct packet; width_max= 0; height_max= 0; height = 7; width = width_max; starty = 0; /* Calculating for a center placement */ startx = 0; /* of the window */ header = create_newwin(height, width, starty, startx); connections = create_newwin(LINES-(height-1), 15, height-1, 0); packages = create_newwin(LINES-(height-1), COLS-14, height-1, 14); getmaxyx(connections,height_max,width_max); getmaxyx(packages,packages_maxy,packages_maxx); printheader(header); mvwprintw(packages,1,1,"For debug mode use -d | For truncate use -drop | \n|You can truncate another table with -drop tablename"); wrefresh(packages); //printf("**********************\n* Serial 2 Mysql *\n* For debug mode: -d *\n*For truncate: -drop *\n* You can truncate *\n* another table with *\n* -drop tablename *\n**********************\n* Script written *\n* by Baranyai Dávid *\n**********************\n"); mysql_connect(connections); signal(SIGINT, sigintHandler); //CTRL + C kezelése. csak szórakozás signal(SIGALRM, timer_callback); //timer megszakítás start_timer(); if(argc>1) { if (!strcmp(argv[1],"-drop")) { if (argc>2) { droptablecontent(argv[2],connections); } else droptablecontent(NULL,connections); } } int fd=serialOpen("/dev/ttyACM0",460800); //serial megnyitása while (fd < 0) { wattron(connections,COLOR_PAIR(1)); mvwprintw(connections,1,1,"Serial Error"); wattroff(connections,COLOR_PAIR(1)); wrefresh(connections); fd=serialOpen("/dev/ttyACM0",460800); } //sikertelen csatlakozás esetén //printf("Serial: Connected succesfully!"); wmove(connections,1,1); wclrtoeol(connections); redrawborder(connections); wattron(connections,COLOR_PAIR(2)); mvwprintw(connections,1,1,"Serial OK"); wattroff(connections,COLOR_PAIR(2)); refresh(); wrefresh(connections); serialFlush(fd); //buffer ürítése while(1) { if(read_packet(packet_size, &raw_buff[0], fd) != -1) { received++; if (serialstatus==0) { wmove(connections,3,1); wclrtoeol(connections); redrawborder(connections); } //sikerült beolvasni egy csomagot, feldolgozás //printf("Sikeres fogadas\n"); wattron(connections,COLOR_PAIR(2)); mvwprintw(connections,3,1,"Receive OK"); wattroff(connections,COLOR_PAIR(2)); mvwprintw(connections,height_max-5,1,"Received: "); wmove(connections,height_max-4,1); wclrtoeol(connections); mvwprintw(connections,height_max-4,(width_max-floor((log10(abs(received+1)) + 2))),"%d",received); packet = *((struct buf_struct*) (&raw_buff[0])); //struktúrává kasztolás és átmásolás egy tényleges struktúrába printdatas(packages, packet, packages_maxy, packages_maxx); //struktúra tagok kiíratása //printf("ch_id:%d, inte:%ld, peak:%d, width:%d, time_sec:%ld, time_ns:%ld, comp_lvl:%d\n", packet.ch_id, packet.inte_data, packet.peak_amp , packet.width, packet.time_sec, packet.time_ns, packet.cmp_level); //mvprintw(3,0,"ch_id:%d, inte:%ld, peak:%d, width:%d, time_sec:%ld, time_ns:%ld, comp_lvl:%d\n", packet.ch_id, packet.inte_data, packet.peak_amp , packet.width, packet.time_sec, packet.time_ns, packet.cmp_level); if (mysql_write(packet, connections)==1) { if (packet.ch_id>31) { count_y++; } else count_x++; writed++; counter++; } //ideiglenes rögtönzött megoldás... struktúra átadása beírásra mvwprintw(connections,height_max-3,1,"Writed: "); wmove(connections,height_max-2,1); mvwprintw(connections,height_max-2,(width_max-floor((log10(writed+1) + 2))),"%d",writed); mvwprintw(connections,height_max-8,1,"y: %d",count_y); mvwprintw(connections,height_max-9,1,"x: %d",count_x); wrefresh(connections); serialstatus = 1; } else { if (serialstatus==1) { wmove(connections,3,1); wclrtoeol(connections); redrawborder(connections); } wattron(connections,COLOR_PAIR(1)); mvwprintw(connections,3,1,"Receive Error"); wattroff(connections,COLOR_PAIR(1)); wrefresh(connections); serialstatus = 0; } } }