Advertisement
Guest User

Untitled

a guest
Dec 20th, 2020
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.10 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <time.h>
  3. #include <stdlib.h>
  4. #include <bcm2835.h>
  5. #include <string.h>
  6.  
  7. //server
  8. #include <sys/socket.h>
  9. #include <arpa/inet.h>
  10. //#include <ads1256.h>
  11.  
  12. #define uint8_t unsigned char // 1 byte
  13. #define uint16_t unsigned short // 2 bytes
  14. #define uint32_t unsigned long // 4 bytes
  15. //#define uint64_t unsigned long long // 8 bytes
  16.  
  17. // Set the Programmable gain amplifier (PGA).
  18. // PGA Provides more resolution when measuring smaller input signals.
  19. // Set the PGA to the highest possible setting.
  20. enum
  21. {
  22. PGA_GAIN1 = 0, // Input voltage range: +- 5 V
  23. PGA_GAIN2 = 1, // Input voltage range: +- 2.5 V
  24. PGA_GAIN4 = 2, // Input voltage range: +- 1.25 V
  25. PGA_GAIN8 = 3, // Input voltage range: +- 0.625 V
  26. PGA_GAIN16 = 4, // Input voltage range: +- 0.3125 V
  27. PGA_GAIN32 = 5, // Input voltage range: +- 0.15625 V
  28. PGA_GAIN64 = 6 // Input voltage range: +- 0.078125 V
  29. };
  30.  
  31. enum
  32. {
  33. DRATE_30000 = 0xF0,
  34. DRATE_15000 = 0xE0,
  35. DRATE_7500 = 0xD0,
  36. DRATE_3750 = 0xC0,
  37. DRATE_2000 = 0xB0,
  38. DRATE_1000 = 0xA1,
  39. DRATE_500 = 0x92,
  40. DRATE_100 = 0x82,
  41. DRATE_60 = 0x72,
  42. DRATE_50 = 0x63,
  43. DRATE_30 = 0x53,
  44. DRATE_25 = 0x43,
  45. DRATE_15 = 0x33,
  46. DRATE_10 = 0x20,
  47. DRATE_5 = 0x13,
  48. DRATE_2d5 = 0x03
  49. };
  50.  
  51. enum
  52. {
  53. REG_STATUS = 0, // Register adress: 00h, Reset value: x1H
  54. REG_MUX = 1, // Register adress: 01h, Reset value: 01H
  55. REG_ADCON = 2, // Register adress: 02h, Reset value: 20H
  56. REG_DRATE = 3, // Register adress: 03h, Reset value: F0H
  57. REG_IO = 4, // Register adress: 04h, Reset value: E0H
  58. REG_OFC0 = 5, // Register adress: 05h, Reset value: xxH
  59. REG_OFC1 = 6, // Register adress: 06h, Reset value: xxH
  60. REG_OFC2 = 7, // Register adress: 07h, Reset value: xxH
  61. REG_FSC0 = 8, // Register adress: 08h, Reset value: xxH
  62. REG_FSC1 = 9, // Register adress: 09h, Reset value: xxH
  63. REG_FSC2 = 10, // Register adress: 0Ah, Reset value: xxH
  64. };
  65.  
  66. enum
  67. {
  68. CMD_WAKEUP = 0x00, // Completes SYNC and Exits Standby Mode
  69. CMD_RDATA = 0x01, // Read Data
  70. CMD_RDATAC = 0x03, // Read Data Continuously
  71. CMD_SDATAC = 0x0F, // Stop Read Data Continuously
  72. CMD_RREG = 0x10, // Read from REG - 1st command byte: 0001rrrr
  73. // 2nd command byte: 0000nnnn
  74. CMD_WREG = 0x50, // Write to REG - 1st command byte: 0001rrrr
  75. // 2nd command byte: 0000nnnn
  76. // r = starting reg address, n = number of reg addresses
  77. CMD_SELFCAL = 0xF0, // Offset and Gain Self-Calibration
  78. CMD_SELFOCAL = 0xF1, // Offset Self-Calibration
  79. CMD_SELFGCAL = 0xF2, // Gain Self-Calibration
  80. CMD_SYSOCAL = 0xF3, // System Offset Calibration
  81. CMD_SYSGCAL = 0xF4, // System Gain Calibration
  82. CMD_SYNC = 0xFC, // Synchronize the A/D Conversion
  83. CMD_STANDBY = 0xFD, // Begin Standby Mode
  84. CMD_RESET = 0xFE, // Reset to Power-Up Values
  85. };
  86.  
  87. // Input analog channels.
  88. enum
  89. {
  90. AIN0 = 0, //Binary value: 0000 0000
  91. AIN1 = 1, //Binary value: 0000 0001
  92. AIN2 = 2, //Binary value: 0000 0010
  93. AIN3 = 3, //Binary value: 0000 0011
  94. AIN4 = 4, //Binary value: 0000 0100
  95. AIN5 = 5, //Binary value: 0000 0101
  96. AIN6 = 6, //Binary value: 0000 0110
  97. AIN7 = 7, //Binary value: 0000 0111
  98. AINCOM = 8 //Binary value: 0000 1000
  99. };
  100.  
  101. // Boolean values.
  102. typedef enum
  103. {
  104. False = 0,
  105. True = 1,
  106. } bool;
  107.  
  108.  
  109. #define DRDY RPI_GPIO_P1_11
  110. #define RST RPI_GPIO_P1_12
  111. #define SPICS RPI_GPIO_P1_15
  112. #define DIN RPI_GPIO_P1_19
  113. #define DOUT RPI_GPIO_P1_21
  114. #define SCLK RPI_GPIO_P1_23
  115. #define CS_1() bcm2835_gpio_write(SPICS, HIGH)
  116. #define CS_0() bcm2835_gpio_write(SPICS, LOW).
  117. #define RST_1() bcm2835_gpio_write(RST, HIGH)
  118. #define RST_0() bcm2835_gpio_write(RST, LOW)
  119. #define DRDY_LOW() bcm2835_gpio_lev(DRDY)==0
  120.  
  121.  
  122. void delayus(uint64_t microseconds)
  123. {
  124. bcm2835_delayMicroseconds(microseconds);
  125. }
  126.  
  127. void send8bit(uint8_t data)
  128. {
  129. bcm2835_spi_transfer(data);
  130. }
  131.  
  132. uint8_t recieve8bit(void)
  133. {
  134. uint8_t read = 0;
  135. read = bcm2835_spi_transfer(0xff);
  136. return read;
  137. }
  138.  
  139. void waitDRDY(void)
  140. {
  141. while(!DRDY_LOW()){
  142. continue;
  143. }
  144. }
  145.  
  146. uint8_t initializeSPI()
  147. {
  148. if (!bcm2835_init())
  149. return -1;
  150. bcm2835_spi_begin();
  151. bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);
  152. bcm2835_spi_setDataMode(BCM2835_SPI_MODE1);
  153. // Spi clock divider: 250Mhz / 256 = 0.97 Mhz ~ between 4 to 10 * 1/freq.clkin.
  154. // Divider 128 is already more than 4 * 1/freq.clckin so it is not apropriate for usage.
  155. bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_256);
  156. bcm2835_gpio_fsel(SPICS, BCM2835_GPIO_FSEL_OUTP); // Set SPICS pin to output
  157. bcm2835_gpio_write(SPICS, HIGH);
  158. bcm2835_gpio_fsel(DRDY, BCM2835_GPIO_FSEL_INPT); // Set DRDY pin to input
  159. bcm2835_gpio_set_pud(DRDY, BCM2835_GPIO_PUD_UP);
  160. return 1;
  161. }
  162.  
  163. void endSPI()
  164. {
  165. bcm2835_spi_end();
  166. bcm2835_close();
  167. }
  168.  
  169.  
  170. // Read 1 byte from register address registerID.
  171. uint8_t readByteFromReg(uint8_t registerID)
  172. {
  173. CS_0();
  174. send8bit(CMD_RREG | registerID); // 1st byte: address of the first register to read
  175. send8bit(0x00); // 2nd byte: number of bytes to read = 1.
  176.  
  177. delayus(7); // min delay: t6 = 50 * 1/freq.clkin = 50 * 1 / 7,68 Mhz = 6.5 micro sec
  178. uint8_t read = recieve8bit();
  179. CS_1();
  180. return read;
  181. }
  182.  
  183. // Write value (1 byte) to register address registerID.
  184. // This could be modified to write any number of bytes to register!
  185. void writeByteToReg(uint8_t registerID, uint8_t value)
  186. {
  187. CS_0();
  188. send8bit(CMD_WREG | registerID); // 1st byte: address of the first register to write
  189. send8bit(0x00); // 2nd byte: number of bytes to write = 1.
  190. send8bit(value); // 3rd byte: value to write to register
  191. CS_1();
  192. }
  193.  
  194. // Send standalone commands to register.
  195. uint8_t writeCMD(uint8_t command)
  196. {
  197. CS_0();
  198. send8bit(command);
  199. CS_1();
  200. }
  201.  
  202. // Set the internal buffer (True - enable, False - disable).
  203. uint8_t setBuffer(bool val)
  204. {
  205. CS_0();
  206. send8bit(CMD_WREG | REG_STATUS);
  207. send8bit((0 << 3) | (1 << 2) | (val << 1));
  208. CS_1();
  209. }
  210.  
  211. // Get data from STATUS register - chip ID information.
  212. uint8_t readChipID(void)
  213. {
  214. waitDRDY();
  215. uint8_t id = readByteFromReg(REG_STATUS);
  216. return (id >> 4); // Only bits 7,6,5,4 are the ones to read (only in REG_STATUS) - return shifted value!
  217. }
  218.  
  219. // Write to MUX register - set channel to read from in single-ended mode.
  220. // Bits 7,6,5,4 determine the positive input channel (AINp).
  221. // Bits 3,2,1,0 determine the negative input channel (AINn).
  222. void setSEChannel(uint8_t channel)
  223. {
  224. writeByteToReg(REG_MUX, channel << 4 | 1 << 3); // xxxx1000 - AINp = channel, AINn = AINCOM
  225. }
  226.  
  227. // Write to MUX register - set channel to read from in differential mode.
  228. // Bits 7,6,5,4 determine the positive input channel (AINp).
  229. // Bits 3,2,1,0 determine the negative input channel (AINn).
  230. void setDIFFChannel(uint8_t positiveCh, uint8_t negativeCh)
  231. {
  232. writeByteToReg(REG_MUX, positiveCh << 4 | negativeCh); // xxxx1000 - AINp = positiveCh, AINn = negativeCh
  233. }
  234.  
  235. // Write to A/D control register - set programmable gain amplifier (PGA).
  236. // CLKOUT and sensor detect options are turned off in this case.
  237. void setPGA(uint8_t pga)
  238. {
  239. writeByteToReg(REG_ADCON, pga); // 00000xxx -> xxx = pga
  240. }
  241.  
  242. // Write to A/D data rate register - set data rate.
  243. void setDataRate(int drate)
  244. {
  245. uint8_t drateH = 0;
  246. switch (drate)
  247. {
  248. case 0:rateH = 0xF0;break;
  249. case 1 :drateH = 0xE0; break;
  250. case 2:drateH = 0xD0;break;
  251. case 3:drateH = 0xC0;break;
  252. case 4:drateH = 0xB0;break;
  253. case 5:drateH = 0xA1;break;
  254. case 6:drateH = 0x92;break;
  255. case 7:drateH = 0x82;break;
  256. case 8:drateH = 0x72;break;
  257. case 9:drateH = 0x63;break;
  258. case 10:drateH = 0x53;break;
  259. case 11:drateH = 0x43;break;
  260. case 12:drateH = 0x33;break;
  261. case 13:drateH = 0x20;break;
  262. case 14:drateH = 0x13;break;
  263. case 15:drateH = 0x03;break;
  264. }
  265. writeByteToReg(REG_DRATE, drateH);
  266. }
  267.  
  268. // Read 24 bit value from ADS1256. Issue this command after DRDY goes low to read s single
  269. // conversion result. Allows reading data from multiple different channels and in
  270. // single-ended and differential analog input.
  271. int32_t readData(void)
  272. {
  273. uint32_t read = 0;
  274. uint8_t buffer[3];
  275.  
  276. CS_0();
  277. send8bit(CMD_RDATA);
  278. delayus(7); // min delay: t6 = 50 * 1/freq.clkin = 50 * 1 / 7,68 Mhz = 6.5 micro sec
  279.  
  280. buffer[0] = recieve8bit();
  281. buffer[1] = recieve8bit();
  282. buffer[2] = recieve8bit();
  283. // DRDY goes high here
  284. // construct 24 bit value
  285. read = ((uint32_t)buffer[0] << 16) & 0x00FF0000;
  286. read |= ((uint32_t)buffer[1] << 8);
  287. read |= buffer[2];
  288. if (read & 0x800000){
  289. read |= 0xFF000000;
  290. }
  291.  
  292. CS_1();
  293.  
  294. return (int32_t)read;
  295. }
  296.  
  297. // Get one single-ended analog input value by issuing command to input multiplexer.
  298. // It reads a value from previous conversion!
  299. // DRDY needs to be low!
  300. int32_t getValSEChannel(uint8_t channel)
  301. {
  302. int32_t read = 0;
  303. setSEChannel(channel); // MUX command
  304. delayus(3); // min delay: t11 = 24 * 1 / 7,68 Mhz = 3,125 micro sec
  305. writeCMD(CMD_SYNC); // SYNC command
  306. delayus(3);
  307. writeCMD(CMD_WAKEUP); // WAKEUP command
  308. delayus(1); // min delay: t11 = 4 * 1 / 7,68 Mhz = 0,52 micro sec
  309. read = readData();
  310. return read;
  311. }
  312.  
  313. // Get one differential analog input value by issuing command to input multiplexer.
  314. // It reads a value from previous conversion!
  315. // DRDY needs to be low!
  316. int32_t getValDIFFChannel(uint8_t positiveCh, uint8_t negativeCh)
  317. {
  318. int32_t read = 0;
  319. setDIFFChannel(positiveCh, negativeCh);
  320. delayus(3); // min delayus: t11 = 24 * 1 / 7,68 Mhz = 3,125 micro sec
  321. writeCMD(CMD_SYNC);
  322. delayus(3);
  323. writeCMD(CMD_WAKEUP);
  324. delayus(1); // min delayus: t11 = 4 * 1 / 7,68 Mhz = 0,52 micro sec
  325. read = readData();
  326. return read;
  327. }
  328.  
  329. // Get one single-ended analog input value from input channels you set (min 1, max 8).
  330. void scanSEChannels(uint8_t channels[], uint8_t numOfChannels, uint32_t *values)
  331. {
  332. for (int i = 0; i < numOfChannels; ++i){
  333. waitDRDY();
  334. values[i] = getValSEChannel(channels[i]);
  335. }
  336. }
  337.  
  338. // Get one differential analog input value from input channels you set (min 1, max 4).
  339. void scanDIFFChannels(uint8_t positiveChs[], uint8_t negativeChs[], uint8_t numOfChannels, uint32_t *values)
  340. {
  341. for (int i = 0; i < numOfChannels; ++i){
  342. waitDRDY();
  343. values[i] = getValDIFFChannel(positiveChs[i], negativeChs[i]);
  344. }
  345. }
  346.  
  347. // Continuously acquire analog data from one single-ended analog input.
  348. // Allows sampling of one single-ended input channel up to 30,000 SPS.
  349. void scanSEChannelContinuous(uint8_t channel, uint32_t numOfMeasure, uint32_t *values, uint32_t *currentTime)
  350. {
  351. uint8_t buffer[3];
  352. uint32_t read = 0;
  353. uint8_t del = 8;
  354.  
  355. // Set single-ended analog input channel.
  356. setSEChannel(channel);
  357. delayus(del);
  358.  
  359. // Set continuous mode.
  360. CS_0();
  361. waitDRDY();
  362. send8bit(CMD_RDATAC);
  363. delayus(del); // min delay: t6 = 50 * 1/7.68 MHz = 6.5 microseconds
  364.  
  365. // Start reading data
  366. currentTime [numOfMeasure];
  367. clock_t startTime = clock();
  368. for (int i = 0; i < numOfMeasure; ++i)
  369. {
  370. waitDRDY();
  371. buffer[0] = recieve8bit();
  372. buffer[1] = recieve8bit();
  373. buffer[2] = recieve8bit();
  374.  
  375. // construct 24 bit value
  376. read = ((uint32_t)buffer[0] << 16) & 0x00FF0000;
  377. read |= ((uint32_t)buffer[1] << 8);
  378. read |= buffer[2];
  379. if (read & 0x800000){
  380. read |= 0xFF000000;
  381. }
  382. values[i] = read;
  383. currentTime[i] = clock() - startTime;
  384. //printf("%f %i\n", (float)read/1670000, clock() - startTime); // TESTING
  385. delayus(del);
  386. }
  387.  
  388. // Stop continuous mode.
  389. waitDRDY();
  390. send8bit(CMD_SDATAC); // Stop read data continuous.
  391. CS_1();
  392. }
  393.  
  394. // Continuously acquire analog data from one differential analog input.
  395. // Allows sampling of one differential input channel up to 30,000 SPS.
  396. void scanDIFFChannelContinuous(uint8_t positiveCh, uint8_t negativeCh, uint32_t numOfMeasure, uint32_t *values, uint32_t *currentTime)
  397. {
  398. uint8_t buffer[3];
  399. uint32_t read = 0;
  400. uint8_t del = 8;
  401.  
  402. // Set differential analog input channel.
  403. setDIFFChannel(positiveCh, negativeCh);
  404. delayus(del);
  405.  
  406. // Set continuous mode.
  407. CS_0();
  408. waitDRDY();
  409. send8bit(CMD_RDATAC);
  410. delayus(del); // min delay: t6 = 50 * 1/7.68 MHz = 6.5 microseconds
  411.  
  412. // Start reading data.
  413. currentTime [numOfMeasure];
  414. clock_t startTime = clock();
  415. for (int i = 0; i < numOfMeasure; ++i)
  416. {
  417. waitDRDY();
  418. buffer[0] = recieve8bit();
  419. buffer[1] = recieve8bit();
  420. buffer[2] = recieve8bit();
  421.  
  422. // construct 24 bit value
  423. read = ((uint32_t)buffer[0] << 16) & 0x00FF0000;
  424. read |= ((uint32_t)buffer[1] << 8);
  425. read |= buffer[2];
  426. if (read & 0x800000){
  427. read |= 0xFF000000;
  428. }
  429. values[i] = read;
  430. currentTime[i] = clock() - startTime;
  431. //printf("%f %i\n", (float)read/1670000, clock() - startTime); // TESTING
  432. delayus(del);
  433. }
  434.  
  435. // Stop continuous mode.
  436. waitDRDY();
  437. send8bit(CMD_SDATAC); // Stop read data continuous.
  438. CS_1();
  439. }
  440.  
  441.  
  442. static int sock = 0;
  443. static int Server(char* ourip)
  444. {
  445. int PORT = 8095;
  446. struct sockaddr_in serv_addr;
  447. char buffer[1024] = {0};
  448. if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
  449. {
  450. printf("\n Socket creation error \n");
  451. return -1;
  452. }
  453.  
  454. serv_addr.sin_family = AF_INET;
  455. serv_addr.sin_port = htons(PORT);
  456. // Convert IPv4 and IPv6 addresses from text to binary form
  457. if(inet_pton(AF_INET, ourip, &serv_addr.sin_addr)<=0)
  458. {
  459. printf("\nInvalid address/ Address not supported \n");
  460. return -1;
  461. }
  462. if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
  463. {
  464. printf("\nConnection Failed \n");
  465. return -1;
  466. }
  467.  
  468. return 0;
  469. }
  470.  
  471.  
  472. int main(int argc, char *argv[]){
  473. if (argc < 2){
  474. printf("Usage: %s <Pin> <Speed> <Gain> <Seconds> <Mode>\n", argv[0]);
  475. return 1;
  476. }
  477.  
  478. printf("a1 = %s, pin = %s, speed = %s, gain = %s, seconds = %s, mode %s\n", argv[0],argv[1],argv[2],argv[3],argv[4],argv[5]);
  479. int ModeArg = atoi(argv[5]);
  480. int TimeArg = atoi(argv[4]) * 1000000;
  481. int GainArg = atoi(argv[3]);
  482. int SpeedArg = atoi(argv[2]);
  483. int PinArg = atoi(argv[1]);
  484. if (!initializeSPI()) return 1;
  485.  
  486. setBuffer(True);
  487. setPGA(GainArg);
  488. setDataRate(SpeedArg);
  489. Server(argv[6]);
  490. char message[20];
  491.  
  492. clock_t start_DIFF, end_DIFF;
  493. int num_ch_DIFF = 1;
  494. uint32_t values_DIFF [num_ch_DIFF];
  495. uint8_t posChannels [1] = {PinArg};
  496. uint8_t negChannels [1] = {AINCOM};
  497. if(ModeArg == 1) //File
  498. {
  499. FILE *file;
  500. file = fopen("file.txt", "w");
  501. start_DIFF = clock();
  502. while(clock() - start_DIFF <= TimeArg)
  503. {
  504. scanDIFFChannels(posChannels, negChannels, num_ch_DIFF, values_DIFF);
  505. for (int ch = 0; ch < num_ch_DIFF; ++ch)
  506. {
  507. fprintf(file, "%f %i", (double)values_DIFF[ch]/1670000, clock() - start_DIFF);
  508. //printf("%f %i", (double)values_DIFF[ch]/1670000, clock() - start_DIFF);
  509. }
  510. fprintf(file,"\n");
  511. }
  512. end_DIFF = clock();
  513. fclose(file);
  514. }
  515. else // WIFI
  516. {
  517. start_DIFF = clock();
  518. while(clock() - start_DIFF <= TimeArg)
  519. {
  520. scanDIFFChannels(posChannels, negChannels, num_ch_DIFF, values_DIFF);
  521. for (int ch = 0; ch < num_ch_DIFF; ++ch)
  522. {
  523. sprintf(message,"%d|%f", clock() - start_DIFF,(double)values_DIFF[ch]/1670000);
  524. send(sock , message , strlen(message) , 0);
  525. }
  526. }
  527. end_DIFF = clock();
  528.  
  529. }
  530.  
  531. endSPI();
  532. return 0;
  533. }
  534.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement