Must-haves for EASY DIY controller?

torhav, make sure you turn the pots enough times. They are 20 turn ones and sometimes it requires quite a bit of turning to see a difference.

I've noticed that without the probe connected, you should see a pH of about 14 on the screen.

Post a close up picture of your board. It sounds like the board might have a problem.

For the LCD backlight, check to see if p15 on the LCD header is connected to digital 8 on the main AVR (middle row of pins N8). Then measure the voltage on that pin, it should be 5V when Hydra starts. If it isn't, put these two lines anywhere in your setup():
PHP:
  pinMode(PWM_BACKLIGHT_PIN, OUTPUT);
  digitalWrite(PWM_BACKLIGHT_PIN,HIGH);

If that fixes it, it means your LCD library is not the correct one. If that still doesn't work and you've verified that p15 on the LCD header is connected to digital 8, then either your AVR header is not soldered right, or you have a broken trace.
 
case closed!

case closed!

Alright, I finally got to paint my hydra box and finished all IO ports that I planned to get out for now, which includes: PWM pins for LEDs, I2C for realys, 1-wire for temp probes, Ethernet and ph probe. Not to forget the 2 programming ports as well.

Photo time:
box_011.jpg

box_012.jpg

box_013.jpg

box_014.jpg
 
It helps to upload the scetch to the right chip.:headwallblue:
I had only 0,3 V on pin 8 (14) and discovered that I had been using the wrong FTDI when I uploaded the scetch. Thanks thera! I woldn't check the scematics so thoroughly if I didn't find this fault.

I think the pH is working now. I haven't tried to calibrate it yet, but it shows reasonable numbers when I connect the probe.
Readings change when I turn the pots also so I guess I have one problem solved.

Data is also appearing at thingsspeak. So far it is only the pH, but I hope to get temperature readings soon.

Backlight is still missing. After changing sceth on the chips, the voltage on pin 8 is completely gone. I get a flash two seconds after the "welcome screen". I have had light in the display several times, so it has to be a problem with the scetch. I have updated all files from hydra-reef.com.
I have tried to insert the code in all places I could think of, but no luck. If I insert it in the scetch it won't compile.
If I insert it in LCDi2c4bit.cpp I can't see any difference.
 
Glad you figured out the PH part. Now for the LCD, What is the compile error? Insert the code I posted right under "void setup() {" or right under "init_components();"
 
That worked, but line 296 tured it off after some seconds.
Changed it to lcd.LCD_turn_display_on, and it stays on.
Do you see any problems with this change?

Thanks again.
 
Finally - Figured out my issue with the I2C LCD

It was a code problem .... Mine !!

I had both processors accessing the DS1307, and if one was going after the clock, while the other was sending data to the LCD ... garbage happens !!

Its all related to interrupt handling, and the requestEvent()/receiveEvent() handlers. I just made sure that all I2C requests are initiated by the Main processor. Doh !!!!

Toughest part of this project was getting all the I2C messaging working correctly.

I'm really happy with the way this unit is working now.
Main processor:
Reads PH, and sends to Slave
Manages LEDs, and sends current intensity values to Slave
Requests Temperature data from Slave
Manages I2C Relay control
Uses IR control to display menus and edit data values for most of the functions on the board. I'm updating the feature set daily.

Slave processor:
Reads DS18B20 Temperatures, and sends to Master when requested.
Handles Ethernet, including sending PH, Temps, and LED status to thingspeak.com

Both processors:
Use DS1307 for initial Date/Time, then use internal oneSecond() function to keep updated. Request Date/Time again from DS1307 at midnight rollover, just to make sure a few seconds have not been "misplaced".

Not "live" yet, but I can monitor LEDs and Relays on a breadboard.

Thanks again the TeraHZ for all the work that has gone into creating the baseline system and code.

I promise to get my code posted once it has become just a bit more stable.

Waiting now to see if everything keeps working for at least 48 hours without any glitches.
 
alright, i finally got to paint my hydra box and finished all io ports that i planned to get out for now, which includes: Pwm pins for leds, i2c for realys, 1-wire for temp probes, ethernet and ph probe. Not to forget the 2 programming ports as well.

Photo time:
box_011.jpg

*** sweet ***
 
Hi,

a) I bought by mistake five 10uF tantal capacitors instead of one 10uF ceramic (C10) and four 10uF electrolytic (C16,C28,C29,C36). Can I use tantal capacitors instead of both types or should I rather buy ceramic and/or electrolytic? Of course in case of using tantal capacitor as C10 I will put + to 1(VCAP) of ENC28J60SP.

b) I have decided to build own 230V IP55 sockets and to use Opto-isolated 10A 4 relay boards instead of Chauvet SR-8 8-Channel Relay Pack. Does anybode have 2 spare relay PCB which he can send to Europe?

Thanks.
 
Last edited:
Well marcer since you r brought it up - ok by a long stretch.

When sending boards through the mail I would highly recommend just paying for the padded envelope. DWZM sent me a typhoon early on regular post no problem. Well I tried to send a 8 Driver CAT board. I weighed added the postage and dropped it in the mail box. About a week later I got it back asking for $0.20 since it was either odd shaped or not flexible enough. I went to the post office and had the postal worker add $0.20. Well a week later (last night) I got it back in the mail and they would like $0.87.

Now I realize the post office is facing money issues (like the rest of us), but to send the same envelope back for more funds - hmm :)
 
I've got the gerber and eagle files from the wiki. What site makes a better board and are the file good now? I read that the drill files might be off? for both the hydra and relay board....


Thanks
James
 
I have tried to connect temp sensors for a while, but I only get a -127 degrees reading.
When I use the serial monitor, this is what I get:

Code:
Let's do it!
Calling receiveEvent
Calling receiveEvent
PH: 13.28
Device Address: 0000000000000000 Temp C: -127.00 Temp F: -196.60
Device Address: 0000000000000000 Temp C: -127.00 Temp F: -196.60
Device Address: 0000000000000000 Temp C: -127.00 Temp F: -196.60
Calling receiveEvent
Calling receiveEvent
Calling receiveEvent

It will keep running the "Calling recieveEvent" for a minute, and then I get the readings once more.

If I disconnect the sensors, I get a 0 degrees reading, so I guess it gets some reply from the sensors.
I have tried 1 and 3 sensors at once, but get the same results.

The first time I tried to connect a sensor the pull-up resistor disconnected. Could this destroy the sensor in any way?

My scetch looks like this:
Code:
/*
 * Arduino ENC28J60 Ethernet shield web update client
 * Sends temp and humidity data every 30s to a given url using GET method.
 * 
 * Written by Andrew Lindsay, July 2009.
 * Portions of code taken from examples on nulectronics.com (sht11 code)
 * TCP/IP code originally from tuxgraphics.org - combined with ethershield library by me.
 *
 */
#include <Wire.h>
#include <stdlib.h>
#include "etherShield.h"
#include "OneWire.h"
#include "DallasTemperature.h"

#define DEBUG 0
// ** Local Network Setup **
// Please modify the following lines. mac and ip have to be unique
// in your local area network. You can not have the same numbers in
// two devices:
static uint8_t mymac[6] = { 0x00,0x1c,0x42,0x00,0x00,0x15};

// how did I get the mac addr? Translate the first 3 numbers into ascii is: TUX
// The IP address of the arduino.
static uint8_t myip[4] = {192,168,1,11};

// Default gateway. The ip address of your DSL/Cable router.
static uint8_t gwip[4] = {192,168,1,1};

// IP address of the host running php script (IP of the first portion of the URL):
static uint8_t webip[4] = { 184, 106, 153, 149 }; // ThingSpeak IP Address: 184.106.153.149
   
#define THINGSPEAK_KEY "xxxxxxxxxxxxxxxx"

// The name of the virtual host which you want to contact at webip (hostname of the first portion of the URL):
#define WEB_VHOST "api.thingspeak.com"
#define WEBURL "/update?key="THINGSPEAK_KEY

// End of configuration 

// listen port for tcp/www:
#define MYWWWPORT 80

// Data wire is plugged into pin 3 on the Arduino
#define ONE_WIRE_BUS 4

// Precision can be from 9 to 12 on the DS12B20
#define TEMPERATURE_PRECISION 11


// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);


// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);

// arrays to hold device addresses
DeviceAddress DTThermometer;
DeviceAddress RoomThermometer;
DeviceAddress SumpThermometer;


static volatile uint8_t start_web_client=0;  // 0=off but enabled, 1=send update, 2=sending initiated, 3=update was sent OK, 4=diable updates
static uint8_t web_client_attempts=0;
static uint8_t web_client_sendok=0;
static uint8_t resend=0;

int my_temp1 = 0;
int my_temp2 = 0;
int my_temp3 = 0;

union fUnion {
  byte _b[4]; 
  float _fval;
} 
FUnion;	 //DRPS = Drum Revs per Second

byte data[4];
int i = 0;
float PH=0.0;

#define STATUS_BUFFER_SIZE 50

#define BUFFER_SIZE 650
static uint8_t buf[BUFFER_SIZE+1];

// global string buffer for twitter message:
static char statusstr[STATUS_BUFFER_SIZE];

char buffer1[8];
char buffer2[8];
char buffer3[8];
char buffer4[8];
// Instantiate the EtherShield class
EtherShield es=EtherShield();

// prepare the webpage by writing the data to the tcp send buffer
uint16_t print_webpage(uint8_t *buf)
{
  uint16_t plen;

  plen = es.ES_fill_tcp_data_p(buf,0,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\nPragma: no-cache\r\n\r\n"));
  plen=es.ES_fill_tcp_data_p(buf,plen,PSTR(""));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("<html>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("<head>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("<title>TeraHz's Hydra</title>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("</head>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("<body>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("<img src=\"http://hydra-reef.com/wiki/skins/hydralogo.png\" />"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("<br />"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("<table style=\"border:1px solid #6699cc; width:150px;\">"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("<tr>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("<td colspan=\"2\" style=\"text-align:center;\">Temperature</td>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("</tr>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("<tr>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("<td>Sensor 1</td>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("<td>"));
  plen=es.ES_fill_tcp_data(buf,plen,buffer1);
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("C°"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("</td>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("</tr>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("<tr>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("<td>Sensor 2</td>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("<td>"));
  plen=es.ES_fill_tcp_data(buf,plen,buffer2);
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("C°"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("</td>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("</tr>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("<tr>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("<td>Sensor 3</td>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("<td>"));
  plen=es.ES_fill_tcp_data(buf,plen,buffer3);
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("C°"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("</td>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("</tr>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("</table>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("<br />"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("<table style=\"border:1px solid #6699cc; width:150px\">"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("<tr>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("<td colspan=\"2\" style=\"text-align:center;\">PH</td>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("</tr>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("<tr>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("<td>Probe 1</td>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("<td>"));
  plen=es.ES_fill_tcp_data(buf,plen,buffer4);
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("</td>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("</tr>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("</table>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("</body>"));
  plen = es.ES_fill_tcp_data_p(buf,plen,PSTR("</html>"));
  return(plen);
}

// Browser callback, where we get to after receiving a reply to an update, should really 
// do somthing here to check all was OK.
void browserresult_callback(uint8_t statuscode,uint16_t datapos){
  if (statuscode==0){
#ifdef DEBUG
    Serial.println("HTTP OK");
#endif
    web_client_sendok++;
  }
#ifdef DEBUG
  else{
    Serial.print("HTTP status code:");
    Serial.println(statuscode, DEC);
  }
#endif
  // clear pending state at sucessful contact with the
  // web server even if account is expired:
  if (start_web_client==2) start_web_client=3;
}
// Perform setup on ethernet and oneWire
void setup(){
  
#ifdef DEBUG
  Serial.begin(19200);
  Serial.println("Let's do it!");
#endif

  Wire.begin(4);                // join i2c bus with address #4
  Wire.onReceive(receiveEvent); // register event
  // initialize enc28j60
  es.ES_enc28j60Init(mymac);
  //init the ethernet/ip layer:
  es.ES_init_ip_arp_udp_tcp(mymac,myip, MYWWWPORT);
  // init the web client:
  es.ES_client_set_gwip(gwip);  // e.g internal IP of dsl router

  //setup temperature library
  sensors.begin();

  sensors.getAddress(DTThermometer, 0);
  sensors.getAddress(RoomThermometer, 1);
  sensors.getAddress(SumpThermometer, 2);
  //  DTThermometer = { 0x28, 0x14, 0x0B, 0xB2, 0x02, 0x00, 0x00, 0x30 };
  //  RoomThermometer = { 0x28, 0xE9, 0xBC, 0xB1, 0x02, 0x00, 0x00, 0x9E };
  //  SumpThermometer = {  0x28, 0xED, 0xA3, 0xB2, 0x02, 0x00, 0x00, 0xD9 };

  sensors.setResolution(DTThermometer, TEMPERATURE_PRECISION);
  sensors.setResolution(RoomThermometer, TEMPERATURE_PRECISION);
  sensors.setResolution(SumpThermometer, TEMPERATURE_PRECISION);


}


// The business end of things
void loop(){
  uint16_t dat_p;
  int8_t cmd;
  start_web_client=1;
  unsigned long lastSend = millis();
  unsigned long time;
  while(1){
    // handle ping and wait for a tcp packet
    dat_p=es.ES_packetloop_icmp_tcp(buf,es.ES_enc28j60PacketReceive(BUFFER_SIZE, buf));
    if(dat_p==0){
      // Nothing received, jus see if there is anythng to do 
      // update every 60s
      time = millis();
      if( time > (lastSend + 59625) ) {
        resend=1; // resend once if it failed
        start_web_client=1;
        lastSend = time;
      }

      if (start_web_client==1) {
        // Read values from the sensor
        //        my_temp1 = read_value(buffer1, 0);//room
        //        my_temp2 = read_value(buffer2, 2);//sump
        //        my_temp2 = read_value(buffer3, 3);//DT
        dtostrf(PH,4,2,buffer4);
#ifdef DEBUG
        Serial.print("PH: "); 
        Serial.println(buffer4);
#endif

        sensors.requestTemperatures();
        dtostrf(printData(RoomThermometer),4,2,buffer1);
        dtostrf(printData(DTThermometer),4,2,buffer3);
        dtostrf(printData(SumpThermometer),4,2,buffer2);

        sprintf( statusstr, "&field1=%s&field2=%s&field3=%s", buffer4, buffer2, buffer3);
        es.ES_client_set_wwwip(webip);
        es.ES_client_browse_url(PSTR(WEBURL),statusstr,PSTR(WEB_VHOST), &browserresult_callback);
        start_web_client=2;
        web_client_attempts++;
      }

      continue;
    }

    dat_p=print_webpage(buf);
    es.ES_www_server_reply(buf,dat_p); // send data
  }
}

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    // zero pad the address if necessary
    if (deviceAddress[i] < 16) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
  }
}

// function to print the temperature for a device
float printTemperature(DeviceAddress deviceAddress)
{
  float tempC = sensors.getTempC(deviceAddress);
#ifdef DEBUG
  Serial.print("Temp C: ");
  Serial.print(tempC);
  Serial.print(" Temp F: ");
  Serial.print(DallasTemperature::toFahrenheit(tempC));
#endif
  return tempC;
}


float printData(DeviceAddress deviceAddress)
{
  float tmp;
#ifdef DEBUG
  Serial.print("Device Address: ");
  printAddress(deviceAddress);
  Serial.print(" ");
#endif
  tmp = printTemperature(deviceAddress);
#ifdef DEBUG
  Serial.println();
#endif
  return tmp;
}
void receiveEvent(int howMany)
{
#ifdef DEBUG
  Serial.println("Calling receiveEvent");
#endif
  int i = 0;
  while(Wire.available())    // slave may send less than requested
  {
    data[i] = Wire.receive(); // receive a byte as character
    i = i + 1;
  } 
  FUnion._b[0] = data[0];
  FUnion._b[1] = data[1];
  FUnion._b[2] = data[2];
  FUnion._b[3] = data[3];

  PH = FUnion._fval;
}

I have updated all files with revision 64 as posted by teraHz.
Any clues to why it doesn't work?

BTW: At thingsspeak I get -127 reading from two sensors, but the third doesn't work. This is the same regardless if I connect 1 or 3 sensors.
 
I am using DS18B20 sensors.

They are connected like this:
Tempsensor.jpg


The pins are connected to the corresponding headers on slave, D4.
I had the same problem when I used pin 3, but i broke a piece of solid wire in the header and had to change digital pin #.

Wires are soldered to the sensor, so the only place there could be a bad connection is at the header. I don't think bad connection is the problem as I have tried several alternatives with the same results.

I don't know if it helps, but a couple of times the last two digits on sensor adress on sensor 3 has appeared as numbers in stead of 0s.
 
Sorry guys, I hope I haven't wasted too much of your time.
I switched the gnd and +5 V leads, and it works like a charm.
Read the pin numbers by looking from the top of the sensor :headwalls:

Next project is to connect the IR remote.
I guess you will hear from me again in a couple of days...
 
How many Watt power supplies are you using for Hydra? I plan to use one 12V PS for one or two Relay boards, two or four Opto-isolated 10A 4 relay board and Hydra. I will get 7.5V and 5.0V from 7875 and 7805 from relay board.
 
Sorry for bothering you again, nobody knows about Hydra consumption in Watts? I am considering Meanwell T-40 (5V 5A, 12V 3A)? I want to use it for 1 Hydra, 1-2 relay boards, 2-4 Opto-isolated 10A 4 relay boards a 24 CAT4101 IC on 10 PCB. Isn't it too much power? What power supplies do you use?

Also nobody seems to have additional Relay boards PCB. I have to CAt4101 spare PCB which I can offer too. Registered mail from Europe to US is only 2.30 Euro for 50g or 3.10 for 100g.
 
Hydra by itself uses little power. With all components connected it is probably ~500mA. I think what you have listed will work just fine.
 
Back
Top