I have a weird problem. I am using an Arduino Mega and three of these thermocouples https://www.adafruit.com/product/269
They work perfectly when my Arduino is connected to the computer, but when I run it with a power supply( I tried 12V and 9V) the values are totally wrong. They show NAN or much too high or too low values changing every second. It happens when I use only the power supply and when I use the power supply and my laptop.
Here is my code, temperature measurement is in the TEMPERATURE sections. But I'm pretty sure it is a Hardware problem. It should be wired correctly because it works with my computer...
Code: Select all
//Pump durability tester code
//includes:
//-thermal shutdown circuit
//-motor speed control via relay
//-pump flowrate monitoring
// include the library code for I2C and the LCD shield:
#include "Adafruit_MAX31855.h"
#include <Wire.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>
//DATALOGGING---------------------------------------------------------------------------
#include <SD.h>
#include "RTClib.h"
#define SYNC_INTERVAL 1000 // mills between calls to flush() - to write data to the card
uint32_t syncTime = 0; // time of last sync()
#define LOG_INTERVAL 1000 // mills between entries (reduce to take more/faster data)
RTC_DS1307 RTC; // define the Real Time Clock object
// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10;
// the logging file
File logfile;
//DATALOGGING---------------------------------------------------------------------------
#define PIN_BUTTON 52 // connects to the ON/OFF button
//#define PIN_I2C_1 A4 // these pins provide serial communication with the LCD shield
//#define PIN_I2C_2 A5 // these pins provide serial communication with the LCD shield
#define THRESHOLD_TEMPERATURE_Reservoir1 100 // maximum oil temperature for normal operation
#define THRESHOLD_TEMPERATURE_Reservoir2 100 // maximum oil temperature for normal operation
#define THRESHOLD_TEMPERATURE_AMBIENT 60 // maximum ambient temperature for normal operation
#define STATE_ESTOP_ACTIVE HIGH // E-stop pin is pulled high internally, then grounded through E-stop button
// the button is NC, thus pressed means open means not grounded means HIGH
#define Relay_STOP 44 // Relay control output
#define Relay1 46 // Relay speed1
#define Relay2 48 // Relay speed2
#define Relay3 50 // Relay speed3
#define thermoDO 6 // Data out (shared)
#define thermoCS1 3 // Chip select for thermocouple 1
#define thermoCLK 5 // Clock (shared)
#define thermoCS2 2 // Chip select for thermocouple 2
#define thermoCS3 4 // Chip select for thermocouple 3
#define time double (millis()/1000)/60 // Program runtime.
// Variables will change:
long previousMillis = 0;
// The shield uses the I2C SCL and SDA pins. On classic Arduinos
// this is Analog 4 and 5 so you can't use those for analogRead() anymore
// However, you can connect other I2C sensors to the I2C bus and share
// the I2C bus.
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();
// this creates an LCD object that is controlled using the Adafruit library
Adafruit_MAX31855 thermocouple1(thermoCLK, thermoCS1, thermoDO);
Adafruit_MAX31855 thermocouple2(thermoCLK, thermoCS2, thermoDO);
Adafruit_MAX31855 thermocouple3(thermoCLK, thermoCS3, thermoDO);
//FLOWMETERS-------------------------------------------------------------------------------------
typedef struct Meter_t
{
uint8_t pin;
uint16_t pulses;
uint8_t lastflowpinstate;
uint32_t lastflowratetimer;
float flowrate;
float wert;
float lmin;
};
volatile Meter_t meters[] = { // initialize meter array
{ 28, 0, 0, 0, 0.0 }, // meter 1: pin, pulses, lastflowpinstate, lastflowratetimer, flowrate
// { 30, 0, 0, 0, 0.0 }, // meter 2: pin, pulses, lastflowpinstate, lastflowratetimer, flowrate
// { 32, 0, 0, 0, 0.0 }, // meter 3: pin, pulses, lastflowpinstate, lastflowratetimer, flowrate
{ 34, 0, 0, 0, 0.0 }, // meter 4: pin, pulses, lastflowpinstate, lastflowratetimer, flowrate
{ 36, 0, 0, 0, 0.0 }, // meter 5: pin, pulses, lastflowpinstate, lastflowratetimer, flowrate
// { 38, 0, 0, 0, 0.0 }, // meter 6: pin, pulses, lastflowpinstate, lastflowratetimer, flowrate
{ 40, 0, 0, 0, 0.0 }, // meter 7: pin, pulses, lastflowpinstate, lastflowratetimer, flowrate
{ 42, 0, 0, 0, 0.0 } // meter 8: pin, pulses, lastflowpinstate, lastflowratetimer, flowrate
// add more meters as needed
};
#define NUM_METERS (sizeof(meters) / sizeof(Meter_t))
SIGNAL(TIMER0_COMPA_vect) {
for (int m = 0; m < NUM_METERS; m++)
{
uint8_t x = digitalRead(meters[m].pin);
if (x == meters[m].lastflowpinstate) {
meters[m].lastflowratetimer++;
}
else
{
if (x == HIGH) {
//low to high transition!
meters[m].pulses++;
}
meters[m].lastflowpinstate = x;
meters[m].flowrate = 1000.0;
meters[m].flowrate /= meters[m].lastflowratetimer; // in hertz
meters[m].lastflowratetimer = 0;
}
}
}
void useInterrupt(boolean v) {
if (v) {
// Timer0 is already used for millis() - we'll just interrupt somewhere
// in the middle and call the "Compare A" function above
OCR0A = 0xAF;
TIMSK0 |= _BV(OCIE0A);
}
else {
// do not call the interrupt function COMPA anymore
TIMSK0 &= ~_BV(OCIE0A);
}
//FLOWMETERS-------------------------------------------------------------------------------------
}
void setup() {
Serial.begin(9600);
Serial.print("Flow sensor test!");
// declare the number of columns and rows for the LCD:
lcd.begin(16, 2);
//FLOWMETERS-------------------------------------------------------------------------------------
for (int m = 0; m < NUM_METERS; m++)
{
pinMode(meters[m].pin, INPUT);
digitalWrite(meters[m].pin, HIGH);
meters[m].lastflowpinstate = digitalRead(meters[m].pin);
}
useInterrupt(true);
//FLOWMETERS-------------------------------------------------------------------------------------
//pinMode(PIN_ESTOP, INPUT_PULLUP);
pinMode(PIN_BUTTON, INPUT_PULLUP);
pinMode(Relay_STOP, OUTPUT);
digitalWrite(Relay_STOP, LOW);
lcd.setCursor(0,0);
lcd.print("Motor ON");
lcd.setCursor(0,1);
lcd.print("VFD Enabled");
//SPEEDCONTROL-------------------------------------------------------------------------------------
pinMode(Relay1, OUTPUT);
digitalWrite(Relay1, HIGH);
pinMode(Relay2, OUTPUT);
digitalWrite(Relay2, HIGH);
pinMode(Relay3, OUTPUT);
digitalWrite(Relay3, HIGH);
//SPEEDCONTROL-------------------------------------------------------------------------------------
//DATALOGGING--------------------------------------------------------------------------------------
// initialize the SD card
Serial.print("Initializing SD card...");
// make sure that the default chip select pin is set to
// output, even if you don't use it:
pinMode(10, OUTPUT);
Serial.println("card initialized.");
// create a new file
char filename[] = "LOGGER00.CSV";
for (uint8_t i = 0; i < 100; i++) {
filename[6] = i/10 + '0';
filename[7] = i%10 + '0';
if (! SD.exists(filename)) {
// only open a new file if it doesn't exist
logfile = SD.open(filename, FILE_WRITE);
break; // leave the loop!
}
}
Serial.print("Logging to: ");
Serial.println(filename);
// connect to RTC
Wire.begin();
logfile.println("millis,temperatureAmbient");
//DATALOGGING--------------------------------------------------------------------------------------
} //end of setup()
void loop()
{
//digitalWrite(Relay_STOP, LOW);
//checkBUTTON();
//checkThermocouples();
//TIMEKEEPING---------------------------------------------------------------------------------------
unsigned long runtime = millis(); //runtime in millis
int cycles = runtime/150000; // calculate cycles
runtime /= 1000; //runtime in seconds
Serial.print("Runtime: "); Serial.print(runtime); Serial.println(" seconds");
Serial.print("Cycles: "); Serial.println(cycles);
Serial.println(" ");
//TIMEKEEPING---------------------------------------------------------------------------------------
//FLOWMETERS-------------------------------------------------------------------------------------
float lmin_max = 0.0;
float lmin_min = 1000.0;
int pump_max = 0;
int pump_min = 0;
for (int m = 0; m < NUM_METERS; m++)
{
//average filter
int i;
meters[m].wert = 0;
for(i = 0; i < 50; i++) {
meters[m].wert += meters[m].flowrate;}
meters[m].wert /= 50;
meters[m].lmin = meters[m].wert;
meters[m].lmin *=0.12;
if( meters[m].lmin > lmin_max){
lmin_max = meters[m].lmin;
pump_max = m;
}
if (meters[m].lmin < lmin_min)
{
lmin_min = meters[m].lmin;
pump_min = m;
}
// Serial.print("Min: "); Serial.print(lmin_min);Serial.print(" ");
// Serial.print("Max: "); Serial.print(lmin_max);Serial.print(" ");
//Serial.print("Diff: "); Serial.print(lmin_max - lmin_min);Serial.print(" ");
// Serial.print("\n");
if ((lmin_max - lmin_min) >= 3.0)
{
digitalWrite(Relay_STOP, HIGH);
Serial.print(" ");
Serial.print("Failed Pumps:");
Serial.print(pump_min+1);
Serial.print(" ");
Serial.print(pump_max+1);
Serial.print("Min: "); Serial.print(lmin_min);Serial.print(" ");
Serial.print("Max: "); Serial.print(lmin_max);Serial.print(" ");
unsigned long failtime = runtime;
int failcycles = failtime/150000;
Serial.print("Failed after Cycles:");
Serial.print(cycles);
lcd.setCursor(0,0);
lcd.print("Failed Pump:");
lcd.setCursor(1,0);
lcd.print("Cycles:");
lcd.print(failcycles);
while(1) {}
}
//lcd.print(flowrate);
Serial.print("Meter ");
Serial.print(m+1);
Serial.print(" FLowrate in l/min: ");
Serial.println(meters[m].lmin);
Serial.println("");
// Serial.print("Pulses: ");
// Serial.println(meters[m].pulses, DEC);
}
//FLOWMETERS-------------------------------------------------------------------------------------
//SPEEDCONTROL-------------------------------------------------------------------------------------
unsigned long currentMillis = millis();
if(currentMillis - previousMillis < 120000) {
digitalWrite(Relay1, LOW);
}
else {
digitalWrite(Relay1, HIGH);
}
if(currentMillis - previousMillis > 120000 && currentMillis - previousMillis < 135000) {
digitalWrite(Relay2, LOW);
}
else {
digitalWrite(Relay2, HIGH);
}
if(currentMillis - previousMillis > 135000 && currentMillis - previousMillis < 150000) {
digitalWrite(Relay3, LOW);
}
else {
digitalWrite(Relay3, HIGH);
}
if(currentMillis - previousMillis >= 150000) {// reset the timer and start again
previousMillis = currentMillis;
}
//SPEEDCONTROL-------------------------------------------------------------------------------------
//TEMPMONITORING-----------------------------------------------------------------------------------
double temperatureAmbient = thermocouple1.readCelsius(); // read motor temperature from thermocouple
double temperatureReservoir1 = temperatureReservoir1 = thermocouple2.readCelsius();// read ambiant temperature from thermocouple
double temperatureReservoir2 = temperatureReservoir2 = thermocouple3.readCelsius();// read ambiant temperature from thermocouple
Serial.print("Temperature Motor: ");
Serial.print(temperatureAmbient); Serial.println(" C");
Serial.print("Temperature Reservoir 1: ");
Serial.print(temperatureReservoir1); Serial.println(" C");
Serial.print("Temperature Reservoir 2: ");
Serial.print(temperatureReservoir2); Serial.println(" C");
Serial.println(" ");
// lcd.setCursor(0,0); // display data on LCD
// lcd.print("Motor: ");
// lcd.print(temperatureAmbient);
// lcd.print(" C");
// lcd.setCursor(0,1); // display data on LCD
// lcd.print("Ambient: ");
// lcd.print(temperatureReservoir1);
// lcd.print(" C");
if (temperatureAmbient >= THRESHOLD_TEMPERATURE_AMBIENT) // if temperature is too high
{
digitalWrite(Relay_STOP, HIGH); // shut down Motor
// lcd.setBacklight(RED); // display warning on LCD
lcd.clear();
lcd.setCursor(0,0);
lcd.print("T_Motor Limit Reached");
// lcd.setCursor(0,1);
// lcd.print("RT: ");
// lcd.println(time);
// lcd.println( " (min)");
while(1) {} // wait for reset
}
if (temperatureReservoir1 > THRESHOLD_TEMPERATURE_Reservoir1) // if temperature is too high
{
digitalWrite(Relay_STOP, HIGH); // shut down Motor
// lcd.setBacklight(RED); // display warning on LCD
lcd.clear();
lcd.setCursor(0,0);
lcd.print("T_RES1 Limit Reached");
// lcd.setCursor(0,1);
// lcd.print("RT: ");
// lcd.println(time);
// lcd.println( " (min)");
while(1) {} // wait for reset
}
if (temperatureReservoir2 > THRESHOLD_TEMPERATURE_Reservoir2) // if temperature is too high
{
digitalWrite(Relay_STOP, HIGH); // shut down Motor
// lcd.setBacklight(RED); // display warning on LCD
lcd.clear();
lcd.setCursor(0,0);
lcd.print("T_RES2 Limit Reached");
// lcd.setCursor(0,1);
// lcd.print("RT: ");
// lcd.println(time);
// lcd.println( " (min)");
while(1) {} // wait for reset
}
//TEMPMONITORING-----------------------------------------------------------------------------------
//PROGRAM RUNTIME---------------------------------------------------------------------------------------
if( cycles > 100000){
digitalWrite(Relay_STOP, HIGH);
while(1) {} // wait for reset
}
//PROGRAM RUNTIME---------------------------------------------------------------------------------------
//DATALOGGING--------------------------------------------------------------------------------------
DateTime now;
// log milliseconds since starting
uint32_t m = millis();
logfile.print(m); // milliseconds since start
logfile.print(", ");
// fetch the time
now = RTC.now();
// log time
logfile.print(now.unixtime()); // seconds since 1/1/1970
logfile.print(", ");
logfile.print('"');
logfile.print(now.year(), DEC);
logfile.print("/");
logfile.print(now.month(), DEC);
logfile.print("/");
logfile.print(now.day(), DEC);
logfile.print(" ");
logfile.print(now.hour(), DEC);
logfile.print(":");
logfile.print(now.minute(), DEC);
logfile.print(":");
logfile.print(now.second(), DEC);
logfile.print('"');
logfile.print(", ");
logfile.print(temperatureAmbient);
//DATALOGGING--------------------------------------------------------------------------------------
} // end of loop()