parallelbatterycontroller_v0.4
/*
4 parallel charge controller for cheap lead acid batteries
with 4ch SD card datalogger for STM32 Blue Pill
The circuit:
analog sensors on analog ins - A0, A1, A2 and A3
CDS for detect brightness - B0
photoLED switch - B12, B13, B14, B15
SD card attached to SPI bus as follows:
MOSI - pin A7
MISO - pin A6
CLK - pin A5
CS - pin A4 (for MKRZero SD : SDCARD_SS_PIN)
RTC module
SDA - B7
SCL - B6
created 20 Aug 2017
modified 10 Sep 2017
code by knet-ore.no-p.biz
*/
#include "SPI.h"
#include "SD.h"
#include "Wire.h"
#include "RTClib.h"
const int chipSelect = 4;
const int timer = 8; //Wait time after changing charge-line
const int sunref = 2000; //Boundaries of brightness
const int chargeref = 1840; //Boundary of charging current
const int pinCount = 3; //the number of pins (i.e. the length of the array)
const int ledPins[] = { 28, 29, 30, 31}; //an array of pin numbers to which Batterys are attached "led"=>"Battery"
const int sensPins[] = { 0, 1, 2, 3 , 16}; //Current sensors PA0-PA3 and brightness sensor PB0
int timecount = 0; //counter for timer
int chargeline = 0; //Battery line for charging
float sensor[] = { 0, 1, 2, 3, 16};
float avgcur; //current average to determine change chargeline
float avgsun; //brightness average to determine change night-mode
String dataString = ""; //string for date to log
String dayString = ""; //string for data to log
RTC_DS1307 RTC;
void setup () {
Serial1.begin(9600);
Serial1.print("Initializing SD card...");
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial1.println("Card failed, or not present");
// don't do anything more:
return;
}
Serial1.println("card initialized.");
Serial.begin(9600);
Wire.begin();
RTC.begin();
if (! RTC.isrunning()) {
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
// RTC.adjust(DateTime(__DATE__, __TIME__));
}
// RTC.adjust(DateTime(__DATE__, __TIME__));
pinMode(ledPins[0], OUTPUT);
pinMode(ledPins[1], OUTPUT);
pinMode(ledPins[2], OUTPUT);
pinMode(ledPins[3], OUTPUT);
pinMode(sensPins[0], INPUT_ANALOG);
pinMode(sensPins[1], INPUT_ANALOG);
pinMode(sensPins[2], INPUT_ANALOG);
pinMode(sensPins[3], INPUT_ANALOG);
pinMode(sensPins[4], INPUT_ANALOG);
}
void sense() {
int analogPin = sensPins[4];
float average = 0;
for (int i = 0; i < 1000; i++) {
average = average + (1 * (analogRead(analogPin) - 0) );
delay(1);
}
sensor[4] = average / 1000;
analogPin = sensPins[0];
average = 0;
for (int i = 0; i < 1000; i++) {
average = average + (1 * (analogRead(analogPin) - 0) );
delay(1);
}
sensor[0] = average / 1000;
analogPin = sensPins[1];
average = 0;
for (int i = 0; i < 1000; i++) {
average = average + (1 * (analogRead(analogPin) - 0) );
delay(1);
}
sensor[1] = average / 1000;
analogPin = sensPins[2];
average = 0;
for (int i = 0; i < 1000; i++) {
average = average + (1 * (analogRead(analogPin) - 0) );
delay(1);
}
sensor[2] = average / 1000;
analogPin = sensPins[3];
average = 0;
for (int i = 0; i < 1000; i++) {
average = average + (1 * (analogRead(analogPin) - 0) );
delay(1);
}
sensor[3] = average / 1000;
}
void readdate () {
// make a string for assembling the day to log:
DateTime now = RTC. now();
dayString = String(now.year(), DEC);
dayString += String('/');
if ((now.month()) < 10)
dayString += String('0');
dayString += String(now.month(), DEC);
dayString += String('/');
if ((now.day()) < 10)
dayString += String('0');
dayString += String(now.day(), DEC);
dayString += String(' ');
if ((now.hour()) < 10)
dayString += String('0');
dayString += String(now.hour(), DEC);
dayString += String(':');
if ((now.minute()) < 10)
dayString += String('0');
dayString += String(now.minute(), DEC);
dayString += String(':');
if ((now.second()) < 10)
dayString += String('0');
dayString += String(now.second(), DEC);
dayString += String(',');
}
void writedata() {
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
File dataFile = SD.open("datalog.txt", FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
dataFile.println(dataString);
dataFile.close();
// print to the serial port too:
Serial.println(dataString);
Serial1.println(dataString);
}
// if the file isn't open, pop up an error:
else {
Serial.println("error opening datalog.txt");
Serial1.println("error opening datalog.txt");
}
delay(1000);
}
void maint0() {
timecount = 0;
avgsun = 0;
avgcur = 0;
do {
readdate();
dataString = dayString;
sense();
dataString = dataString + "9," + String(sensor[4]) + "," + String(sensor[0]) + "," + String(sensor[1]) + "," + String(sensor[2]) + "," + String(sensor[3]);
writedata();
delay(5);
timecount++;
avgsun = avgsun + sensor[4];
avgcur = avgcur + sensor[chargeline];
} while (timecount < timer);
avgsun = avgsun / timer;
avgcur = avgcur / timer;
}
void maint1() {
timecount = 0;
avgsun = 0;
avgcur = 0;
do {
readdate();
dataString = dayString;
sense();
dataString = dataString + String(chargeline) + "," + String(sensor[4]) + "," + String(sensor[0]) + "," + String(sensor[1]) + "," + String(sensor[2]) + "," + String(sensor[3]);
writedata();
delay(5);
timecount++;
avgsun = avgsun + sensor[4];
avgcur = avgcur + sensor[chargeline];
} while (timecount < timer);
avgsun = avgsun / timer;
avgcur = avgcur / timer;
}
void loop() {
do {
digitalWrite(ledPins[chargeline], LOW);
maint0();
} while (avgsun >= sunref);
do {
digitalWrite(ledPins[chargeline], HIGH);
maint1();
if (avgcur < chargeref) {
maint1();
} else {
;
digitalWrite(ledPins[chargeline], LOW);
maint0();
chargeline++;
if (chargeline > pinCount) {
chargeline = 0;
}
digitalWrite(ledPins[chargeline], HIGH);
maint1();
}
} while (avgsun < sunref);
}
0 件のコメント:
コメントを投稿