SMALL - espritmodel.com SMALL - Telemetry SMALL - Radio
Reply
Thread Tools
Old Feb 15, 2013, 11:13 PM
Registered User
Deckie's Avatar
Australia, WA, Garden Island
Joined Nov 2010
465 Posts
Idea
Arduino based anti thermal/flood system (Ship-Tect).

********** I have gone through and made all programming comments (denoted by //) bold and italicized for easy recognition . This will be done with every posted code update from now on

A while ago, I started a thread on an Arduino based ship safety system (encompassing thermal and flood control).

The link to the original thread is here:
http://www.rcgroups.com/forums/showt...ighlight=decki

This thread will provide a continuation of that project within the Homebrew Hacks section (the most appropriate location). Below is a diagram of the original vision, and the latest version of the code, SHIP-TECT 0.3b Mega.

Current development is focusing on the addition of a menu allowing change of basic settings, calbration, and the ability to enable/disable the different functions, as well as the ability to have an Arduino Uno connected via I2C for water ballast control in multiple tanks. Basic Slave sender code has been implemented and some keypad control code is implemented. As you can see, the concept is ever-evolving

Links to the major components used in the development hardware:
Freetronics Ethermega 2560 (100% Arduino Mega compatible

Freetronics Arduino Eleven 100% Uno compatible

Freetronics LCD and Keypad Shield

Freetronics 8 Channel Relay Driver Shield

Please find the Main Mega code below, and the Slave Arduino Uno code below that:


Main Arduino Mega code:
************************************************** ******

Code:
  // SHIP-TECT Emergency Management v0.3bMega. By Michael Ryan Judge, Licensed under Creative Commons, 2013 for Arduino Uno. 
//Pins used by LCD & Keypad Shield:  
  
   // A0: Buttons, analog input from voltage ladder
  //  D4: LCD bit 4
  //  D5: LCD bit 5
   // D6: LCD bit 6
 //   D7: LCD bit 7
   // D8: LCD RS
  //  D9: LCD E
 //   D3: LCD Backlight (high = on, also has pullup high so default is on)
  
  //ADC voltages for the 5 buttons on analog input pin A0:
  
   // RIGHT:  0.00V :   0 @ 8bit ;   0 @ 10 bit
  //  UP:     0.71V :  36 @ 8bit ; 145 @ 10 bit
 //   DOWN:   1.61V :  82 @ 8bit ; 329 @ 10 bit
  //  LEFT:   2.47V : 126 @ 8bit ; 505 @ 10 bit
   // SELECT: 3.62V : 185 @ 8bit ; 741 @ 10 bit

 // Can include  temperature monitoring for up to 3 main engines realistically (just cut, paste and rename values for each motor) thermal cut-out of the main engine (and any other additional main engines or motors), monitoring of the water cooling (keel cooling in this version) system efficiency. Working Relay support is for the
//Freetronics 8 channel relayshield or "Relay8", which the code has been test with, on a Freetronics Arduino Mega with Freetronics 16x2 LCD and Keypad shield, and Relay 8 shield. Will leave all systems running in the event
//of an error condition, and will sound the horn 5 times and then once every two seconds while printing sensor data, then repeat. 
#include <LiquidCrystal.h>   // include LCD library
#include <Wire.h>
#define I2C_ADDR  0x20  // 0x20 is the address with all jumpers removed
#define LCD_BACKLIGHT_PIN         3  // D3 controls LCD backlight

// ADC readings expected for the 5 buttons on the ADC input
#define RIGHT_10BIT_ADC           0  // right
#define UP_10BIT_ADC            145  // up
#define DOWN_10BIT_ADC          329  // down
#define LEFT_10BIT_ADC          505  // left
#define SELECT_10BIT_ADC        741  // right
#define BUTTONHYSTERESIS         10  // hysteresis for valid button sensing window
//return values for ReadButtons()
#define BUTTON_NONE               0  // 
#define BUTTON_RIGHT              1  // 
#define BUTTON_UP                 2  // 
#define BUTTON_DOWN               3  // 
#define BUTTON_LEFT               4  // 
#define BUTTON_SELECT             5  // 

/*--------------------------------------------------------------------------------------
  Variables
--------------------------------------------------------------------------------------*/
byte buttonJustPressed  = false;          //this will be true after a ReadButtons() call if triggered 
byte buttonJustReleased = false;          //this will be true after a ReadButtons() call if triggered 
byte buttonWas          = BUTTON_NONE;    //used by ReadButtons() for detection of button events 
  //Set up liquid crystal display. 
LiquidCrystal lcd( 8, 9, 4, 5, 6, 7 );    //Pins for the freetronics 16x2 LCD shield. LCD: ( RS, E, LCD-D4, LCD-D5, LCD-D6, LCD-D7 ) 

void setup(){

  
  //start serial connection 
Serial.begin(14400);
  //Wake up the I2C BUS and assign Bank a as relay outputs. 
Wire.begin(); // Wake up I2C bus
 // Set I/O bank A to outputs
  Wire.beginTransmission(I2C_ADDR);
  Wire.write(0x00); // IODIRA register
  Wire.write(0x00); // Set all of bank A to outputs
  Wire.endTransmission();
 
//configure Flood detection pins as inputs and enable the internal pull-up resistors for each 
//HIGHFLOOD 
pinMode(33, INPUT_PULLUP);
//MIDFLOOD
pinMode(41, INPUT_PULLUP);
//LOWFLOOD
pinMode(47, INPUT_PULLUP);


 
//MOTOR TEMPERATURE SENSORs INPUTs 
pinMode(A12, INPUT); //INPUT FOR MAIN ENGINE

pinMode(A13, INPUT); //INPUT FOR WATER PRIOR TO ESC COOLER

pinMode(A14, INPUT); //INPUT FOR EXTERNAL WATER TEMPERATURE

pinMode(A15, INPUT);//INPUT FOR WATER AFTER ESC COOLER


 
//CURRENT FEED FOR WATERLEVEL SENSORS 
//All output pin modes ommitted as relay board now does the work. 

//Initialise and turn on the backlight. 
digitalWrite( LCD_BACKLIGHT_PIN, HIGH );    //backlight control pin D3 is high (on) 
   pinMode( LCD_BACKLIGHT_PIN, OUTPUT ); 
  //Initialise the LCD display and format character usage. 
lcd.begin( 16, 2 );
  //Boot-up. Show software name, version and copyright. 
lcd.setCursor( 0, 0 );
lcd.print( "SHIP-TECT 0.3bMega" );
lcd.setCursor( 0, 1 );
lcd.print( "M.R.JUDGE 2013" );
Serial.println("SHIP-TECT v0.3bMega, Creative Commons Michael R. Judge 2013");
delay(2000);
  //Initialisation screen, not really required, but gives a more professional look to the system. 6 Cycles of the backlight  
lcd.setCursor( 0, 0 );
lcd.print( "INITIALISING........");
Serial.println("INITIALISING.......");
lcd.setCursor( 0, 1);
lcd.print( "                      ");
  //Pulse the LED Backlight on and off during initialisation. 
    
        digitalWrite( LCD_BACKLIGHT_PIN, LOW );
        delay( 500 );
           
        digitalWrite( LCD_BACKLIGHT_PIN, HIGH );    //leave the backlight on at exit 
        Wire.beginTransmission(I2C_ADDR);   // Test the relays during initialisation 
 Wire.write(0x12); // Select bank A
 Wire.write(15); // Send value to bank A
 Wire.endTransmission(); 
        delay( 500 );
       
          digitalWrite( LCD_BACKLIGHT_PIN, LOW );
        delay( 500 );
       
        digitalWrite( LCD_BACKLIGHT_PIN, HIGH );  
        delay( 500 );
       
        digitalWrite( LCD_BACKLIGHT_PIN, LOW );
        delay( 500 );

        digitalWrite( LCD_BACKLIGHT_PIN, HIGH );   
        delay( 500 );
            
        digitalWrite( LCD_BACKLIGHT_PIN, LOW );
        delay( 500 );
        
        digitalWrite( LCD_BACKLIGHT_PIN, HIGH );   
        delay( 500 );
 
        digitalWrite( LCD_BACKLIGHT_PIN, LOW );
        delay( 500 );
           
        digitalWrite( LCD_BACKLIGHT_PIN, HIGH );  
        delay( 500 );
 
  // Power on RC gear (normal operating state). 
       Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12);   // Select bank A 
 Wire.write(8); // Send value to bank A
 Wire.endTransmission(); 

}
  // Main control loop. 
void loop(){
  // Clear the LCD screen at each run of the loop with BLANKS.  
  lcd.setCursor( 0, 1);
  lcd.print( "                ");
[/i] [/b] //Print some blank lines for some blank space on the serial monitor to denote space between each run of the loop [/i] [/b]
Serial.println(" ");
Serial.println(" ");
Serial.println(" ");
Serial.println(" ");
Serial.println(" ");
Serial.println(" ");
Serial.println(" ");
Serial.println(" ");
Serial.println(" ");

 // Main loop. Checks the individual pins as to whether HIGH (dry) or LOW (wet) and takes appropriate action by disabling motors and/or starting pumps depending
//on the situation, such as motor overheating or flooding.
Serial.println("Analysing.....");
lcd.setCursor( 0, 0 );
lcd.print( "Analysing.............." );


 //Check for 1st stage flooding

int lowfloodVal = digitalRead(47);
Serial.println(lowfloodVal); Serial.print(" lowflood");
delay(500);

 //Check for 2nd stage flooding.

int midfloodVal = digitalRead(41);
Serial.println(midfloodVal); Serial.print(" midflood");

 //Check for high level flooding
delay(500);

int highfloodVal = digitalRead(33);
Serial.println(highfloodVal); Serial.print(" highflood");

 //read slave arduino for bow flooding status
Wire.requestFrom(2, 1);    // request 6 bytes from slave device #2

  
   int bowfloodVal = Wire.read(); // receive a byte as character
    Serial.println( "bow flooding level is " ); Serial.print(bowfloodVal);         // print the character
 
  delay(100);

 //Read  main motortemp
int port = analogRead(A12);
float voltageport = port * 5.0;
 voltageport /= 1024.0; 
float motortemp = (voltageport - 0.5) * 100;
Serial.println(" Main Engine temperature is (in Celcius) "); Serial.print(motortemp);
Serial.println(" ");
 
 //Read intake water temp
int intake = analogRead(A13);
float voltageintake = intake * 5.0;
 voltageintake /= 1024.0; 
float intaketemp = (voltageintake - 0.5) * 100;
Serial.println(" Intake water temperature is in (Celcius) "); Serial.print(intaketemp);
Serial.println(" ");
 
  //Read external water temp 
int external = analogRead(A14);
float voltageexternal = external * 5.0;
 voltageexternal /= 1024.0; 
float externaltemp = (voltageexternal - 0.5) * 100;
Serial.println(" External water temperature is (Celcius) "); Serial.print(externaltemp);
Serial.println(" ");

  //Read ESC after-cooler water temp 
int esc = analogRead(A15);
float voltageexhaust = esc * 5.0;
 voltageexhaust /= 1024.0; 
float exhausttemp = (voltageexhaust - 0.5) * 100;
Serial.println(" Exhaust water temperature is (Celcius) "); Serial.print(externaltemp);
Serial.println(" ");
 
 //Indicates all sensors successfully read on the LCD and Serial monitor. 
lcd.setCursor( 0, 0);
lcd.print( "......DONE......" );
Serial.println("......DONE......");
delay(500);

 //Calculates and Indicates ESC cooler efficiency
int escefficiency = (intaketemp / exhausttemp) * 100;

lcd.setCursor( 0, 1);
lcd.print( "ESC Eff: " ); lcd.print(escefficiency);
Serial.println("Efficiency of the ESC Cooler is "); Serial.print(escefficiency);
Serial.println(" ");
delay(500);
lcd.setCursor( 0, 1);
lcd.print( "                             ");


  //Calculates and Indicates keel cooler efficiency
int keelefficiency = (externaltemp / intaketemp) * 100;

lcd.setCursor( 0, 1);
lcd.print( "Cooler Eff: " ); lcd.print(keelefficiency);
Serial.println("Efficiency of the Keel Cooler is "); Serial.print(keelefficiency);
Serial.println(" ");
delay(500);
lcd.setCursor( 0, 1);
lcd.print( "                             ");
 
//Calculates and Indicates overall water cooling system efficiency
int totalefficiency = (escefficiency / keelefficiency) * 100;

lcd.setCursor( 0, 1);
lcd.print( "Total Eff: " ); lcd.print(totalefficiency);
Serial.println("Total Efficiency of the  Cooler is "); Serial.print(totalefficiency);
Serial.println(" ");
delay(500);
lcd.setCursor( 0, 1);
lcd.print( "                             ");




 
 
//If high level flooding is detected, will enable pumping, power isolation to motor and all RC gear, and ballast pump-out. From this point on it is a case of evaluating each if section of code, till we find one where all sensor values match the requirements, executing that code, then starting the main loop over again 


if (lowfloodVal == LOW && midfloodVal == LOW && highfloodVal == LOW && bowfloodVal == 3) {
 
  Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(7); // Send value to bank A
 Wire.endTransmission(); 
Serial.println("Stage 3 flood");
lcd.setCursor( 0, 1);
lcd.print( "Stage 3 flood");
delay(750);
lcd.setCursor( 0, 1);
lcd.print( "All pumps on........");
Serial.println("All pumps ON........");
delay(750);
lcd.setCursor( 0, 1);
lcd.print( "ALL DISABLED.....");
Serial.println("ALL GEAR DISABLED.....");
delay(750);


} 
else {
 // If 2nd stage flooding detected, will enable pumping and power isolation.
 if (lowfloodVal == LOW && midfloodVal == LOW && highfloodVal == HIGH && bowfloodVal == 2) {
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(11); // Send value to bank A
 Wire.endTransmission(); 
Serial.println("Stage 2 flood");
lcd.setCursor( 0, 1);
lcd.print( "Stage 2 flood");
delay(750);
lcd.setCursor( 0, 1);
lcd.print( "E. Pump ON.....");
Serial.println("E. Pump ON......");
delay(750);
lcd.setCursor( 0, 1);
lcd.print( "MOTORS DISABLED.....");
Serial.println("MOTORS DISABLED.....");
delay(750);
digitalWrite(31, LOW);
digitalWrite(41, LOW);
digitalWrite(47, LOW);
}
else {
 // If 1st stage flooding detected, will enable pumping.  
if (lowfloodVal == LOW && midfloodVal == HIGH && highfloodVal == HIGH && bowfloodVal == 1) {
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(10); // Send value to bank A
 Wire.endTransmission(); 
Serial.println("Stage 1 flood");
lcd.setCursor( 0, 1);
lcd.print( "Stage 1 flood");
delay(750);
lcd.setCursor( 0, 1);
lcd.print( "E. Pump is ON.....");
Serial.println("E. Pump is ON......");
delay(750);
lcd.setCursor( 0, 1);
lcd.print( "MOTORS ENABLED.....");
Serial.println("MOTORS ENABLED.....");                
delay(750);

}

else {
 //If no flooding detected, but main motor overheats, ESC's OFF, all pumps off, valves closed, and all major electronics isolated.)  
if (lowfloodVal == HIGH && midfloodVal == HIGH && highfloodVal == HIGH && bowfloodVal == 0 && motortemp > 0 && motortemp >= 60 && motortemp < 130 && totalefficiency > 0 && totalefficiency >= 60 && totalefficiency < 101 ) {
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(9); // Send value to bank A
 Wire.endTransmission(); 
Serial.println("Nil flooding...");
lcd.setCursor( 0, 1);
lcd.print( "Nil flooding...");
delay(750);
Serial.println("E. Pump is OFF......");
lcd.setCursor( 0, 1);
lcd.print( "E. Pump is OFF......");
delay(750);
Serial.println("MOTOR OVERHEATED....."); Serial.print(motortemp); 
lcd.setCursor( 0, 1);
lcd.print( "MOTOR TEMP   "); lcd.print(motortemp);
delay(10000);

}

else {
 //If no flooding detected, but ESC overheats, ESC's OFF, all pumps off, valves closed, and all major electronics isolated.)  
if (lowfloodVal ==HIGH && midfloodVal == HIGH && highfloodVal == HIGH && bowfloodVal == 0 && motortemp > 0 && motortemp <= 59 && motortemp < 130 && totalefficiency > 0 && totalefficiency <= 59 && totalefficiency < 101  ) {
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(9); // Send value to bank A
 Wire.endTransmission(); 
Serial.println("Nil flooding...");
lcd.setCursor( 0, 1);
lcd.print( "Nil flooding...");
delay(750);
Serial.println("E. Pump is OFF......");
lcd.setCursor( 0, 1);
lcd.print( "E. Pump is OFF......");
delay(750);
Serial.println("ESC OVERHEATED....."); Serial.print(totalefficiency);
lcd.setCursor( 0, 1);
lcd.print( "H/E EFF %   "); lcd.print(totalefficiency);
delay(10000);

}

else {
 //If no flooding detected, leave motors running and all pumps off, valves closed.)  
if (lowfloodVal == HIGH && midfloodVal == HIGH && highfloodVal == HIGH && bowfloodVal == 0 && motortemp >= 1 && motortemp <= 59 && totalefficiency > 0 && totalefficiency >= 60 && totalefficiency < 101 ) {
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission(); 
Serial.println("Nil flooding...");
lcd.setCursor( 0, 1);
lcd.print( "Nil flooding...");
delay(750);
Serial.println("Pump is OFF......");
lcd.setCursor( 0, 1);
lcd.print( "Pump is OFF......");
delay(750);
Serial.println("Motor NORMAL-ON.....");
lcd.setCursor( 0, 1);
lcd.print( "Motor NORMAL-ON.....");
delay(750);

}

else {
   //IF ANY anomalous sensor states detected, return everything to normal operation state, note that pumps are disabled until the problem is found. Print the sensor statuses. Blink the masthead warning light. 
   Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(24); // Send value to bank A
 Wire.endTransmission();  
 delay(250);
    Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission();  
 delay(250);
    Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(24); // Send value to bank A
 Wire.endTransmission();  
 delay(250);
    Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission();  
 delay(250);
    Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(24); // Send value to bank A
 Wire.endTransmission();  
 delay(250);
    Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission();  
 delay(250);
    Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(24); // Send value to bank A
 Wire.endTransmission();  
 delay(250);
    Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission();  
 delay(250);
    Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(24); // Send value to bank A
 Wire.endTransmission();  
 delay(250);
    Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission();  
 delay(250);
 
 
Serial.println("Error with sensors. Pumps on. All rc gear and motor off!");
Serial.println( "Main engine temperature:   " ); 
Serial.println(motortemp);
Serial.println( "Cooling water intake temperature:   " ); 
Serial.println(intaketemp);
Serial.println( "External water temperature:   " ); 
Serial.println(externaltemp);
Serial.println( "ESC exhaust water temperature:   " ); 
Serial.println(exhausttemp);
Serial.println( "Total cooling efficiency:   " ); 
Serial.println(totalefficiency);
Serial.println( "Low water level sensor status:   " ); 
Serial.println(lowfloodVal);
Serial.println( "Mid water level sensor status:   " ); 
Serial.println(midfloodVal);
Serial.println( "High water level sensor status:   " ); 
Serial.println(highfloodVal);
}
 //Print Warning on the lCD
 {  Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(24); // Send value to bank A
 Wire.endTransmission();  
lcd.setCursor( 0, 0);
lcd.print( " SENSOR/s ERROR......" );
//Print Motor temperature
lcd.setCursor( 0, 1);
lcd.print( "Motor C*: " ); 
lcd.setCursor( 11, 1);
lcd.print(motortemp);
delay(2000);
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission();  
 
  //Print ESC heat exchanger intake cooling water temperature, and then each sensor value thereafter, one per second 
lcd.setCursor( 0, 1);
lcd.print( "                     " );
lcd.setCursor( 0, 1);
lcd.print( " Intake C*: " );
lcd.setCursor( 12, 1);
lcd.print(intaketemp);
delay(2000);
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(24); // Send value to bank A
 Wire.endTransmission();  
  //Print external water temperature 
lcd.setCursor( 0, 1);
lcd.print( "                     " );
lcd.setCursor( 0, 1);
lcd.print( " Extern. C*%: " ); 
lcd.setCursor( 14, 1);
lcd.print(externaltemp);
delay(2000);
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission();  
  //Print exhaust water temperature 
lcd.setCursor( 0, 1);
lcd.print( "                     " );
lcd.setCursor( 0, 1);
lcd.print( " Exhaus. C*%: " ); 
lcd.setCursor( 14, 1);
lcd.print(exhausttemp);
delay(2000);
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(24); // Send value to bank A
 Wire.endTransmission();  
  //Print cooling loop efficiency 
lcd.setCursor( 0, 1);
lcd.print( "                     " );
lcd.setCursor( 0, 1);
lcd.print( " Total EFF%: " ); 
lcd.setCursor( 12, 1);
lcd.print(totalefficiency);
delay(2000);
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission();  
  //Print Low water level sensor HIGH 1 (no water detected)/LOW 0 (Detected) status 
lcd.setCursor( 0, 1);
lcd.print( "                     " );
lcd.setCursor( 0, 1);
lcd.print( " LOW Sens.: " );
lcd.setCursor( 12, 1);
lcd.print(lowfloodVal);
delay(2000);
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(24); // Send value to bank A
 Wire.endTransmission();  
  //Print Mid water level sensor HIGH 1 (no water detected)/LOW 0 (Detected) status 
lcd.setCursor( 0, 1);
lcd.print( "                     " );
lcd.setCursor( 0, 1);
lcd.print( " MID Sens.: " ); 
lcd.setCursor( 12, 1);
lcd.print(midfloodVal);
delay(2000);
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission();  
  //Print High water level sensor HIGH 1 (no water detected)/LOW 0 (Detected) status 
lcd.setCursor( 0, 1);
lcd.print( "                     " );
lcd.setCursor( 0, 1);
lcd.print( " HIGH Sens.: " );
lcd.setCursor( 13, 1);
lcd.print(highfloodVal);
delay(2000);
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission();  
  //Print Bow flooding status 
lcd.setCursor( 0, 1);
lcd.print( "                     " );
lcd.setCursor( 0, 1);
lcd.print( " BOW. Sens.: " );
lcd.setCursor( 13, 1);
lcd.print(bowfloodVal);
delay(2000);
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission();  
 


  //END OF LOOP 





















 // MOTOR TEMPERATURE CONTROL ACTIVE IN THIS VERSION 
 }

}
}

}
}
}

}
 //END OF ARDUINO MEGA SHIP-TECT 0.3b CODE!!!!!!!! 












************************************************** ************************************************** ************************************************** ************************************************** *************************
************************************************** ************************************************** ************************************************** ************************************************** *************************

Code:
 //SLAVE UNO CODE (work in progress. Reads water level sensors and provides a single byte status to the Mega via I2C)

// Arduino Uno Wire Slave Sender for ShipTect 0.3b
// by Michael Judge 2013.
//Borrows some I2C sender code from the work of Nicholas Zambetti as it works perfectly :).
// <http://www.zambetti.com>

// This program at the current version, detects the water level from three sensors, low, mid and High, the same 
// as the ship-tect mega version, and provides single byte value to the mega via
// I2C to indicate water level in the bow of the ship. This will be expanded
// to ballast tank water levels for multiple tanks in future versions.  


#include <Wire.h>

void setup()
{
   Serial.begin(14400);
  Wire.begin(2);                 // join i2c bus with address #2 
  Wire.onRequest (floodCheck); // register event
 //define flood detection pins 
  //configure pin2 as an input and enable the internal pull-up resistor 
//HIGHFLOOD 
pinMode(3, INPUT_PULLUP);
//MIDFLOOD
pinMode(2, INPUT_PULLUP);
//LOWFLOOD
pinMode(1, INPUT_PULLUP);
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
}


void loop()
{

  delay(100);
}

 // function that executes whenever data is requested by master
// this function is registered as an event, see setup() 
void floodCheck()
{

   
    //Check sensors for flooding.
 //Check for low-level flooding 
  int lowfloodVal = digitalRead(1);
Serial.println(lowfloodVal); Serial.print(" lowflood");

   //Check for 2nd stage flooding. 

int midfloodVal = digitalRead(2);
Serial.println(midfloodVal); Serial.print(" midflood");
  //Check for high level flooding 

int highfloodVal = digitalRead(3);
Serial.println(highfloodVal); Serial.print(" highflood");


  // If third stage flooding detected, send the high flood value 3 
if (lowfloodVal == LOW && midfloodVal == LOW && highfloodVal == LOW) {
 Wire.write(3); // respond with message of 1 bytes
                       // as expected by master
Serial.println( "High flood sent" );
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
delay(100);
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
delay(100);
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
} 
else {

  // If 2nd stage flooding detected, send the mid flood value 2. 
 if (lowfloodVal == LOW && midfloodVal == LOW && highfloodVal == HIGH) {
Wire.write(2); // respond with message of 1 bytes
                       // as expected by master
Serial.println( "Medium flood sent" );
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
delay(100);
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
delay(100);

}
else {

  // If 1st stage flooding detected, send the low flood value 1.   
if (lowfloodVal == LOW && midfloodVal == HIGH && highfloodVal == HIGH) {
Wire.write(1); // respond with message of 1 bytes
                       // as expected by master
Serial.println( "Low flood sent" );
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
delay(100);

}

else {
   //If no flooding detected. send the no flood value 0.   
if (lowfloodVal == HIGH && midfloodVal == HIGH && highfloodVal == HIGH  ) {
Wire.write(0); // respond with message of 1 bytes
                       // as expected by master
Serial.println( "None flood sent" );
digitalWrite(13, HIGH);
delay(500);
digitalWrite(13, LOW);
delay(100);
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);


}

else {
  //If ERROR detected with sensor reads. Send the value 6, recognised by the mega as an error
// and flash the onboard D13 LED to indicate error. 
Wire.write(6); // respond with message of 1 bytes
                       // as expected by master
Serial.println( "Error detected. error sent" );
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
delay(100);
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
delay(100);
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
delay(100);
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
delay(100);
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
delay(100);
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
delay(100);
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
}
}
}
}
}
Deckie is offline Find More Posts by Deckie
Last edited by Deckie; Feb 28, 2013 at 03:08 AM.
Reply With Quote
Sign up now
to remove ads between posts
Old Feb 15, 2013, 11:25 PM
Registered User
Ariel WA
Joined Apr 2005
344 Posts
That just makes my head hurt. I wish I understood what I am looking at better.I hope as time goes along with this forum that I will start to under stand programing.

Dave
Phoneman2005 is offline Find More Posts by Phoneman2005
Reply With Quote
Old Feb 15, 2013, 11:29 PM
Registered User
Deckie's Avatar
Australia, WA, Garden Island
Joined Nov 2010
465 Posts
That's a signal for me to go through and highlight the comments explaining functions
Deckie is offline Find More Posts by Deckie
Reply With Quote
Old Feb 16, 2013, 01:31 AM
Spreckels Lake, GGP, SF, CA
craig_c's Avatar
USA, CA, San Francisco
Joined Apr 2007
3,658 Posts
Quote:
Originally Posted by Phoneman2005 View Post
That just makes my head hurt. I wish I understood what I am looking at better.I hope as time goes along with this forum that I will start to under stand programing.
Hey Dave, don' worry man!! Me too, Bro, me too!

Just take it in tiny, tiny bites - a subroutine at a time, and soon it'll start to fall together.

Also, you really need to get hands on for this stuff. Get an (in this case) an Arduino and a copy of Getting Started with Arduino and

Programming Arduino Getting Started with Sketches
craig_c is offline Find More Posts by craig_c
RCG Plus Member
Old Feb 16, 2013, 08:32 AM
Registered User
Ariel WA
Joined Apr 2005
344 Posts
I have an arduino book and bread board kit. Now I just need to find the time to learn it.

Dave
Phoneman2005 is offline Find More Posts by Phoneman2005
Reply With Quote
Old Feb 27, 2013, 04:04 AM
Registered User
Deckie's Avatar
Australia, WA, Garden Island
Joined Nov 2010
465 Posts
Stand-by for a re-write incorporating breaks and switches, in a an effort to shorten the whole program.

I might be a little while as uni has started and work days getting longer with certain vessels in critical phases of their schedules, fun fun fun
Deckie is offline Find More Posts by Deckie
Reply With Quote
Old Feb 27, 2013, 12:14 PM
Registered User
Joined Dec 2012
117 Posts
FYI, your LCD keypad shield link is wrong... it points to the Arduino UNO clone.
Skystream is offline Find More Posts by Skystream
Reply With Quote
Old Feb 28, 2013, 03:08 AM
Registered User
Deckie's Avatar
Australia, WA, Garden Island
Joined Nov 2010
465 Posts
Quote:
Originally Posted by Skystream View Post
FYI, your LCD keypad shield link is wrong... it points to the Arduino UNO clone.
Fixed
Deckie is offline Find More Posts by Deckie
Reply With Quote
Old Apr 07, 2013, 05:33 AM
Registered User
Deckie's Avatar
Australia, WA, Garden Island
Joined Nov 2010
465 Posts
Haven't had a lot of time for this in the last few weeks, but here's Ship-Tect 0.4Mega, now with fully functioning SD Card data logging. A sample of a test logfile is in the second code box. No date stamp because I don't have a real-time clock, but you do get a time stamp (in seconds) with every run of the main loop. It also wipes the file every time Ship-Tect is freshly booted, taking care of the work for you, just don't forget to remove the card and copy the data off after every run if you want to save it (before powering up again).

Code:
// SHIP-TECT Emergency Management v0.4Mega. By Michael Ryan Judge, Licensed under Creative Commons, 2013 for Arduino Uno. 
//Now includes data logging for use with Freetronics Ethermega or any mega with an SD card shield (remember to change the pin!).
//Pins used by LCD & Keypad Shield:
  
   // A0: Buttons, analog input from voltage ladder
  //  D4: LCD bit 4
  //  D5: LCD bit 5
   // D6: LCD bit 6
 //   D7: LCD bit 7
   // D8: LCD RS
  //  D9: LCD E
 //   D3: LCD Backlight (high = on, also has pullup high so default is on)
  
  //ADC voltages for the 5 buttons on analog input pin A0:
  
   // RIGHT:  0.00V :   0 @ 8bit ;   0 @ 10 bit
  //  UP:     0.71V :  36 @ 8bit ; 145 @ 10 bit
 //   DOWN:   1.61V :  82 @ 8bit ; 329 @ 10 bit
  //  LEFT:   2.47V : 126 @ 8bit ; 505 @ 10 bit
   // SELECT: 3.62V : 185 @ 8bit ; 741 @ 10 bit

// Now includes temperature monitoring for 3 main engines, thermal cut-out of the main engine, monitoring of the water cooling (keel cooling in this version) system efficiency. Working Relay support is for the
//Freetronics 8 channel relayshield or "Relay8", which the code has been test with, on a Freetronics Arduino Mega with Freetronics 16x2 LCD and Keypad shield, and Relay 8 shield. Will leave all systems running in the event
//of an error condition, and will sound the horn 5 times and then once every two seconds while printing sensor data, then repeat.
#include <LiquidCrystal.h>   // include LCD library
#include <Wire.h>
#include <SD.h>

// On the Ethernet Shield, CS is pin 4. Note that even if it's not
// used as the CS pin, the hardware CS pin (10 on most Arduino boards,
// 53 on the Mega) must be left as an output or the SD library
// functions will not work.
const int chipSelect = 53;

#define I2C_ADDR  0x20  // 0x20 is the address with all jumpers removed
#define LCD_BACKLIGHT_PIN         3  // D3 controls LCD backlight

// ADC readings expected for the 5 buttons on the ADC input
#define RIGHT_10BIT_ADC           0  // right
#define UP_10BIT_ADC            145  // up
#define DOWN_10BIT_ADC          329  // down
#define LEFT_10BIT_ADC          505  // left
#define SELECT_10BIT_ADC        741  // right
#define BUTTONHYSTERESIS         10  // hysteresis for valid button sensing window
//return values for ReadButtons()
#define BUTTON_NONE               0  // 
#define BUTTON_RIGHT              1  // 
#define BUTTON_UP                 2  // 
#define BUTTON_DOWN               3  // 
#define BUTTON_LEFT               4  // 
#define BUTTON_SELECT             5  // 

/*--------------------------------------------------------------------------------------
  Variables
--------------------------------------------------------------------------------------*/
byte buttonJustPressed  = false;         //this will be true after a ReadButtons() call if triggered
byte buttonJustReleased = false;         //this will be true after a ReadButtons() call if triggered
byte buttonWas          = BUTTON_NONE;   //used by ReadButtons() for detection of button events
unsigned long time;
//Set up liquid crystal display.
LiquidCrystal lcd( 8, 9, 4, 5, 6, 7 );   //Pins for the freetronics 16x2 LCD shield. LCD: ( RS, E, LCD-D4, LCD-D5, LCD-D6, LCD-D7 )

void setup(){
lcd.begin( 16, 2 );
  lcd.setCursor( 0, 0 );
lcd.print( "Starting Serial........");
lcd.setCursor( 0, 1);
lcd.print( "                      ");
  Serial.println("Starting Serial.....");
//start serial connection
Serial.begin(14400);
delay(1000);
//Wake up the I2C BUS and assign Bank a as relay outputs.
Wire.begin(); // Wake up I2C bus
 // Set I/O bank A to outputs
  Wire.beginTransmission(I2C_ADDR);
  Wire.write(0x00); // IODIRA register
  Wire.write(0x00); // Set all of bank A to outputs
  Wire.endTransmission();
lcd.setCursor( 0, 0 );
lcd.print( "Relays.................");
lcd.setCursor( 0, 1);
lcd.print( "                      ");
  Serial.println("Configuring Relays........");
  delay(1000);
//configure pin2 as an input and enable the internal pull-up resistor
//HIGHFLOOD 
pinMode(33, INPUT_PULLUP);
//MIDFLOOD
pinMode(41, INPUT_PULLUP);
//LOWFLOOD
pinMode(47, INPUT_PULLUP);
//Initialise and test sd card.
pinMode(53, OUTPUT);
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
   lcd.setCursor( 0, 0 );
lcd.print( "SDcard not present.....");
lcd.setCursor( 0, 1);
lcd.print( "                      ");
  Serial.println("SD card not present");
    // don't do anything more:
    return;
  }
 //DELETE THE OLD LOG FILE****************************
 SD.remove("datalog.txt");
 
lcd.setCursor( 0, 0 );
lcd.print( "SDcard OK...........");
lcd.setCursor( 0, 1);
lcd.print( "                      ");
  Serial.println("SD card initialized.");
delay(1000);

lcd.setCursor( 0, 0 );
lcd.print( "Config. Sensors......");
lcd.setCursor( 0, 1);
lcd.print( "                      ");
  Serial.println("Configuring Sensors......");
//MOTOR TEMPERATURE SENSORs INPUTs
pinMode(A12, INPUT); //INPUT FOR MAIN ENGINE

pinMode(A13, INPUT); //INPUT FOR WATER PRIOR TO ESC COOLER

pinMode(A14, INPUT); //INPUT FOR EXTERNAL WATER TEMPERATURE

pinMode(A15, INPUT);//INPUT FOR WATER AFTER ESC COOLER
delay(1000);


//CURRENT FEED FOR WATERLEVEL SENSORS
//All output pin modes ommitted as relay board now does the work.

//Initialise and turn on the backlight.
digitalWrite( LCD_BACKLIGHT_PIN, HIGH );  //backlight control pin D3 is high (on)
   pinMode( LCD_BACKLIGHT_PIN, OUTPUT ); 
//Initialise the LCD display and format character usage.

//Boot-up. Show software name, version and copyright.
lcd.setCursor( 0, 0 );
lcd.print( "SHIP-TECT 0.4Mega" );
lcd.setCursor( 0, 1 );
lcd.print( "M.R.JUDGE 2013" );
Serial.println("SHIP-TECT v0.4Mega, Creative Commons Michael R. Judge 2013");
delay(2000);

//SELECT is a special case, it pulses the LCD backlight off and on for demo
    lcd.setCursor( 0, 0 );
lcd.print( "TurnON Rc gear.........");
lcd.setCursor( 0, 1);
lcd.print( "                      ");
  Serial.println("Starting all subsystems......");
    
 Wire.write(0x12); // Select bank A
 Wire.write(15); // Send value to bank A
 Wire.endTransmission(); 

 
 // Power on RC gear (normal operating state).
       Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission(); 
delay(3000);
}
// Main control loop.
void loop(){
  // make a string for assembling the data to log:
  String dataString = "";
// Clear the LCD screen at each run of the loop with BLANKS.  
  lcd.setCursor( 0, 1);
  lcd.print( "                ");
//Print some blank lines for some blank space on the serial monitor
Serial.println(" ");
Serial.println(" ");
Serial.println(" ");
Serial.println(" ");
Serial.println(" ");
Serial.println(" ");
Serial.println(" ");
Serial.println(" ");
Serial.println(" ");


 
  
// Main loop. Checks the individual pins as to whether HIGH (dry) or LOW (wet) and takes appropriate action by disabling motors and/or starting pumps depending
//on the situation, such as motor overheating or flooding.
Serial.println("Analysing.....");
lcd.setCursor( 0, 0 );
lcd.print( "Analysing |-|-|-|-|" );
delay( 100 );
lcd.setCursor( 0, 0 );
lcd.print( "Analysing -|-|-|-|-" );
delay( 100 );
lcd.setCursor( 0, 0 );
lcd.print( "Analysing |-|-|-|-|" );
delay( 100 );
lcd.setCursor( 0, 0 );
lcd.print( "Analysing -|-|-|-|-" );
delay( 100 );
lcd.setCursor( 0, 0 );
lcd.print( "Analysing |-|-|-|-|" );
delay( 100 );
lcd.setCursor( 0, 0 );
lcd.print( "Analysing -|-|-|-|-" );
delay( 100 );
lcd.setCursor( 0, 0 );
lcd.print( "Analysing |-|-|-|-|" );
delay( 100 );
lcd.print( "                          " );
delay( 100 );

//Check for 1st stage flooding
 // Start a new log for this pass
 File dataFile = SD.open("datalog.txt", FILE_WRITE);

  // if the file is available, write to it:
  if (dataFile) {
    dataFile.println( " ");
    dataFile.println( " ");
    dataFile.println( " ");
    dataFile.println( "New Analysis.........");
    time = millis();
    float seconds = (time / 1000);
   dataFile.println( "Elapsed seconds since last loop is: "); dataFile.print(seconds); 
     dataFile.println( " SECONDS " );
      dataFile.println( "**********************************************" );
    
    
 

int lowfloodVal = digitalRead(47);
dataString += String(lowfloodVal);
      dataString += " lowfloodVal,"; 
       
Serial.println(lowfloodVal); Serial.print(" lowflood");
delay(50);
//Check for 2nd stage flooding.

int midfloodVal = digitalRead(41);
dataString += String(midfloodVal);
      dataString += " midfloodVal,"; 
       
Serial.println(midfloodVal); Serial.print(" midflood");
//Check for high level flooding
delay(50);

int highfloodVal = digitalRead(33);
dataString += String(highfloodVal);
      dataString += " highfloodVal,"; 
       
Serial.println(highfloodVal); Serial.print(" highflood");

//read slave arduino for bow flooding status
Wire.requestFrom(2, 1);    // request 6 bytes from slave device #2

  
   int bowfloodVal = Wire.read(); // receive a byte as character
   dataString += String(bowfloodVal);
      dataString += " bowfloodVal,"; 
       
    Serial.println( "bow flooding level is " ); Serial.print(bowfloodVal);        // print the character
 
  delay(50);

//Read  main motortemp
int port = analogRead(A12);
float voltageport = port * 5.0;
 voltageport /= 1024.0; 
float motortemp = (voltageport - 0.5) * 100;
int motor = motortemp;
dataString += String(motor);
      dataString += " motor temperature,"; 
Serial.println(" Main Engine temperature is (in Celcius) "); Serial.print(motortemp);
Serial.println(" ");
 
//Read intake water temp
int intake = analogRead(A13);
float voltageintake = intake * 5.0;
 voltageintake /= 1024.0; 
float intaketemp = (voltageintake - 0.5) * 100;
int intakewater = intaketemp;
dataString += String(intakewater);
      dataString += " intakewater,"; 
Serial.println(" Intake water temperature is in (Celcius) "); Serial.print(intaketemp);
Serial.println(" ");
 
 //Read external water temp
int external = analogRead(A14);
float voltageexternal = external * 5.0;
 voltageexternal /= 1024.0; 
float externaltemp = (voltageexternal - 0.5) * 100;
int extwater = externaltemp;
dataString += String(extwater);
      dataString += " external water temperature,"; 
Serial.println(" External water temperature is (Celcius) "); Serial.print(externaltemp);
Serial.println(" ");

 //Read ESC after-cooler water temp
int esc = analogRead(A15);
float voltageexhaust = esc * 5.0;
 voltageexhaust /= 1024.0; 
float exhausttemp = (voltageexhaust - 0.5) * 100;
int exhaustwater = exhausttemp;
dataString += String(exhaustwater);
      dataString += " exhaust water temperature,"; 
Serial.println(" Exhaust water temperature is (Celcius) "); Serial.print(externaltemp);
Serial.println(" ");
 
//FINISHED LOGGING ALL SENSOR READINGS TO SD CARD

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
 
 





//Indicates all sensors successfully read.
lcd.setCursor( 0, 0);
lcd.print( "......DONE......" );
Serial.println("......DONE......");
delay(250);

//Calculates and Indicates ESC cooler efficiency
int escefficiency = (intaketemp / exhausttemp) * 100;

dataString += String(escefficiency);
      dataString += " % esc efficiency,"; 
//lcd.setCursor( 0, 1);
//lcd.print( "ESC Eff: " ); lcd.print(escefficiency);
//Serial.println("Efficiency of the ESC Cooler is "); Serial.print(escefficiency);
//Serial.println(" ");
//delay(500);
//lcd.setCursor( 0, 1);
//lcd.print( "                             ");


//Calculates and Indicates keel cooler efficiency
int keelefficiency = (externaltemp / intaketemp) * 100;
dataString += String(keelefficiency);
      dataString += " % keel efficiency,"; 
//lcd.setCursor( 0, 1);
//lcd.print( "Cooler Eff: " ); lcd.print(keelefficiency);
//Serial.println("Efficiency of the Keel Cooler is "); Serial.print(keelefficiency);
//Serial.println(" ");
//delay(500);
//lcd.setCursor( 0, 1);
//lcd.print( "                             ");

//Calculates and Indicates overall water cooling system efficiency
int totalefficiency = (escefficiency / keelefficiency) * 100;
dataString += String(totalefficiency);
      dataString += " % overall efficiency,"; 
//lcd.setCursor( 0, 1);
//lcd.print( "Total Eff: " ); lcd.print(totalefficiency);
//Serial.println("Total Efficiency of the  Cooler is "); Serial.print(totalefficiency);
//Serial.println(" ");
//delay(500);
//lcd.setCursor( 0, 1);
//lcd.print( "                             ");

dataFile.println(dataString);




//If high level flooding is detected, will enable pumping, power isolation to motor and all RC gear, and ballast pump-out


if (lowfloodVal == LOW && midfloodVal == LOW && highfloodVal == LOW && bowfloodVal == 3) {
   if (dataFile) 
  dataFile.println( "High Level Flooding Detected" );
   dataFile.close();
  Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(7); // Send value to bank A
 Wire.endTransmission(); 
Serial.println("Stage 3 flood");
lcd.setCursor( 0, 1);
lcd.print( "Stage 3 flood");
delay(750);
lcd.setCursor( 0, 1);
lcd.print( "All pumps on........");
Serial.println("All pumps ON........");
delay(750);
lcd.setCursor( 0, 1);
lcd.print( "ALL DISABLED.....");
Serial.println("ALL GEAR DISABLED.....");

delay(750);


} 
else {
// If 2nd stage flooding detected, will enable pumping and power isolation.
   if (dataFile) 
 if (lowfloodVal == LOW && midfloodVal == LOW && highfloodVal == HIGH && bowfloodVal == 2) {
    dataFile.println( "Mid Level Flooding Detected" );
     dataFile.close();
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(11); // Send value to bank A
 Wire.endTransmission(); 
Serial.println("Stage 2 flood");
lcd.setCursor( 0, 1);
lcd.print( "Stage 2 flood");
delay(750);
lcd.setCursor( 0, 1);
lcd.print( "E. Pump ON.....");
Serial.println("E. Pump ON......");
delay(750);
lcd.setCursor( 0, 1);
lcd.print( "MOTORS DISABLED.....");
Serial.println("MOTORS DISABLED.....");
delay(750);
digitalWrite(31, LOW);
digitalWrite(41, LOW);
digitalWrite(47, LOW);

}
else {
// If 1st stage flooding detected, will enable pumping.  
if (lowfloodVal == LOW && midfloodVal == HIGH && highfloodVal == HIGH && bowfloodVal == 1) {
  if (dataFile) 
  dataFile.println( "Low Level Flooding Detected" );
  dataFile.close();
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(10); // Send value to bank A
 Wire.endTransmission(); 
Serial.println("Stage 1 flood");
lcd.setCursor( 0, 1);
lcd.print( "Stage 1 flood");
delay(750);
lcd.setCursor( 0, 1);
lcd.print( "E. Pump is ON.....");
Serial.println("E. Pump is ON......");
delay(750);
lcd.setCursor( 0, 1);
lcd.print( "MOTORS ENABLED.....");
Serial.println("MOTORS ENABLED.....");                
 
delay(750);

}

else {
//If no flooding detected, but main motor overheats, ESC's OFF, all pumps off, valves closed, and all major electronics isolated.)  
if (lowfloodVal == LOW && midfloodVal == LOW && highfloodVal == LOW && bowfloodVal == 0 && motortemp > 0 && motortemp >= 60 && motortemp < 130 && totalefficiency > 0 && totalefficiency >= 60 && totalefficiency < 101 ) {
  if (dataFile) 
  dataFile.println( "Motor Overheated" );
  dataFile.close();
  Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(9); // Send value to bank A
 Wire.endTransmission(); 
Serial.println("Nil flooding...");
lcd.setCursor( 0, 1);
lcd.print( "Nil flooding...");
delay(750);
Serial.println("E. Pump is OFF......");
lcd.setCursor( 0, 1);
lcd.print( "E. Pump is OFF......");
delay(750);
Serial.println("MOTOR OVERHEATED....."); Serial.print(motortemp); 
lcd.setCursor( 0, 1);
lcd.print( "MOTOR TEMP   "); lcd.print(motortemp);
 
delay(10000);

}

else {
//If no flooding detected, but ESC overheats, ESC's OFF, all pumps off, valves closed, and all major electronics isolated.)  
if (lowfloodVal == LOW && midfloodVal == LOW && highfloodVal == LOW && bowfloodVal == 0 && motortemp > 0 && motortemp <= 59 && motortemp < 130 && totalefficiency > 0 && totalefficiency <= 59 && totalefficiency < 101  ) {
  if (dataFile) 
  dataFile.println( "ESC overheated" );
  dataFile.close();
  Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(9); // Send value to bank A
 Wire.endTransmission(); 
Serial.println("Nil flooding...");
lcd.setCursor( 0, 1);
lcd.print( "Nil flooding...");
delay(750);
Serial.println("E. Pump is OFF......");
lcd.setCursor( 0, 1);
lcd.print( "E. Pump is OFF......");
delay(750);
Serial.println("ESC OVERHEATED....."); Serial.print(totalefficiency);
lcd.setCursor( 0, 1);
lcd.print( "H/E EFF %   "); lcd.print(totalefficiency);
 
delay(10000);

}

else {
//If no flooding detected, leave motors running and all pumps off, valves closed.)  
if (lowfloodVal == LOW && midfloodVal == LOW && highfloodVal == LOW && bowfloodVal == 0 && motortemp >= 1 && motortemp <= 59 && totalefficiency > 0 && totalefficiency >= 60 && totalefficiency < 101 ) {
  if (dataFile) 
   dataFile.close();
  dataFile.println( "No problems, all is well until the next pass" );
  Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission(); 
Serial.println("Nil flooding...");
lcd.setCursor( 0, 1);
lcd.print( "Nil flooding...");
delay(750);
Serial.println("Pump is OFF......");
lcd.setCursor( 0, 1);
lcd.print( "Pump is OFF......");
delay(750);
Serial.println("Motor NORMAL-ON.....");
lcd.setCursor( 0, 1);
lcd.print( "Motor NORMAL-ON.....");

delay(750);

}

else {
    Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission();  
 delay(250);
   if (dataFile) 
  dataFile.println( "Error with sensors detected. Check sensor values" );
   dataFile.close();
Serial.println("Error with sensors. Pumps on. All rc gear and motor off!");
Serial.println( "Main engine temperature:   " ); 
Serial.println(motortemp);
Serial.println( "Cooling water intake temperature:   " ); 
Serial.println(intaketemp);
Serial.println( "External water temperature:   " ); 
Serial.println(externaltemp);
Serial.println( "ESC exhaust water temperature:   " ); 
Serial.println(exhausttemp);
Serial.println( "Total cooling efficiency:   " ); 
Serial.println(totalefficiency);
Serial.println( "Low water level sensor status:   " ); 
Serial.println(lowfloodVal);
Serial.println( "Mid water level sensor status:   " ); 
Serial.println(midfloodVal);
Serial.println( "High water level sensor status:   " ); 
Serial.println(highfloodVal);
}
//Print Warning
 {  Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(24); // Send value to bank A
 Wire.endTransmission();  
lcd.setCursor( 0, 0);
lcd.print( " SENSOR/s ERROR......" );
//Print Motor temperature
lcd.setCursor( 0, 1);
lcd.print( "Motor C*: " ); 
lcd.setCursor( 11, 1);
lcd.print(motortemp);
delay(750);
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission();  
 
//Print ESC heat exchanger intake cooling water temperature
lcd.setCursor( 0, 1);
lcd.print( "                     " );
lcd.setCursor( 0, 1);
lcd.print( " Intake C*: " );
lcd.setCursor( 12, 1);
lcd.print(intaketemp);
delay(750);
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(24); // Send value to bank A
 Wire.endTransmission();  
//Print external water temperature
lcd.setCursor( 0, 1);
lcd.print( "                     " );
lcd.setCursor( 0, 1);
lcd.print( " Extern. C*%: " ); 
lcd.setCursor( 14, 1);
lcd.print(externaltemp);
delay(750);
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission();  
 //Print exhaust water temperature
lcd.setCursor( 0, 1);
lcd.print( "                     " );
lcd.setCursor( 0, 1);
lcd.print( " Exhaus. C*%: " ); 
lcd.setCursor( 14, 1);
lcd.print(exhausttemp);
delay(750);
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(24); // Send value to bank A
 Wire.endTransmission();  
//Print cooling loop efficiency
lcd.setCursor( 0, 1);
lcd.print( "                     " );
lcd.setCursor( 0, 1);
lcd.print( " Total EFF%: " ); 
lcd.setCursor( 12, 1);
lcd.print(totalefficiency);
delay(750);
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission();  
//Print Low water level sensor HIGH 1 (no water detected)/LOW 0 (Detected) status
lcd.setCursor( 0, 1);
lcd.print( "                     " );
lcd.setCursor( 0, 1);
lcd.print( " LOW Sens.: " );
lcd.setCursor( 12, 1);
lcd.print(lowfloodVal);
delay(750);
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(24); // Send value to bank A
 Wire.endTransmission();  
//Print Mid water level sensor HIGH 1 (no water detected)/LOW 0 (Detected) status
lcd.setCursor( 0, 1);
lcd.print( "                     " );
lcd.setCursor( 0, 1);
lcd.print( " MID Sens.: " ); 
lcd.setCursor( 12, 1);
lcd.print(midfloodVal);
delay(750);
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission();  
//Print High water level sensor HIGH 1 (no water detected)/LOW 0 (Detected) status
lcd.setCursor( 0, 1);
lcd.print( "                     " );
lcd.setCursor( 0, 1);
lcd.print( " HIGH Sens.: " );
lcd.setCursor( 13, 1);
lcd.print(highfloodVal);
delay(750);
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission();  
//Print Bow flooding status
lcd.setCursor( 0, 1);
lcd.print( "                     " );
lcd.setCursor( 0, 1);
lcd.print( " BOW. Sens.: " );
lcd.setCursor( 13, 1);
lcd.print(bowfloodVal);
delay(750);
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission();  
 


//END OF LOOP





















// MOTOR TEMPERATURE CONTROL ACTIVE IN THIS VERSION
 }

}
}

}
}
}
  }
}

Sample log file:

Code:
New Analysis.........
Elapsed seconds since last loop is: 
10.00 SECONDS 
**********************************************
1 lowfloodVal,1 midfloodVal,1 highfloodVal,-1 bowfloodVal,352 motor temperature,287 intakewater,237 external water temperature,218 exhaust water temperature,131 % esc efficiency,82 % keel efficiency,100 % overall efficiency,
Error with sensors detected. Check sensor values
 
 
 
New Analysis.........
Elapsed seconds since last loop is: 
19.00 SECONDS 
**********************************************
1 lowfloodVal,1 midfloodVal,1 highfloodVal,-1 bowfloodVal,179 motor temperature,179 intakewater,173 external water temperature,175 exhaust water temperature,102 % esc efficiency,96 % keel efficiency,100 % overall efficiency,
Error with sensors detected. Check sensor values
 
 
 
New Analysis.........
Elapsed seconds since last loop is: 
27.00 SECONDS 
**********************************************
1 lowfloodVal,1 midfloodVal,1 highfloodVal,-1 bowfloodVal,175 motor temperature,176 intakewater,170 external water temperature,172 exhaust water temperature,101 % esc efficiency,96 % keel efficiency,100 % overall efficiency,
Error with sensors detected. Check sensor values
 
 
 
New Analysis.........
Elapsed seconds since last loop is: 
36.00 SECONDS 
**********************************************
1 lowfloodVal,1 midfloodVal,1 highfloodVal,-1 bowfloodVal,174 motor temperature,175 intakewater,169 external water temperature,171 exhaust water temperature,101 % esc efficiency,96 % keel efficiency,100 % overall efficiency,
Error with sensors detected. Check sensor values
 
 
 
New Analysis.........
Elapsed seconds since last loop is: 
45.00 SECONDS 
**********************************************
1 lowfloodVal,1 midfloodVal,1 highfloodVal,-1 bowfloodVal,173 motor temperature,174 intakewater,168 external water temperature,171 exhaust water temperature,101 % esc efficiency,96 % keel efficiency,100 % overall efficiency,
Error with sensors detected. Check sensor values
Deckie is offline Find More Posts by Deckie
Last edited by Deckie; Apr 07, 2013 at 06:51 AM.
Reply With Quote
Old Apr 07, 2013, 09:24 AM
---o-O-o---
blutoh's Avatar
United States, NJ, Livingston
Joined Mar 2012
1,603 Posts
Hi Deckie,

Very nice work. Have you considered sending data back to you when a critical event occurs? Just a thought.

Pete
blutoh is offline Find More Posts by blutoh
Reply With Quote
Old Apr 08, 2013, 05:09 AM
Registered User
Deckie's Avatar
Australia, WA, Garden Island
Joined Nov 2010
465 Posts
Quote:
Originally Posted by blutoh View Post
Hi Deckie,

Very nice work. Have you considered sending data back to you when a critical event occurs? Just a thought.

Pete
Ah yes, I have, but i'm waiting on the results of the various automated control system projects going on around here, then I can look into integrating my code into that software if it'll fit
Deckie is offline Find More Posts by Deckie
Reply With Quote
Old Sep 01, 2013, 09:58 PM
Registered User
Deckie's Avatar
Australia, WA, Garden Island
Joined Nov 2010
465 Posts
Ported Ship-Tect 0.4b Mega to run on the Adafruit 2.8inch TFT LCD shield.

SHIP-TECT 0.4b Mega, Adafruit 2.8inch lcd trial (0 min 43 sec)


Works perfectly as you can see. After the load screen it takes a second or two to render all labelling, but the trick is the labels are rendered before the main loop begins. This means that only the readings for each sensor/data value are updated on the LCD in the loop, allowing quicker updates and saving CPU cycles.

On the main loop screen, From the top, you have:

- the status bar, which will tell you whether everything is "NORMAL", "LOW LEVEL FLOOD" , "MODERATE FLOOD", "HIGH LEVEL FLOOD", various overheat messages "<Insert affected system> OVERHEAT", and "ERROR WITH A SENSOR/S". Text Background colour changes between BLUE, ORANGE AND RED, depending on what's going on, as you can see it's red for the error indication (temperature values are out of range triggering the error code).

- Sensor readings, Grouped by type.

- System info bar at the bottom showing version and year.


The sensor readings you see updating are the ones originally included with Ship-Tect. I now have to write code for current sensing, the flow sensors, the hall effect rpm sensor, rudder angle trimpot and various other calcs. Needless to say i've been drawing inspiration from the Praxis Ship Monitoring and Control system on HMAS SIRIUS (converted commercial tanker, to Auxiliary Oiler).

Pic below of some of the components to be utilised....



I have all the sensors now, devicecraft.com makes nifty little 1-80amp hall effect current sensors for $7.50 US each, still waiting on these. Also have nifty little water pumps off Ebay for between $6 to $12.50 a pop. The large black and beige pumps are for water ballast, are brushless and capable of 10 liters per minute each. The small black ones are for the cooling loop, and can do 4 liters per minute. You can also see an adafruit "one wire" digital temp sensor, an adafruit water flow sensor, freetronics piezo buzzer, hall effect rpm sensor, and a few other bits and bobs as examples of components to be used. Also two Freetronics relay/solenoid control breakout boards. The two items to the top are surprises...


Code included below.

SD Card datalogging support is disabled/commented out at the moment as i'm trying to resolve the conflict between the Ethermega's onboard SD Card reader, and the one built in to the TFT LCD shield.... I'll try to make it so it selects the right slot, depending on which one the card is in.

Code:
#include <Wire.h>
//#include <SD.h>
#include <Scheduler.h>
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_TFTLCD.h> // Hardware-specific library
#include <SPI.h>
#define I2C_ADDR  0x20  // 0x20 is the address with all jumpers removed
// SHIP-TECT Emergency Management v0.4Mega. By Michael Ryan Judge, Licensed under Creative Commons, 2013 for Arduino Mega 2560. 
//Now includes data logging for use with Freetronics Ethermega or any mega with an SD card shield (remember to change the pin!).
// NOW designed to work with the Adafruit 2.8" full colour TFT LCD (can print on more data).
const int chipSelect = 53;
//TFT setup code goes in here
// The control pins for the LCD can be assigned to any digital or
// analog pins...but we'll use the analog pins as this allows us to
// double up the pins with the touch screen (see the TFT paint example).
#define LCD_CS A3 // Chip Select goes to Analog 3
#define LCD_CD A2 // Command/Data goes to Analog 2
#define LCD_WR A1 // LCD Write goes to Analog 1
#define LCD_RD A0 // LCD Read goes to Analog 0

#define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin

// When using the BREAKOUT BOARD only, use these 8 data lines to the LCD:
// For the Arduino Uno, Duemilanove, Diecimila, etc.:
//   D0 connects to digital pin 8  (Notice these are
//   D1 connects to digital pin 9   NOT in order!)
//   D2 connects to digital pin 2
//   D3 connects to digital pin 3
//   D4 connects to digital pin 4
//   D5 connects to digital pin 5
//   D6 connects to digital pin 6
//   D7 connects to digital pin 7
// For the Arduino Mega, use digital pins 22 through 29
// (on the 2-row header at the end of the board).

// Assign human-readable names to some common 16-bit color values:
#define	BLACK   0x0000
#define	BLUE    0x001F
#define	RED     0xF800
#define	GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
// If using the shield, all control and data lines are fixed, and
// a simpler declaration can optionally be used:
// Adafruit_TFTLCD tft;

//
void setup(){
 Serial.println("TFT LCD test");

#ifdef USE_ADAFRUIT_SHIELD_PINOUT
  Serial.println("Using Adafruit 2.8\" TFT Arduino Shield Pinout");
#else
  Serial.println("Using Adafruit 2.8\" TFT Breakout Board Pinout");
#endif

  tft.reset();
  tft.fillScreen(BLACK);
    tft.setTextColor(YELLOW); tft.setTextSize(2);
    tft.setRotation(45);
  uint16_t identifier = tft.readID();

  if(identifier == 0x9325) {
    Serial.println("Found ILI9325 LCD driver");
  } else if(identifier == 0x9328) {
    Serial.println("Found ILI9328 LCD driver");
  } else if(identifier == 0x7575) {
    Serial.println("Found HX8347G LCD driver");
  } else {
    Serial.print("Unknown LCD driver chip: ");
    Serial.println(identifier, HEX);
    Serial.println("If using the Adafruit 2.8\" TFT Arduino shield, the line:");
    Serial.println("  #define USE_ADAFRUIT_SHIELD_PINOUT");
    Serial.println("should appear in the library header (Adafruit_TFT.h).");
    Serial.println("If using the breakout board, it should NOT be #defined!");
    Serial.println("Also if using the breakout, double-check that all wiring");
    Serial.println("matches the tutorial.");
    return;
  }
    tft.begin(identifier);
    //Boot-up. Show software name, version and copyright.

tft.setCursor(0, 0);
tft.println("**************************");
tft.setCursor(50, 30);
tft.println( "SHIP-TECT 0.4 MEGA" );
tft.setCursor(15, 50);
tft.println( "Copyright M.R.JUDGE 2013" );
tft.setCursor(0, 220);
tft.println("**************************");
delay(2000);
  
Serial.println("SHIP-TECT v0.4Mega, Creative Commons Michael R. Judge 2013");

tft.setTextColor(BLUE);
tft.setCursor(0, 80);
tft.println( "Starting Serial........");
delay(500);
 Serial.println("Starting Serial.....");
//start serial connection
Serial.begin(115200);
delay(100);
//Wake up the I2C BUS and assign Bank a as relay outputs.
Wire.begin(); // Wake up I2C bus
 // Set I/O bank A to outputs
  Wire.beginTransmission(I2C_ADDR);
  Wire.write(0x00); // IODIRA register
  Wire.write(0x00); // Set all of bank A to outputs
  Wire.endTransmission();
delay(500);
//tft.setCursor(15, 150);
tft.println( "Configuring Relays.....");
  Serial.println("Configuring Relays........");
delay(500);
//tft.setCursor(0, 0);
//  tft.fillScreen(BLACK);
//tft.setCursor(0, 0);
//tft.println( "                      ");


//configure pin2 as an input and enable the internal pull-up resistor
//HIGHFLOOD 
pinMode(33, INPUT_PULLUP);
//MIDFLOOD
pinMode(41, INPUT_PULLUP);
//LOWFLOOD
pinMode(47, INPUT_PULLUP);
//Initialise and test sd card.
pinMode(53, OUTPUT);
//{  // see if the card is present and can be initialized:
 //if (!SD.begin(chipSelect)) {
// tft.setCursor(0, 0);
//tft.println( "SDcard not present.....");
//delay(1000);
//tft.setCursor(0, 0);
 // tft.fillScreen(BLACK);
  //Serial.println("SD card not present");
    // don't do anything more:
  //  return;
 //}//deconstructor MUST be HERE at ALL COSTS.
 // SD.remove("datalog.txt");

//tft.setCursor(0, 0);
//tft.println( "SDcard OK...........");
//delay(1000);
//tft.setCursor(0, 0);
// tft.fillScreen(BLACK);
//tft.print( "                      ");
//  Serial.println("SD card initialized.");
//delay(1000);
//tft.setCursor(0, 0);
//  tft.fillScreen(BLACK);
// }
//tft.setCursor(0, 0);
tft.println( "Configuring Sensors....");
delay(500);

 //tft.fillScreen(BLACK);
  Serial.println("Configuring Sensors......");
  

//MOTOR TEMPERATURE SENSORs INPUTs


//CURRENT FEED FOR WATERLEVEL SENSORS
//All output pin modes ommitted as relay board now does the work.




 

tft.println( "Powering on TX...");
delay(500);
tft.println( "Starting main loop...");
delay(500);
  Serial.println("Starting all subsystems......");
   pinMode(A14, INPUT); //INPUT FOR MAIN ENGINE

pinMode(A11, INPUT); //INPUT FOR WATER PRIOR TO ESC COOLER

pinMode(A12, INPUT); //INPUT FOR EXTERNAL WATER TEMPERATURE

pinMode(A13, INPUT);//INPUT FOR WATER AFTER ESC COOLER
delay(1000);
 
 Wire.write(0x12); // Select bank A
 Wire.write(15); // Send value to bank A
 Wire.endTransmission(); 

 
 // Power on RC gear (normal operating state).
       Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission(); 
delay(150);
tft.fillScreen(BLACK);
tft.setCursor(0, 220);
tft.setTextColor(YELLOW, BLUE);
tft.println(" SHIP-TECT 0.4b MEGA, 2013" );

tft.setCursor(0, 20);
//Print all permanent screen text. This prevents the arduino from having to reprint
// these labels in the main loop, wasting precious cpu cycles.
tft.setTextSize(1);
tft.setTextColor(YELLOW, BLUE);
tft.setCursor(0, 20);
tft.println( "**TEMPERATURES**" );
tft.setCursor(200, 20);
tft.println( "**FLOOD STATUS**" );
tft.setCursor(200, 80);
tft.println( "CURRENT LVL's (AMPS)");
tft.setCursor(0, 90);
tft.println( "COOLING SYSTEM EFF. + FLOW");
tft.setCursor(0, 140);
tft.println( "PROPULSION + MANOUVERING");
tft.setCursor(200, 160);
tft.println( "***GPS DATA***");

tft.setTextColor(WHITE, BLUE);
tft.setCursor(0, 30);
tft.println( "Propulsion Eng. TEMP:  " );
tft.setCursor(0, 40);
tft.println( "Ambient Water TEMP:    " );
tft.setCursor(0, 50);
tft.println( "H/E Exh. Water TEMP:   " );
tft.setCursor(0, 60);
tft.println( "H/E Int. Water TEMP:   " );
tft.setCursor(0, 70);
tft.println( "Shaft Bearing. TEMP:   " );
tft.setCursor(200, 30);
tft.println( "HI LVL.Flood: " );
tft.setCursor(200, 40);
tft.println( "MID LVL.Flood:" );
tft.setCursor(200, 50);
tft.println( "LOW LVL.Flood:" );
tft.setCursor(200, 60);
tft.println( "BOW LVL.Flood:" );
tft.setCursor(0, 100);
tft.println( "System Efficiency %:   ");
tft.setCursor(0, 110);
tft.println( "FW Loop Flow Rt. (Lph):");
tft.setCursor(0, 120);
tft.println( "RW Loop Flow Rt. (Lph):");
tft.setCursor(200, 90);
tft.println( "At Batteries:   " );
tft.setCursor(200, 100);
tft.println( "Control Systems:" );
tft.setCursor(200, 110);
tft.println( "Cooling Pumps:  " );
tft.setCursor(200, 120);
tft.println( "Ballast Pumps:  " );
tft.setCursor(200, 130);
tft.println( "Elec.Spd.Ctrl's:" );
tft.setCursor(200, 140);
tft.println( "Battery Voltage:" );
tft.setCursor(312, 140);
tft.println("v");
tft.setCursor(0, 150);
tft.println( "Main Engine RPM:       " );
tft.setCursor(0, 160);
tft.println( "Main Engine Output (W):" );
tft.setCursor(0, 170);
tft.println( "Main Engine Loading %: " );
tft.setCursor(0, 180);
tft.println( "Rudder angle (Deg's):  " );
tft.setCursor(0, 190);
tft.println( "Bow Thruster status:   " );
tft.setCursor(0, 200);
tft.println( "Stern Thruster status: " );
tft.setCursor(200, 170);
tft.println( "Heading (Deg):  ");
tft.setCursor(200, 180);
tft.println( "Avg Spd.(Kts):  ");
tft.setCursor(200, 190);
tft.println( "Max Spd.(kts):  ");
tft.setCursor(200, 200);
tft.println( "Distance (Mi):  ");


}

// Main control loop.
void loop(){
  // make a string for assembling the data to log:

// Clear the LCD screen at each run of the loop with BLANKS.  




//CONFIGURE MAIN OPERATING PAGE TEXT SIZE, COLOUR AND FORMAT PAGE
tft.setTextSize(2);

tft.setTextColor(BLUE, BLACK);  
// Main loop. Checks the individual pins as to whether HIGH (dry) or LOW (wet) and takes appropriate action by disabling motors and/or starting pumps depending
//on the situation, such as motor overheating or flooding.



//Check for 1st stage flooding
 // Start a new log for this pass
 //File dataFile = SD.open("datalog.txt", FILE_WRITE);

  // if the file is available, write to it:
 // if (dataFile) {
  //  dataFile.println( " ");
   // dataFile.println( " ");
  //  dataFile.println( " ");
   // dataFile.println( "New Analysis.........");



     
  //    dataFile.println( "**********************************************" );
 
 
 

int lowfloodVal = digitalRead(47);

       
//Serial.println(lowfloodVal); Serial.print(" lowflood");
delay(50);
//Check for 2nd stage flooding.

int midfloodVal = digitalRead(41);
//dataString += String(midfloodVal);
   //   dataString += " midfloodVal,"; 
       
//Serial.println(midfloodVal); Serial.print(" midflood");
//Check for high level flooding
delay(50);

int highfloodVal = digitalRead(33);
//dataString += String(highfloodVal);
 //     dataString += " highfloodVal,"; 
       
//Serial.println(highfloodVal); Serial.print(" highflood");

//read slave arduino for bow flooding status
Wire.requestFrom(2, 1);    // request 6 bytes from slave device #2

  
   int bowfloodVal = Wire.read(); // receive a byte as character
 //  dataString += String(bowfloodVal);
  //    dataString += " bowfloodVal,"; 
       
    //Serial.println( "bow flooding level is " ); Serial.print(bowfloodVal);        // print the character
 
  delay(50);

//Read  main motortemp
int port = analogRead(A14);
float voltageport = port * 5.0;
 voltageport /= 1024.0; 
float motortemp = (voltageport - 0.5) * 100;
int motor = motortemp;
//dataString += String(motor);
    //  dataString += " motor temperature,"; 
//Serial.println(" Main Engine temperature is (in Celcius) "); Serial.print(motortemp);
//Serial.println(" ");
 
//Read intake water temp
int intake = analogRead(A1);
float voltageintake = intake * 5.0;
 voltageintake /= 1024.0; 
float intaketemp = (voltageintake - 0.5) * 100;
int intakewater = intaketemp;
//dataString += String(intakewater);
    //  dataString += " intakewater,"; 
//Serial.println(" Intake water temperature is in (Celcius) "); Serial.print(intaketemp);
//Serial.println(" ");
 
 //Read external water temp
int external = analogRead(A2);
float voltageexternal = external * 5.0;
 voltageexternal /= 1024.0; 
float externaltemp = (voltageexternal - 0.5) * 100;
int extwater = externaltemp;
//dataString += String(extwater);
   //   dataString += " external water temperature,"; 
//Serial.println(" External water temperature is (Celcius) "); Serial.print(externaltemp);
//Serial.println(" ");

 //Read ESC after-cooler water temp
int esc = analogRead(A3);
float voltageexhaust = esc * 5.0;
 voltageexhaust /= 1024.0; 
float exhausttemp = (voltageexhaust - 0.5) * 100;
int exhaustwater = exhausttemp;
//dataString += String(exhaustwater);
    //  dataString += " exhaust water temperature,"; 
//Serial.println(" Exhaust water temperature is (Celcius) "); Serial.print(externaltemp);
//Serial.println(" ");
 
//FINISHED LOGGING ALL SENSOR READINGS TO SD CARD

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
 
 








delay(50);

//Calculates and Indicates ESC cooler efficiency
int escefficiency = (intaketemp / exhausttemp) * 100;

//dataString += String(escefficiency);
  //    dataString += " % esc efficiency,"; 
//lcd.setCursor( 0, 1);
//lcd.print( "ESC Eff: " ); lcd.print(escefficiency);
//Serial.println("Efficiency of the ESC Cooler is "); Serial.print(escefficiency);
//Serial.println(" ");
//delay(500);
//lcd.setCursor( 0, 1);
//lcd.print( "                             ");


//Calculates and Indicates keel cooler efficiency
int keelefficiency = (externaltemp / intaketemp) * 100;
//dataString += String(keelefficiency);
  //    dataString += " % keel efficiency,"; 
//lcd.setCursor( 0, 1);
//lcd.print( "Cooler Eff: " ); lcd.print(keelefficiency);
//Serial.println("Efficiency of the Keel Cooler is "); Serial.print(keelefficiency);
//Serial.println(" ");
//delay(500);
//lcd.setCursor( 0, 1);
//lcd.print( "                             ");

//Calculates and Indicates overall water cooling system efficiency
int totalefficiency = (escefficiency / keelefficiency) * 100;
//dataString += String(totalefficiency);
   //   dataString += " % overall efficiency,"; 
//lcd.setCursor( 0, 1);
//lcd.print( "Total Eff: " ); lcd.print(totalefficiency);
//Serial.println("Total Efficiency of the  Cooler is "); Serial.print(totalefficiency);
//Serial.println(" ");
//delay(500);
//lcd.setCursor( 0, 1);
//lcd.print( "                             ");

//dataFile.println(dataString);
tft.setCursor(20, 30);
//INDICATES Successfull read and data processing.

//PRINT AND UPDATE SENSOR DATA TO THE TFT

//TEMPERATURE SECTION
tft.setTextColor(WHITE, BLUE);
tft.setTextSize(1);
tft.setCursor(140, 30);
tft.println(motortemp);
tft.setCursor(140, 40);
tft.println(externaltemp);
tft.setCursor(140, 50);
tft.println(exhausttemp);
tft.setCursor(140, 60);
tft.println(intaketemp);
//shaft bearing
tft.setCursor(140, 70);
tft.println("      ");


//FLOODING STATUS SECTION
tft.setCursor(290, 30);
tft.println(highfloodVal);
tft.setCursor(290, 40);
tft.println(midfloodVal);
tft.setCursor(290, 50);
tft.println(lowfloodVal);
tft.setCursor(290, 60);
tft.println(bowfloodVal);

//LIQUID COOLING SYSTEM EFFICIENCY AND FLOW 
tft.setCursor(140, 100);
tft.println(totalefficiency);
tft.setCursor(140, 110);
tft.println("   ");
tft.setCursor(140, 120);
tft.println("   ");

//CURRENT SENSOR READINGS
//Current reading at batteries
tft.setCursor(300, 90);
tft.println("   ");
//Current reading at Automated control and radio gear.
tft.setCursor(300, 100);
tft.println("   ");
//At coolant pumps
tft.setCursor(300, 110);
tft.println("   ");
//At ballast pumps
tft.setCursor(300, 120);
tft.println("   ");
//All Esc's on one bus
tft.setCursor(300, 130);
tft.println("   ");
//All Esc's on one bus
tft.setCursor(300, 140);
tft.println(readVcc());


//PROPULSION AND MANOUVERING DATA 
//Main engine RPM
tft.setCursor(140, 150);
tft.println("   ");
// Power produced by main engine in Watts (amps x volts)
tft.setCursor(140, 160);
tft.println("   ");
// Main engine load as a function of Amp draw vs known maximum permissable draw (70 amps for Turnigy 149kv
// SK3  59mm diameter outrunner).
tft.setCursor(140, 170);
tft.println("   ");
// Rudder angle.
tft.setCursor(140, 180);
tft.println("   ");
// Bow thruster's ON/OFF
tft.setCursor(140, 190);
tft.println("   ");
//Stern thruster's ON/OFF
tft.setCursor(140, 200);
tft.println("   ");
delay(200);

//GPS DATA

tft.setCursor(300, 170);
tft.println( "   ");
tft.setCursor(300, 180);
tft.println( "   ");
tft.setCursor(300, 190);
tft.println( "   ");
tft.setCursor(300, 200);
tft.println( "   ");




//If high level flooding is detected, will enable pumping, power isolation to motor and all RC gear, and ballast pump-out


if (lowfloodVal == LOW && midfloodVal == LOW && highfloodVal == LOW && bowfloodVal == 3) {
  // if (dataFile) 
 // dataFile.println( "High Level Flooding Detected" );
 //  dataFile.close();
  Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(7); // Send value to bank A
 Wire.endTransmission(); 
Serial.println("Stage 3 flood");

tft.print( "Stage 3 flood");
delay(750);

tft.print( "All pumps on........");
Serial.println("All pumps ON........");
delay(750);

tft.print( "ALL DISABLED.....");
Serial.println("ALL GEAR DISABLED.....");

delay(750);


} 
else {
// If 2nd stage flooding detected, will enable pumping and power isolation.
 //  if (dataFile) 
 if (lowfloodVal == LOW && midfloodVal == LOW && highfloodVal == HIGH && bowfloodVal == 2) {
    //dataFile.println( "Mid Level Flooding Detected" );
    // dataFile.close();
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(11); // Send value to bank A
 Wire.endTransmission(); 
Serial.println("Stage 2 flood");

tft.print( "Stage 2 flood");
delay(750);

tft.print( "E. Pump ON.....");
Serial.println("E. Pump ON......");
delay(750);

tft.print( "MOTORS DISABLED.....");
Serial.println("MOTORS DISABLED.....");
delay(750);
digitalWrite(31, LOW);
digitalWrite(41, LOW);
digitalWrite(47, LOW);

}
else {
// If 1st stage flooding detected, will enable pumping.  
if (lowfloodVal == LOW && midfloodVal == HIGH && highfloodVal == HIGH && bowfloodVal == 1) {
 // if (dataFile) 
//  dataFile.println( "Low Level Flooding Detected" );
//  dataFile.close();
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(10); // Send value to bank A
 Wire.endTransmission(); 
Serial.println("Stage 1 flood");

tft.print( "Stage 1 flood");
delay(750);

tft.print( "E. Pump is ON.....");
Serial.println("E. Pump is ON......");
delay(750);

tft.print( "MOTORS ENABLED.....");
Serial.println("MOTORS ENABLED.....");                
 
delay(750);

}

else {
//If no flooding detected, but main motor overheats, ESC's OFF, all pumps off, valves closed, and all major electronics isolated.)  
if (lowfloodVal == LOW && midfloodVal == LOW && highfloodVal == LOW && bowfloodVal == 0 && motortemp > 0 && motortemp >= 60 && motortemp < 130 && totalefficiency > 0 && totalefficiency >= 60 && totalefficiency < 101 ) {
 // if (dataFile) 
 // dataFile.println( "Motor Overheated" );
 // dataFile.close();
  Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(9); // Send value to bank A
 Wire.endTransmission(); 
Serial.println("Nil flooding...");

tft.print( "Nil flooding...");
delay(750);
Serial.println("E. Pump is OFF......");

tft.print( "E. Pump is OFF......");
delay(750);
Serial.println("MOTOR OVERHEATED....."); Serial.print(motortemp); 

tft.print( "MOTOR TEMP   "); tft.print(motortemp);
 
delay(10000);

}

else {
//If no flooding detected, but ESC overheats, ESC's OFF, all pumps off, valves closed, and all major electronics isolated.)  
if (lowfloodVal == LOW && midfloodVal == LOW && highfloodVal == LOW && bowfloodVal == 0 && motortemp > 0 && motortemp <= 59 && motortemp < 130 && totalefficiency > 0 && totalefficiency <= 59 && totalefficiency < 101  ) {
 // if (dataFile) 
 // dataFile.println( "ESC overheated" );
 // dataFile.close();
  Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(9); // Send value to bank A
 Wire.endTransmission(); 
Serial.println("Nil flooding...");

tft.print( "Nil flooding...");
delay(750);
Serial.println("E. Pump is OFF......");

tft.print( "E. Pump is OFF......");
delay(750);
Serial.println("ESC OVERHEATED....."); Serial.print(totalefficiency);

tft.print( "H/E EFF %   "); tft.print(totalefficiency);
 
delay(10000);

}

else {
//If no flooding detected, leave motors running and all pumps off, valves closed.)  
if (lowfloodVal == LOW && midfloodVal == LOW && highfloodVal == LOW && bowfloodVal == 0 && motortemp >= 1 && motortemp <= 59 && totalefficiency > 0 && totalefficiency >= 60 && totalefficiency < 101 ) {
//  if (dataFile) 
  // dataFile.close();
//  dataFile.println( "No problems, all is well until the next pass" );
  Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission(); 
Serial.println("Nil flooding...");

tft.print( "Nil flooding...");
delay(750);
Serial.println("Pump is OFF......");

tft.print( "Pump is OFF......");
delay(750);
Serial.println("Motor NORMAL-ON.....");

tft.print( "Motor NORMAL-ON.....");

delay(750);

}

else {
    Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission();  
 delay(250);
//   if (dataFile) 
//  dataFile.println( "Error with sensors detected. Check sensor values" );
//   dataFile.close();
//Serial.println("Error with sensors. Pumps on. All rc gear and motor off!");
//Serial.println( "Main engine temperature:   " ); 
//Serial.println(motortemp);
//Serial.println( "Cooling water intake temperature:   " ); 
//Serial.println(intaketemp);
//Serial.println( "External water temperature:   " ); 
//Serial.println(externaltemp);
//Serial.println( "ESC exhaust water temperature:   " ); 
//Serial.println(exhausttemp);
//Serial.println( "Total cooling efficiency:   " ); 
//Serial.println(totalefficiency);
//Serial.println( "Low water level sensor status:   " ); 
//Serial.println(lowfloodVal);
//Serial.println( "Mid water level sensor status:   " ); 
//Serial.println(midfloodVal);
//Serial.println( "High water level sensor status:   " ); 
//Serial.println(highfloodVal);
}
//Print Warning
 {  Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(24); // Send value to bank A
 Wire.endTransmission();  

tft.setTextSize(2);



tft.setTextColor(WHITE, RED);
tft.setCursor(10, 0);
tft.println( "  ERROR WITH A SENSOR/S  " );
//Print Motor temperature


 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission();  
 
//Print ESC heat exchanger intake cooling water temperature



delay(50);

 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(24); // Send value to bank A
 Wire.endTransmission();  
//Print external water temperature



delay(50);
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission();  
 //Print exhaust water temperature




delay(50);
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(24); // Send value to bank A
 Wire.endTransmission();  
//Print cooling loop efficiency



delay(50);
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission();  
//Print Low water level sensor HIGH 1 (no water detected)/LOW 0 (Detected) status




delay(50);
 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(24); // Send value to bank A
 Wire.endTransmission();  
//Print Mid water level sensor HIGH 1 (no water detected)/LOW 0 (Detected) status
delay(50);




 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission();  
//Print High water level sensor HIGH 1 (no water detected)/LOW 0 (Detected) status

delay(50);



 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission();  
//Print Bow flooding status

delay(50);



 Wire.beginTransmission(I2C_ADDR);
 Wire.write(0x12); // Select bank A
 Wire.write(8); // Send value to bank A
 Wire.endTransmission();  
 
delay(100);

//END OF LOOP









 //***********












// MOTOR TEMPERATURE CONTROL ACTIVE IN THIS VERSION
 }

}
}

}
}
}
  }



//Determine state of battery charge 
 long readVcc() {
  // Read 1.1V reference against AVcc
  // set the reference to Vcc and the measurement to the internal 1.1V reference
  #if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
    ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  #elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
    ADMUX = _BV(MUX5) | _BV(MUX0);
  #elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
    ADMUX = _BV(MUX3) | _BV(MUX2);
  #else
    ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  #endif  
 
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Start conversion
  while (bit_is_set(ADCSRA,ADSC)); // measuring
 
  uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH  
  uint8_t high = ADCH; // unlocks both
 
  long result = (high<<8) | low;
 
  result = 1125300L / result * 0.0024; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
  return result;} // Vcc in millivolts
Deckie is offline Find More Posts by Deckie
Last edited by Deckie; Sep 01, 2013 at 10:21 PM.
Reply With Quote
Old Nov 26, 2013, 02:28 AM
Registered User
Ticonderoga's Avatar
Australia, QLD, Mudgeeraba
Joined Feb 2010
257 Posts
Hi Deckie,

Just what the doctor ordered I will be using an Arduino to mimic a fire control system in my 1/72 scale Slava (Russian CCG). She will also have active stabilizers which could leak as the shafts will terminate in the hull below the water line.

I will build coffer dams around the shafts to contain flooding and use your "uno" code, running on a second processor, from your earlier thread as the basis for controlling pumps to evacuate the coffer dams if required

Could you share a bit more details please on the sensor hardware and shields you are using, where to purchase etc. Forgive me if I have missed an earlier post.

Andrew
Ticonderoga is offline Find More Posts by Ticonderoga
Reply With Quote
Old Nov 26, 2013, 03:20 AM
Registered User
Dutchraptor's Avatar
The Netherlands, ZH, Hoogvliet
Joined Jul 2008
302 Posts
Hello Deckie,
Just downloaded your system. Looks good. I think I should be possible to send the data to a remote TFT/Uno screen. Are you staying with 1 main motor, or will there also be a second motor, perhaps like XXXX/YYYY rpm? I'm really interested in how and which components are used and connected. If it's allright with you I would like to find out if I can port it to a remote screen.

This is indeed, just what the doctor ordered. Keep up the good work.

Danny
Dutchraptor is offline Find More Posts by Dutchraptor
Reply With Quote
Old Dec 02, 2013, 03:45 AM
Registered User
Deckie's Avatar
Australia, WA, Garden Island
Joined Nov 2010
465 Posts
G'day fella's

Feel free to do whatever you want with the code, it won't bother me

Keep in mind that the version i've posted is configured for my future 1/72 Container ship. That doesn't mean you can't configure it for a second motor, just duplicated that bit of code and modify accordingly.

At the moment i'm looking at a modified version for my Stereguschy build (a much simpler version).

A remote screen setup would be interesting. All you would have to do is have the display code i've written running on the remote screen, with some code for recieving data via X-bee modules or whatever from the main arduino on board your vessel. Replace the display code on the main arduino with code for sending that stream via x-bee. Very interesting *rubs hands with glee*

On that note we got back from deployment today. And subsequently picked up the hull, the fleetscale plans and running gear from the mailroom! merry christmas

P.S.

For those wondering, here is the explanation i've given to Ticonderoga, regarding how I determine the decimal values for controlling the relay shield channels:

The 8 channels of the relay shield can be represented in the following binary diagram, channel 8 on the far left, channel 1 on the far right. I don't know why it works this way for the Freetronics shield, but it does.

0 0 0 0 0 0 0 0

If I want to turn on channel 7, I supply 0 1 0 0 0 0 0 0 to my binary/decimal and decimal/binary converter, and it spits out the value 64. Provide this to the arduino and it will do exactly what it's told. It will turn any of the 0 channels that are already ON to OFF, leaving channel 7 turned on, unless channel 7 was OFF in which case it will now be ON.

Now , we don't want to have to turn all of the channels off again before activating another channel/channels, i'd like to leave channel 7 turned on but also turn on channel 5 and channel 4, what value do I need for that?

I supply 0 1 0 1 1 0 0 0 to the binary/decimal converter and it gives me 88. Supply this to the arduino and it will do exactly that. If I want to turn off channel 4 and turn on channel 3 without affecting the others, I can use 01010100 which gives me 84.

Easy
Deckie is offline Find More Posts by Deckie
Reply With Quote
Reply


Thread Tools

Similar Threads
Category Thread Thread Starter Forum Replies Last Post
Discussion DIY Telemetry System base on TI CC110L RF BoosterPack spy004 DIY Electronics 2 Mar 06, 2013 07:58 AM
Discussion Land Based FPV System (what's best)? tsull FPV Talk 12 Feb 26, 2013 03:52 AM
Discussion Arduino Uno Based Flight Controller? alexgator Multirotor Electronics 4 Feb 15, 2013 12:49 AM
Discussion Arduino based ship safety (flood/overheat) system :D Deckie Scale Boats 29 Jan 27, 2013 05:27 AM
For Sale anti-collision flasher,NIP..$15. shipped epoxyearl Aircraft - General - Miscellaneous (FS/W) 0 Jan 04, 2013 04:32 AM