2017年9月26日火曜日

40B19Lを複数個並列充電時に循環電流をおさえる ソフト編

BluePill STM32 用の sketch
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 件のコメント:

コメントを投稿