Quantcast
Channel: Blogs at All About Circuits
Viewing all articles
Browse latest Browse all 742

HYGROMAX 630 - Made with Maxim !!! (Final Submission)

$
0
0
Introduction
Hydroponics is the science of growing plants without soil. Nutrients are fed directly to the plant via nutrient solution in a very carefully monitored environment. This level of control allows us to predict various parameters such as yield, time to bear fruit, etc.
There are certain requirements that need to be met in order to be able to control this environment successfully. Sensors need to be scanned periodically, data collected, stored and available on the cloud for viewing and monitoring from a remote location.
The MAX32630FTHR suits this requirement perfectly. An ARM processor which comfortably processes all the sensor activity, SD Card on board which is used here to set up the unit (configuration), a gyro and accelerometer to monitor and alert the user if any disturbances occur and BLE to be able to use a mobile phone or tablet to view data and also to upload the data to the cloud.


BOM
MAX32630FTHR
MAX7219 - 4 nos.
74HC164 - 5 nos.
Light Dependent Resistors - 9 nos.
MH-Z14 CO2 sensor - 1 no.
pH Electrode - 3 nos.
Water Level Sensor - 3 nos.
DHT-11 - Humidity/Temperature Sensor - 3 nos.
74HC4067 - ADC MUX - 2 nos.


Schematics



Instructions
Discussed in previous blogs
Video
Just a small clip to show most of the sensors hooked up and the actuators kicking in to light up the unit or switch on the fans. Also seen in the clip are the BLE notifications coming in from the unit. Since we are using custom characteristics, the values are not recognized in any particular format and are also not named since this is a proprietary software that I am using to check the notifications..




Source Code
Code (Text):
  1.  
  2. #include "mbed.h"
  3. #include "max32630fthr.h"
  4. #include "shiftreg.h"
  5. #include "adc.h"
  6. #include "Dht11.h"
  7. #include "bmi160.h"
  8. #include "ble/BLE.h"
  9. #include "ble/services/BatteryService.h"
  10. #include "ble/services/EnvironmentalService.h"
  11. #include "DeviceInformationService.h"
  12. #include "FATFileSystem.h"
  13. #include "SDBlockDevice.h"
  14.  
  15.  
  16. #define MAX_RELAYS                 8
  17. #define MAX_ADC                    32
  18. #define    MAX_SUBSYSTEMS            6        // temperature, humidity, pH, CO2, Oxygen, Water Level
  19. #define    GYRO_TRIGGER            5.0        // no real need for this to be less than 20, really
  20. #define GYRO_SCAN_INTERVAL        1.0      // seconds - consider bumping this to 200ms
  21. #define    ADC_SETTLE_TIME            20    // milliseconds
  22.  
  23. #define    ALL_GREEN_OFFSET        204
  24. #define    QUAD1_OFFSET            1
  25. #define    QUAD2_OFFSET            16
  26. #define    QUAD3_OFFSET            32
  27. #define    QUAD4_OFFSET            2
  28.  
  29. //////////////////////////////////////
  30. //
  31. //ADC MUX INPUT DEFINITIONS
  32.  
  33. #define T1HUM                    0
  34. #define T2HUM                    1
  35. #define T3HUM                    2
  36.  
  37. #define T1CO2                    3
  38. #define T2CO2                    4
  39. #define T3CO2                    5
  40.  
  41. #define T1pH                    6
  42. #define T2pH                    7
  43. #define T3pH                    8
  44.  
  45. #define    T1WLEVEL                9
  46. #define    T2WLEVEL                10
  47. #define    T3WLEVEL                11
  48.  
  49. #define    T1L1                    16
  50. #define    T1L2                    17
  51. #define    T1L3                    18
  52. #define    T2L1                    19
  53. #define    T2L2                    20
  54. #define    T2L3                    21
  55. #define    T3L1                    22
  56. #define    T3L2                    23
  57. #define    T3L3                    24
  58.  
  59. //////////////////////////////////////
  60.  
  61. //RELAYS DEFINITIONS
  62. #define    RELAY_T1_LIGHT1        0
  63. #define    RELAY_T1_LIGHT2        1
  64. #define    RELAY_T1_LIGHT3        2
  65. #define    RELAY_T2_LIGHT1        3
  66. #define    RELAY_T2_LIGHT2        4
  67. #define    RELAY_T2_LIGHT3        5
  68. #define    RELAY_T3_LIGHT1        6
  69. #define    RELAY_T3_LIGHT2        7
  70. #define    RELAY_T3_LIGHT3        8
  71. #define    RELAY_T1_FAN        9
  72. #define    RELAY_T2_FAN        10
  73. #define    RELAY_T3_FAN        11
  74. #define    RELAY_T1_OXYPUMP    12
  75. #define    RELAY_T2_OXYPUMP    13
  76. #define    RELAY_T3_OXYPUMP    14
  77. #define    RELAY_T1_CO2        15
  78. #define    RELAY_T2_CO2        16
  79. #define    RELAY_T3_CO2        17
  80.  
  81.  
  82.  
  83.     ////////////////////////////////////////////////////////////////////////////
  84.     // BMI160 Initialization
  85.     I2C i2cBus(P5_7, P6_0);
  86.     BMI160_I2C imu(i2cBus, BMI160_I2C::I2C_ADRS_SDO_LO);
  87.     BMI160::AccConfig accConfig;
  88.     BMI160::GyroConfig gyroConfig;
  89.  
  90.  
  91.  
  92.  
  93. // Shift Register Initialization
  94. ShiftOut sr(P3_5,P3_2,P3_3,24); // CLK, DATA, CLR  for the 3 74LS164's handling the relays
  95. ShiftOut adcmux(P5_4,P5_5,P5_3,8); // CLK, DATA, CLR for the single 164 handling the ADC signal multiplexers
  96. ShiftOut levelmon(P3_0,P3_1,P4_0,8); // CLK, DATA, CLR for the single 164 displaying level disturbances (dual LEDs)
  97.  
  98. // DHT-11 Initialization
  99. Dht11 hum_sensor1(P5_6);
  100. Dht11 hum_sensor2(P5_6);
  101. Dht11 hum_sensor3(P5_6);
  102.  
  103. // SPI Initialization - for MAX7219
  104. SPI spi(P5_1, P5_2, P5_0);          //  MOSI, MISO, SCLK - MISO not used here, though
  105. DigitalOut cs(P3_4);                // Chip select (LOAD)
  106.  
  107. // On board LED
  108. DigitalOut rLED(LED1, LED_OFF);
  109. DigitalOut gLED(LED2, LED_OFF);
  110. DigitalOut bLED(LED3, LED_OFF);
  111.  
  112. //Level Monitor Reset Pin
  113.  
  114. BatteryService *batteryServicePtr;
  115. DeviceInformationService *deviceInformationServicePtr;
  116. EnvironmentalService *environServicePtr;
  117.  
  118. char config_buffer[128];
  119.  
  120. const char     DEVICE_NAME[]        = "HYGROMAX630";
  121. const uint16_t uuid16_list[]        = {    GattService::UUID_BATTERY_SERVICE,
  122.                                         GattService::UUID_DEVICE_INFORMATION_SERVICE,
  123.                                         GattService::UUID_ENVIRONMENTAL_SERVICE};
  124.  
  125. int    mon_temperature        =     77;    // farenheit
  126. int mon_humidity        =    85;    // percentage
  127. int mon_pH                =    75;    // pH*10
  128. int mon_fans            =    7;    // powers of 2 format
  129. int mon_lights            =    32; // powers of 2 format
  130. int mon_waterlevel        =    80;    // percentage
  131. int    mon_oxygen            =    1;    // 1 or 0
  132. int    mon_co2                =    99;    // ppm
  133.  
  134. int    batteryPercentage    = 100;
  135.  
  136. Ticker sec_tick;
  137. Ticker fivesecs_tick;
  138. Ticker fifteensecs_tick;
  139. Ticker eighteensecs_tick;
  140. Ticker levelmon_tick;
  141.  
  142. int mc_seconds = 0;
  143. int mc_minutes = 39;
  144. int mc_hours = 10;
  145. int mc_days = 17;
  146. int start_hours = 0;
  147. int start_minutes = 0;
  148.  
  149.  
  150. int lightintensitytrigger = 500;   // probably needs further calibration
  151.                                   // also, consider moving this to the SD card
  152.                                  // along with the others
  153.  
  154. int lightdutycycle = 0;
  155. int co2trigger = 0;
  156. int pHtrigger = 0;
  157. int lp_lights = 0;
  158. int lp_oxygen = 0;
  159. int lp_co2 = 0;
  160.  
  161.  
  162. int    subsys_count = 0;
  163.  
  164. int adc_int;
  165.  
  166. float imuTemperature;
  167. BMI160::SensorData accData;
  168. BMI160::SensorData gyroData;
  169. BMI160::SensorTime sensorTime;
  170. int disturbed = 0;
  171. int QUAD1 = 0;
  172. int QUAD2 = 0;
  173. int QUAD3 = 0;
  174. int QUAD4 = 0;
  175.  
  176.  
  177. int RELAYS[MAX_RELAYS];
  178. int srcount = 0;
  179. int adc_count = 3;  //0,1,2 - humidity
  180.  
  181. int TWOPOWERS[] = {1,
  182.         2,
  183.         4,
  184.         8,
  185.         16,
  186.         32,
  187.         64,
  188.         128,
  189.         256,
  190.         512,
  191.         1024,
  192.         2048,
  193.         4096,
  194.         8192,
  195.         16384,
  196.         32768,
  197.         65536,
  198.         131072,
  199.         262144,
  200.         524288,
  201.         1048576,
  202.         2097152,
  203.         4194304,
  204.         8388608,
  205.         16777216};
  206.  
  207. unsigned char ADC_SELECT[32] = {32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
  208.                                 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};
  209.  
  210.  
  211. unsigned char BUFFER_MSB[4][8];
  212. unsigned char BUFFER_LSB[4][8];
  213.  
  214.  
  215. void periodicCallback(void)
  216. {
  217.  
  218.  
  219. }
  220.  
  221. /* Restart Advertising on disconnection*/
  222. void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
  223. {
  224.     BLE::Instance().gap().startAdvertising();
  225. }
  226.  
  227. /* Connection */
  228. void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
  229. {
  230. }
  231.  
  232.  
  233. /**
  234. * This function is called when the ble initialization process has failed
  235. */
  236. void onBleInitError(BLE &ble, ble_error_t error)
  237. {
  238.     /* Avoid compiler warnings */
  239.     (void) ble;
  240.     (void) error;
  241.     /* Initialization error handling should go here */
  242. }
  243.  
  244. /**
  245. * Callback triggered when the ble initialization process has finished
  246. */
  247. void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
  248. {
  249.     BLE&        ble   = params->ble;
  250.     ble_error_t error = params->error;
  251.  
  252.     if (error != BLE_ERROR_NONE) {
  253.         /* In case of error, forward the error handling to onBleInitError */
  254.         onBleInitError(ble, error);
  255.         return;
  256.     }
  257.  
  258.     /* Ensure that it is the default instance of BLE */
  259.     if (ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
  260.         return;
  261.     }
  262.  
  263.     ble.gap().onDisconnection(disconnectionCallback);
  264.     ble.gap().onConnection(connectionCallback);
  265.  
  266.     /* Setup primary service. */
  267.     deviceInformationServicePtr = new DeviceInformationService(ble, "Maxim", "FTHR", "00001", "0.1", "0.0", "0.0");
  268.     batteryServicePtr = new BatteryService(ble, batteryPercentage);
  269.     environServicePtr = new EnvironmentalService(ble);
  270.  
  271.     /* Setup advertising */
  272.     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
  273.     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
  274.     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
  275.     ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
  276.     ble.gap().setAdvertisingInterval(250); /* 250ms */
  277.     ble.gap().startAdvertising();
  278. }
  279.  
  280. void ClearLoadPin()
  281. {
  282.     cs = 0;                         // Set CS Low
  283. }
  284.  
  285. void SetLoadPin()
  286. {
  287.     cs = 1;                         // Set CS High
  288. }
  289.  
  290. /// Send two bytes to SPI bus
  291. void SPI_Write2(unsigned char MSB, unsigned char LSB)
  292. {
  293.     spi.write(MSB);                 // Send two bytes
  294.     spi.write(LSB);
  295.  
  296. }
  297.  
  298. void ReadADC(int select)
  299. {
  300.     float adc_f = 0.0;
  301.     float adc_norm = 0.0;
  302.  
  303.     uint16_t adc_value;
  304.     unsigned int overflow;
  305.     ADC_StartConvert(ADC_CH_1_DIV_5, 0, 1); // AIN1 div 5
  306.     overflow = (ADC_GetData(&adc_value) == E_OVERFLOW ? 1 : 0);
  307.     printf("AIN1/5: 0x%04x%s  %d    %d\r\n", adc_value, overflow ? "*" : " ", ADC_SELECT[select], adc_value);
  308.     adc_f = adc_value;
  309.     adc_norm = (adc_f/1024.0)*100.0;
  310.     adc_int = adc_norm;
  311.     if(adc_int > 99)
  312.         adc_int = 99;
  313. }
  314. /*
  315. void TestADCMUX()
  316. {
  317.     ClearAllRelays();
  318.     adcmux.setclr();
  319.  
  320.     if(adc_count==MAX_RELAYS)
  321.     {
  322.            adc_count = 3;  //0,1,2 - humidity
  323.            wait(1.0);
  324.     }
  325.  
  326.     adcmux.write(ADC_SELECT[adc_count]);
  327.     wait_ms(1);
  328.     ReadADC(adc_count);
  329.  
  330.     SetRelay(adc_count);
  331.     int relay_data = GetRelayData();
  332.     sr.write(relay_data);
  333.     wait(1);
  334. }
  335. */
  336.  
  337. /// Send eight control bytes to SPI bus to 4 7219's
  338. void SPI_Write8(unsigned char MSB, unsigned char LSB)
  339. {
  340.     ClearLoadPin();
  341.     spi.write(MSB);                 // Send two bytes to 4
  342.     spi.write(LSB);
  343.     spi.write(MSB);                 // Send two bytes to 3
  344.     spi.write(LSB);
  345.     spi.write(MSB);                 // Send two bytes to 2
  346.     spi.write(LSB);
  347.     spi.write(MSB);                 // Send two bytes to 1
  348.     spi.write(LSB);
  349.     SetLoadPin();
  350. }
  351.  
  352. /// Send eight bytes to SPI bus to 4 7219's
  353. void SPI_Write8BUF()
  354. {
  355.     for(int digit=0;digit<8;digit++)
  356.     {
  357.         ClearLoadPin();
  358.  
  359.         spi.write(BUFFER_MSB[3][digit]);                 // Send two bytes to 3
  360.         spi.write(BUFFER_LSB[3][digit]);
  361.         spi.write(BUFFER_MSB[2][digit]);                 // Send two bytes to 2
  362.         spi.write(BUFFER_LSB[2][digit]);
  363.         spi.write(BUFFER_MSB[1][digit]);                 // Send two bytes to 1
  364.         spi.write(BUFFER_LSB[1][digit]);
  365.         spi.write(BUFFER_MSB[0][digit]);                 // Send two bytes to 4
  366.         spi.write(BUFFER_LSB[0][digit]);
  367.  
  368.         SetLoadPin();
  369.     }
  370. }
  371.      
  372. void SPI_WriteToBuf(int bufslot, int digit, unsigned char MSB, unsigned char LSB)
  373. {
  374.        BUFFER_MSB[bufslot][digit] = MSB;              
  375.        BUFFER_LSB[bufslot][digit] = LSB;
  376.      
  377. }
  378.  
  379. void Update_MAX7219()
  380. {
  381.                  
  382.           SPI_Write8BUF();
  383. }
  384.  
  385.  
  386.  
  387. /// MAX7219 initialisation
  388. void Init_MAX7219(void)
  389. {
  390.     SPI_Write8(0x09, 0xFF);         // Decoding on
  391.     SPI_Write8(0x0A, 0x08);         // Brightness to intermediate
  392.     SPI_Write8(0x0B, 0x07);         // Scan limit = 7
  393.     SPI_Write8(0x0C, 0x01);         // Normal operation mode
  394.     SPI_Write8(0x0F, 0x0F);         // Enable display test
  395.     wait_ms(100);                   // 500 ms delay
  396.     /*
  397.     SPI_Write8(0x01, 0x00);         // Clear row 0.
  398.     SPI_Write8(0x02, 0x00);         // Clear row 1.
  399.     SPI_Write8(0x03, 0x00);         // Clear row 2.
  400.     SPI_Write8(0x04, 0x00);         // Clear row 3.
  401.     SPI_Write8(0x05, 0x00);         // Clear row 4.
  402.     SPI_Write8(0x06, 0x00);         // Clear row 5.
  403.     SPI_Write8(0x07, 0x00);         // Clear row 6.
  404.     SPI_Write8(0x08, 0x00);         // Clear row 7.
  405.     */
  406.     SPI_Write8(0x0F, 0x00);         // Disable display test
  407.     wait_ms(100);
  408. }
  409.  
  410. int GetRelayData()
  411. {
  412.     int rd = 0;
  413.     for(int i=0;i<MAX_RELAYS;i++)
  414.         if(RELAYS[i])
  415.             rd += TWOPOWERS[i];
  416.     return(rd);
  417. }
  418.  
  419.  
  420. void ScanLight()
  421. {
  422.     adcmux.setclr();
  423.     adcmux.write(ADC_SELECT[T1L1]);
  424.     wait_ms(1);
  425.     printf("Light T1L1 - ");
  426.     ReadADC(T1L1);
  427.     SPI_WriteToBuf(1,0,1,13);
  428.     SPI_WriteToBuf(1,1,2,1);
  429.     SPI_WriteToBuf(1,2,3,(adc_int/10));
  430.     SPI_WriteToBuf(1,3,4,(adc_int%10));
  431.  
  432.     adcmux.setclr();
  433.     adcmux.write(ADC_SELECT[T1L2]);
  434.     wait_ms(1);
  435.     printf("Light T1L2 -");
  436.     ReadADC(T1L2);
  437.     SPI_WriteToBuf(1,4,5,(adc_int/10));
  438.     SPI_WriteToBuf(1,5,6,(adc_int%10));
  439.  
  440.     adcmux.setclr();
  441.     adcmux.write(ADC_SELECT[T1L3]);
  442.     wait_ms(1);
  443.     printf("Light T1L3 - ");
  444.     ReadADC(T1L3);
  445.     SPI_WriteToBuf(1,6,7,(adc_int/10));
  446.     SPI_WriteToBuf(1,7,8,(adc_int%10));
  447.  
  448.     adcmux.setclr();
  449.     adcmux.write(ADC_SELECT[T2L1]);
  450.     wait_ms(1);
  451.     printf("Light T2L1 - ");
  452.     ReadADC(T2L1);
  453.     SPI_WriteToBuf(2,0,1,13);
  454.     SPI_WriteToBuf(2,1,2,1);
  455.     SPI_WriteToBuf(2,2,3,(adc_int/10));
  456.     SPI_WriteToBuf(2,3,4,(adc_int%10));
  457.  
  458.     adcmux.setclr();
  459.     adcmux.write(ADC_SELECT[T2L2]);
  460.     wait_ms(1);
  461.     printf("Light T2L2 - ");
  462.     ReadADC(T2L2);
  463.     SPI_WriteToBuf(2,4,5,(adc_int/10));
  464.     SPI_WriteToBuf(2,5,6,(adc_int%10));
  465.  
  466.     adcmux.setclr();
  467.     adcmux.write(ADC_SELECT[T2L3]);
  468.     wait_ms(1);
  469.     printf("Light T2L3 - ");
  470.     ReadADC(T2L3);
  471.     SPI_WriteToBuf(2,6,7,(adc_int/10));
  472.     SPI_WriteToBuf(2,7,8,(adc_int%10));
  473.  
  474.     adcmux.setclr();
  475.     adcmux.write(ADC_SELECT[T3L1]);
  476.     wait_ms(1);
  477.     printf("Light T3L1 - ");
  478.     ReadADC(T3L1);
  479.     SPI_WriteToBuf(3,0,1,13);
  480.     SPI_WriteToBuf(3,1,2,1);
  481.     SPI_WriteToBuf(3,2,3,(adc_int/10));
  482.     SPI_WriteToBuf(3,3,4,(adc_int%10));
  483.  
  484.     adcmux.setclr();
  485.     adcmux.write(ADC_SELECT[T3L2]);
  486.     wait_ms(1);
  487.     printf("Light T3L2 -  ");
  488.     ReadADC(T3L2);
  489.     SPI_WriteToBuf(3,4,5,(adc_int/10));
  490.     SPI_WriteToBuf(3,5,6,(adc_int%10));
  491.  
  492.     adcmux.setclr();
  493.     adcmux.write(ADC_SELECT[T3L3]);
  494.     wait_ms(1);
  495.     printf("Light T3L3 - ");
  496.     ReadADC(T3L3);
  497.     SPI_WriteToBuf(3,6,7,(adc_int/10));
  498.     SPI_WriteToBuf(3,7,8,(adc_int%10));
  499.  
  500. }
  501.  
  502. void ScanHumidity()
  503. {
  504.     adcmux.setclr();
  505.     adcmux.write(ADC_SELECT[T1HUM]);
  506.     wait_ms(ADC_SETTLE_TIME);
  507.     hum_sensor1.read();
  508.     wait_ms(ADC_SETTLE_TIME);
  509.     float ftemp1 = hum_sensor1.getFahrenheit();
  510.     int ihum = hum_sensor1.getHumidity();
  511.     printf("T: %f, H: %d\r\n",ftemp1 , ihum);
  512.     SPI_WriteToBuf(1,0,1,12);
  513.     SPI_WriteToBuf(1,1,2,10);
  514.     SPI_WriteToBuf(1,2,3,(ihum/10));
  515.     SPI_WriteToBuf(1,3,4,(ihum%10));
  516.     int itemp = ftemp1;
  517.     SPI_WriteToBuf(1,5,6,(itemp/10));
  518.     SPI_WriteToBuf(1,6,7,(itemp%10));
  519.     SPI_WriteToBuf(1,7,8,14);
  520.  
  521.     adcmux.setclr();
  522.     adcmux.write(ADC_SELECT[T2HUM]);
  523.     wait_ms(ADC_SETTLE_TIME);
  524.     hum_sensor2.read();
  525.     wait_ms(ADC_SETTLE_TIME);
  526.     float ftemp2 = hum_sensor2.getFahrenheit();
  527.     ihum = hum_sensor2.getHumidity();
  528.     printf("T: %f, H: %d\r\n",ftemp2 , ihum);
  529.     SPI_WriteToBuf(2,0,1,12);
  530.     SPI_WriteToBuf(2,1,2,10);
  531.     SPI_WriteToBuf(2,2,3,(ihum/10));
  532.     SPI_WriteToBuf(2,3,4,(ihum%10));
  533.     itemp = ftemp2;
  534.     SPI_WriteToBuf(2,5,6,(itemp/10));
  535.     SPI_WriteToBuf(2,6,7,(itemp%10));
  536.     SPI_WriteToBuf(2,7,8,14);
  537.  
  538.     adcmux.setclr();
  539.     adcmux.write(ADC_SELECT[T3HUM]);
  540.     wait_ms(ADC_SETTLE_TIME);
  541.     hum_sensor3.read();
  542.     wait_ms(ADC_SETTLE_TIME);
  543.     float ftemp3 = hum_sensor3.getFahrenheit();
  544.     ihum = hum_sensor3.getHumidity();
  545.     printf("T: %f, H: %d\r\n",ftemp3 , ihum);
  546.     SPI_WriteToBuf(3,0,1,12);
  547.     SPI_WriteToBuf(3,1,2,10);
  548.     SPI_WriteToBuf(3,2,3,(ihum/10));
  549.     SPI_WriteToBuf(3,3,4,(ihum%10));
  550.     itemp = ftemp3;
  551.     SPI_WriteToBuf(3,5,6,(itemp/10));
  552.     SPI_WriteToBuf(3,6,7,(itemp%10));
  553.     SPI_WriteToBuf(3,7,8,14);
  554.     /*
  555.     if((ftemp1>80.0)||(ftemp2>80.0)||(ftemp3>80))
  556.     {
  557.         RELAYS[21] = 1;
  558.         RELAYS[22] = 1;
  559.         RELAYS[23] = 1;
  560.     }
  561.     else
  562.     {
  563.         RELAYS[21] = 0;
  564.         RELAYS[22] = 0;
  565.         RELAYS[23] = 0;    
  566.     }
  567.     int relay_data = GetRelayData();
  568.     sr.write(relay_data);
  569.     */
  570. }
  571.  
  572. void ScanCO2()
  573. {
  574.     adcmux.setclr();
  575.     adcmux.write(ADC_SELECT[T1CO2]);
  576.     wait_ms(1);
  577.     printf("CO2  T1CO2 - ");
  578.     ReadADC(T1CO2);
  579.     SPI_WriteToBuf(1,0,1,14);
  580.     SPI_WriteToBuf(1,1,2,14);
  581.     SPI_WriteToBuf(1,2,3,10);
  582.     SPI_WriteToBuf(1,3,4,(adc_int/10));
  583.     SPI_WriteToBuf(1,4,5,(adc_int%10));
  584.  
  585.     SPI_WriteToBuf(2,0,1,14);
  586.     SPI_WriteToBuf(2,1,2,14);
  587.     SPI_WriteToBuf(2,2,3,10);
  588.     SPI_WriteToBuf(2,3,4,(adc_int/10));
  589.     SPI_WriteToBuf(2,4,5,(adc_int%10));
  590.  
  591.     SPI_WriteToBuf(3,0,1,14);
  592.     SPI_WriteToBuf(3,1,2,14);
  593.     SPI_WriteToBuf(3,2,3,10);
  594.     SPI_WriteToBuf(3,3,4,(adc_int/10));
  595.     SPI_WriteToBuf(3,4,5,(adc_int%10));
  596. }
  597.  
  598. void ScanOxygen()
  599. {
  600.     if(RELAYS[RELAY_T1_OXYPUMP] == 1)
  601.         printf("Oxygen Flow is ON \r\n");
  602.     else
  603.         printf("Oxygen Flow is OFF \r\n");
  604. }
  605.  
  606.  
  607. void UpdateClock()
  608. {
  609.     int sec_tens = mc_seconds / 10;
  610.     int sec_units = mc_seconds % 10;
  611.     int min_tens = mc_minutes / 10;
  612.     int min_units = mc_minutes % 10;
  613.     int hour_tens = mc_hours / 10;
  614.     int hour_units = mc_hours % 10;
  615.     int day_tens = mc_days / 10;
  616.     int day_units = mc_days % 10;
  617.  
  618.     SPI_WriteToBuf(0,0,1,hour_tens);
  619.     SPI_WriteToBuf(0,1,2,hour_units);
  620.     SPI_WriteToBuf(0,2,3,min_tens);
  621.     SPI_WriteToBuf(0,3,4,min_units);
  622.     SPI_WriteToBuf(0,4,5,sec_tens);
  623.     SPI_WriteToBuf(0,5,6,sec_units);
  624.     SPI_WriteToBuf(0,6,7,day_tens);
  625.     SPI_WriteToBuf(0,7,8,day_units);
  626.  
  627.     // Get our ADC mux to fire every 2 seconds without setting up an extra ticker for this
  628.     if((mc_seconds % 2)==0)
  629.     {
  630.         if(subsys_count==MAX_SUBSYSTEMS)
  631.             subsys_count = 0;
  632.         int selected_disp = subsys_count % MAX_SUBSYSTEMS;
  633.         switch (selected_disp)
  634.         {
  635.         case 0:
  636.             //Light
  637.             ScanLight();
  638.             break;
  639.         case 1:
  640.             // Humidity Temperature
  641.             ScanHumidity();
  642.             break;
  643.         case 2:
  644.             // Oxygen
  645.             //ScanOxygen();
  646.             break;
  647.         case 3:
  648.             //CO2
  649.             ScanCO2();
  650.             break;
  651.         case 4:
  652.             //pH
  653.             //ScanpH();
  654.             break;
  655.         case 5:
  656.             //Water Level
  657.             //ScanWaterLevel();
  658.             break;
  659.         }
  660.         subsys_count++;
  661.     } // mc_seconds % 2
  662.  
  663.     Update_MAX7219();
  664.  
  665.  
  666.     Update_MAX7219();
  667. }
  668.  
  669. void MonitorLevel()
  670. {
  671.     imu.getGyroAccXYZandSensorTime(accData, gyroData, sensorTime, accConfig.range, gyroConfig.range);
  672.     imu.getTemperature(&imuTemperature);
  673.  
  674.     if(!disturbed)
  675.     {
  676.      
  677.        //    QUADRANTS
  678.        //
  679.        //     2     1
  680.        //  
  681.        //     3     4
  682.      
  683.        int xval = gyroData.xAxis.scaled;
  684.        int yval = gyroData.yAxis.scaled;
  685.        //int zval = gyroData.zAxis.scaled; // we'll come back for this some other day
  686.      
  687.        if((QUAD1!=0)||(QUAD2!=0)||(QUAD3!=0)||(QUAD4!=0))
  688.             disturbed = 1;
  689.      
  690.        if(xval > GYRO_TRIGGER)  // 3 or 4 lowered
  691.           if(yval > GYRO_TRIGGER) // 4
  692.               QUAD4 = 1;
  693.           else if(yval < -(GYRO_TRIGGER))  //3
  694.               QUAD3 = 1;
  695.           else // 3 and 4
  696.               QUAD3 = QUAD4 = 1;
  697.        else if(xval < -(GYRO_TRIGGER))  // 1 or 2 lowered
  698.           if(yval > GYRO_TRIGGER) // 1
  699.               QUAD1 = 1;
  700.           else if(yval < -(GYRO_TRIGGER))  //2
  701.               QUAD2 = 1;
  702.           else
  703.               QUAD1 = QUAD2 = 1;
  704.        else if(yval > GYRO_TRIGGER) // 1 and 4
  705.           QUAD1 = QUAD4 = 1;
  706.        else if(yval < -(GYRO_TRIGGER)) // 2 and 3
  707.           QUAD2 = QUAD3 = 1;
  708.        // else // basically, all is well - no disturbance
  709.        //    QUAD1 = QUAD2 = QUAD3 = QUAD4 = 0;
  710.     }  // if(!disturbed)
  711.  
  712.     levelmon.setclr();
  713.     int level_pattern = ALL_GREEN_OFFSET;
  714.     if(QUAD1==1)
  715.         level_pattern += QUAD1_OFFSET;
  716.     if(QUAD2==1)
  717.         level_pattern += QUAD2_OFFSET;
  718.     if(QUAD3==1)
  719.         level_pattern += QUAD3_OFFSET;
  720.     if(QUAD4==1)
  721.         level_pattern += QUAD4_OFFSET;
  722.  
  723.     levelmon.write(level_pattern);
  724.  
  725.  
  726. }
  727.  
  728. void SetRelay(int relno)
  729. {
  730.     RELAYS[relno] = 1;
  731. }
  732.  
  733. void ClearRelay(int relno)
  734. {
  735.     RELAYS[relno] = 0;
  736. }
  737.  
  738. void ClearAllRelays(){
  739.     for(int i=0;i<MAX_RELAYS;i++)
  740.         RELAYS[i] = 0;
  741.     sr.setclr();
  742. }
  743.  
  744.  
  745.  
  746. void TestAllRelays()
  747. {
  748.     if(srcount==MAX_RELAYS)
  749.     {
  750.        srcount = 0;
  751.        ClearAllRelays();
  752.     }
  753.     SetRelay(srcount);
  754.     int relay_data = GetRelayData();
  755.     sr.write(relay_data);
  756.     printf("RELAYS SWITCHED ON - %d\r\n", relay_data);
  757.     wait_ms(10);
  758.     srcount++;
  759. }
  760.  
  761.  
  762. void EverySecond()
  763. {
  764.  
  765.     gLED = !gLED;
  766.     bLED = !bLED;
  767.     rLED = !rLED; /* Blink LED while we're waiting for BLE events */
  768.  
  769.  
  770.     batteryServicePtr->updateBatteryLevel(batteryPercentage);
  771.  
  772.     environServicePtr->updateTemperature(mon_temperature);
  773.     environServicePtr->updateHumidity(mon_humidity);
  774.  
  775.     environServicePtr->updatepH(mon_pH);
  776.     environServicePtr->updateLights(mon_lights);
  777.     environServicePtr->updateWaterLevel(mon_waterlevel);
  778.     environServicePtr->updateOxygen(mon_oxygen);
  779.     environServicePtr->updateFans(mon_fans);
  780.     environServicePtr->updateCO2(mon_co2);
  781.  
  782.     /*
  783.  
  784.     printf("\033[H");  //home
  785.     printf("\033[0J");  //erase from cursor to end of screen
  786.  
  787.     printf("ACC xAxis = %s%4.3f\r\n", "\033[K", accData.xAxis.scaled);
  788.     printf("ACC yAxis = %s%4.3f\r\n", "\033[K", accData.yAxis.scaled);
  789.     printf("ACC zAxis = %s%4.3f\r\n\n", "\033[K", accData.zAxis.scaled);
  790.  
  791.     printf("GYRO xAxis = %s%5.1f\r\n", "\033[K", gyroData.xAxis.scaled);
  792.     printf("GYRO yAxis = %s%5.1f\r\n", "\033[K", gyroData.yAxis.scaled);
  793.     printf("GYRO zAxis = %s%5.1f\r\n\n", "\033[K", gyroData.zAxis.scaled);
  794.  
  795.     printf("Sensor  Time = %s%f\r\n", "\033[K", sensorTime.seconds);
  796.     printf("Sensor  Temperature = %s%5.3f\r\n", "\033[K", imuTemperature);
  797.  
  798.     printf("%d        %d\r\n\n",QUAD2,QUAD1);
  799.     printf("%d        %d\r\n\n",QUAD3,QUAD4);
  800.  
  801.     */
  802.     if(mc_seconds==59){
  803.         mc_seconds=0;
  804.         if(mc_minutes==59)
  805.         {
  806.             mc_minutes=0;
  807.             if(mc_hours==23)
  808.             {
  809.                 mc_hours=0;
  810.                 mc_days++;
  811.             }
  812.             else
  813.                 mc_hours++;
  814.         }
  815.         else
  816.             mc_minutes++;
  817.     }
  818.     else
  819.         mc_seconds++;
  820.  
  821.     UpdateClock();
  822.  
  823.  
  824. }
  825.  
  826.  
  827. void LevelResetFunc()
  828. {
  829.     disturbed = 0;
  830.     QUAD1 = QUAD2 = QUAD3 = QUAD4 = 0;
  831.  
  832.  
  833. }
  834.  
  835.  
  836.  
  837. void LoadConfigParam(int entry)
  838. {
  839.     int mc_int;
  840.     mc_int = atoi(config_buffer);
  841.     switch (entry)
  842.         {
  843.         case 0:
  844.             //Current Time
  845.             printf("Start with %d\r\n", mc_int);
  846.             mc_days = mc_int % 100;
  847.             mc_int = (mc_int - mc_days)/100;
  848.             printf("Now at %d\r\n",mc_int);
  849.             mc_seconds = mc_int % 100;
  850.             mc_int = (mc_int - mc_seconds)/100;
  851.             printf("Now at %d\r\n",mc_int);
  852.             mc_minutes = mc_int % 100;
  853.             mc_int = (mc_int - mc_minutes)/100;
  854.             printf("Now at %d\r\n",mc_int);
  855.             mc_hours = mc_int % 100;
  856.          
  857.             printf("System Clock Reset to %d hours, %d minutes, %d seconds (%d Days)\r\n", mc_hours, mc_minutes, mc_seconds, mc_days);
  858.             break;
  859.         case 1:
  860.             // Cycle Start Time
  861.             start_minutes = mc_int % 100;
  862.             start_hours = (mc_int - start_minutes)/100;
  863.             printf("Cycle Starts at %d hours and %d minutes\r\n", start_hours, start_minutes);
  864.             break;
  865.         case 2:
  866.             //Light Duty Cycle
  867.             lightdutycycle = mc_int;
  868.             printf("Light Duty Cycle set at %d hours\r\n", mc_int);
  869.             break;
  870.         case 3:
  871.             // CO2 PPM Trigger
  872.             co2trigger = mc_int;
  873.             printf("CO2 Trigger set at %d (ppm)\r\n", co2trigger);
  874.             break;
  875.         case 4:
  876.             // pH Trigger
  877.             pHtrigger = mc_int;
  878.             printf("pH Trigger set at %d (Scale x10)\r\n",pHtrigger);
  879.             break;
  880.         case 5:
  881.             // Lights - Low Power
  882.             lp_lights = mc_int;
  883.             printf("Lights on Low Power Mode - %d\r\n",lp_lights);
  884.         case 6:
  885.             // Oxygen - Low Power
  886.             lp_oxygen = mc_int;
  887.             printf("Oxygen on Low Power Mode - %d\r\n",lp_oxygen);
  888.             break;
  889.         case 7:
  890.             // CO2 - Low Power
  891.             lp_co2 = mc_int;
  892.             printf("CO2 on Low Power Mode - %d\r\n",lp_co2);
  893.             break;
  894.         }
  895. }
  896.  
  897. void ReadConfig()
  898. {
  899.     SDBlockDevice sd(P0_5,P0_6,P0_4,P0_7); // mosi, miso, sclk, cs
  900.     FATFileSystem fs("fs");
  901.  
  902.     printf("Mounting the filesystem on \"/fs\". ");
  903.     fs.mount(&sd);
  904.  
  905.     FILE* fd = fopen("/fs/config.txt", "r");
  906.  
  907.  
  908.     int entry = 0;
  909.     while(fgets(config_buffer, 128, fd)) {
  910.         LoadConfigParam(entry);
  911.         entry++;
  912.     }
  913.  
  914.     /*
  915.     char ch = fgetc(fd);
  916.     while(!feof(fd)){
  917.        printf("%c",ch);
  918.        ch = fgetc(fd);
  919.     }
  920.  
  921.  
  922.     fclose(fd);
  923. }
  924.  
  925.  
  926. int main()
  927. {
  928.     uint32_t i = 0;
  929.     LowPowerTicker ticker;
  930.     BLE &ble = BLE::Instance();
  931.     ble.init(bleInitComplete);
  932.  
  933.     /* SpinWait for initialization to complete. This is necessary because the
  934.      * BLE object is used in the main loop below. */
  935.     while (ble.hasInitialized() == false) { /* spin loop */ }
  936.     sec_tick.attach(&EverySecond,1.0);
  937.     //ticker.attach(periodicCallback, 1.5);
  938.  
  939.     // MAX32630FTHR Initialization
  940.     MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3);
  941.  
  942.     // Initialize ADC
  943.     ADC_Init();
  944.  
  945.     // BMI160 Initialization
  946.     i2cBus.frequency(400000);
  947.  
  948.     cs = 1;                         // CS initially High
  949.     spi.format(8,0);                // 8-bit format, mode 0,0
  950.     spi.frequency(1000000);         // SCLK = 1 MHz
  951.  
  952.     Init_MAX7219();                 // Initialize the LED controller
  953.    
  954.     uint32_t failures = 0;
  955.      
  956.     if(imu.setSensorPowerMode(BMI160::GYRO, BMI160::NORMAL) != BMI160::RTN_NO_ERROR)
  957.     {
  958.         printf("Failed to set gyroscope power mode\n");
  959.         failures++;
  960.     }
  961.     wait_ms(100);
  962.  
  963.     if(imu.setSensorPowerMode(BMI160::ACC, BMI160::NORMAL) != BMI160::RTN_NO_ERROR)
  964.     {
  965.         printf("Failed to set accelerometer power mode\n");
  966.         failures++;
  967.     }
  968.     wait_ms(100);
  969.  
  970.  
  971.     //example of using getSensorConfig
  972.     if(imu.getSensorConfig(accConfig) == BMI160::RTN_NO_ERROR)
  973.     {
  974.         printf("ACC Range = %d\r\n", accConfig.range);
  975.         printf("ACC UnderSampling = %d\r\n", accConfig.us);
  976.         printf("ACC BandWidthParam = %d\r\n", accConfig.bwp);
  977.         printf("ACC OutputDataRate = %d\r\n\n", accConfig.odr);
  978.     }
  979.     else
  980.     {
  981.         printf("Failed to get accelerometer configuration\r\n");
  982.         failures++;
  983.     }
  984.  
  985.     //example of setting user defined configuration
  986.     accConfig.range = BMI160::SENS_4G;
  987.     accConfig.us = BMI160::ACC_US_OFF;
  988.     accConfig.bwp = BMI160::ACC_BWP_2;
  989.     accConfig.odr = BMI160::ACC_ODR_8;
  990.     if(imu.setSensorConfig(accConfig) == BMI160::RTN_NO_ERROR)
  991.     {
  992.         printf("ACC Range = %d\r\n", accConfig.range);
  993.         printf("ACC UnderSampling = %d\r\n", accConfig.us);
  994.         printf("ACC BandWidthParam = %d\r\n", accConfig.bwp);
  995.         printf("ACC OutputDataRate = %d\r\n\n", accConfig.odr);
  996.     }
  997.     else
  998.     {
  999.         printf("Failed to set accelerometer configuration\r\n");
  1000.         failures++;
  1001.     }
  1002.  
  1003.  
  1004.     if(imu.getSensorConfig(gyroConfig) == BMI160::RTN_NO_ERROR)
  1005.     {
  1006.         printf("GYRO Range = %d\r\n", gyroConfig.range);
  1007.         printf("GYRO BandWidthParam = %d\r\n", gyroConfig.bwp);
  1008.         printf("GYRO OutputDataRate = %d\r\n\n", gyroConfig.odr);
  1009.     }
  1010.     else
  1011.     {
  1012.         printf("Failed to get gyroscope configuration\r\n");
  1013.         failures++;
  1014.     }
  1015.  
  1016.  
  1017.     /////////////////////////////////////////////////////////////////////////////////////
  1018.  
  1019.  
  1020.  
  1021.     fivesecs_tick.attach(&LevelResetFunc,5.0);
  1022.  
  1023.  
  1024.  
  1025.     levelmon_tick.attach(&MonitorLevel,GYRO_SCAN_INTERVAL);    // GYRO SCAN INTERVAL
  1026.  
  1027.     ReadConfig();
  1028.  
  1029.     while (1) {
  1030.         if (++i == 1000) {
  1031.            i = 0;
  1032.         }    
  1033.         ble.waitForEvent();
  1034.         //int relay_data = GetRelayData();
  1035.         //sr.write(relay_data);
  1036.     } // while(1)
  1037. }
  1038.  
  1039.  
  1040.  
  1041.  

Viewing all articles
Browse latest Browse all 742

Trending Articles