A modified Arduino library to let mbed boards to behave as modbus slave. See readme. Tested on Nucleo F401RE.
Dependencies: MODSERIAL ModbusSlave232 mbed mbed-rtos millis
Example code for modified arduino modbus library.
main.cpp@1:77e7cf856fae, 2016-07-28 (annotated)
- Committer:
- AfdhalAtiffTan
- Date:
- Thu Jul 28 13:23:10 2016 +0000
- Revision:
- 1:77e7cf856fae
- Parent:
- 0:74eb078d4846
- Child:
- 4:80f3ac4b1c8b
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?
User | Revision | Line number | New 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 | } |