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.
Revision 4:80f3ac4b1c8b, committed 2016-07-28
- Comitter:
- AfdhalAtiffTan
- Date:
- Thu Jul 28 14:59:54 2016 +0000
- Parent:
- 3:4178c25493ba
- Commit message:
- Reverting back to working version.
Changed in this revision
diff -r 4178c25493ba -r 80f3ac4b1c8b DS18B20.lib --- a/DS18B20.lib Thu Jul 28 14:22:56 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -https://developer.mbed.org/users/AfdhalAtiffTan/code/DS18B20/#9ff078416e17
diff -r 4178c25493ba -r 80f3ac4b1c8b ModbusSlave232.lib --- a/ModbusSlave232.lib Thu Jul 28 14:22:56 2016 +0000 +++ b/ModbusSlave232.lib Thu Jul 28 14:59:54 2016 +0000 @@ -1,1 +1,1 @@ -https://developer.mbed.org/users/AfdhalAtiffTan/code/ModbusSlave232/#5318159b5eab +https://developer.mbed.org/users/AfdhalAtiffTan/code/ModbusSlave232/#35fdc7056f66
diff -r 4178c25493ba -r 80f3ac4b1c8b SoftSerial.lib --- a/SoftSerial.lib Thu Jul 28 14:22:56 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/Sissors/code/SoftSerial/#a0029614de72
diff -r 4178c25493ba -r 80f3ac4b1c8b TSL2561_I2C.lib --- a/TSL2561_I2C.lib Thu Jul 28 14:22:56 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/karlmaxwell67/code/TSL2561_I2C/#17fef2caa563
diff -r 4178c25493ba -r 80f3ac4b1c8b includes.h --- a/includes.h Thu Jul 28 14:22:56 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -#include "mbed.h" -#include "DHT.h" //humidity and air temperature -#include "ModbusSlave232.h" //see readme, for modbus -#include "millis.h" //see readme, for modbus -#include "SoftSerial.h" //for co2 sensor -#include "TSL2561_I2C.h" //for light sensor -#include "DS1820.h" //water temp sensor - -#include "pin_definitions.h" //anythign related to physical pins -#include "objects_and_variables.h" //public objs and vars \ No newline at end of file
diff -r 4178c25493ba -r 80f3ac4b1c8b main.cpp --- a/main.cpp Thu Jul 28 14:22:56 2016 +0000 +++ b/main.cpp Thu Jul 28 14:59:54 2016 +0000 @@ -1,134 +1,53 @@ -#include "includes.h" +#include "mbed.h" +#include "rtos.h" +#include "ModbusSlave232.h" //see readme +#include "millis.h" //see readme -float get_EC(float temperature); -float get_pH(); +ModbusSlave232 mbs; // Create new mbs instance -void update_modbus() //check for request and update relays -{ - led1 = !led1; //for debug - mbs.update(regs, MB_REGS); +// Slave registers +enum { + MB_0, // Register 0 + MB_1, // Register 1 + MB_2, // Register 2 + MB_3, // Register 3 + MB_4, // Register 4 + MB_REGS // Dummy register. using 0 offset to keep size of array +}; - R0 = (regs[MB_9] & (0x0001<<0)); - R1 = (regs[MB_9] & (0x0001<<1)); - R2 = (regs[MB_9] & (0x0001<<2)); - R3 = (regs[MB_9] & (0x0001<<3)); - R4 = (regs[MB_9] & (0x0001<<4)); - R5 = (regs[MB_9] & (0x0001<<5)); - R6 = (regs[MB_9] & (0x0001<<6)); - R7 = (regs[MB_9] & (0x0001<<7)); +DigitalOut led1(LED1); + +int regs[MB_REGS]; + +void another_thread(void const *argument) // do stuff +{ + while (true) { + Thread::wait(100); + led1 = !led1; + } } int main() { - regs[MB_9] = 0xFFFF; //force all relay off + const unsigned char SLAVE = 1; + const long BAUD = 9600; + const unsigned PARITY = 'n'; startMillis(); // milliseconds (arduino like) - mbs.configure(SLAVE, BAUD, PARITY); - - CO2sensor.baud(9600); - CO2sensor.printf("\nK 2\r\n"); //set the sensor into polling mode - //CO2sensor.scanf(" %[^\n]", &co2string); //dummy - blocking call enable later - - lux_sensor.enablePower(); - window_switch.mode(PullUp); - shell_switch.mode(PullUp); - water_temp.set_configuration_bits(10); //9bit of resolution so that it is faster - - modbus_updater.attach(&update_modbus, 0.1); //visit modbus every 100ms - while (true) //main thread (updates sensors' status) - { - led2 = !led2; //for debug - - dht22.readData(); - water_temp.convert_temperature(DS1820::all_devices); //Start temperature conversion, wait until ready - water_temperature = water_temp.temperature('c'); - - CO2sensor.printf("Z\r\n"); //request CO2 reading - //see: http://stackoverflow.com/questions/16447759/scanf-inside-while-loop-working-only-one-time - CO2sensor.scanf(" %[^\n]", &co2string); //store it in a buffer (blocking call) - sscanf(co2string, "%*c %d", &CO2_PPM); - - regs[MB_0] = CO2_PPM; //air_co2 - regs[MB_1]= (int)100.0*dht22.ReadHumidity(); //air_humidity - regs[MB_2]= (int)100.0*dht22.ReadTemperature(CELCIUS); //air_temp - regs[MB_3] = (int)100.0*water_temperature;//water_temp in celcius - regs[MB_4] = (int)100.0*get_EC(water_temperature); //water_ec - regs[MB_5] = (int)100.0*get_pH(); //water_ph - regs[MB_6] = lux_sensor.getLux(); //light_lux - regs[MB_7]= window_switch.read(); //window_switch - regs[MB_8] = shell_switch.read(); //shell_switch - } -} + mbs.configure(SLAVE, BAUD, PARITY); -//For water pH level. Taken from http://www.dfrobot.com/wiki/index.php?title=PH_meter(SKU:_SEN0161) -float get_pH() -{ - float avgValue_; //Store the average value of the sensor feedback - float buf_[10],temp_; - float phValue_; + Thread thread(another_thread, NULL, osPriorityNormal, DEFAULT_STACK_SIZE); - for(int i=0;i<10;i++) //Get 10 sample value from the sensor for smooth the value - { - buf_[i]=water_pH.read(); - wait_ms(10); - } - for(int i=0;i<9;i++) //sort the analog from small to large - { - for(int j=i+1;j<10;j++) - { - if(buf_[i]>buf_[j]) - { - temp_=buf_[i]; - buf_[i]=buf_[j]; - buf_[j]=temp_; - } - } - } - avgValue_ = 0.0f; - for(int i=2;i<8;i++) //take the average value of 6 center sample - avgValue_ += buf_[i]; + //test values (updatable) + regs[MB_0] = 0xCA1F; + regs[MB_1] = 0xFACE; + regs[MB_2] = 0xC0DE; + regs[MB_3] = 0x1234; - phValue_= avgValue_*5.0f/6.0f; //convert the analog into millivolt - return 3.5f*phValue_; -} - - -//Water Electrical Conductivity Sensor. Taken from http://www.dfrobot.com/wiki/index.php/Analog_EC_Meter_SKU:DFR0300 -float get_EC(float temperature) -{ - float avgValue_; //Store the average value of the sensor feedback - float buf_[10], temp_; - float ECcurrent_; - - for(int i=0;i<10;i++) //Get 10 sample value from the sensor for smooth the value - { - buf_[i]=water_EC.read(); - wait_ms(10); - } - - for(int i=0;i<9;i++) //sort the analog from small to large - { - for(int j=i+1;j<10;j++) - { - if(buf_[i]>buf_[j]) - { - temp_=buf_[i]; - buf_[i]=buf_[j]; - buf_[j]=temp_; - } + while (true) //main thread + { + mbs.update(regs, MB_REGS); // Pass current register values to mbs + Thread::wait(10); // not too sure if this is needed } - } - - 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!) - - float averageVoltage = avgValue_ * 5000.0f / 6.0f; //divide by 6 because to get average value - float TempCoefficient_ = 1.0f + 0.0185f*(temperature - 25.0f); //temperature compensation formula: fFinalResult(25^C) = fFinalResult(current)/(1.0+0.0185*(fTP-25.0)); - float CoefficientVoltage_ = averageVoltage / TempCoefficient_; - - if (CoefficientVoltage_ <= 448.0f) {ECcurrent_ = 6.84f*CoefficientVoltage_ - 64.320f;} //1ms/cm<EC<=3ms/cm - else if (CoefficientVoltage_ <= 1457.0f) {ECcurrent_ = 6.98f*CoefficientVoltage_ - 127.00f;} //3ms/cm<EC<=10ms/cm - else {ECcurrent_ = 5.30f*CoefficientVoltage_ + 2278.0f;} //10ms/cm<EC<20ms/cm - - return ECcurrent_/=1000.0f; //convert us/cm to ms/cm } \ No newline at end of file
diff -r 4178c25493ba -r 80f3ac4b1c8b mbed-rtos.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Thu Jul 28 14:59:54 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-rtos/#4c105b8d7cae
diff -r 4178c25493ba -r 80f3ac4b1c8b mbed.bld --- a/mbed.bld Thu Jul 28 14:22:56 2016 +0000 +++ b/mbed.bld Thu Jul 28 14:59:54 2016 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/mbed/builds/f9eeca106725 \ No newline at end of file +http://mbed.org/users/mbed_official/code/mbed/builds/6c34061e7c34 \ No newline at end of file
diff -r 4178c25493ba -r 80f3ac4b1c8b objects_and_variables.h --- a/objects_and_variables.h Thu Jul 28 14:22:56 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -//for modbus -const unsigned char SLAVE = 1; -const long BAUD = 9600; -const unsigned PARITY = 'n'; -ModbusSlave232 mbs; // Create new mbs instance - -Ticker modbus_updater; - -// Slave registers -enum { - MB_0, // Register 0 air_co2 - MB_1, // Register 1 air_humidity - MB_2, // Register 2 air_temp - MB_3, // Register 3 water_temp - MB_4, // Register 4 water_ec - MB_5, // Register 5 water_ph - MB_6, // Register 6 light_lux - MB_7, // Register 7 window_switch - MB_8, // Register 8 shell_switch - MB_9, // Register 9 relays - MB_REGS // Dummy register. using 0 offset to keep size of array -}; - -int regs[MB_REGS]; - -char co2string[32]; -int CO2_PPM; -float water_temperature; \ No newline at end of file
diff -r 4178c25493ba -r 80f3ac4b1c8b pin_definitions.h --- a/pin_definitions.h Thu Jul 28 14:22:56 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -//should be compatible with arduino sketch v2 - -//leds for debug purposes -DigitalOut led1(PA_13); -DigitalOut led2(PA_14); -DigitalOut led3(PA_15); - -DHT dht22(D2,DHT22); - -DS1820 water_temp(D3); - -DigitalOut R0(D4); -DigitalOut R1(D5); -DigitalOut R2(D6); -DigitalOut R3(D7); -DigitalOut R4(D8); -DigitalOut R5(D9); -DigitalOut R6(D10); -DigitalOut R7(D11); - -SoftSerial CO2sensor(D13, D12); - -TSL2561_I2C lux_sensor(D14, D15); - -AnalogIn water_pH(A0); -AnalogIn water_EC(A1); - -DigitalIn shell_switch(A2); -DigitalIn window_switch(A3); \ No newline at end of file