Arduino for monitoring a remote solar powered router volts/current/thermal/light

i have been designing a solar powered wireless router for a while now and have decided to use a small arduino board to monitor it over the wifi network.

the router is a TP-link WR703N http://wiki.openwrt.org/toh/tp-link/tl-wr703n

i love this router due to it only using around 0.6w so it makes it ideal for solar power and that it has a serial port that i can access over the network via SER2NET so the next step was to build a way of monitoring the battery voltage, how many amps the solar panel is putting into the battery, thermal management of the batteries and how bright the sun is so i know if the batteries are charging like they should.

using what coding remembered from school 10 years ago and some tinkering with settings i have done setting some some RC flight controllers i managed to copy and paste something together from a few different sources that appears to look okish when I run it on my test arduino nano and monitor the serial output but i think it will need some calibration when all the parts arrive.

it started out as this program for monitoring temperature and AC voltage that i edited down to what i needed from it

i then grafted the current monitoring part from here by simply deleting everything i didnt need then copy and pasting.

i got the part to turn the led on if it gets too hot from here i will use it to turn on a cooler for the batteries
http://www.electroschematics.com/9540/arduino-fan-speed-controlled-temperature/

and the LDR code from here
http://bildr.org/2012/11/photoresistor-arduino/

the code is not finished yet i am going to add a second thermal switch to heat the batteries if it gets too cold and im still not 100% sure on how to get the light to show as a calibrated percentage ie i would like 2 values that i can set on a sunny day and in the dark.

I doubt this code will work as is but can anyone point out any mistakes or is there a better way of doing any part of it?

int voltPin = A0;     // voltage divider (middle terminal) connected to analog pin 0
int tempPin = A2;     // TMP36 data pin
int val = 0;           // variable to store the value read
int volt = 0;           // variable to store the voltage calculated

int analogInPin = A1;  // Analog input pin that the carrier board OUT is connected to
int sensorValue = 0;        // value read from the carrier board
int outputValue = 0;        // output in milliamps

int LDR_Pin = A4; //analog pin 0

int ledPin = 13; // choose the pin for the LED

float amps = 0.0;
unsigned long msec = 0;
float time = 0.0;
int sample = 0;



void setup()
{
  Serial.begin(9600);          //  setup serial
  pinMode(ledPin, OUTPUT);  // declare LED as output
}

void loop()
{
  // Voltage Calculation
  val = analogRead(voltPin);    // read the input pin
  volt = map(val, 0, 1023, 0, 29); // map 29v range
  delay(50);
  
  
  // temp calculaton
  int reading = analogRead(tempPin);    // read the input pin
  float voltage = reading * 5.0;
  voltage /= 1024.0;


  //current monitor

  // read the analog in value:
  sensorValue = analogRead(analogInPin);

  // convert to milli amps
  outputValue = (((long)sensorValue * 5000 / 1024) - 500 ) * 1000 / 133;
  amps = (float) outputValue / 1000;
  float watts = amps * voltage;

 //light dependsnt resistor
 int LDRReading  = analogRead (LDR_Pin)/10 ; 

  //uptime
  msec = millis();
  time = (float) msec / 1000.0;


  //Fan control
{
  float temperatureC = (voltage - 0.5) * 100;
  if (temperatureC < 1000) {
    digitalWrite(ledPin, LOW);  // turn LED OFF
  } else {
    digitalWrite(ledPin, HIGH);  // turn LED ON
  }


// serial output
}
  Serial.print(voltage);
  Serial.print(" volts");
  Serial.print("\t Current (amps) = ");     
  Serial.print(amps); 
  Serial.print("\t Power (Watts) = ");  
  Serial.print(watts);  
  float temperatureC = (voltage - 0.5) * 100;
  Serial.print("\t degrees C = ");
  Serial.print(temperatureC);
  
  Serial.print("\t Solar output % = ");  
  Serial.print(LDRReading);
  
  Serial.print("\t Time (hours) = ");
  Serial.println(time/3600);
  
  
  delay(500);
}

ok done v2 with the low temp protection

int voltPin = A0;     // voltage divider (middle terminal) connected to analog pin 0
int tempPin = A2;     // TMP36 data pin
int val = 0;           // variable to store the value read
int volt = 0;           // variable to store the voltage calculated

int analogInPin = A1;  // Analog input pin that the carrier board OUT is connected to
int sensorValue = 0;        // value read from the carrier board
int outputValue = 0;        // output in milliamps

int LDR_Pin = A4; //analog pin 0

int hightemp = 13; // choose the pin for the LED
int lowtemp = 12; // choose the pin for the LED

float amps = 0.0;
unsigned long msec = 0;
float time = 0.0;
int sample = 0;



void setup()
{
  Serial.begin(9600);          //  setup serial
  pinMode(hightemp, OUTPUT);  // declare LED as output
  pinMode(lowtemp, OUTPUT);  // declare LED as output
}

void loop()
{
  // Voltage Calculation
  val = analogRead(voltPin);    // read the input pin
  volt = map(val, 0, 1023, 0, 29); // map 29v range
  delay(50);
  
  
  // temp calculaton
  int reading = analogRead(tempPin);    // read the input pin
  float voltage = reading * 5.0;
  voltage /= 1024.0;


  //current monitor

  // read the analog in value:
  sensorValue = analogRead(analogInPin);

  // convert to milli amps
  outputValue = (((long)sensorValue * 5000 / 1024) - 500 ) * 1000 / 133;
  amps = (float) outputValue / 1000;
  float watts = amps * voltage;

 //light dependsnt resistor
 int LDRReading  = analogRead (LDR_Pin)/10 ; 

  //uptime
  msec = millis();
  time = (float) msec / 1000.0;


  //Fan control
{
  float temperatureC = (voltage - 0.5) * 100;
  if (temperatureC > 40) {
    digitalWrite(hightemp, LOW);  // turn LED OFF
  } else {
    digitalWrite(hightemp, HIGH);  // turn LED ON
  }
  if (temperatureC < 10) {
    digitalWrite(lowtemp, LOW);  // turn LED OFF
  } else {
    digitalWrite(lowtemp, HIGH);  // turn LED ON
  }
  

// serial output
}
  Serial.print(voltage);
  Serial.print(" volts");
  Serial.print("\t Current (amps) = ");     
  Serial.print(amps); 
  Serial.print("\t Power (Watts) = ");  
  Serial.print(watts);  
   float temperatureC = (voltage - 0.5) * 100;
  Serial.print("\t degrees C = ");
  Serial.print(temperatureC);
 
  Serial.print("\t Solar output % = ");  
  Serial.print(LDRReading);
  
  Serial.print("\t Time (hours) = ");
  Serial.println(time/3600);
  
  
  delay(500);
}

or is there a better way of doing any part of it?

#7 below would be a start.

http://forum.arduino.cc/index.php/topic,148850.0.html

OK done any other thoughts?

ok i have added a notificaton on the serial output to give an overheat or cold alarm if the thermal protection kicks in

int voltPin = A0;     // voltage divider (middle terminal) connected to analog pin 0
int tempPin = A2;     // TMP36 data pin
int val = 0;           // variable to store the value read
int volt = 0;           // variable to store the voltage calculated

int analogInPin = A1;  // Analog input pin that the carrier board OUT is connected to
int sensorValue = 0;        // value read from the carrier board
int outputValue = 0;        // output in milliamps

int LDR_Pin = A4; //analog pin 0

int hightemp = 13; // choose the pin for the LED
int lowtemp = 12; // choose the pin for the LED

float amps = 0.0;
unsigned long msec = 0;
float time = 0.0;
int sample = 0;



void setup()
{
  Serial.begin(9600);          //  setup serial
  pinMode(hightemp, OUTPUT);  // declare LED as output
  pinMode(lowtemp, OUTPUT);  // declare LED as output
}

void loop()
{
  // Voltage Calculation
  val = analogRead(voltPin);    // read the input pin
  volt = map(val, 0, 1023, 0, 29); // map 29v range
  delay(50);
  
  
  // temp calculaton
  int reading = analogRead(tempPin);    // read the input pin
  float voltage = reading * 5.0;
  voltage /= 1024.0;


  //current monitor

  // read the analog in value:
  sensorValue = analogRead(analogInPin);

  // convert to milli amps
  outputValue = (((long)sensorValue * 5000 / 1024) - 500 ) * 1000 / 133;
  amps = (float) outputValue / 1000;
  float watts = amps * voltage;

 //light dependsnt resistor
 int LDRReading  = analogRead (LDR_Pin)/10 ; 

  //uptime
  msec = millis();
  time = (float) msec / 1000.0;


  //Fan control
{
  float temperatureC = (voltage - 0.5) * 100;
  if (temperatureC < 40) {
    digitalWrite(hightemp, LOW);  // turn LED OFF
  } else {
    digitalWrite(hightemp, HIGH);  // turn LED ON
    Serial.println("OVERHEAT");
  }
  if (temperatureC > 10) {
    digitalWrite(lowtemp, LOW);  // turn LED OFF
  } else {
    digitalWrite(lowtemp, HIGH);  // turn LED ON
    Serial.println("COLD");
  }
  

// serial output
}
  Serial.print(voltage);
  Serial.print(" volts");
  Serial.print("\t Current (amps) = ");     
  Serial.print(amps); 
  Serial.print("\t Power (Watts) = ");  
  Serial.print(watts);  
   float temperatureC = (voltage - 0.5) * 100;
  Serial.print("\t degrees C = ");
  Serial.print(temperatureC);
 
  Serial.print("\t Solar output % = ");  
  Serial.print(LDRReading);
  
  Serial.print("\t Time (hours) = ");
  Serial.println(time/3600);
  
  
  delay(500);
}

i think i figured out how to get the light sensor to show a calibrated percentage.

int voltPin = A0;     // voltage divider (middle terminal) connected to analog pin 0
int tempPin = A2;     // TMP36 data pin
int val = 0;           // variable to store the value read
int volt = 0;           // variable to store the voltage calculated

int analogInPin = A1;  // Analog input pin that the carrier board OUT is connected to
int sensorValue = 0;        // value read from the carrier board
int outputValue = 0;        // output in milliamps


int hightemp = 13; // choose the pin for the LED
int lowtemp = 12; // choose the pin for the LED

float amps = 0.0;
unsigned long msec = 0;
float time = 0.0;
int sample = 0;

const int pinLDR = A5; // Analog Pin A0 connects across LDR
float valueVolt; // We'll need these float variables for calculations
float valueBrightness;
const int pinLED = A1; // Analog Pin A1 connects across LED



void setup()
{
  Serial.begin(9600);          //  setup serial
  pinMode(hightemp, OUTPUT);  // declare LED as output
  pinMode(lowtemp, OUTPUT);  // declare LED as output
}

void loop()
{
  // Voltage Calculation
  val = analogRead(voltPin);    // read the input pin
  volt = map(val, 0, 1023, 0, 29); // map 29v range
  delay(50);
  
  
  // temp calculaton
  int reading = analogRead(tempPin);    // read the input pin
  float voltage = reading * 5.0;
  voltage /= 1024.0;


  //current monitor

  // read the analog in value:
  sensorValue = analogRead(analogInPin);

  // convert to milli amps
  outputValue = (((long)sensorValue * 5000 / 1024) - 500 ) * 1000 / 133;
  amps = (float) outputValue / 1000;
  float watts = amps * voltage;

 //light dependsnt resistor
 
 valueVolt = analogRead(pinLED)*5.0/1024; // Store the calculated voltage in a float var
 valueBrightness = map(analogRead(pinLDR),990,645,0,100);

  //uptime
  msec = millis();
  time = (float) msec / 1000.0;


  //Fan control
{
  float temperatureC = (voltage - 0.5) * 100;
  if (temperatureC < 40) {
    digitalWrite(hightemp, LOW);  // turn LED OFF
  } else {
    digitalWrite(hightemp, HIGH);  // turn LED ON
    Serial.println("OVERHEAT");
  }
  if (temperatureC > 10) {
    digitalWrite(lowtemp, LOW);  // turn LED OFF
  } else {
    digitalWrite(lowtemp, HIGH);  // turn LED ON
    Serial.println("COLD");
  }
  

// serial output
}
  Serial.print(voltage);
  Serial.print(" volts");
  Serial.print("\t Current (amps) = ");     
  Serial.print(amps); 
  Serial.print("\t Power (Watts) = ");  
  Serial.print(watts);  
   float temperatureC = (voltage - 0.5) * 100;
  Serial.print("\t degrees C = ");
  Serial.print(temperatureC);
 
  Serial.print("\t Solar output % = ");  
  Serial.print(valueBrightness);
  
  Serial.print("\t Time (hours) = ");
  Serial.println(time/3600);
  
  
  delay(500);
}

I am wanting to make a smart charger for my 12v NiMH aircraft battery with a 2000mah compacitance. I have a ATMEGA328Pchip that i plan to use to monitor the voltage and cut it when it needs to. I plan to fast charge the battery until the ATmega reads 85% maximum voltage of the battery, and then it will become a trickle-down chargeruntil it reaches the full 12 volts. i plan to have it turn on an RGB led to signal charging and full charge as well. What I dont understand is how o configure the chip to be able to read the coltage of the battery without frying the chip. any ideas??

You can use a pair of resistors as a voltage divider to bring the 12V - ish signal down to the 0..5V range that the Arduino can handle. I suggest you provide some form of protection against overvoltage, because the incoming voltage could easily exceed 12V.

After you have read the analog value, the map() function provides a convenient way to transform this to a voltage - it would be reasonable to represent the voltage as a number of millivolts.

Alright, I used two resistors in configuration , and i got about 4.95 volts, however the voltage immediately began to drop down to less than 1 volt, how is this possible? am i using resistors that are too weak to take that kind of voltage?

and also the map function, would it look more like this the??

int analogVal = analogRead(Pin);
Voltage = map(analogVal,0,255,0,1000);

i have made more progress on this project the only thing still to finish is the current monitoring since i havent received the sensor yet

i have hooked up 30k and 4.7k resistors as a voltage divider and calibrated it for my 3.3v arduino,
10k LDR and 10k resistor to measure sunlight
TMP36 thermistor is working but needs better calibrated
i have a graphing function now too using Simplot

the only thing stopping me installing this in a router just now is waiting for my current sensor.

//volts  
int batMonPin = A0;    // input pin for the voltage divider
int batVal = 0;       // variable for the A/D value
float pinVoltage = 0; // variable to hold the calculated voltage
float batteryVoltage = 0;


//current 
int analogInPin = A1;  // Analog input pin that the carrier board OUT is connected to
int sensorValue = 0;        // value read from the carrier board
int outputValue = 0;        // output in milliamps
unsigned long msec = 0;
float time = 0.0;
int sample = 0;
float totalCharge = 0.0;
float averageAmps = 0.0;
float ampSeconds = 0.0;
float ampHours = 0.0;
float wattHours = 0.0;
float amps = 0.0;


int R1 = 30000; // Resistance of R1 in ohms
int R2 = 4620; // Resistance of R2 in ohms
float ratio = 0;  // Calculated from R1 / R2


//Temperature

int tempPin = A2;     // TMP36 data pin
const int pinLDR = A3; // Analog Pin A0 connects across LDR

//Brightness
float valueBrightness;




//graphing
int buffer[20];
float deltaAngle = 3.14/51; //Arbitrary angle increment size
float angle = 0;
int amplitude = 100;


void setup()
{
  Serial.begin(9600);          //  setup serial
}

void loop()
{
  
  
  int data1;
  int data2;
  int data3;
  int data4;
  
  

  
  
  // Voltage Calculation
    
int sampleBVal = 0;
int avgBVal = 0; 
int sampleAmpVal = 0;
int avgSAV = 0;
 
for (int x = 0; x < 10; x++){ // run through loop 10x

  // read the analog in value:
  sensorValue = analogRead(analogInPin);  
  sampleAmpVal = sampleAmpVal + sensorValue; // add samples together

  batVal = analogRead(batMonPin);    // read the voltage on the divider
  sampleBVal = sampleBVal + batVal; // add samples together
 
  delay (10); // let ADC settle before next 0sample

}

avgBVal = sampleBVal / 10; //divide by 10 (number of samples) to get a steady reading

  pinVoltage = avgBVal * 0.00334;       //  Calculate the voltage on the A/D pin
                           
  ratio = (float)R1 / (float)R2;
  batteryVoltage = pinVoltage * ratio;    //  Use the ratio calculated for the voltage divider
                                          //  to calculate the battery voltage
                                         

  
  
  // temp calculaton
  int reading = analogRead(tempPin);    // read the input pin

 // converting that reading to voltage, for 3.3v arduino use 3.3
 float voltage = reading * 3.3 / 1024; 
 

 


  //current monitor

  float amps = 0;
  for(int i = 0; i < 1000; i++) {
    amps = amps + (.0264 * analogRead(A1) -13.51) / 1000;
    delay(1);
  }



 //light dependsnt resistor
 

  valueBrightness = map(analogRead(pinLDR),200,0,0,100);

  //uptime
  msec = millis();
  time = (float) msec / 1000.0;

 




// serial output
  Serial.print("Volts = " );                      
  Serial.print(batteryVoltage);     
  Serial.print("\t Current (amps) = ");     
  Serial.print(amps); 
  float watts = amps * batteryVoltage;
  Serial.print("\t Power (Watts) = ");  
  Serial.print(watts);  
 
   float temperatureC = (voltage - 0.5) * 100;
  Serial.print("\t degrees C = ");
  Serial.print(temperatureC);
 
  Serial.print("\t Solar output % = ");  
  Serial.print(valueBrightness);
  
  Serial.print("\t Time (hours) = ");
  Serial.println(time/3600);
  
  
  
  //Generating data that will be plotted
  data1 = batteryVoltage;
  data2 = watts;
  
  data3 = temperatureC;
  data4 = valueBrightness;
  
  angle = angle + deltaAngle;
  
  plot(data1,data2,data3,data4);
  
  delay(100); //Need some delay else the program gets swamped with data
  
} 

void plot(int data1, int data2, int data3, int data4)
{
  int pktSize;
  
  buffer[0] = 0xCDAB;             //SimPlot packet header. Indicates start of data packet
  buffer[1] = 4*sizeof(int);      //Size of data in bytes. Does not include the header and size fields
  buffer[2] = data1;
  buffer[3] = data2;
  buffer[4] = data3;
  buffer[5] = data4;
    
  pktSize = 2 + 2 + (4*sizeof(int)); //Header bytes + size field bytes + data
  
  //IMPORTANT: Change to serial port that is connected to PC
  Serial.write((uint8_t * )buffer, pktSize);

  
  
  

}