Go Down

Topic: Yet another Servo Arduino problem. (Read 1 time) previous topic - next topic

Greg87

Sep 04, 2016, 08:15 am Last Edit: Sep 04, 2016, 02:43 pm by Greg87 Reason: Updating Images
I've attached my Fritzing code.
Schematic is here.


I couldn't find an LCD in Fritzing that matched the one I use.
Here is the LCD that I use in my setup.


The succinct explanation of how my setup works is as follows:
Panel provides unregulated power to buck converter (Deswadj3)
Buck converter outputs 8v regulated power with 3amps of usable current.
Arduino receives 8v DC in.
Same 8v supply is provided to servos.
Servos move according to light input on LDR.

The pan servo is the only one currently hooked up in my circuit.(Only one that does any work via signal volt)
Tilt servo comes later after I find out how to get the pan servo working...
---
The problem:
The moment I've put my solar tracker into the sun, my arduino powers on and because of the LDRs it realizes an imbalance in its orientation and attempts to re-orient itself. All good so far, until the servo receives it's 2.5 or 5.0 signal voltage. The moment the servo gets that, it draws power to make an attempted left or right pan swing movement. At that moment, I run into my arduino locking up. The screen doesn't dim nor does the system power down at all. The LCD output essentially just freezes and nothing on it responds anymore. If I unplug the signal voltage after a freeze has occurred, the problem does not resolve on its own. The only way to resolve is to disconnect all power and reconnect.

I've read around about load power might be causing the issue or voltage drop when load is applied. I'm a hobbyist who is self-teaching electronics and engineering through trial and error. I've encountered my first issue that I can't logically find my way around at this time. I've got myself a multimeter as my only piece of testing equipment so I often use it to half split my way through a circuit to locate problems, but am unable to find my problem thus far.

Here are 4 photos of my project built thus far. If any more photos of specific areas of my circuit are useful or necessary, please tell me and I will get clearer photos of those areas.





Thank you for anyone who has read this far.

Robin2

Unfortunately it is not ANOTHER problem. I think it it the same problem AGAIN.

You seem to have your servo power connected to Arduino Vin. Don't. Give the servos their own power supply with a common GND with the Arduino

For the future please attach your images so we don't have to go to other websites to find them.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Greg87

Appreciate the reply.

I will try to edit my post to include the images. I couldn't find the attach button earlier when I clicked edit.(Will double check after posting this.)

Just out of curiosity... you've suggested that I separate my servo and arduino power. Currently I am using a 25W switching regulator(Deswadj3) to give them both power from a 50W capable panel. Is it feasible or even recommended for me to use a voltage divider circuit after the solar panel to split its potential 50 watts of power into two 25W segments which can feed two separate Deswadj3's so that one can go to my arduino and the other to my servo?

Again. I appreciate your insight into my problem.

I will grab a 9v battery for now to power the MCU and let the solar panel power the servos.


Robin2

#3
Sep 04, 2016, 11:21 am Last Edit: Sep 04, 2016, 11:23 am by Robin2
You need to use the full editor (not quick edit) to get the attach options.

If you mean a PP3 type of 9v battery - don't. They can't produce enough current. Use a pack of 6xAA cells.

A voltage divider is not appropriate for a power circuit.

One option may be to power the Arduino through its 5v pin from the output of a 7805 voltage regulator which gets its input from the solar panels.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Greg87

Robin2, when you suggested the 7805 getting its input from the solar panel to power the arduino via the 5v VIN pin, were you meaning to suggest putting it in parallel with my DESWADj3(Switching buck regulator) which is already fed from the single solar panel I'm using?

If so, I like that idea over using batteries to power my arduino as I don't want to have batteries in my project if I can help it.

TomGeorge

Hi, Greg.
I see you have opened Serial.begin(9600), but have you used serial.prints you have commented out to send debug data to your monitor.

I suggest you put some in to check your input values and any calculated values.

Did you write this code a stage at a time?
1) read LDR input values, get working.
2) calculate differences/sun directions.
3) write servo drive code, get working
4) write display code, get working.
5) then one at a time combine and get working each addition before adding the next.

Using serial monitor as debugging all the time.

I would not have even bothered with the display at this stage, just get the tracking working, take all reference to displays out until the basic function of tracking the sun has been accomplished.

Tom.... :)


OPs Code.

Code: [Select]

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);


#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH  16
static const unsigned char PROGMEM logo16_glcd_bmp[] =
{ B00000000, B11000000,
  B00000001, B11000000,
  B00000001, B11000000,
  B00000011, B11100000,
  B11110011, B11100000,
  B11111110, B11111000,
  B01111110, B11111111,
  B00110011, B10011111,
  B00011111, B11111100,
  B00001101, B01110000,
  B00011011, B10100000,
  B00111111, B11100000,
  B00111111, B11110000,
  B01111100, B11110000,
  B01110000, B01110000,
  B00000000, B00110000 };

#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

float HighestVoltage = 0.0;

float sample1;
float sample2;
float sample3;
float sample4;
float sample5;
float average;
int iteration;
float percent;
float previous;

int LDR1Value = 0;
int LDR2Value = 0;
int LDR1Average = 0;
int LDR2Average = 0;





float startcount;
float endcount;

void setup()   {               
  Serial.begin(9600);

  iteration = 1;
  previous = 1.00;
  startcount = 1.00;
  endcount = 100.00;
 
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

  display.clearDisplay();
  display.display();
  display.setTextSize(1);
  display.setTextColor(WHITE);
}











void loop() {

  GetSolarVolt();
  DrawSolarOutline();
  //DrawSolarImage(HighestVoltage, average);
  LDRcode();
 
  display.setCursor(122,0);
  //display.println(iteration);
 
 
  display.display();
  display.clearDisplay();

}











void GetSolarVolt(void) {
  display.setTextSize(1);
 
  //float input = analogRead(0); //We should be getting a low millivolt reading from our voltage divider
  //float Resolution = (1.1/1024.0); //Setup our voltage resolution
  //float Millivolt = input * Resolution; //Multiply what is felt on AnalogPin0 by our resolution
 

  display.setCursor(0, 0);
  //display.println(Millivolt, 3);
  display.setCursor(30, 0);
  //display.println("mV@A0");

  float R1 = 9850000.0; //Hardcoded Resistor 1 value for my circuit
  float R2 = 99100.0; //Hardcoded Resistor 2 value for my circuit
  float Divider = (R2 / (R1 + R2)); //This should equal 0.00996 with hardcoded values
 
  //float SolarVolt = Millivolt / Divider; //Now we divide our converted digital output by the voltage divider product from before

  display.setCursor(0,9);
  //display.println(SolarVolt, 2);
  display.setCursor(36,9);
  //display.println("PV Volts");

  //float VoltageHolder = SolarVolt;
   
  //if((VoltageHolder > HighestVoltage) && (VoltageHolder < 23.0))
  //{HighestVoltage = VoltageHolder;}
/* 
  if(HighestVoltage < 23.0)
  {
 
    display.setCursor(0,18);
    display.println(HighestVoltage);
  }

   switch (iteration) {
    case 1:
      sample1 = SolarVolt;
      iteration+=1;
    break;
    case 2:
      sample2 = SolarVolt;
      iteration+=1;
    break;
    case 3:
      sample3 = SolarVolt;
      iteration+=1;
    break;
    case 4:
      sample4 = SolarVolt;
      iteration+=1;
    break;
    case 5:
      sample5 = SolarVolt;
      iteration+=1;
    break;
    case 6:
      average = ((sample1+sample2+sample3+sample4+sample5)/5);
      iteration+=1;
    break;
   }
   if(iteration == 7)
   {
     iteration = 1;
   }
     display.setCursor(70,36);
     display.println(average, 1);
     display.setCursor(96,36);
     display.print("Volts");
*/
}
   
   
   
   
   
   
  void DrawSolarOutline(void)
  {
        //Horizontal Lines TOP BTM
      for (int y=0; y < 2; y++) {
      for (int x=69; x < 127; x++) {
        display.drawPixel(x, (63-(y*20)), WHITE);
       
      }
    }
        //Vertical Lines LFT RGT
      for (int y=44; y < 63; y++) {
      for (int x=0; x < 2; x++) {
        display.drawPixel((127-(x*59)), y, WHITE);
       
      }
    }
   
  }
 
 
 
 
 
 
 
  void DrawSolarImage(float high, float avr) {
   

 
  float val = 0.0;
  float range = 0;
  float i = 0;
  if(avr < high)
  {
    percent = ((avr / high)*100);
    val = map(percent, 0, 100, 70, 126);
       
    if(val > previous)
    {
      range = val - previous;
      while(i != range)
      {
      for (int x=70; x < previous+i; x++) {
        for (int y=45; y < 62; y++) {
          display.drawPixel(x, y, WHITE);
          }
        }
        i+=1;
      }
    }

    else if(val < previous)
    {
      range = val - previous;
               
      while(i != range)
      {
        for (int x=70; x < previous; x++) {
        for (int y=45; y < 62; y++) {
          display.drawPixel(x, y, WHITE);
          }
        }
       
        for (int x=previous; x > val; x--) {
        for (int y=45; y < 62; y++) {
          display.drawPixel(x, y, BLACK);
          }
        }
        i-=1;

      }
    }

    else
    {
      for (int x=70; x < previous; x++) {
        for (int y=45; y < 62; y++) {
          display.drawPixel(x, y, WHITE);
          }
        }
    }
   
    display.setTextColor(BLACK);
    display.setCursor(85,50);
    display.println(percent,1);
    display.setCursor(109,50);
    display.println("%");
    display.setTextColor(WHITE);
   
  }
  previous = val;
}















  void LDRcode(void) {
    LDR1Value = analogRead(0);
    LDR2Value = analogRead(1);
    for(int i=0;i<5;i++)
    {
      LDR1Average += LDR1Value;
      LDR2Average += LDR2Value;
      //delay(20); 
    }
     display.setCursor(112,16);
     display.println("R");
     display.setCursor(103,23);
     display.println(LDR1Average/5);
     
     display.setCursor(6,16);
     display.println("L");
     display.setCursor(0,23);
     display.println(LDR2Average/5);

     //Serial.println(LDR1Average/5);      // print the value to the serial port
     //Serial.println(LDR2Average/5);      // print the value to the serial port
   
     //delay(100);   
     DrawGraphic(LDR1Average/5, LDR2Average/5);
     
     LDR1Average = 0;
     LDR2Average = 0;
     
  }

  void DrawGraphic(int L, int R) {
  int spread;
  int large = max(L,R);
  int small = min(L,R);
  spread = large - small;
  //Serial.println(spread);

  int adjust = round(spread / 10.23);
  //Serial.println(adjust);
  //delay(1000);

  if(R>L)
  {adjust = adjust*(-1);}
  if(adjust<=-62)
  {adjust = -62;}
  if(adjust>=62)
  {adjust = 61;}
 
  int sun = 62+adjust;
  display.setCursor(sun,1);
  display.println(F("*"));
  display.setCursor(62,16);
  display.println(F("|"));
  //Serial.println(sun);
  //if(sun < 60 | sun > 64)
  //{
     ServoCall(sun);
  //}
 
  }

  void ServoCall(int offset)
  {
    //int output = map(offset, 0, 123, 138, 255);
    //Serial.println(output);
    //analogWrite(11, output);

    if(offset < 60)
    {
      Serial.println("138 Lowest Volt Sent");
      analogWrite(11, 138);
    }
    if(offset > 64)
    {
      Serial.println("255 Highest Volt Sent");
      analogWrite(11, 255);
    }
    else if (offset >= 60 & offset <= 64)
    {
      Serial.println("Don't send");
    }
   
  }


Everything runs on smoke, let the smoke out, it stops running....

Greg87

So about my code, yes it has been written in stages of development.

I made sure to test every piece one step at a time to ensure the code was all well and good, but as you know - projects can evolve over time. My GetSolarVolt() function was originally written when I was using a 12v solar panel trickle charger for which I hardcoded some resistor values in to let my GUI show how many real volts were present on the panel. As that was merely my starting point to see if I could power the Uno off solar, I never touched that part of the code when I added my full-size panel to the project and removed the 12v trickle charger panel.

I guess I should just offload any and all code that isn't being used to a txt file somewhere so that it isn't confusing to anyone who reads through it.

As to your questions.
1) Read LDR values and verify that worked, Yes.
2) Calculate differences and sun directions, verified, Yes.
3) Write servo drive code, using PWM analogWrite, verified signal voltage was output between 2.5 and 5.0v, Yes.
4) Display code verified and working, Yes.
5) All pieces of code working together, Yes.

I was pleasantly surprised how well the arduino could render animated images on this LCD in real-time. When I step outside, without the servo signal wire plugged into my servo, I have a rather nice "sun finder" HUD.

Wawa

#7
Sep 04, 2016, 01:32 pm Last Edit: Sep 04, 2016, 01:47 pm by Wawa
The system might work if you use a lead-acid battery (and backflow diode) on the solar side of the buck regulator. Solar cells are complex voltage/current devices.
The startup current of the servos will dip the supply, and lock up or restart the Arduino.

It also might help to supply the Uno on the DC socket.
The reverse voltage protection diode between DC socket and V-in will stop the servos discharging the supply caps of the Uno.

The pull up resistors/LDRs are drawn wrong.
They go in series with the LDRs, with the center tap to the analogue inputs.
Resistor values are rather low. I would have picked 1k or higher.
Leo..

Greg87

#8
Sep 04, 2016, 02:10 pm Last Edit: Sep 04, 2016, 02:44 pm by Greg87
Wawa, you are absolutely correct!

I totally drew my schematic incorrectly. Rest assured that the actual device is wired up properly though. I will fix my schematic now.

Wonder if that is the problem I'm having... the startup power cost draining all the juice.
If it was, I would have figured the UNO would have just turned off rather than freezing on though. Granted, I'm just pondering.

Would be awesome if I had a bench power supply because as I am now, I need a clear sunny day to do any testing and this weekend was all rain (-_-).

When you say DC socket, you mean the wallwart plug right?
I am using it. Sorry that my photos are kinda... crowded. It does make it hard to see stuff easily.

Fixed Schematic:



Robin2

I will fix my schematic now.
PLEASE ensure that you leave the existing incorrect schematic in place (so the Forum comments relating to it make sense) and show you new schematic in a new Reply.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Robin2

Robin2, when you suggested the 7805 getting its input from the solar panel to power the arduino via the 5v VIN pin, were you meaning to suggest putting it in parallel with my DESWADj3(Switching buck regulator) which is already fed from the single solar panel I'm using?
I think that is what I have in mind - but I don't know enough about your buck regulator to be certain.

I can't imagine a solar system without a battery to even out the fluctuations in output from the solar panels.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Greg87

Yea, I hear ya on that with the fluctuations. That is why I purposely sourced a 50w panel with high efficiency cells and a 25w regulator with really high efficiency. My goal was to have more power than necessary to move the unit so that I hopefully wouldn't run into any 'issues' during daylight hours.

I am eventually going to install a cutoff circuit so that the regulator is isolated from the panel unless the panel has a minimum of 10v present because I don't want to under supply my regulator at any time in the early dawn or late dusk hours. (Granted, this is all speculative. Gotta get the servos working before I add / refine my work)

Robin2

#12
Sep 04, 2016, 07:05 pm Last Edit: Sep 04, 2016, 07:06 pm by Robin2
I don't know where you live but in Ireland and Britain it would be very common to get a 10 to 1 variation in solar panel output within a few seconds when a cloud passes across the sun.

I would buy a bigger solar panel if I wished to capture more energy - but not to reduce the effect of fluctuations in output.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

MarkT

You seem to be trying to drive a buck converter that requires a voltage source using
a PV panel (which is more like a weather-dependent current source).  That's not going
to work well without a storage battery to stiffen up the voltage to something solid.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

TomGeorge

Hi,
Quote
Just out of curiosity... you've suggested that I separate my servo and arduino power. Currently I am using a 25W switching regulator(Deswadj3) to give them both power from a 50W capable panel.
Where is your energy storage device, your rechargeable batteries?
You cannot use a PV panel as a battery, it is not a voltage source, it is a current source.

You need a charge controller with the 50W panel to charge a storage device, then use the DC to DC regulator to get your regulated supply.

Put a DMM across your panel and measure its volts as you put your system into the sunlight.

Replace the panel with a "capable" supply, that is a 12V battery, able to provide at least 3A to cover the load that the servos will draw as they turn the panel.


Thanks...  Tom... :)
Everything runs on smoke, let the smoke out, it stops running....

Go Up