Rack Controller

Build a rack control panel that:connect

  • Reads temperature and relative humidity from two locations on the rack (DS22 sensors)

  • Provides 6 potentiometers - one for each bank - acting as dimmer controllers

  • Includes a display showing temperatures, humidity, lux and light percentages for each bank

  • AC voltage and amperage 

  • Main power switch to PS’s

  • Air conditioning thermostat control

  • Records cumulative times for bottle exposure and lumens 

The rack controller is based on a Arduino UNO configuration like this:

  1. connect 6 potentiometers

  2. connect 6 mosfets to control led strips

  3. connect DH22 temperature/humidity sensor

  4. connect 4 Relay module to PS

  5. connect ESP8266 WIFI module

  6. connect display?

Arduino Nano pinouts

Pin

Destination

color

A0

redPOT

 

A1

greenPOT

 

A2

bluePOT

 

A3

warmPOT

 

A4

esp8266 TX

green

A5

esp8266 RX

blue

A6

neutralPOT

 

A7

coldPOT

 

0

-

 

1

-

 

2

DHT-22

 

3

redLED

 

4

relay4

celeste

5

greenLED

 

6

blueLED

 

7

relay1

yellow

8

relay2

blue

9

warmLED

 

10

neutralLED

 

11

coldLED

 

12

relay3

green

13

piezo buzzer

 

 

 

Burning the nano bootloader

After several sketch uploads to the nano board, the bootloader can be corrupted and a new bootloader needs to be uploaded.

To do this, we use an Arduino UNO as a programmer, and the Nano as the target:

 

 

 

Then connect the working Arduino UNO to the computer vía USB

- Go to Tools>Serial Port>COM (and make sure again that the correct COM port is chosen - ask me if you don't what this means)

- Go to Tools>Board>Arduino Nano w/Atmega 328 (this time we choose the non working arduino, in my case nano atmega 328) 

- Go to Tools>Programmer>Arduino as ISP

- Go to Tools>Burn Bootloader (this is it, after the LEDs stop flashing your board is ready to use !!!)

Connecting 6 Potentiometers and IRF520 Mosfets

We connect six 10K potentiometers, to control the 6 different lighting configurations.

 

These are 10K linear slide pots from Bourns (PTF60-TS05-103A2) that were previously used in a mixing console at Zentraus in Barcelona.

Pin 1 on the potentiometers represents the wiper, and is connected to the analog input pins on the arduino. Pin 2 is connected to 5v and pin 3 to ground.

Pins 1', 2', and 3' are not used.

 

If rotary pots are used, as seen from behind the pot, the left pin connects to 5V, and the right pin to ground.

 

 

// the setup routine runs once when you press reset:
void setup() {
// initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
// read the input on analog pin 0:

int redPOT = analogRead(A0); // the PWM pin the blueLED is attached to
int greenPOT = analogRead(A1); // the PWM pin the greenLED is attached to
int bluePOT = analogRead(A2); // the PWM pin the redLED is attached to
int warmPOT = analogRead(A3); // the PWM pin the coldLED is attached to
int neutralPOT = analogRead(A6); // the PWM pin the neutralLED is attached to
int coldPOT = analogRead(A7); // the PWM pin the warmLED is attached to


// print out the value you read:
Serial.print("Blue ");
Serial.println(bluePOT);
Serial.print("Green ");
Serial.println(greenPOT);
Serial.print("Red ");
Serial.println(redPOT);
Serial.print("Cold ");
Serial.println(coldPOT);
Serial.print("Neutral ");
Serial.println(neutralPOT);
Serial.print("Warm ");
Serial.println(warmPOT);
delay(500);
}

Connecting the OLED display

Connect the 4 Relay module

The four 250W (220VAC) 12V power supplies for the LED strips are connected to a four channel relay module, allowing the arduino to power on/off the power supplies. This is necessary for timing the number of hours of light exposure. Also, it enables us to power on/off the 12V power supplies in sequence, reducing the chances of a power spike tripping the 10A breaker switch. However, it mandates that we use a separate 12v power supply for the rack controller, rather than stealing power from one of the 4 PSU's.

There are six connections on the relay module

Pin

Connection on Arduino

GND

Ground

IN1

7

IN2

8

IN3

12

IN4

4

The oode for testing the relay modules is as follows:

/**********************************************/
const int relay1 = 7; //the "s" of relay module attach to
const int relay2 = 8;
const int relay3 = 12;
const int relay4 = 14;
/**********************************************/
void setup()
{
pinMode(relay1, OUTPUT); //initialize relay as an output
pinMode(relay2, OUTPUT); //initialize relay as an output
pinMode(relay3, OUTPUT); //initialize relay as an output
pinMode(relay4, OUTPUT); //initialize relay as an output
}
/***********************************************/
void loop()
{
digitalWrite(relay1, HIGH); //Close the relay
delay(1000); //wait for 1 second
digitalWrite(relay2, HIGH); //Close the relay
delay(1000); //wait for 1 second
digitalWrite(relay3, HIGH); //Close the relay
delay(1000); //wait for 1 second
digitalWrite(relay4, HIGH); //Close the relay
delay(1000); //wait for 1 second
digitalWrite(relay1, LOW); //disconnect the relay
delay(1000); //wait for 1 second
digitalWrite(relay2, LOW); //disconnect the relay
delay(1000); //wait for 1 second
digitalWrite(relay3, LOW); //disconnect the relay
delay(1000); //wait for 1 second
digitalWrite(relay4, LOW); //disconnect the relay
delay(1000); //wait for 1 second
}
/*************************************************/

Connecting the DHT22 temperature / humidity sensor

We are using a DHT22 temperature and humidity sensor. The sensor has 4 pins, but only pins 1,2, and 4 (left to right) are used. 

 

Pin

Connection on Arduino

1

5V

2

2

3

-

4

GND

The oode for testing the temperature/humidity sensor is as follows:

// Example testing sketch for various DHT humidity/temperature sensors
// Written by ladyada, public domain

// REQUIRES the following Arduino libraries:
// - DHT Sensor Library: https://github.com/adafruit/DHT-sensor-library
// - Adafruit Unified Sensor Lib: https://github.com/adafruit/Adafruit_Sensor

#include "DHT.h"

#define DHTPIN 2 // Digital pin connected to the DHT sensor#define DHTTYPE DHT22

// Connect pin 1 (on the left) of the sensor to +5V
// NOTE: If using a board with 3.3V logic like an Arduino Due connect pin 1
// to 3.3V instead of 5V!
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

// Initialize DHT sensor.
// Note that older versions of this library took an optional third parameter to
// tweak the timings for faster processors. This parameter is no longer needed
// as the current DHT reading algorithm adjusts itself to work on faster procs.
DHT dht(DHTPIN, DHTTYPE);

void setup() {
Serial.begin(9600);
Serial.println(F("DHTxx test!"));

dht.begin();
}

void loop() {
// Wait a few seconds between measurements.
delay(2000);

// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
float h = dht.readHumidity();
// Read temperature as Celsius (the default)
float t = dht.readTemperature();
// Read temperature as Fahrenheit (isFahrenheit = true)
float f = dht.readTemperature(true);

// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t) || isnan(f)) {
Serial.println(F("Failed to read from DHT sensor!"));
return;
}

// Compute heat index in Fahrenheit (the default)
float hif = dht.computeHeatIndex(f, h);
// Compute heat index in Celsius (isFahreheit = false)
float hic = dht.computeHeatIndex(t, h, false);

Serial.print(F("Humidity: "));
Serial.print(h);
Serial.print(F("% Temperature: "));
Serial.print(t);
Serial.print(F("°C "));
Serial.print(f);
Serial.print(F("°F Heat index: "));
Serial.print(hic);
Serial.print(F("°C "));
Serial.print(hif);
Serial.println(F("°F"));
}

Connecting the ESP8266 WIFI module

The ESP8266 connects the arduino to the world, vía WIFI. This enables us to use Blynk, or other tools to connect remotely and monitor the status of everything.

These are the pinouts on the ESP8266 module:

 

We are going to use the Arduino IDE to program the initial setup of the ESP8266. To do this, we need to first CAREFULLY remove the MCU from the Arduino UNO.

 

 

The connection for the initial programming between the arduino UNO and the ESP8266 are:

ESP8266

Arduino

TX

TX (1)

CH_PD

3.3V (External)

RST

.

3.3VCC

3.3V (External)

GND

GND

GPIO2

-

GPIO0

-

RX

RX(0)

Although you can power the ESP8266 from the Arduino 3v3 connector, it is recommended that you use an external power source like this:

 

From the Arduino IDE serial monitor, we can issue AT commands to setup the wifi configuration (and change the serial speed to 9600 baud = AT+UART_DEF=9600,8,1,0,0)

AT

OK

AT+GMR
AT version:0.40.0.0(Aug 8 2015 14:45:58)
SDK version:1.3.0
Ai-Thinker Technology Co.,Ltd.
Build:1.3.0.2 Sep 11 2015 11:48:04
OK

AT+CWMODE?
+CWMODE:2

OK
AT+CWMODE=1

OK
AT+CWLAP
+CWLAP:(0,"costaflores",-61,"98:01:a7:e7:c7:02",1,5)
+CWLAP:(4,"openvino",-75,"d4:6e:0e:32:44:d2",6,1)

AT+CWJAP="costaflores",""
WIFI CONNECTED
WIFI GOT IP

OK

AT+CIPMUX=1

OK
AT+CIPSERVER=1,80

OK
AT+CIFSR
+CIFSR:STAIP,"192.168.0.73"
+CIFSR:STAMAC,"18:fe:34:e1:16:ff"

OK
0,CONNECT

+IPD,0,352:GET / HTTP/1.1
Host: 192.168.0.73
Upgrade-Insecure-Requests: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Safari/605.1.15
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: keep-alive

0,CLOSED
0,CONNECT

 

After the initial programming of the ESP8266 module, we can replace the Arduino MCU and rewire the Arduino and ESP8266 such that Arduino TX goes to ESP8266 RX, and RX to TX (crossed). Because the Arduino Nano needs to communicate over a serial connection to the ESP8266, and because we want to keep our ability to use a serial monitor and data upload over USB (mostly for testing and updates), we use SoftwareSerial on pins 18,19 (A4 and A5), leaving TX and RX free.

ESP8266 Pinounts

 

 

ESP8266

Arduino

Color

TX

A4

Green

CH_PD

3.3V (External)

Red

RST

.

 

3.3VCC

3.3V (External)

Orange

GND

GND

Yellow

GPIO2

-

 

GPIO0

-

 

RX

A5

Blue

The ESP8266 is a 3.3V device. Although CH_PD and VCC can be connected to the 3.3V rail of an external power supply (the Nano 3.3V supply is insufficient for operations), we still need to setup a voltage divider to reduce the 5V transmit voltage on the Nano (A5) to 3.3V receive voltage (RX) on the ESP8266.

 

 

Here is a good tutorial on the voltage divider: https://arduino.stackexchange.com/questions/38255/how-to-select-which-resistor-is-required-for-my-curcuit-to-reduce-voltage

 

 

From then on, we can program the ESP8266 from the Arduino:

  1. Install the Blynk app, create an initial project , and register the Auth token.

  2. Install the Blynk libraries (do this by copying the library files and tools manually! - not through the Arduino IDE)

  3. Test with a basic sketch created on examples.blynk.cc 

  4. Modify the sketch to accommodate other winewall requirements.

There are many tutorials on YouTube showing how to do this. This is a good one, though you have to turn down the volume because of the horrible music. 

Here is the final sketch for the winewall:

 

// Blynk Setup
// #define BLYNK_DEBUG
#define BLYNK_HEARTBEAT 10
#define BLYNK_TIMEOUT_MS 5000
#define BLYNK_PRINT Serial
#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
#include "DHT.h"

#include <TimeLib.h>
#include <WidgetRTC.h>

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).

char auth[] = "NBJFyqPu2_AGly0F3AU2J6n2zBUvv2Xn";

// Your WiFi credentials.
// Set password to "" for open networks.

char ssid[] = "costaflores";
char pass[] = "";

// Hardware Serial on Mega, Leonardo, Micro...
//#define EspSerial Serial1
// or Software Serial on Uno, Nano...

#include <SoftwareSerial.h>
SoftwareSerial EspSerial(18, 19); // RX, TX

// Your ESP8266 baud rate:

#define ESP8266_BAUD 9600

ESP8266 wifi(&EspSerial);

#define DHTPIN 2 // What digital pin we're connected to

// Uncomment whatever type you're using!
//#define DHTTYPE DHT11 // DHT 11
#define DHTTYPE DHT22 // DHT 22, AM2302, AM2321
//#define DHTTYPE DHT21 // DHT 21, AM2301

DHT dht(DHTPIN, DHTTYPE);

BlynkTimer timer;

// This function sends Arduino's up time every second to Virtual Pin (5).
// In the app, Widget's reading frequency should be set to PUSH. This means
// that you define how often to send data to Blynk App.


void myTimerEvent()
{
// You can send any value at any time.
// Please don't send more that 10 values per second.


Blynk.virtualWrite(V5, millis() / 1000);

}

WidgetRTC rtc;

// Digital clock display of the time
void clockDisplay()
{
// You can call hour(), minute(), ... at any time
// Please see Time library examples for details

String currentTime = String(hour()) + ":" + minute() + ":" + second();
String currentDate = String(day()) + " " + month() + " " + year();
Serial.print("Current time: ");
Serial.print(currentTime);
Serial.print(" ");
Serial.print(currentDate);
Serial.println();

// Send time to the App
Blynk.virtualWrite(V1, currentTime);
// Send date to the App
Blynk.virtualWrite(V2, currentDate);
}

BLYNK_CONNECTED() {
// Synchronize time on connection
rtc.begin();
}

void sendSensor()
{
float h = dht.readHumidity();
float t = dht.readTemperature(); // or dht.readTemperature(true) for Fahrenheit

Serial.print(F("Humidity: "));
Serial.print(h);
Serial.print(F("% Temperature: "));
Serial.print(t);
Serial.println(F("°C "));

Blynk.virtualWrite(V6, h);
Blynk.virtualWrite(V7, t);

}
// Buzzer setup

//Specify digital pin on the Arduino that the positive lead of piezo buzzer is attached.
int piezoPin = 13;


//Specify the analog pins used to read each slider

int redPOT = analogRead(A0); // the PWM pin the LED sliders are attached to
int greenPOT = analogRead(A1);
int bluePOT = analogRead(A2);
int warmPOT = analogRead(A3);
int neutralPOT = analogRead(A6);
int coldPOT = analogRead(A7);

//Specify the PWM pins used to graduate the LED strips

const int redLED = 3; // the PWM pins the LED strips (mosfet gates) are attached to
const int greenLED = 5;
const int blueLED = 6;
const int warmLED = 9;
const int neutralLED = 10;
const int coldLED = 11;

// Define the initial slider values

int red = 0;
int green = 0;
int blue = 0;
int warm = 0;
int neutral = 0;
int cold = 0;

//Relay setup: specify the digital pins used to control the 4 Power Supply units

const int relay1 = 7; //the "s" of relay module attach to
const int relay2 = 8;
const int relay3 = 12;
const int relay4 = 4;

void turnon()
{

if (hour() <= 14 )

{

digitalWrite(relay1, HIGH);
digitalWrite(relay2, HIGH);
digitalWrite(relay3, HIGH);
digitalWrite(relay4, HIGH);

}
else

{
digitalWrite(relay1, LOW);
digitalWrite(relay2, LOW);
digitalWrite(relay3, LOW);
digitalWrite(relay4, LOW);
}

}


void setup() {
// Debug console
Serial.begin(9600);

//Play the Close Enounters theme to annouce we are running
tone(piezoPin, 587, 400);
delay(450);
tone(piezoPin, 659, 400);
delay(450);
tone(piezoPin, 523, 400);
delay(450);
tone(piezoPin, 277, 400);
delay(450);
tone(piezoPin, 391, 800);
delay(1500);

// Set ESP8266 baud rate
EspSerial.begin(ESP8266_BAUD);
delay(100);

Blynk.begin(auth, wifi, ssid, pass);
// You can also specify server:
//Blynk.begin(auth, wifi, ssid, pass, "blynk-cloud.com", 80);
//Blynk.begin(auth, wifi, ssid, pass, IPAddress(192,168,1,100), 8080);


dht.begin();


tone(piezoPin, 2600, 50);

// Turn on the relays (default)

pinMode(relay1, OUTPUT); //initialize relay as an output
pinMode(relay2, OUTPUT); //initialize relay as an output
pinMode(relay3, OUTPUT); //initialize relay as an output
pinMode(relay4, OUTPUT); //initialize relay as an output

digitalWrite(relay1, HIGH); //Close the relay
delay(100); //wait for 1 second
digitalWrite(relay2, HIGH); //Close the relay
delay(100); //wait for 1 second
digitalWrite(relay3, HIGH); //Close the relay
delay(100); //wait for 1 second
digitalWrite(relay4, HIGH); //Close the relay
delay(100); //wait for 1 second


// Setup a function to be called every second

timer.setInterval(10000L, sendSensor);
timer.setTimeout(100000L, sendSensor);

// Other Time library functions can be used, like:
// timeStatus(), setSyncInterval(interval)...
// Read more: http://www.pjrc.com/teensy/td_libs_Time.html

setSyncInterval(10 * 60); // Sync interval in seconds (10 minutes)

// Display digital clock every 10 seconds
timer.setInterval(10000L, clockDisplay);

// Turn on/off the relays
timer.setInterval(100000L, turnon);

timer.setInterval(1000L, myTimerEvent);
timer.setTimeout(10000L, myTimerEvent);

}

void loop() {

Blynk.run();
timer.run(); // Initiates BlynkTimer

/*

int redPOT = analogRead(A0);
int greenPOT = analogRead(A1);
int bluePOT = analogRead(A2);
int warmPOT = analogRead(A3);
int neutralPOT = analogRead(A6);
int coldPOT = analogRead(A7);

 

blue = map(bluePOT, 0, 1023, 0, 255);
green = map(greenPOT, 0, 1023, 0, 255);
red = map(redPOT, 0, 1023, 0, 255);
cold = map(coldPOT, 0, 1023, 0, 255);
neutral = map(neutralPOT, 0, 1023, 0, 255);
warm = map(warmPOT, 0, 1023, 0, 255);


// print out the value you read:
Serial.print("Blue ");
Serial.println(blue);
Serial.print("Green ");
Serial.println(green);
Serial.print("Red ");
Serial.println(red);
Serial.print("Cold ");
Serial.println(cold);
Serial.print("Neutral ");
Serial.println(neutral);
Serial.print("Warm ");
Serial.println(warm);


analogWrite(blueLED, blue);
analogWrite(greenLED, green);
analogWrite(redLED, red);
analogWrite(coldLED, cold);
analogWrite(neutralLED, neutral);
analogWrite(warmLED, warm);


*/

}