Reverse Osmosis control system

Hi Guys,

I am a complete newbie to this and I think I may have bitten off more than I can chew. I am a aging diy hobby tinkerer and have been put onto Arduino by a friend. My programming skills are very rusty and I am not getting anywhere fast. Any help would be greatly appreciated.

I am trying to design an auto controller for my ro system. It has a pump and three solenoids that control water flow. I need the system to be on for four hours and then off for four over a twenty four hour period. I also need to flush the system with one of the solenoids for one minute every hour. I have compiled a program that does not seem to do the job. The timings are not right on the relays as I was using seconds to show it working over time. Please could anyone help me sort this program out?

#include <Wire.h>
#include "ds3231.h"
#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
/* Basic 4 Realy board connection with clock and 1602 display, to control a water RO system with pump and three solenoids.

 Each relay is turned on, then relay 1 is switched off after 1 minute. Relay one is then switched on again every hour for 1 minute.
 All four relays are then switched off for 4 hours and then the cycle repeats.
 There is a real time clock on a 1602 display that can also display time to next flush (relay 1)
 You will also see the corresponding Red LED on the 4 Relay board

 light up when the relay is on.

 define names for the 4 Digital pins On the Arduino

 These data pins link to 4 Relay board pins IN1, IN2, IN3,IN4
*/

#define RELAY1  3

#define RELAY2  4

#define RELAY3  5

#define RELAY4  6

#define BUFF_MAX 128

uint8_t time[8];
char recv[BUFF_MAX];
unsigned int recv_size = 0;
unsigned long prev, interval = 1000;

void setup()
{
 Serial.begin(9600);
 Wire.begin();
 DS3231_init(DS3231_INTCN);
 memset(recv, 0, BUFF_MAX);
 Serial.println("GET time");
 lcd.begin(16, 2);
 lcd.clear();

 //Serial.println("Setting time");
 //parse_cmd("T302911604102014", 16);

 // Initialise the Arduino data pins for OUTPUT

 pinMode(RELAY1, OUTPUT);

 pinMode(RELAY2, OUTPUT);

 pinMode(RELAY3, OUTPUT);

 pinMode(RELAY4, OUTPUT);

}

void loop()


{
 char in;
 char tempF[6];
 float temperature;
 char buff[BUFF_MAX];
 unsigned long now = millis();
 struct ts t;

 // show time once in a while
 if ((now - prev > interval) && (Serial.available() <= 0)) {
   DS3231_get(&t); //Get time
   parse_cmd("C", 1);
   temperature = DS3231_get_treg(); //Get temperature
   dtostrf(temperature, 5, 1, tempF);

   lcd.clear();
   lcd.setCursor(1, 0);

   lcd.print(t.mday);

   printMonth(t.mon);

   lcd.print(t.year);

   lcd.setCursor(0, 1); //Go to second line of the LCD Screen
   lcd.print(t.hour);
   lcd.print(":");
   if (t.min < 10)
   {
     lcd.print("0");
   }
   lcd.print(t.min);
   lcd.print(":");
   if (t.sec < 10)
   {
     lcd.print("0");
   }
   lcd.print(t.sec);

   lcd.print(' ');
   lcd.print(tempF);
   lcd.print((char)223);
   lcd.print("C ");
   prev = now;
 }


 if (Serial.available() > 0) {
   in = Serial.read();

   if ((in == 10 || in == 13) && (recv_size > 0)) {
     parse_cmd(recv, recv_size);
     recv_size = 0;
     recv[0] = 0;
   } else if (in < 48 || in > 122) {
     ;       // ignore ~[0-9A-Za-z]
   } else if (recv_size > BUFF_MAX - 2) {   // drop lines that are too long
     // drop
     recv_size = 0;
     recv[0] = 0;
   } else if (recv_size < BUFF_MAX - 2) {
     recv[recv_size] = in;
     recv[recv_size + 1] = 0;
     recv_size += 1;
   }

 }
}

void parse_cmd(char *cmd, int cmdsize)
{
 uint8_t i;
 uint8_t reg_val;
 char buff[BUFF_MAX];
 struct ts t;

 //snprintf(buff, BUFF_MAX, "cmd was '%s' %d\n", cmd, cmdsize);
 //Serial.print(buff);

 // TssmmhhWDDMMYYYY aka set time
 if (cmd[0] == 84 && cmdsize == 16) {
   //T355720619112011
   t.sec = inp2toi(cmd, 1);
   t.min = inp2toi(cmd, 3);
   t.hour = inp2toi(cmd, 5);
   t.wday = inp2toi(cmd, 7);
   t.mday = inp2toi(cmd, 8);
   t.mon = inp2toi(cmd, 10);
   t.year = inp2toi(cmd, 12) * 100 + inp2toi(cmd, 14);
   DS3231_set(t);
   Serial.println("OK");
 } else if (cmd[0] == 49 && cmdsize == 1) {  // "1" get alarm 1
   DS3231_get_a1(&buff[0], 59);
   Serial.println(buff);
 } else if (cmd[0] == 50 && cmdsize == 1) {  // "2" get alarm 1
   DS3231_get_a2(&buff[0], 59);
   Serial.println(buff);
 } else if (cmd[0] == 51 && cmdsize == 1) {  // "3" get aging register
   Serial.print("aging reg is ");
   Serial.println(DS3231_get_aging(), DEC);
 } else if (cmd[0] == 65 && cmdsize == 9) {  // "A" set alarm 1
   DS3231_set_creg(DS3231_INTCN | DS3231_A1IE);
   //ASSMMHHDD
   for (i = 0; i < 4; i++) {
     time[i] = (cmd[2 * i + 1] - 48) * 10 + cmd[2 * i + 2] - 48; // ss, mm, hh, dd
   }
   byte flags[5] = { 0, 0, 0, 0, 0 };
   DS3231_set_a1(time[0], time[1], time[2], time[3], flags);
   DS3231_get_a1(&buff[0], 59);
   Serial.println(buff);
 } else if (cmd[0] == 66 && cmdsize == 7) {  // "B" Set Alarm 2
   DS3231_set_creg(DS3231_INTCN | DS3231_A2IE);
   //BMMHHDD
   for (i = 0; i < 4; i++) {
     time[i] = (cmd[2 * i + 1] - 48) * 10 + cmd[2 * i + 2] - 48; // mm, hh, dd
   }
   byte flags[5] = { 0, 0, 0, 0 };
   DS3231_set_a2(time[0], time[1], time[2], flags);
   DS3231_get_a2(&buff[0], 59);
   Serial.println(buff);
 } else if (cmd[0] == 67 && cmdsize == 1) {  // "C" - get temperature register
   Serial.print("temperature reg is ");
   Serial.println(DS3231_get_treg(), DEC);
 } else if (cmd[0] == 68 && cmdsize == 1) {  // "D" - reset status register alarm flags
   reg_val = DS3231_get_sreg();
   reg_val &= B11111100;
   DS3231_set_sreg(reg_val);
 } else if (cmd[0] == 70 && cmdsize == 1) {  // "F" - custom fct
   reg_val = DS3231_get_addr(0x5);
   Serial.print("orig ");
   Serial.print(reg_val, DEC);
   Serial.print("month is ");
   Serial.println(bcdtodec(reg_val & 0x1F), DEC);
 } else if (cmd[0] == 71 && cmdsize == 1) {  // "G" - set aging status register
   DS3231_set_aging(0);
 } else if (cmd[0] == 83 && cmdsize == 1) {  // "S" - get status register
   Serial.print("status reg is ");
   Serial.println(DS3231_get_sreg(), DEC);
 } else {
   Serial.print("unknown command prefix ");
   Serial.println(cmd[0]);
   Serial.println(cmd[0], DEC);
 }
}

void printMonth(int month)
{
 switch (month)
 {
   case 1: lcd.print(" January "); break;
   case 2: lcd.print(" February "); break;
   case 3: lcd.print(" March "); break;
   case 4: lcd.print(" April "); break;
   case 5: lcd.print(" May "); break;
   case 6: lcd.print(" June "); break;
   case 7: lcd.print(" July "); break;
   case 8: lcd.print(" August "); break;
   case 9: lcd.print(" September "); break;
   case 10: lcd.print(" October "); break;
   case 11: lcd.print(" November "); break;
   case 12: lcd.print(" December "); break;
   default: lcd.print(" Error "); break;
 }
}

void digitalwrite(int relay)
{


 digitalWrite(RELAY2, LOW);          // Turns ON Relays 2
 digitalWrite(RELAY3, LOW);          // Turns ON Relays 3
 digitalWrite(RELAY4, LOW);          // Turns ON Relays 4
 digitalWrite(RELAY1, LOW);          // Turns ON Relays 1

 delay(2000);                                      // Wait 2 seconds

 digitalWrite(RELAY1, HIGH);         // Turns Relay Off

 delay(6000);                                      // Wait 6 seconds


 digitalWrite(RELAY2, HIGH);         // Turns Relay Off
 digitalWrite(RELAY3, HIGH);          // Turns Relays off
 digitalWrite(RELAY4, HIGH);         // Turns Relay Off

 delay(6000);

}

Please edit your posting and enclose the code in code tags </>.

It's bad style to name a function digitalwrite(), and it gets never called. No wonder that your program does not what you expect.

DrDiettrich,

Thankyou for pointing out my mistake with posting. Hopefully I have now corrected it to everyones liking.

As I mentioned before, I have little or no coding skills, so I am building this code from searches and my best guesses. So any help would be greatly appreciated. For example, why is digitalwrite () bad style? I found this on an early web search, it worked so I tried to use it.

I am sorry if I am infuriating you guys but I was only hoping to learn from you all.

Your code looks good now :slight_smile:

It's not a good idea to have functions digitalWrite() and digitalwrite(), which differ only in the case of one letter. Be careful, there is much crap in the web :frowning:

Thanks for that.

Sadly my question is the same, how do I alter my basic code to get it to work? :frowning:

As already mentioned, you'll have to call your function. It's not clear to me when and how often it has to be called.

Most probably you need code that waits for the next time, when something should happen, then do that and increment the time to the next event. Something like

if (currentTime >= nextEventTime) {
  digitalwrite(what?);
  nextEventTime = what?
}

Replace "what?" as appropriate.

I am hoping to run the relays on for four hours and then off for four, and then keep cycling over the twenty four hour period.

I also want to add a switch to the lcd display to show a countdown to the relay 1 coming on to flush the system.

My head is spinning with all this code.....

Please can someone help me with these issues, I am struggling to code time delays at four hour intervals to control my relays. also how to I add a display line to show time to next relay on state?

many thanks

Simon

Have you tried BlinkWithoutDelay? And the example I gave above?

The current time is obtained from the RTC, and you have to supply the time of the elapse of the next interval.