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

Files at this revision

API Documentation at this revision

Comitter:
AfdhalAtiffTan
Date:
Thu Jul 28 13:23:10 2016 +0000
Parent:
0:74eb078d4846
Child:
2:9f6a0d8a5c9a
Commit message:
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.

Changed in this revision

DHT.lib Show annotated file Show diff for this revision Revisions of this file
DS18B20.lib Show annotated file Show diff for this revision Revisions of this file
FoodComputerARM-Rev1.lib Show annotated file Show diff for this revision Revisions of this file
ModbusSlave232.lib Show annotated file Show diff for this revision Revisions of this file
SoftSerial.lib Show annotated file Show diff for this revision Revisions of this file
TSL2561_I2C.lib Show annotated file Show diff for this revision Revisions of this file
includes.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-rtos.lib Show diff for this revision Revisions of this file
objects_and_variables.h Show annotated file Show diff for this revision Revisions of this file
pin_definitions.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DHT.lib	Thu Jul 28 13:23:10 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/Wimpie/code/DHT/#9b5b3200688f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DS18B20.lib	Thu Jul 28 13:23:10 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/TuanPM/code/ds18b20_test/#9ff078416e17
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FoodComputerARM-Rev1.lib	Thu Jul 28 13:23:10 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/AfdhalAtiffTan/code/ModbusRTU-RS232/#74eb078d4846
--- a/ModbusSlave232.lib	Fri Jul 22 09:45:54 2016 +0000
+++ b/ModbusSlave232.lib	Thu Jul 28 13:23:10 2016 +0000
@@ -1,1 +1,1 @@
-https://developer.mbed.org/users/AfdhalAtiffTan/code/ModbusSlave232/#35fdc7056f66
+https://developer.mbed.org/users/AfdhalAtiffTan/code/ModbusSlave232/#5318159b5eab
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SoftSerial.lib	Thu Jul 28 13:23:10 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/Sissors/code/SoftSerial/#a0029614de72
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TSL2561_I2C.lib	Thu Jul 28 13:23:10 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/karlmaxwell67/code/TSL2561_I2C/#17fef2caa563
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/includes.h	Thu Jul 28 13:23:10 2016 +0000
@@ -0,0 +1,10 @@
+#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
--- a/main.cpp	Fri Jul 22 09:45:54 2016 +0000
+++ b/main.cpp	Thu Jul 28 13:23:10 2016 +0000
@@ -1,53 +1,134 @@
-#include "mbed.h"
-#include "rtos.h"
-#include "ModbusSlave232.h" //see readme
-#include "millis.h" //see readme
+#include "includes.h"
 
-ModbusSlave232 mbs; // Create new mbs instance
+float get_EC(float temperature);
+float get_pH();
 
-// 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
-};
+void update_modbus() //check for request and update relays
+{          
+        led1 = !led1;  //for debug 
+        mbs.update(regs, MB_REGS);
 
-DigitalOut led1(LED1);
-
-int regs[MB_REGS];
-
-void another_thread(void const *argument) // do stuff
-{
-    while (true) {
-        Thread::wait(100); 
-        led1 = !led1;
-    }
+        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));
 }
 
 int main()
 {
-    const unsigned char SLAVE = 1;
-    const long BAUD = 9600;            
-    const unsigned PARITY = 'n';
+    regs[MB_9] = 0xFFFF; //force all relay off       
     
     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
 
-    mbs.configure(SLAVE, BAUD, PARITY);
+    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                      
+    }
+}
 
-    Thread thread(another_thread, NULL, osPriorityNormal, DEFAULT_STACK_SIZE);
+//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_;
     
-    //test values (updatable)  
-    regs[MB_0] = 0xCA1F;
-    regs[MB_1] = 0xFACE;
-    regs[MB_2] = 0xC0DE;
-    regs[MB_3] = 0x1234;
+  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];
     
-    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
+  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_;
+      }
     }
+  }
+  
+  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
--- a/mbed-rtos.lib	Fri Jul 22 09:45:54 2016 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/mbed_official/code/mbed-rtos/#4c105b8d7cae
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/objects_and_variables.h	Thu Jul 28 13:23:10 2016 +0000
@@ -0,0 +1,28 @@
+//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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pin_definitions.h	Thu Jul 28 13:23:10 2016 +0000
@@ -0,0 +1,29 @@
+//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