Skip to content

Instantly share code, notes, and snippets.

@mattrude
Created March 9, 2020 21:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mattrude/134609e95161fe0a566e526f97c90230 to your computer and use it in GitHub Desktop.
Save mattrude/134609e95161fe0a566e526f97c90230 to your computer and use it in GitHub Desktop.
/* SolarBear MPPT Controller - Version 6.3
* Copyright (c) December 2017 - Sergey Vekli, Ted Luginbuhl, & Matt Rude
*
* https://www.rcgroups.com/forums/showthread.php?3007750-BNF-SolarBear-pure-solar-powered-32-wing-Free-plans
*
* **************************************************************************************
*
* Solar Cells
*
* The solar cells are soldered in series with a piece of 29guage magnet wire going to each pad on the
* cells. Start on one end and then go to the other running the wire from positive to negative to
* positive..etc. Then take 24gauge magnet wire from each end and run it to the center. Be sure to solder a
* piece of 29ga on the end cells from one pad to the other on the same polarity of the same cell to let the
* current flow easier. Each cell should have 2 wires connecting it to the next except the end cells that
* have the heavier wire coming to the center.
*
* ATtiny85
*
* First you can wire up the DIP 8 socket according to the diagram at the beginning of the mppt code.
* The optional power on reset IC has 3 pins and can be purchased from Microchip directly. If you do not
* use this IC you will have to put a switch on the main power to keep the Attiny85 from locking up. If
* using the switch you will need to connect the reset pin of the Attiny85 to ground thru a 10kohm resistor
*
* The power on reset IC has 3 pins 1 is connected to the reset pin on the Attiny85 thru a 10kohm resistor.
* Pin 2 is connect to Vcc and pin 3 is connected to ground.
*
* I use the “Tiny AVR programmer” from Sparkfun https://www.sparkfun.com/products/11801
* And the Arduino IDE running the “attiny” bootloader by David Mellis
*
* - pin2 Solar Voltage coming off a divider. 1.1v max. 300k and pin2 across 47k to ground
* - pin3 RC Input comeing from RX
* - pin4 RC Output going to ESC
*
* **************************************************************************************
* __ __
* Reset -|o |- VCC
* RX - 3 -| |- 2 - Solar Voltage
* ESC - 4 -| |- 1
* GND -|_____|- 0
*
* **************************************************************************************
*/
#include <avr/wdt.h> // Watch Dog Timer
#define Vmpp 0.55 // Good setting: 0.84 for 12 cell and .55 for 8 cell. If too low motor will be faster at less than full throttle.
#define VmppLOW 0.63 // Low throttle mpp voltage. 0.97 seems to be good for 12 cell and .63 for 8 cell.Set so that motor cuts off when parallel with suns rays.
#define STEPdown 2 // Default 2 If too high throttle will oscilate, if too low esc will reset
#define STEPup 1 //
#define iterations 15 // Default 15. This is how many times the algo averages the array voltage.
#define transition 150 // Point at wich transition takes place from Vmpp to VmppLOW between 110 and 230. Default 150.If too high it will kick in too soon and mimick Vmpp set too low.
#define LOW false
#define HIGH true
int x = 0;
int Vcell = 0;
int VMPP = 0.00;
int VMPPlow = 0.00;
boolean cur_level = LOW;
void setup() {
wdt_enable(WDTO_500MS); //Enable Watch Dog Timer.
// Set pins mode
pinMode(4, OUTPUT); // Going to esc
pinMode(3, INPUT); // Coming from rx
// Convert Vmpp to adc levels
VMPP = Vmpp * 925;
VMPPlow = VmppLOW * 925;
// Set freq and interrupts registers
GIMSK = B00100000;
PCMSK = B00001000;
TCCR0A = B00000010;
TCCR0B = B00000010;
TIMSK = B00010000;
OCR0A = 110;
analogReference(INTERNAL1V1);
}
// Main control timer
ISR(TIMER0_COMPA_vect) {
if (cur_level == HIGH) {
digitalWrite(4, LOW);
cur_level = LOW;
}
TCNT0 = 0;
}
// Interrupt for rx repeater mode
ISR(PCINT0_vect) {
if (digitalRead(3) > cur_level) {
digitalWrite(4, HIGH);
cur_level = HIGH;
TCNT0 = 0;
} else {
if (cur_level == HIGH) {
digitalWrite(4, LOW);
cur_level = LOW;
}
}
}
// Main measurement-set cycle
void loop() {
wdt_reset(); // Feed the dog
// Throttle level at wich higher Vmpp kicks in else statement.
if (OCR0A <= transition) {
x = VMPPlow;
} else {
x = VMPP;
}
Vcell = 0;
// Iterations for average array voltage.
for (int XX = 0; XX < iterations; XX++) {
delay(1);
Vcell = Vcell + analogRead(A1);
}
Vcell = Vcell / iterations;
// Vcell=analogRead(A1);
if (Vcell > x) {
// 230
if (OCR0A <= 230 ) {
OCR0A += STEPup;
}
}
if (Vcell < x) {
if (OCR0A >= 110) { //110
OCR0A -= STEPdown;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment