See: https://github.com/EEEManchester/Food-Computer

Dependencies:   DHT DS1820 MODSERIAL ModbusSlave232 SoftSerial TSL2561_I2C mbed millis

Fork of ModbusRTU-RS232 by Afdhal Atiff Tan

Committer:
AfdhalAtiffTan
Date:
Thu Jul 28 13:23:10 2016 +0000
Revision:
1:77e7cf856fae
Parent:
0:74eb078d4846
Child:
4:796586b35695
First Rev_1 alpha code. May contain bugs. All sensors and actuators should be working. Doesn't use RTOS because SoftSerial can't handle it, it uses Ticker instead. Communication via MODBUS RTU on serial.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AfdhalAtiffTan 1:77e7cf856fae 1 #include "includes.h"
AfdhalAtiffTan 0:74eb078d4846 2
AfdhalAtiffTan 1:77e7cf856fae 3 float get_EC(float temperature);
AfdhalAtiffTan 1:77e7cf856fae 4 float get_pH();
AfdhalAtiffTan 0:74eb078d4846 5
AfdhalAtiffTan 1:77e7cf856fae 6 void update_modbus() //check for request and update relays
AfdhalAtiffTan 1:77e7cf856fae 7 {
AfdhalAtiffTan 1:77e7cf856fae 8 led1 = !led1; //for debug
AfdhalAtiffTan 1:77e7cf856fae 9 mbs.update(regs, MB_REGS);
AfdhalAtiffTan 0:74eb078d4846 10
AfdhalAtiffTan 1:77e7cf856fae 11 R0 = (regs[MB_9] & (0x0001<<0));
AfdhalAtiffTan 1:77e7cf856fae 12 R1 = (regs[MB_9] & (0x0001<<1));
AfdhalAtiffTan 1:77e7cf856fae 13 R2 = (regs[MB_9] & (0x0001<<2));
AfdhalAtiffTan 1:77e7cf856fae 14 R3 = (regs[MB_9] & (0x0001<<3));
AfdhalAtiffTan 1:77e7cf856fae 15 R4 = (regs[MB_9] & (0x0001<<4));
AfdhalAtiffTan 1:77e7cf856fae 16 R5 = (regs[MB_9] & (0x0001<<5));
AfdhalAtiffTan 1:77e7cf856fae 17 R6 = (regs[MB_9] & (0x0001<<6));
AfdhalAtiffTan 1:77e7cf856fae 18 R7 = (regs[MB_9] & (0x0001<<7));
AfdhalAtiffTan 0:74eb078d4846 19 }
AfdhalAtiffTan 0:74eb078d4846 20
AfdhalAtiffTan 0:74eb078d4846 21 int main()
AfdhalAtiffTan 0:74eb078d4846 22 {
AfdhalAtiffTan 1:77e7cf856fae 23 regs[MB_9] = 0xFFFF; //force all relay off
AfdhalAtiffTan 0:74eb078d4846 24
AfdhalAtiffTan 0:74eb078d4846 25 startMillis(); // milliseconds (arduino like)
AfdhalAtiffTan 1:77e7cf856fae 26 mbs.configure(SLAVE, BAUD, PARITY);
AfdhalAtiffTan 1:77e7cf856fae 27
AfdhalAtiffTan 1:77e7cf856fae 28 CO2sensor.baud(9600);
AfdhalAtiffTan 1:77e7cf856fae 29 CO2sensor.printf("\nK 2\r\n"); //set the sensor into polling mode
AfdhalAtiffTan 1:77e7cf856fae 30 //CO2sensor.scanf(" %[^\n]", &co2string); //dummy - blocking call enable later
AfdhalAtiffTan 1:77e7cf856fae 31
AfdhalAtiffTan 1:77e7cf856fae 32 lux_sensor.enablePower();
AfdhalAtiffTan 1:77e7cf856fae 33 window_switch.mode(PullUp);
AfdhalAtiffTan 1:77e7cf856fae 34 shell_switch.mode(PullUp);
AfdhalAtiffTan 1:77e7cf856fae 35 water_temp.set_configuration_bits(10); //9bit of resolution so that it is faster
AfdhalAtiffTan 1:77e7cf856fae 36
AfdhalAtiffTan 1:77e7cf856fae 37 modbus_updater.attach(&update_modbus, 0.1); //visit modbus every 100ms
AfdhalAtiffTan 0:74eb078d4846 38
AfdhalAtiffTan 1:77e7cf856fae 39 while (true) //main thread (updates sensors' status)
AfdhalAtiffTan 1:77e7cf856fae 40 {
AfdhalAtiffTan 1:77e7cf856fae 41 led2 = !led2; //for debug
AfdhalAtiffTan 1:77e7cf856fae 42
AfdhalAtiffTan 1:77e7cf856fae 43 dht22.readData();
AfdhalAtiffTan 1:77e7cf856fae 44 water_temp.convert_temperature(DS1820::all_devices); //Start temperature conversion, wait until ready
AfdhalAtiffTan 1:77e7cf856fae 45 water_temperature = water_temp.temperature('c');
AfdhalAtiffTan 1:77e7cf856fae 46
AfdhalAtiffTan 1:77e7cf856fae 47 CO2sensor.printf("Z\r\n"); //request CO2 reading
AfdhalAtiffTan 1:77e7cf856fae 48 //see: http://stackoverflow.com/questions/16447759/scanf-inside-while-loop-working-only-one-time
AfdhalAtiffTan 1:77e7cf856fae 49 CO2sensor.scanf(" %[^\n]", &co2string); //store it in a buffer (blocking call)
AfdhalAtiffTan 1:77e7cf856fae 50 sscanf(co2string, "%*c %d", &CO2_PPM);
AfdhalAtiffTan 1:77e7cf856fae 51
AfdhalAtiffTan 1:77e7cf856fae 52 regs[MB_0] = CO2_PPM; //air_co2
AfdhalAtiffTan 1:77e7cf856fae 53 regs[MB_1]= (int)100.0*dht22.ReadHumidity(); //air_humidity
AfdhalAtiffTan 1:77e7cf856fae 54 regs[MB_2]= (int)100.0*dht22.ReadTemperature(CELCIUS); //air_temp
AfdhalAtiffTan 1:77e7cf856fae 55 regs[MB_3] = (int)100.0*water_temperature;//water_temp in celcius
AfdhalAtiffTan 1:77e7cf856fae 56 regs[MB_4] = (int)100.0*get_EC(water_temperature); //water_ec
AfdhalAtiffTan 1:77e7cf856fae 57 regs[MB_5] = (int)100.0*get_pH(); //water_ph
AfdhalAtiffTan 1:77e7cf856fae 58 regs[MB_6] = lux_sensor.getLux(); //light_lux
AfdhalAtiffTan 1:77e7cf856fae 59 regs[MB_7]= window_switch.read(); //window_switch
AfdhalAtiffTan 1:77e7cf856fae 60 regs[MB_8] = shell_switch.read(); //shell_switch
AfdhalAtiffTan 1:77e7cf856fae 61 }
AfdhalAtiffTan 1:77e7cf856fae 62 }
AfdhalAtiffTan 0:74eb078d4846 63
AfdhalAtiffTan 1:77e7cf856fae 64 //For water pH level. Taken from http://www.dfrobot.com/wiki/index.php?title=PH_meter(SKU:_SEN0161)
AfdhalAtiffTan 1:77e7cf856fae 65 float get_pH()
AfdhalAtiffTan 1:77e7cf856fae 66 {
AfdhalAtiffTan 1:77e7cf856fae 67 float avgValue_; //Store the average value of the sensor feedback
AfdhalAtiffTan 1:77e7cf856fae 68 float buf_[10],temp_;
AfdhalAtiffTan 1:77e7cf856fae 69 float phValue_;
AfdhalAtiffTan 0:74eb078d4846 70
AfdhalAtiffTan 1:77e7cf856fae 71 for(int i=0;i<10;i++) //Get 10 sample value from the sensor for smooth the value
AfdhalAtiffTan 1:77e7cf856fae 72 {
AfdhalAtiffTan 1:77e7cf856fae 73 buf_[i]=water_pH.read();
AfdhalAtiffTan 1:77e7cf856fae 74 wait_ms(10);
AfdhalAtiffTan 1:77e7cf856fae 75 }
AfdhalAtiffTan 1:77e7cf856fae 76 for(int i=0;i<9;i++) //sort the analog from small to large
AfdhalAtiffTan 1:77e7cf856fae 77 {
AfdhalAtiffTan 1:77e7cf856fae 78 for(int j=i+1;j<10;j++)
AfdhalAtiffTan 1:77e7cf856fae 79 {
AfdhalAtiffTan 1:77e7cf856fae 80 if(buf_[i]>buf_[j])
AfdhalAtiffTan 1:77e7cf856fae 81 {
AfdhalAtiffTan 1:77e7cf856fae 82 temp_=buf_[i];
AfdhalAtiffTan 1:77e7cf856fae 83 buf_[i]=buf_[j];
AfdhalAtiffTan 1:77e7cf856fae 84 buf_[j]=temp_;
AfdhalAtiffTan 1:77e7cf856fae 85 }
AfdhalAtiffTan 1:77e7cf856fae 86 }
AfdhalAtiffTan 1:77e7cf856fae 87 }
AfdhalAtiffTan 1:77e7cf856fae 88 avgValue_ = 0.0f;
AfdhalAtiffTan 1:77e7cf856fae 89 for(int i=2;i<8;i++) //take the average value of 6 center sample
AfdhalAtiffTan 1:77e7cf856fae 90 avgValue_ += buf_[i];
AfdhalAtiffTan 0:74eb078d4846 91
AfdhalAtiffTan 1:77e7cf856fae 92 phValue_= avgValue_*5.0f/6.0f; //convert the analog into millivolt
AfdhalAtiffTan 1:77e7cf856fae 93 return 3.5f*phValue_;
AfdhalAtiffTan 1:77e7cf856fae 94 }
AfdhalAtiffTan 1:77e7cf856fae 95
AfdhalAtiffTan 1:77e7cf856fae 96
AfdhalAtiffTan 1:77e7cf856fae 97 //Water Electrical Conductivity Sensor. Taken from http://www.dfrobot.com/wiki/index.php/Analog_EC_Meter_SKU:DFR0300
AfdhalAtiffTan 1:77e7cf856fae 98 float get_EC(float temperature)
AfdhalAtiffTan 1:77e7cf856fae 99 {
AfdhalAtiffTan 1:77e7cf856fae 100 float avgValue_; //Store the average value of the sensor feedback
AfdhalAtiffTan 1:77e7cf856fae 101 float buf_[10], temp_;
AfdhalAtiffTan 1:77e7cf856fae 102 float ECcurrent_;
AfdhalAtiffTan 1:77e7cf856fae 103
AfdhalAtiffTan 1:77e7cf856fae 104 for(int i=0;i<10;i++) //Get 10 sample value from the sensor for smooth the value
AfdhalAtiffTan 1:77e7cf856fae 105 {
AfdhalAtiffTan 1:77e7cf856fae 106 buf_[i]=water_EC.read();
AfdhalAtiffTan 1:77e7cf856fae 107 wait_ms(10);
AfdhalAtiffTan 1:77e7cf856fae 108 }
AfdhalAtiffTan 1:77e7cf856fae 109
AfdhalAtiffTan 1:77e7cf856fae 110 for(int i=0;i<9;i++) //sort the analog from small to large
AfdhalAtiffTan 1:77e7cf856fae 111 {
AfdhalAtiffTan 1:77e7cf856fae 112 for(int j=i+1;j<10;j++)
AfdhalAtiffTan 1:77e7cf856fae 113 {
AfdhalAtiffTan 1:77e7cf856fae 114 if(buf_[i]>buf_[j])
AfdhalAtiffTan 1:77e7cf856fae 115 {
AfdhalAtiffTan 1:77e7cf856fae 116 temp_=buf_[i];
AfdhalAtiffTan 1:77e7cf856fae 117 buf_[i]=buf_[j];
AfdhalAtiffTan 1:77e7cf856fae 118 buf_[j]=temp_;
AfdhalAtiffTan 1:77e7cf856fae 119 }
AfdhalAtiffTan 0:74eb078d4846 120 }
AfdhalAtiffTan 1:77e7cf856fae 121 }
AfdhalAtiffTan 1:77e7cf856fae 122
AfdhalAtiffTan 1:77e7cf856fae 123 avgValue_ = 0.0f; for(int i=2;i<8;i++) {avgValue_ += buf_[i];} //take the average value of 6 center sample (don't forget to divide!)
AfdhalAtiffTan 1:77e7cf856fae 124
AfdhalAtiffTan 1:77e7cf856fae 125 float averageVoltage = avgValue_ * 5000.0f / 6.0f; //divide by 6 because to get average value
AfdhalAtiffTan 1:77e7cf856fae 126 float TempCoefficient_ = 1.0f + 0.0185f*(temperature - 25.0f); //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.0185*(fTP-25.0));
AfdhalAtiffTan 1:77e7cf856fae 127 float CoefficientVoltage_ = averageVoltage / TempCoefficient_;
AfdhalAtiffTan 1:77e7cf856fae 128
AfdhalAtiffTan 1:77e7cf856fae 129 if (CoefficientVoltage_ <= 448.0f) {ECcurrent_ = 6.84f*CoefficientVoltage_ - 64.320f;} //1ms/cm<EC<=3ms/cm
AfdhalAtiffTan 1:77e7cf856fae 130 else if (CoefficientVoltage_ <= 1457.0f) {ECcurrent_ = 6.98f*CoefficientVoltage_ - 127.00f;} //3ms/cm<EC<=10ms/cm
AfdhalAtiffTan 1:77e7cf856fae 131 else {ECcurrent_ = 5.30f*CoefficientVoltage_ + 2278.0f;} //10ms/cm<EC<20ms/cm
AfdhalAtiffTan 1:77e7cf856fae 132
AfdhalAtiffTan 1:77e7cf856fae 133 return ECcurrent_/=1000.0f; //convert us/cm to ms/cm
AfdhalAtiffTan 0:74eb078d4846 134 }