I have been making some progress with this project, though it feels glacial.
I had been stuck on getting the code to run properly through the calibration process. Initially I was using millis() in a while loop to stay in the calibration loop, but that was causing issues.
Here is what needs to happen:
- System turns on and initializes the inputs/outputs and display.
- System enters a calibration mode where air is allowed to flow throughout the system by opening a solenoid (airSupp). Next the sensors are calibrated in an embedded loop to find the max values for each and then the loop continues.
- At some interval a second solenoid opens to vent the pressure to establish the sensor minimums.
- the calibration stops. We make sure to close the "airVent" and leave the "airSupp" open and turn off the calibration indicator.
- We enter the main loop and scan each sensor to display it's output on the graph.
Some further thoughts. There are two buttons currently in the circuit and these with need to be used to select the mode and calibration. The calibration routine will only be able to run when the tanks are full. The sensors should be seperated so that the process can be completed one at a time. Also once the initial reads are completed there is little need to ontinue polling the sensors. This could be done via interupt that runs a "sensorCheck" function. This would open the "airSupp" and take each new reading.
This code is kinda crude, even for me, but I have just been concentrating on getting different pieces working. It does not display properly on the screen when calibrating, but I know where I screwed up there. I am open to suggestions for a better layout.
#include <TVout.h>
#include <fontALL.h>
TVout TV;
/*
This sketch was designed by Sean Shoemaker, Feb, 2013. It is designed to
read and display the liquid level in 5 seperate tanks to a "TV." It utilizes one
Freescale MPX5050 Pressure transducer per tank, a control solenoid for an air supply
and an Arduino.
MXP 5050
Pin 1 (notch) - Analog output to Arduino pins A0-A4
Pin 2 - Gnd
Pin 3 - 5V
*/
int tankPin[] = {A0, A1, A2, A3, A4}; // set analog pins to pin 1 on the MXP-5050
int tankValue[] = {0, 0, 0, 0, 0}; // Variable stores value coming from Tank 1-5
//Arduino Uno pin 7 (video) to TV center pin through 1 kohm resistor
//Arduino Uno pin 9 (sync) to TV center pin through 470 ohm resistor(330 seems to work fine)
int airSupp = 6; //12VDC air solenoid controled by FQP30N06L MOSFET to purge air lines and prep for test.
int airVent = 5; //addntl solenoid to vent the pressure in the airline for auto calibration.
int modeButt = 4; //Change between display modes and allow for future expansion
int testStart = 3; //button to start test routine and allow for future expansion
int tankMin[] = {1023, 1023, 1023, 1023, 1023}; // minimum sensor value
int tankMax[] = {0, 0, 0, 0, 0}; // maximum sensor value
int whiteFill = 0;
int calibLed = 13;
int columnSelect[] = {0, 23, 46, 69, 92}; //Set the column array for the tanks
int tankDis = 0; //Set a variable for which tank is being displayed
int tankCalib = 0; //Set a variable for which sensor is being calibrated
void setup() { //Setup the "TV" Output
TV.begin(NTSC, 120, 96);
TV.select_font(font6x8);
TV.println("Welcome to the Shoetronics Oil Level Monitoring System.");
TV.delay(2500);
Serial.begin(9600);
// turn on LED to signal the start of the calibration period:
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
TV.clear_screen(); // clears the screen and buffer
int ventTime = 0;
// calibrate during the first seven seconds
for (int calibTime = 0; calibTime < 70; calibTime++) {
Serial.print(calibTime);
digitalWrite(airSupp, HIGH);
for (int tankCalib = 0; tankCalib < 5; tankCalib++) {
tankValue[tankCalib] = analogRead(tankPin[tankCalib]);
// record the maximum sensor value
if (tankValue[tankCalib] > tankMax[tankCalib]) {
tankMax[tankCalib] = tankValue[tankCalib];
}
// record the minimum sensor value
if (tankValue[tankCalib] < tankMin[tankCalib]) {
tankMin[tankCalib] = tankValue[tankCalib];
}
if (ventTime < 10 ) { //|| millis() == 2000 || millis() == 3000 || millis() == 4000 || millis() == 5000 || millis() == 6000)
digitalWrite(airVent, HIGH);
}
else {
digitalWrite(airVent, LOW);
}
TV.print(10,0, "Now Calibrating");
TV.print(columnSelect[tankCalib], tankCalib + 10, tankCalib); // Display numeric result
TV.print("H");
TV.print(tankMax[tankCalib]);
TV.print(" L");
TV.println(tankMin[tankCalib]); // Display result
TV.delay(100);
if (ventTime > 24) {
ventTime = 0;
}
Serial.println(ventTime);
ventTime++;
}
//signal the end of calibration period
}
digitalWrite(airSupp, LOW);
digitalWrite(airVent, LOW);
digitalWrite(13, LOW);
TV.println("Calibration completed");
TV.delay(1000);
TV.clear_screen(); // clears the screen and buffer
}
void loop() {
testTank();
//tank1 meter
}
void testTank () {
for (int tankDis = 0; tankDis < 5; tankDis++) {
tankValue[tankDis] = analogRead(tankPin[tankDis]); // Read sensor
tankValue[tankDis] = map(tankValue[tankDis], tankMin[tankDis], tankMax[tankDis], 0, 80);
tankValue[tankDis] = constrain(tankValue[tankDis], 0, 80);
whiteFill = map(tankValue[tankDis], 0, 80, 80, 0);
TV.print(columnSelect[tankDis], 0, tankValue[tankDis], DEC); // Display numeric result
TV.draw_rect(columnSelect[tankDis], 10, 18, 80, WHITE, BLACK);
TV.draw_rect(columnSelect[tankDis], whiteFill + 9, 18, tankValue[tankDis], WHITE, WHITE);
delay(400);
}
}