element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      • Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Vietnam
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Vertical Farming
  • Challenges & Projects
  • Design Challenges
  • Vertical Farming
  • More
  • Cancel
Vertical Farming
Blog Vertical Hydroponics - Blog 9: Arduino Code
  • Blog
  • Forum
  • Documents
  • Polls
  • Files
  • Events
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: jamesod
  • Date Created: 17 Oct 2015 10:00 PM Date Created
  • Views 467 views
  • Likes 2 likes
  • Comments 0 comments
  • vertical_hydroponics
  • vertical_farming
  • arduino
Related
Recommended

Vertical Hydroponics - Blog 9: Arduino Code

jamesod
jamesod
17 Oct 2015

To get this project running quickly, I will be using an Arduino for a lot of the control. As time goes by I plan on replacing the Arduino funcions with code on the EZR32WG, but this is the only way I can see to complet the project by the deadline. The Arduino will be directly interfacing with the sensors and relays, and the EZR32WG will be sending commands to it through UART. These commands will all be in the form c, ##, val; where c is the command type, ## is the ID, and val is a value. There are 3 types of commands the Arduino can receive:

  1. Input commands.

When c='i', the Arduino will read the input that corresponds to the ID # and report that command back over the serial line. The val field is irrelevant. Here is a table of the inputs:


Input            InputID Pin          Type

Light1           1           A5           Bool <<evaluates to a bool

Light2           2           A4           Bool <<evaluates to a bool

Light3           3           A3           Bool <<evaluates to a bool

Current         4           A2           Float <<Instaneous current

TempGerm    5           2             Float <<One Wire bus

Temp2           6           2            Float <<One Wire bus

Temp1           7           2           Float <<One Wire bus

TempRes      8           2           Float <<One Wire bus

WaterLvl       9            3           Float <<Water level/volume after processing of Echo value from HC-SR04

 

2. Output commands.

When c='o', the Arduino will set the output that corresponds to the ID # to the value in the value field. For this application, this value will always be 1 or 0. This will turn the corresponding output to on or off, and report the change over the serial line. Here is a table of the outputs:

 

Output           OutputID           Pin

Light3                1                     5 << Top level light turned on and off on a schedule

Light2                2                     7 << Middle level light turned on and off on a schedule

Light1                3                     8 << Bottom level light turned on and off on a schedule

GermHeat           4                     6 << Heat pad for germination zone. Controlled by evaluation of TempGerm and GermTempGoal

MainHeat           5                     9 << Main Space Heater. Controlled by evaluation of Temp1, Temp2, and Temp1Goal

ResHeat           6                     10 << Reservoir Heater. Controlled by evaluation of TempRes, and ResTemp1Goal

Pump1                7                     11 << Pump for bottom level. Controlled by timer set by Pump1OnTime and Pump1OffTime

Pump2                8                     12 << Pump for middle level. Controlled by timer set by Pump2OnTime and Pump2OffTime

WaterTrigger       9                       4 << Trigger for water level sensor. Contolled by sensor reading function.


3. Variable changes.

When c='v', the Arduino will change the value of one of the control varibles and echo that change over the serial line. These variables include current time, on/off times, alarm settings, etc. Here is a table of all of the variables.


Variable                VarID                Default Val

GermTempGoal      1                          75.0 << Temperature goal for germinating seedlings

Temp1Goal             2                          65.0 << Goal for level one and two

Temp2Goal             3                          65.0 << Currently unused

ResTempGoal         4                          70.0 << Goal for reservoir temperature

Pump1OnTime         5                          20000 << Pump 1 is on for 20 seconds and off an hour by default

Pump1OffTime        6                          3600000

Pump2OnTime         7                          20000 << Pump 2 is on for 20 seconds and off an hour by default

Pump2OffTime        8                          3600000

WaterLowLevel        9                          20 << By default an alarm will be sent if the water level drops below 20L

Time                     10                          unset      <<Time is a special value in Time.h that has time_t format

Light1OnHour         11                          8 <<hour value for turing light1 on

Light1OffHour         12                          24 <<hour value for turing light1 off

Light2OnHour         13                          8 <<hour value for turing light2 on

Light2OffHour         14                          24 <<hour value for turing light2 off

Light3OnHour         15                          6 <<hour value for turing light3 on

Light3OffHour         16                          24 <<hour value for turing light3 off

LastScanPower      17                          0 <<amount of power used since the last system scan

TotalPower             18                          0 <<total amount of power used since startup.

 

The Arduino will monitor the serial line for an input from the EZR32WG. If it doesn't receive an input, it will scan the I/O and make changes based on the current time and the state of the inputs and outputs compared with control variables. If sensor input doesn't match the output state, for example if the photocell detects a light is off when it should be on, the Arduino will send the alarm to the host. These alarms will trigger emails from the BBB to the user. If a scan of the variables indicates a needed variable is not set, the Arduino will request it from the host.


Here is the code. I have also attached it. It has not been tested yet, and it is really pretty sloppy. However, like everything else with this project, I am just trying to get something finished in the limited amount of time left and with my hectic schedule. As long as it works I am ok with the sloppiness. Code can always be tidied up later. (although it usually isn't if it works). Next task is to wire this into the control system and make sure it works. Then I will get the communications working between the EZR32WG and the Arduino. The end is in sight!

 

// Sketch for HydroNode1
// Reads sensors, activates outputs, and reports information to the controller on demand
//
// Code by James O'Donnell -


#include <OneWire.h>
#include <DallasTemperature.h>
#include <Time.h>




/* Device and variable list. All inputs have float or boolean values
Input         InputID   Pin     Type
Light1        1         A5      Bool        <<evaluates to a bool
Light2        2         A4      Bool        <<evaluates to a bool
Light3        3         A3      Bool        <<evaluates to a bool
Current       4         A2      Float       <<Instaneous current
TempGerm      5         2       Float       <<One Wire bus
Temp2         6         2       Float       <<One Wire bus
Temp1         7         2       Float       <<One Wire bus
TempRes       8         2       Float       <<One Wire bus
WaterLvl      9         3       Float       <<Water level/volume after processing of Echo value from HC-SR04


All Outputs also have an associated boolean value stored in the Outputs array
Output        OutputID  Pin
Light3        1         5           << Top level light turned on and off on a schedule
Light2        2         7           << Middle level light turned on and off on a schedule
Light1        3         8           << Bottom level light turned on and off on a schedule
GermHeat      4         6           << Heat pad for germination zone. Controlled by evaluation of TempGerm and GermTempGoal
MainHeat      5         9           << Main Space Heater. Controlled by evaluation of Temp1, Temp2, and Temp1Goal
ResHeat       6         10          << Reservoir Heater. Controlled by evaluation of TempRes, and ResTemp1Goal
Pump1         7         11          << Pump for bottom level. Controlled by timer set by Pump1OnTime and Pump1OffTime
Pump2         8         12          << Pump for middle level. Controlled by timer set by Pump2OnTime and Pump2OffTime
WaterTrigger  9         4           << Trigger for water level sensor. Contolled by sensor reading function.


All Variables are floats or ints (except for Time).
Variable          VarID     Default Val
GermTempGoal      1         75.0    << Temperature goal for germinating seedlings
Temp1Goal         2         65.0    << Goal for level one and two 
Temp2Goal         3         65.0        << Currently unused
ResTempGoal       4         70.0    << Goal for reservoir temperature
Pump1OnTime       5         20000       << Pump 1 is on for 20 seconds and off an hour by default
Pump1OffTime      6         3600000  
Pump2OnTime       7         20000        << Pump 2 is on for 20 seconds and off an hour by default
Pump2OffTime      8         3600000
WaterLowLevel     9         20          << By default an alarm will be sent if the water level drops below 20L
Time              10        unset   <<Time is a special value in Time.h that has year, month, day, hour, minute, second format
Light1OnHour      11        unset   <<hour value for turing light1 on
Light1OffHour     12        unset   <<hour value for turing light1 off
Light2OnHour      13        unset   <<hour value for turing light2 on
Light2OffHour     14        unset   <<hour value for turing light2 off
Light3OnHour      15        unset   <<hour value for turing light3 on
Light3OffHour     16        unset   <<hour value for turing light3 off
LastScanPower     17        0       <<amount of power used since the last system scan
TotalPower        18        0       <<total amount of power used since startup.
*/
#define SERIAL_BAUD 115200    //default for communications over UART with EZR32WG
#define MAX_INPUT_SIZE 20     //ten characters max per command
/************ Define One Wire sensors ************************************/
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(2);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
DeviceAddress TempGerm_add = { 0x28, 0x3A, 0xDF, 0x8A, 0x06, 0x00, 0x00, 0x1E };
DeviceAddress Temp2_add = { 0x28, 0xC5, 0xF5, 0x89, 0x06, 0x00, 0x00, 0x85 };
DeviceAddress Temp1_add = { 0x28, 0xBD, 0x80, 0x89, 0x06, 0x00, 0x00, 0x03 };
DeviceAddress TempRes_add = { 0x28, 0x0D, 0xBD, 0x8A, 0x06, 0x00, 0x00, 0xE4 };
/*************************************************************************/
/**************************** Define Ultrasonic Sensor *******************/
#define TRIGGER_PIN  4  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     3  // Arduino pin tied to echo pin on the ultrasonic sensor.
/*************************************************************************/
/***************************Define Analog sensors ************************/
#define Light1_Apin   A5
#define Light2_Apin   A4
#define Light3_Apin   A3
#define Current_Apin  A2
#define LightOnThresh 55   //If An in is over this value light is on
/*************************************************************************/
/************************* Define Outputs ********************************/
#define Light3_pin    5   //1
#define Light2_pin    7   //2
#define Light1_pin    8   //3
#define GermHeat_pin  6   //4
#define MainHeat_pin  9   //5
#define ResHeat_pin   10   //6
#define Pump1_pin     11   //7
#define Pump2_pin     12   //8
int OutputStates[8] = {0, 0, 0, 0, 0, 0, 0, 0}; //here 0 = off.
/*************************************************************************/
/************************* Define Inputs ********************************/
float TempGermVal, Temp1Val, Temp2Val, TempResVal, ResVolume;
bool Light1, Light2, Light3;


/*************************************************************************/
/************************* Define/Initialize Global Variables **************************/
float GermTempGoal = 75.0, Temp1Goal = 65.0, Temp2Goal = 65.0, TempResGoal = 70;  //Temperature goals in deg F
int Pump1OnTime = 20000, Pump1OffTime = 600000, Pump2OnTime = 20000, Pump2OffTime = 200000;  //Pump Times in milliseconds
float WaterLowLevel = 20, TotalPower = 0; // Level to give alarm for low water level.
unsigned long ScanPeriod = 1000, LastScanTime = 0, CurrentTime = 0, LastGermHeatChangeTime = 0, LastMainHeatChangeTime = 0,
LastResHeatChangeTime = 0, LastPump1ChangeTime = 0, LastPump2ChangeTime = 0, TempChangeMin = 30000, TransmitAllPeriod = 60000; //scan i/o to every second. Temp can only change every 30 seconds.
time_t currentTime;
int Light1OnHour, Light1OffHour, Light2OnHour, Light2OffHour, Light3OnHour, Light3OffHour;


/*************************************************************************/
/************************* Functions *************************************/
//Reads WaterLevel and returns volume.
float WaterLevel(){
  long pulsewidth, distance;
  float volume;
  float distToVolumeMult = 1;
  digitalWrite(TRIGGER_PIN, LOW);
  delayMicroseconds(10);
  digitalWrite(TRIGGER_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIGGER_PIN, LOW);
  pulsewidth = pulseIn(ECHO_PIN, HIGH);
  distance = (((float)pulsewidth)/58.2);
  if (distance >= 200 || distance <= 0){
    Serial.println("Out of range");
  }
  else {
    distance * distToVolumeMult;
  }
  delay(10);
  return volume;
}
//Compares WaterLevel to alarm level and sends an alarm to the host if it is too low.
int EvalH2OLevel(){
  float volume = WaterLevel();
  if (volume < WaterLowLevel){
    Serial.println("v,9,low");
    return 1;
  }
  return 0;
}
//Changes the light state based on the time set.
int EvalLightState(int LightNum){
  time_t currentHour = hour();
  switch(LightNum){
    case 1: if(currentHour == Light1OnHour){
              OutputStates[LightNum - 1] = 1;
              digitalWrite(Light1_pin, HIGH);
            }else if (currentHour == Light1OffHour){
              OutputStates[LightNum - 1] = 0;
              digitalWrite(Light1_pin, LOW);
            }
    case 2: if(currentHour == Light2OnHour){
              OutputStates[LightNum - 1] = 1;
              digitalWrite(Light2_pin, HIGH);
            }else if (currentHour == Light2OffHour){
              OutputStates[LightNum - 1] = 0;
              digitalWrite(Light2_pin, LOW);
            }
    case 3: if(currentHour == Light3OnHour){
              OutputStates[LightNum - 1] = 1;
              digitalWrite(Light3_pin, HIGH);
            }else if (currentHour == Light3OffHour){
              OutputStates[LightNum - 1] = 0;
              digitalWrite(Light3_pin, LOW);
            }           
  }
}




//Reads lights and compare to threshhold value to see if light is on or off. Returns 1 or 0
int ReadLight(int LightNum){
  int analogVal = 0, state = 0;
  switch(LightNum){
    case 1: analogVal = analogRead(Light1_Apin); break;
    case 2: analogVal = analogRead(Light2_Apin); break;
    case 3: analogVal = analogRead(Light3_Apin); break;
  }
  if (analogVal > LightOnThresh){
     state = 1;
  }
  return state;
}
//Compares light input with the output to make sure light is on. Returns 0 if there is an error, and 1 if not.
int EvalLight(int LightNum){
  int outState = OutputStates[LightNum - 1];
  int inState = ReadLight(LightNum);
  if (inState != outState){
    //SendAlarm(LightNum, outState, inState);
    return 0;
  } else{
    return 1;
  }
}
//Reads Current
float ReadCurrent(){
  float current;
  current = (float) analogRead(Current_Apin);
  return (current * 4.9)/100;
}
//Calculates power
float CalculatePower(){
  float instCurrent, power;
  instCurrent = ReadCurrent();
  power = instCurrent * 115 * ((CurrentTime - LastScanTime) / 1000); //current * volts * time since last scan. **approximation only
  Serial.print("v,17,"); Serial.print(power); Serial.println(";");
  return power;
}
//Gets Temperature from Dallas One Wire sensors
float GetTemperature(DeviceAddress deviceAddress)
{

  float tempC = sensors.getTempC(deviceAddress);
  float tempF = DallasTemperature::toFahrenheit(tempC);
  if (tempC == -127.00) {
    Serial.println("problem");
    //SendAlarm(); //send an alarm that the sensor is not working.
  }
  return tempF;
}
//Evaluates whether or not to turn on/off heater based on current temperature and last time the heat was switched. Returns a 1 if turned on, a 0 if turned off or a 2 if nothing.
int EvalTemp(int heater){
  float temp;
  int state, newState;
  switch (heater){
    case 4: state = OutputStates[3];
            temp = GetTemperature(TempGerm_add);      //Germination heater
            if (state == 1 && (temp > GermTempGoal + 5) && ((CurrentTime - LastGermHeatChangeTime) >  TempChangeMin)){
              digitalWrite(GermHeat_pin, HIGH);
              LastGermHeatChangeTime = CurrentTime;
              newState = 0; 
            }else if(state == 0 && (temp < GermTempGoal + 5) && ((CurrentTime - LastGermHeatChangeTime) >  TempChangeMin)){
              digitalWrite(GermHeat_pin, LOW);
              LastGermHeatChangeTime = CurrentTime;
              newState = 1;
            }
            break;
    case 5: state = OutputStates[4];
            temp = (GetTemperature(Temp2_add) + GetTemperature(Temp1_add))/2;      //Average of the level one and two temperatures
            if (state == 1 && (temp > Temp1Goal + 5) && ((CurrentTime - LastMainHeatChangeTime) >  TempChangeMin)){
              digitalWrite(MainHeat_pin, HIGH);
              LastMainHeatChangeTime = CurrentTime;
              newState = 0;
            }else if(state == 0 && (temp < Temp1Goal + 5) && ((CurrentTime - LastMainHeatChangeTime) >  TempChangeMin)){
              digitalWrite(MainHeat_pin, LOW);
              LastMainHeatChangeTime = CurrentTime;
              newState = 1;
            }
             break;
    case 6: state = OutputStates[4];
            temp = GetTemperature(TempRes_add);      //Reservoir Temp
            if (state == 1 && (temp > TempResGoal + 5) && ((CurrentTime - LastResHeatChangeTime) >  TempChangeMin)){
              digitalWrite(ResHeat_pin, HIGH);
              LastResHeatChangeTime = CurrentTime;
              newState = 0; 
            }else if(state == 0 && (temp < TempResGoal + 5) && ((CurrentTime - LastResHeatChangeTime) >  TempChangeMin)){
              digitalWrite(ResHeat_pin, LOW);
              LastResHeatChangeTime = CurrentTime;
              newState = 1;
            }
            break;                
  }
  if (newState != state ){
    Serial.print('o'); Serial.print(","); Serial.print(heater); Serial.print(","); Serial.print(newState); Serial.println(";");
    OutputStates[heater - 1] = newState;
    return newState;
  }
  return 2; 
}
//Checks if pump shoud turn on or off. Returns a 1 if turned on, a 0 if turned off or a 2 if nothing. 
int EvalPump(int pump){
  int state, newState;
  state = OutputStates[pump-1];
  newState = state;
  // Serial.print(state); Serial.print(","); Serial.print(pump); Serial.print(","); Serial.print(newState); Serial.println(";");
  switch(pump){
    case 7: if ((state == 1) && ((CurrentTime - LastPump1ChangeTime) > Pump1OnTime)){
              digitalWrite(Pump1_pin, HIGH);
              LastPump1ChangeTime = CurrentTime;
              newState = 0;
            }else if ((state == 0) && ((CurrentTime - LastPump1ChangeTime) > Pump1OffTime)){
              digitalWrite(Pump1_pin, LOW);
              LastPump1ChangeTime = CurrentTime;
              newState = 1;
            }
            break;
     case 8: if ((state == 1) && ((CurrentTime - LastPump2ChangeTime) > Pump2OnTime)){
              digitalWrite(Pump2_pin, HIGH);
              LastPump2ChangeTime = CurrentTime;
              newState = 0;
            }else if ((state == 0) && ((CurrentTime - LastPump2ChangeTime) > Pump2OffTime)){
              digitalWrite(Pump2_pin, LOW);
              LastPump2ChangeTime = CurrentTime;
              newState = 1;
            }
            break;       
  }
  if (newState != state ){
    Serial.print('o'); Serial.print(","); Serial.print(pump); Serial.print(","); Serial.print(newState); Serial.println(";");
    OutputStates[pump - 1] = newState;
    return newState;
  }
}
//Transfers all output states, variable values, and input data to host
void SendAll(){

}
void setup() {
  // setup pinmodes
  pinMode(Light3_pin, OUTPUT);  // Light3_pin
  pinMode(GermHeat_pin, OUTPUT);  // GermHeat_pin
  pinMode(Light2_pin, OUTPUT);  // Light2_pin
  pinMode(Light1_pin, OUTPUT);  // Light1_pin
  pinMode(MainHeat_pin, OUTPUT);  // MainHeat_pin
  pinMode(ResHeat_pin, OUTPUT); // ResHeat_pin
  pinMode(Pump1_pin, OUTPUT); // Pump1_pin
  pinMode(Pump2_pin, OUTPUT); // Pump2_pin
  pinMode(Light1_Apin, INPUT); // Light1 Analog Input
  pinMode(Light2_Apin, INPUT); // Light2 Analog Input
  pinMode(Light3_Apin, INPUT); // Light3 Analog Input
  pinMode(Current_Apin, INPUT); // Current Analog Input
  pinMode(ECHO_PIN, INPUT); // ultrasonic echo pin
  pinMode(TRIGGER_PIN, OUTPUT); // ultrasonic trigger pin

  //intialize outputs to off. Outputs will sink current to turn on Relays
  digitalWrite(Light3_pin, HIGH);
  digitalWrite(GermHeat_pin, HIGH);
  digitalWrite(Light2_pin, HIGH);
  digitalWrite(Light1_pin, HIGH);
  digitalWrite(MainHeat_pin, HIGH);
  digitalWrite(ResHeat_pin, HIGH);
  digitalWrite(Pump1_pin, HIGH);
  digitalWrite(Pump2_pin, HIGH);
  digitalWrite(Pump2_pin, HIGH);
  digitalWrite(TRIGGER_PIN, LOW);
  
  // Start Dallas Temp library and set the resolution to 10 bit
  sensors.begin();
  sensors.setResolution(TempGerm_add, 10);
  sensors.setResolution(Temp2_add, 10);
  sensors.setResolution(Temp1_add, 10);
  sensors.setResolution(TempRes_add, 10);
  //Begin Serial Comms
  Serial.begin(SERIAL_BAUD);
}
/*******************************************************************************************************************************************
* Main Loop will check for and process serial data, scan inputs, and adjust outputs based on input values.
*
*/


void loop() {
  //get time since program started
  CurrentTime = millis();
  // read and parse serial input
  // Protocol will be: x,xx,xxx = i/o/v,##,val
  // All input will be in the form: input/output/variable, i/o/v number, value, except for time: v,10, year, month, day, hour, minute, second;....
  // Inputs will read the input number, outputs will turn on or off based on 1 or 0 variable value, variables will be modified by a numerical value or read by an 'r' value
  if (Serial.available() > 0)
  {
    char input[MAX_INPUT_SIZE+1];
    byte size = Serial.readBytes(input, MAX_INPUT_SIZE);
    input[size] = 0;
    char type;
    int id, y, m, d, h, mi, s;
    float value;
    int count = 0;
    char* inPart =  strtok(input, ",;");
    type = inPart[0];
    count++;
    while (inPart != 0)
    {
       inPart =  strtok(0, ",;");
       if (count == 1)
       {
           id = atoi(inPart);
           count++;
       }else if (count == 2)
       {
          value = atof(inPart);
          count++;
       }else if (count == 3)
       {
          y = (int) value;
          m = atoi(inPart);
          count++;
       }else if (count == 4)
       {
        d = atoi(inPart);
        count++;
       }else if (count == 5)
       {
        h = atoi(inPart);
        count++;
       }else if (count == 6)
       {
        mi = atoi(inPart);
        count++;
       }else if (count == 7)
       {
        s = atoi(inPart);
        count++;
       }
    }
    //Serial.print("Received: ");  Serial.print(type); Serial.print(","); Serial.print(id); Serial.print(","); Serial.print(value); Serial.println(";");
    if (type == 'i')  //handle input request
    {
      switch (id) {
        case 1:  value = (float) ReadLight(1); break; //create read light function to return 1 if light is sensed and 0 if not.
        case 2:  value = (float) ReadLight(2); break;
        case 3:  value = (float) ReadLight(3); break;
        case 4:  value = ReadCurrent(); break;  //create ReadCurrent function to return two digit precision float
        case 5:  value = GetTemperature(TempGerm_add); break;
        case 6:  value = GetTemperature(Temp2_add); break;
        case 7:  value = GetTemperature(Temp1_add); break;
        case 8:  value = GetTemperature(TempRes_add); break;
        case 9:  value = WaterLevel(); break;
        default: value = 99.99; break;
      }
      Serial.print(type); Serial.print(","); Serial.print(id); Serial.print(","); Serial.print(value); Serial.println(";");
    }else if(type == 'o'){  //handle output change (Low turns relays on)
      bool out = LOW;
      if (value == 0){
        out = HIGH;
      }else{
        out = LOW;
      }
      switch (id) {
        case 1:  digitalWrite(Light3_pin, out); OutputStates[id - 1] = (int)value; break;
        case 2:  digitalWrite(Light2_pin, out); OutputStates[id - 1] = (int)value; break;
        case 3:  digitalWrite(Light1_pin, out); OutputStates[id - 1] = (int)value; break;
        case 4:  digitalWrite(GermHeat_pin, out); OutputStates[id - 1] = (int)value; break;
        case 5:  digitalWrite(MainHeat_pin, out); OutputStates[id - 1] = (int)value; break;
        case 6:  digitalWrite(ResHeat_pin, out); OutputStates[id - 1] = (int)value; break;
        case 7:  digitalWrite(Pump1_pin, out); OutputStates[id - 1] = (int)value; break;
        case 8:  digitalWrite(Pump2_pin, out); OutputStates[id - 1] = (int)value; break;
        default: value = 99.99; break;   
      }
      Serial.print(type); Serial.print(","); Serial.print(id); Serial.print(","); Serial.print(out); Serial.println(";");
    }else if(type == 'v'){  //handle change of control variables.
      switch (id) {
        case 1:  GermTempGoal = value;  break;
        case 2:  Temp1Goal = value;  break;
        case 3:  Temp2Goal = value;  break;
        case 4:  TempResGoal = value;  break;
        case 5:  Pump1OnTime = (int) value;  break;
        case 6:  Pump1OffTime = (int) value;  break;
        case 7:  Pump2OnTime = (int) value;  break;
        case 8:  Pump2OffTime = (int) value;  break;
        case 9:  WaterLowLevel = value;  break;
        case 10:  setTime(h, m, s, d, mi, y); break;
        case 11: Light1OnHour = (int) value; break;
        case 12: Light1OffHour = (int) value; break;
        case 13: Light2OnHour = (int) value; break;
        case 14: Light2OffHour = (int) value; break;
        case 15: Light3OnHour = (int) value; break;
        case 16: Light3OffHour = (int) value; break;  
        default: value = 99.99; break; 
      }
      Serial.print(type); Serial.print(","); Serial.print(id); Serial.print(","); Serial.print(value); Serial.println(";");    
    }
  }
  if(CurrentTime - LastScanTime > ScanPeriod)
  {
     
      //Serial.println("Scanning");
      if (timeStatus() == timeNotSet){  //Check if the time is set before looking to set the time
        Serial.println("v,10,error");   //If the time is not set, ask the host to set the time.
      }else{
        EvalLightState(1);
        EvalLightState(2);
        EvalLightState(3);
      }
      EvalLight(1); //check if the lights are in proper state if not send error.
      EvalLight(2);
      EvalLight(3);
      EvalTemp(4);  //Evaluates temperature and heater state based on output number.
      EvalTemp(5);
      EvalTemp(6);
      EvalPump(7); //Check if pumps should turn on or off.
      EvalPump(8);
      EvalH2OLevel(); //check level of h20 and send alarm if it is too low.
      TotalPower += CalculatePower(); //Calculate power used last second and send to host.
      LastScanTime = CurrentTime;
  }
}

Attachments:
HydroNode1_20151017.ino.zip
  • Sign in to reply
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube