// PPOV with SPI0 = MCP3008, SPI1 = 2x74HC595 i 6x74HC165 // 19.11.2017. Author: YT2FSG, Goran Stankovic dipl.ing.el. // http://www.qsl.net/yt2fsg/ (goranstank@gmail.com) // // gcc -o ppov -l rt ppov.c -l bcm2835 // sudo ./ppov #include #include #include #include int main(int argc, char **argv) { if (!bcm2835_init()) return 1; bcm2835_spi_begin(); bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST); bcm2835_spi_setDataMode(BCM2835_SPI_MODE0); bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_65536); // 250Mhz/65536=3.8kHz bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW); bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS1, LOW); bcm2835_gpio_fsel(25, BCM2835_GPIO_FSEL_OUTP); // Pin 25 - output FILE * fp; char buf[] = { 0x01, 0x80, 0x00 }; // Data to send int adc[8]; // 10-bitna analogna merenja iz MCP3008 float p[8]; // Obradjena analogna merenja za prikaz na php float op[8]; int cmin[8] = {0,0,0,0,0,0,0,0}; // Calibracion MIN int cmax[8] = {1023,1023,1023,1023,1023,1023,1023,1023}; // Calibration MAX int amax[8] = {10,2000,14,1000,100,200,300,400}; // Ubacite MAX vrednosti analognih merenja za prikaz na php int out1,out2; int dmem; int din_new=0, din_old=0; char c; char buffer[100]; long length; int i=0, j=0, k=0; int buffer2[16]; int sec=0, zsec=0, min=0, hour=0, fsec=0 ; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - printf("*** RPi PPOV - Postrojenje za preciscavanje odpadnih voda *** \n"); printf("by: YT2FSG, Goran Stankovic dipl.ing.el. http://www.qsl.net/yt2fsg \n"); time_t t1; struct tm *t2; char filename_a[40]="/var/www/data/a20170101.csv"; char filename_d[40]="/var/www/data/d20170101.txt"; t1=time(NULL); t2=localtime(&t1); strftime(filename_a,40,"/var/www/data/a%Y%m%d.csv",t2); strftime(filename_d,40,"/var/www/data/d%Y%m%d.txt",t2); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Ucitavanje parametara iz File 'ppov_cal.txt' - Calibration // Upisati u File za svako merenje cmin za 4mA, cmax za 20mA i=0; j=0; if ((fp = fopen("ppov_cal.txt","r")) == NULL) { printf("file 'ppov_cal.txt' not found! \n"); } else { while(1) { c = fgetc(fp); if (feof(fp)) { break; } if (c==',') { buffer[i] = 0; i = 0; buffer2[j] = atoi(buffer); j++; } else { buffer[i] = c; i++; } } buffer[i] = 0; buffer2[j] = atoi(buffer); for (k=0; k<8; k=k+1) { cmin[k] = buffer2[2*k]; cmax[k] = buffer2[1+2*k]; } printf("\n cal_min (1-8): "); for (k=0; k<8; k=k+1) { printf("%3d ", cmin[k]); } printf("\n cal_max (1-8): "); for (k=0; k<8; k=k+1) { printf("%3d ", cmax[k]); } printf("\n\n"); } fclose(fp); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bcm2835_gpio_write(25,1); // Dozvoli out (REDY) while (1) { // Prikazi trenutno vreme time(&t1); // t2=gmtime(&t1); t2=localtime(&t1); sec=t2->tm_sec; if (sec != zsec) // ? 1 sekunda { zsec=sec; fsec=1; min=t2->tm_min; hour=t2->tm_hour; printf("%2d:%02d:%02d -- ",hour,min,sec); //================================================================== // Obrada Analognih Ulaza - Merenja //================================================================== bcm2835_spi_chipSelect(BCM2835_SPI_CS0); // Slave on CS0 // Citanje analognih ulaza (MCP3008) for (i=0; i<8; i=i+1) { buf[0] = 0x01; buf[1] = 0x80 + 0x10 * i; buf[2] = 0x00; bcm2835_spi_transfern(buf, sizeof(buf)); adc[i] = buf[1] & 0b00000011; adc[i] = (adc[i] << 8) | buf[2]; } // Calibration for (i=0; i<8; i=i+1) { op[i] = cmax[i] - cmin[i]; if (op[i] < 1 ) { p[i] = adc[i] * amax[i] / 1023; } else { p[i] = (adc[i] - cmin[i]) * amax[i] / op[i]; } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //Upisi podatke u RAM-DISK file 'a_in.txt' - prikaz na php if ((fp = fopen("/var/tmp/a_in.txt","w")) == NULL) { printf("file '/var/tmp/a_in.txt' not open! \n"); } else { fprintf(fp,"%3.1f,%5.f,%4.1f,%5.f,%3.f,%3.f,%3.f,%3.f\n",p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]); } fclose(fp); printf("Ain: %3.1f %5.f %4.1f %5.f %3.f %3.f %3.f %3.f",p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if (sec == 0) // ? 1 min { // Promeni filename u ponoc if ((min==0) && (hour==0)) // ? 00:00:00 { t1=time(NULL); t2=localtime(&t1); strftime(filename_a,40,"/var/www/data/a%Y%m%d.csv",t2); strftime(filename_d,40,"/var/www/data/d%Y%m%d.txt",t2); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //Upisi podatke u file 'aYYYYmmdd.csv' - akvizicija analognih merenja na 1 minut if ((fp = fopen(filename_a,"a")) == NULL) { printf("file %s not open! \n",filename_a); } else { fprintf(fp,"%02d:%02d:%02d;%4.1f;%5.f;%4.1f;%5.f;%4.f;%4.f;%4.f;%4.f\n",hour,min,sec,p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7]); } fclose(fp); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - } bcm2835_delay(20); // delay 20ms //================================================================== // Obrada Digitalnih Ulaza i Izlaza //================================================================== // Ucitavanje parametara iz FLASH-DISK file 'd_out.txt' - komande iz php i=0; j=0; if ((fp = fopen("/var/www/d_out.txt","r")) == NULL) { printf("file '/var/www/d_out.txt' not found! \n"); } else { while(1) { c = fgetc(fp); if (feof(fp)) { break; } if (c==',') { buffer[i] = 0; i = 0; buffer2[j] = atoi(buffer); j++; } else { buffer[i] = c; i++; } } buffer[i] = 0; buffer2[j] = atoi(buffer); out1 = buffer2[0]; out2 = buffer2[1]; } fclose(fp); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bcm2835_spi_chipSelect(BCM2835_SPI_CS1); // Slave on CS1 // Upis i citanje digitalnih izlaza i ulaza (74HC595 i 74HC165) buf[0] = 0xFF; buf[1] = 0xFF; buf[2] = 0xFF; buf[3] = 0xFF; buf[4] = out1; buf[5] = out2; if (fsec==1) { printf(" -- Dout: %02X %02X -- ",buf[4],buf[5]); } bcm2835_spi_transfern(buf, 6); if (fsec==1) { fsec=0; printf("Din: %02X %02X %02X %02X %02X %02X \n",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Detekcija na promenu digitalnih ulaza din_new=buf[0]+buf[1]+buf[2]+buf[3]+buf[4]+buf[5]; if (din_new != din_old) { din_old=din_new; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //Upisi podatke u RAM-DISK file 'd_in.txt' - prikaz na php if ((fp = fopen("/var/tmp/d_in.txt","w")) == NULL) { printf("file '/var/tmp/d_in.txt' not open! \n"); } else { fprintf(fp,"%3d,%3d,%3d,%3d,%3d,%3d\n",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]); } fclose(fp); //Ulazi se promenili upisi podatke u file 'dYYYYmmdd.csv' - akvizicija podataka if ((fp = fopen(filename_d,"a")) == NULL) { printf("file %s not open! \n",filename_d); } else { fprintf(fp,"%02d:%02d:%02d %02X %02X %02X %02X %02X %02X\n",hour,min,sec,buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]); } fclose(fp); } //================================================================== // Automatsko Upravljanje //================================================================== // Ucitavanje parametara iz FLASH-DISK file 'd_mem.txt' - auto/rucno iz php i=0; j=0; if ((fp = fopen("/var/www/d_mem.txt","r")) == NULL) { printf("file '/var/www/d_mem.txt' not found! \n"); } else { while(1) { c = fgetc(fp); if (feof(fp)) { break; } buffer[i] = c; i++; } buffer[1] = 0; dmem = atoi(buffer); // printf(" -- Dmem : %d \n", dmem); } fclose(fp); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Automatika za Puzne Pumpe // Automatika za Resetku // Automatika za Kompresore // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bcm2835_delay(180); // delay 180ms } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bcm2835_gpio_write(25,0); // Zabrani out (/REDY) bcm2835_spi_end(); bcm2835_close(); return 0; }