Beekeepers Sun Tracking Solar Wax Melter Project - Arduino Uno

Hi Folks,
History and Project Description

I am a Honeybee Beekeeper and I have started a winter project of creating a sun tracking solar wax melter, to melt beeswax from my bee hives. My current wax melter I have to manually re-position every half-hour to hour throughout the day to take advantage of the suns rays and heat to melt the wax.

I am looking at using a Arduino Uno to monitor and control several functions:
1)LDR’s & Horizontal Mounted Servo, to track and rotate the wax melter as the sun moves (most likely update in 15 minute intervals)
2)DHT22 Temperature/Humidity sensor with a small PWM cooling fan to (well try to anyway) maintain 140F-155F inside the melter.
3)LCD to Display Temperature Humidity and Fan Speed 0-100% (real time)
4)Save Temperature Humidity & Fan Speed data to a SD Shield in something like 5-15 minute intervals to review later(added just for kicks)

I have a little background in basic old school electronic circuits, but am limited in the scope of micro processing and coding.

I have written some code for:

  1. LDR’s & Horizontal mount servo… a little buggy and still working out trying to incorporate some sort of tolerance feature so not to constantly fight between the Left & Right LDR’s, not having much luck with this…but I have been able to track a flash light. Also Looking to-re code this with the VarSpeedServo Library I came across for speed control
  2. DHT22 & Fan circuit is built/coded out and seems to be working 100%
  3. LCD Display is coded out and working but makes the Servo motion Jitter/Stutter…even more so when I have serial monitor enabled. Not sure how to reduce the Jitter/Stutter this feature is putting on the servo motion.
  4. SD Shield haven’t attempt incorporating this yet
  5. Haven’t looked into the 5-15 minute intervals i would like to add to certain areas…for now keeping it somewhat real time for testing/troubleshooting purposes.

Any suggestions to fix/streamline some of this would be greatly appreciated…again this is a winter project so I am not in a big hurry to get it up and running. I made a mock test platform to work on and plan to get the circuit working first on the bench…then build the full scale rotating enclosure.

Here is my code so far…please excuse the mess it is in…again my skills are poor (which I know is a understatement).

//**********************  Interrupt Service Routine - Soft E-Stop
boolean start = true;
volatile boolean e_stop = false;


//***********************  Liquid Crystal-I2C

#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

#define I2C_ADDR 0x27
#define Rs_pin 0
#define Rw_pin 1
#define En_pin 2
#define BACKLIGHT_PIN 3
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);


//***********************  Temp-Fan

#include <DHT.h>                                                    // add DHT library
#define DHTPIN A0                                                  // what pin we're connected to
#define DHTTYPE DHT22                                           // DHT 22  (AM2302)
DHT dht(DHTPIN, DHTTYPE);                                      // set DHT condition
#define fan 10                                                        // fan Pin 10

int tempMin = 70;                                                   // min Temp "F" set point
int tempMax = 85;                                                  // max Temp "F" set point
int fanSpeed;
int fanLCD;


//**********************  Servo/LDR Sun Tracking

#include <Servo.h>
Servo servo1;                                                        // create servo object to control a servo
int pos = 90;                                                         // initial position
int LLDR = A1;                                                       // LRD1 pin1
int RLDR = A2;                                                       // LDR2 pin2
int tolerance = 3;                                                   // <<- Set LDR Tolerance set point 


//*************************   SETUP

void setup(){
  Serial.begin(9600);                                                // begin writing to the serial monitor
  attachInterrupt(0, e_stop_ISR ,RISING);                    // add interrupt for soft e_stop feature

  lcd.begin (20,4);                                                   // <<-- change for your LCD if needed
  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);          // set back-light condition
  lcd.setBacklight(HIGH);                                         // turn back-light on
  lcd.home ();
  lcd.print("Wax Melter v1.0");
  
  dht.begin();                                                // initializes the interface with the DHT22 Sensor
  pinMode(fan, OUTPUT);
 
  
  servo1.attach(9);                                        // attaches the servo on pin 9 to the servo object
  servo1.write(90);                                       // Move servo1 to 90 degree position
  pinMode(LLDR, INPUT);                               // Set leftLDR as INPUT signal
  pinMode(RLDR, INPUT);                               // Set rightLDR as INPUT signal
  delay(2000);
}


//***********************   LOOP


void loop(){

  
//*********************  Interrupt Service Routine - Soft E-Stop
 
  if(start == true){  
    if(e_stop == false){


//*********************  Temp-Fan
                                                          
    float h = dht.readHumidity();                                       // read Humidity
    float t = dht.readTemperature();                                   // read temp as Celsius
    int f = (t * 1.8 + 32);                                                 // convert to Fahrenheit
                                
    if( f < tempMin){                                                       // if temp is lower than minimum temp
      fanSpeed = 0;                                                         // fan = off
      digitalWrite(fan, LOW);                                             // turn fan off 
    }
    if((f > tempMin) && ( f < tempMax)){                           // if temp is > Min and < Max set point
      fanSpeed = map(f, tempMin, tempMax, 32, 255);         // map fan speed
      fanLCD = map(f, tempMin, tempMax, 0, 100);             // speed of fan to display on LCD
      analogWrite(fan, fanSpeed);
    } 
              

//*********************  Servo/LDR Sun Tracking
      
    int pos = servo1.read();                                // read the value of Left LDR
    int leftLDR = analogRead(LLDR);                     // read the value of Right LDR
    int rightLDR = analogRead(RLDR);                   // read the value of Left LDR
        
    if((abs(leftLDR - rightLDR) < tolerance) || (abs(rightLDR - leftLDR) < tolerance)){}
    // do nothing if the diff. between values is within the tolerance limit
    
      else{                    
        if(leftLDR > rightLDR){                                // if leftLDR value is greater than rightLDR value
          pos = --pos;                                            // move servo in the --direction
          delay(10);
        }
        if(leftLDR < rightLDR){                                // if leftLDR value is less than rightLDR value
          pos = ++pos;                                          // move servo in the ++direction
          delay(100);
        }
      }
      if(pos > 180){
        pos = 170;                                                 // move servo to 170 degrees
        servo1.write(pos);
        delay(10);
      }
      if(pos < 0){
        pos = 10;                                                  // move servo to 10 degrees
        servo1.write(pos);
        delay(10);
      }


      Serial.print("Humidity:       ");
      Serial.print(h);
      Serial.println("%\t");
      Serial.print("Temperature:    ");
      Serial.print(f);
      Serial.println("F");
      Serial.println();
      Serial.print("LeftLDR:           ");
      Serial.println(leftLDR);
      Serial.print("RightLDR Value:     ");
      Serial.println(rightLDR);
      Serial.println();
      
      lcd.setCursor(0,0);
      lcd.print("TEMPERATURE: ");
      lcd.print(f);
      lcd.print("F");
      lcd.setCursor(0,1);
      lcd.print("Humidity: ");
      lcd.print(h);
      lcd.print("%");
      lcd.setCursor(0,2);
      lcd.print("FANS: ");
      lcd.print(fanLCD);
      lcd.print("%");
    }
  }
  else{
    start = false;
  }
}


//*********************  Interrupt Service Routine - Soft E-Stop

void e_stop_ISR(void){
  detachInterrupt(0);
  e_stop = !e_stop;
}

Please edit your post and add code tags (</> button).

rhulandjc2008:
3) LCD Display is coded out and working but makes the Servo motion Jitter/Stutter...even more so when I have serial monitor enabled. Not sure how to reduce the Jitter/Stutter this feature is putting on the servo motion.

Power the servo off an external source (like a 9V battery) and the jitter will go away.

Also, code looks good, but you should use proper indentation (makes it easier to read).

Power_Broker:
Power the servo off an external source (like a 9V battery) and the jitter will go away.

Also, code looks good, but you should use proper indentation (makes it easier to read).

I am using a BASTENS 300 oz-in Servo
Operating voltage: 4.8V - 6.0V / Operating speed: 0.15sec @ 4.8v and 0.13sec @ 6.0v
Torque: 250oz-in @ 4.8v or 300oz-in @ 6.0v / Gear type: All metal gears / Bearing type: Dual ball bearing on output shaft
I went with a big sevo not sure what torque forces will need once the melter is all said and built.

I have a 5VDC/12VDC power supply. Both voltages are wired to different buss-bars on a full size breadboard. From the 12VDC side of the power supply I also have wired in a:

DROK DC-DC Adjustable Buck Voltage Converter Stabilizer 6-32V to 1.25-32V LCD Display Constant Volt Amp 6V 12V 24V Step Down Voltage Regulator Power Module

Which is dialed down from 12VDC to 6VDC per servo specs.

Yes proper indentation makes it easier to read...in my sketch it is indented out but when I pasted it here it crunched everything together.

It sounds like you're having issues with power but it's also possible that your jitter is self induced. The ADC is shared, and readings may be affected by the previous one. A common workaround for this is to read each analog pin twice and ignore the first reading.

Your tolerance is quite low too, I wouldn't rely on the ADC and your LDRs to be that consistent - raise it a bit. Another issue is the frequency of your checks. Make the delays the same - currently one is 10 and the other is 100 milliseconds. But for a sun tracker that's unnecessarily frequent checking. Try 5000 so it's easier to observe and see if the jitter goes away. If not, consider some decoupling capacitors.

Delay is not the best way to proceed however. Look at the blink without delay example that comes with the IDE or Robin2's doing two things at once thread. Then you can service your emergency stop switch without having to resort to interrupts.

This is the demo that @wildbill mentions Several Things at a Time

In your Original Post you say that is sufficient to update the position once every 30 minutes. So why are you reading your LDRs more frequently than (say) once every 30 seconds? In fact I would probably do it less frequently so you are not trying to get your servo to move impossibly small distances.

...R

Robin2:
This is the demo that @wildbill mentions Several Things at a Time

In your Original Post you say that is sufficient to update the position once every 30 minutes. So why are you reading your LDRs more frequently than (say) once every 30 seconds? In fact I would probably do it less frequently so you are not trying to get your servo to move impossibly small distances.

…R

I understand what you are saying…the goal is to check sun position and slew the servo on a long time period interval(15min) or there about… Incorporating a LCD mounted display reading a DHT22 sensor on a short time period interval(<5min)for Temperature and controlling a PWM(scaled 0=100%) over a specific temp range 155F=0 to 165=100% (prolonged temps above 165F start to damage the Wax properties and my current manual melter I have, can easily reach temps of 170-180F) Would also like to incorporate a SD card shield to record temp to view later…though this is more for fun than a operational function.

Yes I’m following the sun not a fighter jet so time periods > 5min are practical… in the sketch I am trying to write and test the code with a flash light (simulating sun movement) where time periods >5min are not practical for testing purposes. If I can get the program to work and follow a flash light at almost real time …then I would think I should be able to adjust the program for long time periods.

Am I wrong in this thinking?

rhulandjc2008:
in the sketch I am trying to write and test the code with a flash light (simulating sun movement) where time periods >5min are not practical for testing purposes

That is perfectly sensible. However you should still tailor your sensor readings to whatever is practical for servo movements. And make sure your “torch” sun moves smoothly - it would be very easy for it to wiggle off target in a way that is not obvious to you but is very obvious to the LDRs. Also keep in mind that the sun is a much larger target than a torch.

It may actually be more practical to use the sun to test your project by rotating the platform with the LDRs - rather than using a light that you can move.

…R