I'm using an uno with a DS18B20 one wire temp sensor and a generic opto-isolated 2 relay board like this:
https://arduino-info.wikispaces.com/RelayIsolation
My goal is to read temperature and pass that as "Input" to the PID. The PID actuates a relay to turn on a light bulb, which provides heat. The sensor & light bulb are in a styrofoam cooler. This is a proof of concept for making an incubator.
My problem is that the relay is not actuating when I put all the code together.
The wiring is fairly simple: DS18B20 on pin 3, relay "In0" on pin 6. Relay JD-Vcc is jumpered to Vcc and Arduino 5V & GND are wired to the relay board Vcc & GND (I'm not using full isolation at the moment.) Relay is active when pin is LOW.
Not changing the hardware configuration...
This works:
// This Arduino sketch reads DS18B20 "1-Wire" digital
// temperature sensors.
// Tutorial:
// http://www.hacktronics.com/Tutorials/arduino-1-wire-tutorial.html
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into pin 3 on the Arduino
#define ONE_WIRE_BUS 3
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// Assign the addresses of your 1-Wire temp sensors.
// See the tutorial on how to obtain these addresses:
// http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html
DeviceAddress insideThermometer = { 0x28, 0xA1, 0xF6, 0xE0, 0x04, 0x00, 0x00, 0x98 }; // this is my address
void setup(void)
{
// start serial port
Serial.begin(9600);
// Start up the library
sensors.begin();
// set the resolution to 10 bit (good enough?)
sensors.setResolution(insideThermometer, 10);
}
void printTemperature(DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC(deviceAddress);
if (tempC == -127.00) {
Serial.print("Error getting temperature");
} else {
Serial.print("C: ");
Serial.print(tempC);
Serial.print(" F: ");
Serial.print(DallasTemperature::toFahrenheit(tempC));
}
}
void loop(void)
{
delay(2000);
Serial.print("Getting temperatures...\n\r");
sensors.requestTemperatures();
Serial.print("Inside temperature is: ");
printTemperature(insideThermometer);
Serial.print("\n\r\n\r");
}
and this works:
#define RELAY1 6
void setup()
{
// Initialise the Arduino data pins for OUTPUT
pinMode(RELAY1, OUTPUT);
}
void loop()
{
digitalWrite(RELAY1,LOW); // Turns ON Relays 1
delay(2000); // Wait 2 seconds
digitalWrite(RELAY1,HIGH); // Turns Relay Off
delay(2000); // Wait 2 seconds
}
and this works:
#define RelayPin 6
int windowSize = 4000;
unsigned long windowStartTime;
double Output;
void setup()
{
// Initialise the Arduino data pins for OUTPUT
pinMode(RelayPin, OUTPUT);
// start serial port
Serial.begin(9600);
windowStartTime = millis();
Output = 2000; // pretend we have a 50% duty cycle
}
void loop()
{
unsigned long now = millis();
if (now - windowStartTime > windowSize)
{ windowStartTime += windowSize;
Serial.print("shifting the window...");
Serial.print("\n\r\n\r");
}
if (Output > now - windowStartTime)
{ digitalWrite(RelayPin,HIGH);
Serial.print("Relay Pin is HIGH");
Serial.print("\n\r\n\r");
}
else
{ digitalWrite(RelayPin,LOW);
Serial.print("Relay Pin is LOW");
Serial.print("\n\r\n\r");
}
Serial.print(now - windowStartTime);
Serial.print("\n\r\n\r");
Serial.print(Output);
Serial.print("\n\r\n\r");
}
but this does not work:
// This Arduino sketch reads a waterpoof DS18B20 temperature sensor
// and passes that value to the "input" of a PID instance.
// The PID then cycles a relay connected to a heater to
// achieve the "setpoint" temperature.
#include <OneWire.h>
#include <DallasTemperature.h>
#include <PID_v1.h>
#define RelayPin 6
#define ONE_WIRE_BUS 3 // Data wire is plugged into pin 3 on the Arduino
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// Assign the addresses of your 1-Wire temp sensors.
// See the tutorial on how to obtain these addresses:
// http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html
DeviceAddress peltierTemp = { 0x28, 0xA1, 0xF6, 0xE0, 0x04, 0x00, 0x00, 0x98 }; // this is my address
//Define Variables we'll be connecting to
double Setpoint, Input, Output;
//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);
int windowSize = 5000;
unsigned long windowStartTime;
void setup()
{
// start serial port
Serial.begin(9600);
// Start up the library
sensors.begin();
// set the resolution to 10 bit (good enough?)
sensors.setResolution(peltierTemp, 10);
windowStartTime = millis();
//initialize the variables we're linked to
Setpoint = 25; // why not make a 37 degree incubator...?
//tell the PID to range between 30 and the full window size
//Operarion Time(10ms) plus Release Time(5ms), doubled to 30ms
//We're using an electromechanical relay. SSR may be faster!
myPID.SetOutputLimits(30, windowSize);
//turn the PID on
myPID.SetMode(AUTOMATIC);
}
void printTemperature(DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC(deviceAddress); // here is where current temp is assigned to "tempC"
Input = tempC;
if (tempC == -127.00) {
Serial.print("Error getting temperature");
} else {
Serial.print("C: ");
Serial.print(tempC);
}
}
void loop()
{
Serial.print("Getting temperatures...\n\r");
sensors.requestTemperatures();
Serial.print("Inside temperature is: ");
printTemperature(peltierTemp);
Serial.print("\n\r\n\r");
// Setting input moved into the printTemperature function
myPID.Compute();
// turn the output pin on/off based on pid output
unsigned long now = millis();
if (now - windowStartTime > windowSize)
{ windowStartTime += windowSize;
Serial.print("shifting the window...");
Serial.print("\n\r\n\r");
}
if (Output > now - windowStartTime)
{ digitalWrite(RelayPin,HIGH);
Serial.print("Relay Pin is HIGH");
Serial.print("\n\r\n\r");
}
else
{ digitalWrite(RelayPin,LOW);
Serial.print("Relay Pin is LOW");
Serial.print("\n\r\n\r");
}
Serial.print(now - windowStartTime);
Serial.print("\n\r\n\r");
Serial.print(Output);
Serial.print("\n\r\n\r");
}
The code is not polished, but the section at the bottom is pasted directly from the relayWithMillis example above it.
Could there be interference between the I2C bus on pin 3 and the relay on pin 6?
Serial output indicates that the state of pin 6 is changing and a multimeter clipped to pin 6 confirms this.
Serial output also indicates that the PID algorithm is behaving as expected.
Tried both USB and external power + USB (to debug.) The relay should only pull a few mA from pin6 to trigger and the coil only pulls ~72 mA from Arduino 5V supply. Could it be a timing issue?
I am perplexed!! Thank you for any suggestions.