Controlling 32 relays
ABSTRACT
The aim of this project is to control 32 relays with
an Android tablet. The Android
application sends a message to an Arduino Mega by Bluetooth. Arduino receives
the Bluetooth message thanks to a HC-06 Bluetooth device. Arduino decodes the
messages and then, activates or deactivates the relays. The period of time of
the activation of the relays depends on the value selected in the Android
application. The app has 32 sliders for selecting the activation time of the
relays.
Figure 1: Image of the relays
|
COMPONENTS
1 x Samsung
Galaxy Tab 10.1’’ with Android 3.1
1 x Arduino
Mega
2 x Modules of 16 relays
1 x Module Bluetooth
HC-06
1 x Wires
DEVELOPMENT
This project is part
of a bigger one but in this blog I will only explain the part of controlling
the 32 relays by Bluetooth.
The Bluetooth device
is connected to the Arduino using the Serial port 3. These pins are 14 for TX3
and 15 for RX3.
Each relay module has
16 male pins for connecting to the Arduino. Also, it has one pin for GND and
another for +5V. Moreover, the board has a block for powering the relay module
with a higher volts supply. In this case, 12V
are provided by a power supply connected to the electrical network.
Figure
3: Module with 16 relays optoacoppler
|
I’ve used the digital
Arduino outputs from 22 to 53 for
connecting the two relays boards to the Arduino Mega.
The following picture
shows how the components must be connected among them.
Figure 5: Schematic of Arduino Mega with the relay and
Bluetooth modules
|
The Android
app is connected to the HC-06 Bluetooth module automatically. Then, I select
the time of period that the relays are activated. There is a slider for each
relay. Also, I can select the timeline sliders to indicate the maximum time the
relay can be activated. After that, if the Bluetooth connection is ready, you
can press the "Send Text" to transmit a 32-character string button.
The data string has the following format:
String dataToSend={‘E’,’:’,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,’.’};
The total size of the string is 35 bytes. The
first character always is an ‘E’, the second is ‘:’ and the last is ‘.’. The
bytes in middle of these characters are the values of time which the relays
will be activate. These values are represented in hexadecimal.
At the beginning of
this project, I wanted to send the time of the relays with integer format.
However, I discovered that the Arduino Serial port has a maximum buffer of 64
bytes. So, if I sent 32 numbers in integer, I will need more than 64 bytes
because the ‘int’ format need at least 2 bytes. We can check this easily with
Arduino writing something like this:
int timeRelays[]={100,40,3,4};//an array of 4
integers Sizeof(timeRelays);//64
So, the reason why
I decided not to sent the data in integer format, it is that the packet to
transmit must be less than 64 bytes.
Arduino Mega
receives the data through SPP thanks to
the HC-06 Bluetooth module. These data are saved in variable type String. Then,
the string of characters are decoded and the values of time for the relays are
stored in an array of integers. The array’s size is 32 integers, one integer
for each relay.
After getting the
time for each relay, I found the problem
of how manage 32 outputs simultaneously. The solution that I adopted was to use
the Timer library coded by Simon Monk [3]. This library can be easily
downloaded from [4]. I had to modify some lines of the library for my purpose.
In the file Timer.h, I changed the line:
#define
MAX_NUMBER_OF_EVENTS (10) to #define MAX_NUMBER_OF_EVENTS (32)
Furthermore, I made a new method based on the method timer::oscillate
described in the file Timer.cpp. My method is called timer::halfPulse. The only difference respect to the other method is that the variable repeatCount is always 1 because I only
wanted a transition, not a full cycle.
Figure 6: Android application without Bluetooth connection. |
Figure 7: Android application connected to the Arduino. |
RESULTS
The Arduino code used in this Project does the
following:
1- Initializes the Serial Ports 1 and 3. Sets up the
Bluetooth and configures the digital outputs.
2- Arduino makes blinking the Digital Outputs
connected to the relays, in order to test if they all work properly. In my
case, one relay is damaged.
3-Once the Bluetooth connection is established between
the Android tablet and the HC-06 module, the program waits to receive messages.
The messages are parsed and if the data is received correctly, Arduino will
activate the relays during an interval of time.
The next video shows how the code works:
REFERENCES
OTHER PROPOSAL WITH
RELAYS
Instead of using an
Arduino Mega for controlling all the relays, I would like to use an Arduino Uno
for managing the 32 relays. I think that
this idea is possible if I use two 16-channel
Analog Multiplexers like the 74HC4067N. This IC need 4 digital outputs an one
analog input. I’ve designed the circuit using Eagle. The schematic is the
following:
Figure
6: Atmega328 with two multiplexers for controlling 32 relays by Bluetooth.
|
APPENDIX
Arduino code:
#include
<Event.h>
#include
<Timer.h>
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Timer library coded by Simon Monk
* Timer.h has been downloaded from this link:
http://www.simonmonk.org
* I've modified the parameter :
MAX_NUMBER_OF_EVENTS (10) by #define MAX_NUMBER_OF_EVENTS (32)
* Furthermore, I've created a new method from
the Oscillate method
+ This new function is called: half-pulse. The
unique difference respect to the Oscillate method is: repeatCount=1
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * */
//Digital
outputs connected to the relays
#define
EV_32 22
#define
EV_31 23
#define
EV_30 24
#define
EV_29 25
#define
EV_28 26
#define
EV_27 27
#define
EV_26 28
#define
EV_25 29
#define
EV_24 30
#define
EV_23 31
#define
EV_22 32
#define
EV_21 33
#define
EV_20 34
#define
EV_19 35
#define
EV_18 36
#define
EV_17 37
#define
EV_16 38
#define
EV_15 39
#define
EV_14 40
#define
EV_13 41
#define
EV_12 42
#define
EV_11 43
#define
EV_10 44
#define
EV_9 45
#define
EV_8 46
#define
EV_7 47
#define
EV_6 48
#define
EV_5 49
#define
EV_4 50
#define
EV_3 51
#define
EV_2 52
#define
EV_1 53
//Functions
used in this skecth
//Bluetooth
void SetupBT(void);
void readAnswer(void);
boolean ReceivingMessages(void);
//Relays
void SetupRelays(void);
void TestRelays (void);
Timer
t;
int
relayIntervals[32];
void
setup()
{
Serial.begin(9600);
SetupRelays();
TestRelays();
SetupBT();
}
void
loop()
{
t.update();
if (ReceivingMessages() == true)
{
Serial.println("Interval times for the
32 relays:");
for (uint8_t n = 0; n < 32; n++)
{
Serial.print("[");
Serial.print(n + 1); Serial.print("]: ");
Serial.print(relayIntervals[n]);
Serial.print(" "); Serial.println(53 - n);
if (relayIntervals[n] > 0)
t.halfPulse(53 - n, relayIntervals[n] * 1000, LOW);
else digitalWrite(53 - n, HIGH); activa
}//If the value is 0, the relays is
deactivated with a high pulse
}
delay(1000);
}
/**************************************
*Configuration
of the Bluetooth Module*
***************************************/
void
SetupBT(void)
{
Serial3.begin(9600);
delay(100);
Serial.println("Initializing the
Bluetooth, wait a moment please...");
Serial3.print("AT");
readAnswer();
Serial.println("ResetingBluetooth");
Serial3.print("AT+RESET");
readAnswer();
Serial.println("Bluetooth Version
");
Serial3.print("AT+VERSION");
readAnswer();
Serial.println("Nombre: RELAYS");
Serial3.print("AT+NAMERELAYS");
readAnswer();
Serial.println("9600 Bauds");
Serial3.print("AT+BAUD4");
readAnswer();
Serial.println("Pin: 1234");
Serial3.print("AT+PIN1234");
readAnswer();
Serial.println("Configuration
finished.");
}
/*****************************************************************
*
Reads the answer of the bluetooth module from the serial port 3*
******************************************************************/
void
readAnswer(void)
{
delay(1000);
if(Serial3.available())
{
do
{
Serial.print((char) Serial3.read());
}while(Serial3.available()>0);
}
Serial.println("\n");
}
boolean
ReceivingMessages(void)
{
String trama="";
boolean state=false;
if(Serial3.available())//Wait until
something is writen in the serial port
{
delay(100);
while(Serial3.available()>0) trama.concat((char)Serial3.read());
Serial.println(trama.length());
if(trama.length()==35)
{
Serial.print(trama.charAt(0));
Serial.print(trama.charAt(1));
for(uint8_t
i=2;i<trama.length()-1;i++)
{
relayIntervals[i-2]=(int)trama.charAt(i);
Serial.print(relayIntervals[i-2]);
if(i==trama.length()-2)
Serial.print("");
else Serial.print(',');
}
Serial.println(trama.charAt(trama.length()-1));
return state=true;
}
else
{
Serial.println(trama);
return state=false;
}
}
}
/*******************************************************************************
* Configuration of the digital outputs for
activate and deactivate the relays *
*******************************************************************************/
void
SetupRelays(void)
{
pinMode(EV_1, OUTPUT);
pinMode(EV_2, OUTPUT);
pinMode(EV_3, OUTPUT);
pinMode(EV_4, OUTPUT);
pinMode(EV_5, OUTPUT);
pinMode(EV_6, OUTPUT);
pinMode(EV_7, OUTPUT);
pinMode(EV_8, OUTPUT);
pinMode(EV_9, OUTPUT);
pinMode(EV_10, OUTPUT);
pinMode(EV_11, OUTPUT);
pinMode(EV_12, OUTPUT);
pinMode(EV_13, OUTPUT);
pinMode(EV_14, OUTPUT);
pinMode(EV_15, OUTPUT);
pinMode(EV_16, OUTPUT);
pinMode(EV_17, OUTPUT);
pinMode(EV_18, OUTPUT);
pinMode(EV_19, OUTPUT);
pinMode(EV_20, OUTPUT);
pinMode(EV_21, OUTPUT);
pinMode(EV_22, OUTPUT);
pinMode(EV_23, OUTPUT);
pinMode(EV_24, OUTPUT);
pinMode(EV_25, OUTPUT);
pinMode(EV_26, OUTPUT);
pinMode(EV_27, OUTPUT);
pinMode(EV_28, OUTPUT);
pinMode(EV_29, OUTPUT);
pinMode(EV_30, OUTPUT);
pinMode(EV_31, OUTPUT);
pinMode(EV_32, OUTPUT);
//For security matters, all the relays are
opened
digitalWrite(EV_1, HIGH);
digitalWrite(EV_2, HIGH);
digitalWrite(EV_3, HIGH);
digitalWrite(EV_4, HIGH);
digitalWrite(EV_5, HIGH);
digitalWrite(EV_6, HIGH);
digitalWrite(EV_7, HIGH);
digitalWrite(EV_8, HIGH);
digitalWrite(EV_9, HIGH);
digitalWrite(EV_10, HIGH);
digitalWrite(EV_11, HIGH);
digitalWrite(EV_12, HIGH);
digitalWrite(EV_13, HIGH);
digitalWrite(EV_14, HIGH);
digitalWrite(EV_15, HIGH);
digitalWrite(EV_16, HIGH);
digitalWrite(EV_17, HIGH);
digitalWrite(EV_18, HIGH);
digitalWrite(EV_19, HIGH);
digitalWrite(EV_20, HIGH);
digitalWrite(EV_21, HIGH);
digitalWrite(EV_22, HIGH);
digitalWrite(EV_23, HIGH);
digitalWrite(EV_24, HIGH);
digitalWrite(EV_25, HIGH);
digitalWrite(EV_26, HIGH);
digitalWrite(EV_27, HIGH);
digitalWrite(EV_28, HIGH);
digitalWrite(EV_29, HIGH);
digitalWrite(EV_30, HIGH);
digitalWrite(EV_31, HIGH);
digitalWrite(EV_32, HIGH);
Serial.println("The configuration of the
digital outputs for the relays is finished.");
}
/*************************************************************************************************
*This
function opens and closes all the relays sequentially in order to test if they
work or not. *
**************************************************************************************************/
void
TestRelays(void)
{
for(int i=54;i>21;i--)
{
digitalWrite(i,HIGH);
delay(100);
digitalWrite(i,LOW);
delay(200);
digitalWrite(i,HIGH);
delay(100);
}
}