Зарядное и измеритель ёмкости аккумуляторов

karl2233
Offline
Зарегистрирован: 05.07.2015

Всем привет!

Проводил уборку, понаходил у себя кучу аккумуляторов - Li-Io, Li-Po так и NIMH с NICD.

Подумал что неплохо бы заиметь приборчик, позволяющий мерять ёмкость и заряжать их.

Полазив в сети с удивлением не нашел подходящего девайса.

1. вот вариант измерителя.

что плохо: дисплей 20х2 а не более распространённый 16х2 и без функции зарядки.

что хорошо: автоопределение типа и измерение ёмкости, есть скетч!

2. вот вариант зарядки.

что плохо: куцее и малоинформативное изображение на дисплее да и сам дисплей однострочный.

что хорошо: заряжает основные типы аккумуляторов.

3. вот варинат зарядки, основан на п.2.

что плохо: один тип аккумуляторов, лишнее ОУ в цепи измерения напряжения.

что хорошо: дисплей 16х2, информативное меню.

 

может сообща, устраним недостатки всех указанных вариантов? 

karl2233
Offline
Зарегистрирован: 05.07.2015

а я всё собираю информацию.

вот ещё весьма интересный проект

vlad72
Offline
Зарегистрирован: 20.03.2016

Интересная тема, есть в продаже готоыве зарядники

http://mysku.ru/blog/china-stores/29989.html

karl2233
Offline
Зарегистрирован: 05.07.2015

есть. но цена для меня сейчас кусачая.

кроме того, детали(не считая корпус) дешевле: Ардуина + LCD + два полевика + сдвоенный ОУ(необязательно) + мелочевка.

теперь по сабжу:

нарыл ещё несколько скетчей на 5110 и на 1602, буду собирать до кучи =)

думаю что 1602 самое оно для этого проекта, тем более что их у меня 2 ))))  хотя на 5110 вроде симатичненько так выходит, иконки всякие опять же.

накидал блок-схему меню

возникает вопрос: как это заорганизовать?

если с пунктами меню более-менее понятно(попытаюсь надёргать из готовых скетчей с алгоритмом) то сама организация, листание (переход между экранами) и возврат в главное непонятны.

 

karl2233
Offline
Зарегистрирован: 05.07.2015

схема, если кому надо, примерно такая(в общем-то всё банально).

три кнопки ("+", "-", "ОК"); входы для измерения тока и напряжения на батарее; вход с термодатчика(например обдувать нагрузочное сопротивление); выход на вентилятор; два выхода с ШИМ - один для управления ключиком заряда(ток заряда), второй - для управления ключиком разряда(ток разряда).

alex_r61
Offline
Зарегистрирован: 20.06.2012

Во втором варианте внизу есть ссылка на апноут AVR450, вот на русском http://www.gaw.ru/html.cgi/txt/app/micros/avr/AVR450.htm

Там надо дисплей добавить и сделать меню.

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

karl2233 Привет!

Эту ветку курил?  Joiner тут зарядкe делал, может что полезное найдешь выдернешь!)

Вот я тестер для лотка делал, может там что выдернешь!)

karl2233
Offline
Зарегистрирован: 05.07.2015

bodriy2014, привет друже!

спс за ссылки, и твой приборчик я не упомянул, хотя  если не смогу сделать на 1602 то буду брать за основу твой - уж больно всё красиво и понятно получилось =)

alex_r61, спасибо! тока не понятно как с той информацией работать - я в программировании "0,1" =)

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

karl2233 пишет:

bodriy2014, привет друже!

спс за ссылки, и твой приборчик я не упомянул, хотя  если не смогу сделать на 1602 то буду брать за основу твой - уж больно всё красиво и понятно получилось =)

alex_r61, спасибо! тока не понятно как с той информацией работать - я в программировании "0,1" =)

То я для лотка делал, себе же хочу сделать еще тот крутой комбайн для разных типов аккумов!

Там по поводу внутреннего сопротивления Димакс много подсказал, все никак не возьмусь.

karl2233
Offline
Зарегистрирован: 05.07.2015

вот и я хочу крутой комбайн =) хотя по мне два типа вполне себе достаточно(машины у мну нет).

можно просто сделать на 3-4 канала.

представляю себе как отдельный блок, к которому на отдельной плате подключать нагрузочные резисторы и обдув.

про сопротивление АКБ... тут такая штука, что емкость всё равно не удасться измерить точно  - условия экпслуатации разные, так что думаю этим моментом можно пренебрегать -  что так, что так измерение в попугаях происходит.

а для подбора одинаковых батарей  -вполне себе годно будет.

примерно так.

количесвто ключей = количеству каналов.

БП можно от ноута, или мощнее, если использовать для зарядки автомобильных.

 

inspiritus
Offline
Зарегистрирован: 17.12.2012

Интересна была бы тема резервирования питания с режимами автоматической зарядки,  хранения и быстрого подхвата ( в тч и из режима зарядки) в случае пропадания основного питания.

соответственно модули :

- потребитель

- емкостной буфер (ионистор ?) для компенсации просадки на время переключения (зависит от тока потребления).

- устройство автоматического переключения питания с основного на резервное.

- зарядный модуль для разных типов аккумуляторов (зависит от выбранного семейства аккумуляторов : <LiPo, Li-ion, LiFe>,  <NiMh, NiCd>, P)

 

хотя в параллельной ветке нашел практически эту тему :)

 

karl2233
Offline
Зарегистрирован: 05.07.2015

но ведь это будет уже мега-супер-пупер бесперебойник! =)

а если добавить электрошокер то можно будет отбиться от зомби во время апокалипсиса

vlad72
Offline
Зарегистрирован: 20.03.2016

здесь измеритель, может что нибудь пригодится.

http://www.komputer.de/wordpress/archives/358

karl2233
Offline
Зарегистрирован: 05.07.2015

vlad72, спасибо!

вот прикольная реализация на 5110 

хорошая реализация, тока дисплей 4-х строчный. 

karl2233
Offline
Зарегистрирован: 05.07.2015

в общем решил за основу брать вот этот проект.

причина проста до банальности - красивенько и три канала что весьма удобно.

сегодня мучал этот скетч.

1. библиотека дисплея какая-то хитрая.

2. учитывая что в Атмеге 328 6 аналоговых входов, то при такой реализации будет три канала, причем идентичных. 

3. надо добавить как-то возможность выбора напряжений разрядки (например от 0,8 до 3) тогда можно будет тестировать литий.

4. ток разряда надо тож как-то регулировать. но как? хз...

5. заряд кажется проще реализовать внешний - Ардуина тока сигнал на заряд(если это литий) или разряд-заряд(никель) будет выдавать.

6. кнопка, нарисованная на схеме, в скетче никак не фигурирует.

итог: не смогу я реализовать ((( одна бибдлиотека дисплея крови выпьет литр, а то и два.

 

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

karl2233 А что там с библиотекой под такой экран может быть хитрого?

Дай ссылку на архив с скетчем и библиотекой гляну.

karl2233
Offline
Зарегистрирован: 05.07.2015

да я, как образец, использую скетч Пультоскопа - там всё ясно и понятно. даж Люксомер переделал используя твои наработки =)

а тут...пытался сделать меню из трёх страниц, так запутался как та обезьяна рассыпавшая горох.

скетч вот

////////////////////////////////////////////////////////////////
// Rechargeable Battery Capacity Tester
//     Tests up to three AA batteries simultaneously and
//     displays the results on a Nokia style LCD display
//     using the PCD8544 library
// Feb 8, 2011  - B. Hobbs
///////////////////////////////////////////////////////////////

#include <PCD8544.h>        // library of functions for Nokia LCD (http://code.google.com/p/pcd8544/)

#define LCD_TEXT_WIDTH      14   // Width of text line for Nokia LCD
#define LCD_LINE1            0
#define LCD_LINE2            1
#define LCD_LINE3            2
#define LCD_LINE4            3
#define LCD_LINE5            4
#define LCD_LINE6            5
#define NUM_LINES_ON_LCD     6
#define MAX_BATTERIES        3
#define LOAD_RESISTANCE      2.5    //load resistance in ohms
#define START_BEEP        5000      // frequency in Hz
#define DONE_BEEP         1800
#define SPKR_PIN             8     // The pin used for the SPEAKER
#define LED_PIN             13     // The pin used for the LED
#define LCD_WIDTH           84     // The dimensions of the Nokia LCD(in pixels)...
#define LCD_HEIGHT          48
#define BAT_WIDTH           18     // Width of battery icon in pixels
#define BAT_HEIGHT           1     // Height of battery Icon (1 line = 8 pixels)
#define BATTERY_ICON_HORIZ  34     // Horizontal position of battery icon (in pixels)
#define MAH_HORIZ_POSITION  60     // Horizontal position of mAh display

// Bitmaps for battery icons, Full, Empty, and Battery with an X (no battery)
static const byte batteryEmptyIcon[] ={ 0x1c, 0x14, 0x77,0x41,0x41,0x41,
           0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x7f};
static const byte batteryFullIcon[] = { 0x1c, 0x14, 0x77,0x7f,0x7f,0x7f,
           0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f};
static const byte noBatteryIcon [] = { 0x1C, 0x14, 0x77, 0x41, 0x41,0x41,
           0x41,0x63,0x77,0x5D,0x5D,0x77,0x63,0x41,0x41,0x41,0x41,0x7f};
///////// Battery voltage limits //////////////////////////////////////////
//  The following constants define the expected voltages for detecting the
//  battery and the minimum voltage at which the discharge test is complete.
// *Lithium Ion cells have a fully charged no-load voltage of 3.6 to 3.7 volts
//    and cause too much power dissapation in the load resistor, so 
//    they will not be tested
// *NiCads have a fully charged no-load voltage of 1.2 to 1.35 volts 
// *NiMH batteries have a fully charged no-load voltage of 1.4 to 1.45 volts
//    Since the NiCad and NiMH batteries are similar (and difficult to 
//    reliably autodetect) they are handled identically in this program.
////////////////////////////////////////////////////////////////////////////
#define MAX_VOLTAGE           1700  // Max Voltage used for detection (in mV)
#define NIMH_MIN_VOLTAGE      950   // niMH/NiCd Min Voltage for load removal (in mV)

static PCD8544 lcd;
enum {NOT_INSTALLED, DETECTING_TYPE, OVER_VOLTAGE, TEST_IN_PROGRESS, DONE};  // battery status values

struct batteryStruct
{
    unsigned long  charge;         // Total microamp hours for this battery
    byte battStatus;               // set this to DONE when this cell's test is complete
    byte batteryVoltagePin;        // Analog sensor pin (0-5) for reading battery voltage
    byte fetVoltagePin;            // Analog sensor pin (0-5) to read voltage across FET
    byte dischargeControlPin;      // Output Pin that controlls the load for this battery
    unsigned int lowerThreshold;   // voltage at which discharge is complete (mV)
    unsigned long PrevTime;        // Previous time reading (in milliseconds)
    unsigned int numSamplesAboveMin; // number of good voltage readings (to determine battery installed)
    unsigned int numSamplesBelowMin; // number of samples read below minimum (to determine battery discharged)
    
}battery[MAX_BATTERIES];




static const byte progressIndicator[] = "-\0|/";
static const byte backslashNokia[] =    //define backslach LCD character for Nokia5110 (PCD8544)
{
   B0000010,
   B0000100,
   B0001000,
   B0010000,
   B0100000
};

//Prototypes for utility functions
void printRightJustifiedUint(unsigned int n, unsigned short numDigits);
void ClearDisplayLine(int line);   // function to clear specified line of LCD display
unsigned int getBatteryVoltage(unsigned int batteryNum);
unsigned int getFetVoltage(unsigned int batteryNum);
void printVoltage(unsigned int n);
//-------------------------------------------


void setup()
{
   unsigned int batteryNum;
   unsigned int battVoltage;
  
   Serial.begin(9600);             // Initialize serial port
   pinMode(SPKR_PIN, OUTPUT);      //Set output mode for pin used for spkr
   
   lcd.begin(LCD_WIDTH, LCD_HEIGHT);// set up the LCD's dimensions in pixels
   // Register the backslash character as a special character
   // since the standard library doesn't have one
   lcd.createChar(0, backslashNokia);
   tone(SPKR_PIN, START_BEEP,50);   // short beep
   
   battery[0].dischargeControlPin = 13;    // setup the corresponding pins
   battery[0].fetVoltagePin = 0;           // for each battery according to
   battery[0].batteryVoltagePin = 1;       // schematic wiring diagram.
   
   battery[1].dischargeControlPin = 12;       
   battery[1].fetVoltagePin = 2; 
   battery[1].batteryVoltagePin = 3; 

   battery[2].dischargeControlPin = 11;
   battery[2].fetVoltagePin = 4; 
   battery[2].batteryVoltagePin = 5; 
  
   battery[0].battStatus = DETECTING_TYPE;  // initialize status of each battery
   battery[1].battStatus = DETECTING_TYPE; 
   battery[2].battStatus = DETECTING_TYPE;
  
   battery[0].numSamplesAboveMin = 0;
   battery[1].numSamplesAboveMin = 0;
   battery[2].numSamplesAboveMin = 0;
  
   battery[0].numSamplesBelowMin = 0;
   battery[1].numSamplesBelowMin = 0;
   battery[2].numSamplesBelowMin = 0;  

   // Set the three FET control pins for output
   pinMode(battery[0].dischargeControlPin, OUTPUT); 
   pinMode(battery[1].dischargeControlPin, OUTPUT); 
   pinMode(battery[2].dischargeControlPin, OUTPUT); 

   lcd.setCursor(0, LCD_LINE1);// First Character, First line
   lcd.print(" Rechargeable");  // Print a message to the LCD.
   lcd.setCursor(0, LCD_LINE3);
   lcd.print("   Battery    "); 
   lcd.setCursor(0, LCD_LINE5);   
   lcd.print("    Tester    "); 

   delay(3000);

   lcd.clear();        // clear the display 
   lcd.print(" ** Testing * "); 
   lcd.setCursor(0, LCD_LINE3);//  set cursor to 3rd line 
   lcd.print("Volts      mAh");  
   
}

void loop() 
{
   static unsigned int i = 0 ;
   static unsigned int  line , p, batteryNum, width1;
   static unsigned long duration, currentTime;
   static unsigned int battVoltage,fetVoltage, loadCurrent;
   static boolean done = false;
   static unsigned int beepCounter = 0;

   if (!done)

   {
      lcd.setCursor(LCD_WIDTH-5, LCD_LINE1);  // end of line 1
      lcd.write(progressIndicator[i  % (sizeof(progressIndicator)-1)]);
      lcd.home();
      lcd.write(progressIndicator[i++ % (sizeof(progressIndicator)-1)]);
      
      for (batteryNum= 0 ; batteryNum < MAX_BATTERIES ; batteryNum++)
      {
         battVoltage = getBatteryVoltage(batteryNum);
         fetVoltage = getFetVoltage(batteryNum);
         // Calculate the display line number for this battery
         line = batteryNum + LCD_LINE4;  // first battery displayed on line4
            
         if ( battery[batteryNum].battStatus == TEST_IN_PROGRESS)
         {
            ClearDisplayLine(line);
            printVoltage(battVoltage);
            lcd.setCursor(BATTERY_ICON_HORIZ , line);   // indent to horiz pixel location for battery icon     
            width1 =  3 + (i % (sizeof(batteryEmptyIcon)-3)) ; //start at offset of 3 pixels
  
            // Display the left half of the Battery Icon (Empty), at calculated width
            lcd.drawBitmap(batteryEmptyIcon, width1, 1); // Battery Empty icon (partial) one line tall
            // Display the remainder of the Battery Icon (Full) 
            lcd.drawBitmap(&batteryFullIcon[width1], sizeof(batteryFullIcon) - width1, 1);

            // Calculate the time duration between the last reading (in milliseconds)
            currentTime = millis();
            duration = (currentTime - battery[batteryNum].PrevTime);
            battery[batteryNum].PrevTime = currentTime;
            // Current through resistor is voltage across the resistor divided by load restistance
            // Since the voltage is in millivolts, the current will be in milliamps
            loadCurrent = (battVoltage - fetVoltage) / LOAD_RESISTANCE;
            // milliAmpHours = current (in milliAmps)  * duration (in Hours)
            // Must divide by (60*60*1000) to convert duration in micro seconds to hours
            // But doing this now would cause a loss of precision, so
            // divide by 3600 which will result in microamp hours to be summed.
            // Divide by 1000 when milliamp hours are desired for display
            battery[batteryNum].charge +=   (loadCurrent * duration) / 3600;
            Serial.print("Bat");
            Serial.print(batteryNum+1);
            Serial.print("  V=");
            Serial.print(battVoltage);
            Serial.print("   duration ");
            Serial.print(duration);
            Serial.print("ms   loadCurrent=");
            Serial.print(loadCurrent );
            Serial.print("mA     ChargeDrawn=");
            Serial.println(battery[batteryNum].charge/1000);
    
            lcd.setCursor(MAH_HORIZ_POSITION, line);  // indent to pixel location for mAh
            printRightJustifiedUint(battery[batteryNum].charge/1000,4);
            // Has the battery voltage dropped below the minimum?
            // Must have several battery voltage samples below minimum
            // in a row, before declaring 'done'
            if (battVoltage <  battery[batteryNum].lowerThreshold)
            {
               Serial.print("Batt");
               Serial.print(batteryNum);
               Serial.print(" Below threshold: ");
               Serial.println(battVoltage);
               if ( battery[batteryNum].numSamplesBelowMin < 3 )
               {
                  battery[batteryNum].numSamplesBelowMin++;
               }
               else
               {
                  // This testing on this battery is complete, set status to DONE
                  // Turn off the discharge load and update the display
                  battery[batteryNum].battStatus = DONE;
                  digitalWrite(battery[batteryNum].dischargeControlPin, LOW); // turn off the load
                  ClearDisplayLine(line);
                  // Display the Empty Battery Icon 
                  lcd.setCursor(BATTERY_ICON_HORIZ , line);   // indent to horiz pixel location for battery icon     
                  lcd.drawBitmap(batteryEmptyIcon, sizeof(batteryEmptyIcon), 1);
                  lcd.setCursor(MAH_HORIZ_POSITION, line);  // indent to pixel location for mAh
                  printRightJustifiedUint(battery[batteryNum].charge/1000,4); 
                  tone(SPKR_PIN, DONE_BEEP,50); // short beep
                  // Check to see if ALL installed batteries are in the DONE state.
                  done = checkAllDone();
               }
            }
            else
            {
              // reset counter since this reading was good.
             battery[batteryNum].numSamplesBelowMin = 0;
            } 
         }
         else if (battery[batteryNum].battStatus == DONE)
         {
            // don't update this line of the display    
         }
         else if (battery[batteryNum].battStatus == NOT_INSTALLED)
         {
           ClearDisplayLine(line);
           lcd.setCursor(BATTERY_ICON_HORIZ , line);   // indent to horiz pixel location for battery icon     
           lcd.drawBitmap(noBatteryIcon, sizeof(noBatteryIcon), 1);
           if (battVoltage >= NIMH_MIN_VOLTAGE)
           {
              // This condition indicates that a battery has 
              // been installed, change status to Detecting
              battery[batteryNum].battStatus = DETECTING_TYPE;
           }   
         }  
         else if (battery[batteryNum].battStatus == OVER_VOLTAGE )
         {
           lcd.setCursor(0, line);
           lcd.print(" OVER VOLTAGE ");
           battery[batteryNum].battStatus =  DETECTING_TYPE;
         } 
         else if (battery[batteryNum].battStatus == DETECTING_TYPE)
         {
           lcd.setCursor(0, line);
           lcd.print(" Detecting... ");
           detectBatteryType(batteryNum, battVoltage );
         }
         else // undefined battery status
         {
            // should never get here
            lcd.setCursor(0, line);
            lcd.print("???");
         }  
      }
   }
   else
   {
      // we're done - all batteries are discharged
      if (beepCounter  < 3 )
      {
         lcd.setCursor(0, LCD_LINE1);// First Character, First line
         lcd.print("     Test     ");
         lcd.setCursor(0, LCD_LINE2);// First Character, First line
         lcd.print("   Complete   ");
         lcd.setInverse(beepCounter % 2); // Invert the display
         tone(SPKR_PIN, DONE_BEEP,200);  // done beep
         beepCounter++;
      }
      // continue to update battery voltage
      for (batteryNum= 0 ; batteryNum < MAX_BATTERIES ; batteryNum++)
      {
         battVoltage = getBatteryVoltage(batteryNum);
         line = batteryNum + LCD_LINE4;  // first battery displayed on line4
         if (battery[batteryNum].battStatus == DONE)
         {
           // set cursor at beginning of line but don't erase battery icon
           // or the result mAh
           lcd.setCursor(0 , line);
           printVoltage(battVoltage);
         }
         else
         {
           ClearDisplayLine(line);
           lcd.setCursor(BATTERY_ICON_HORIZ , line);   // indent to horiz pixel location for battery icon     
           lcd.drawBitmap(noBatteryIcon, sizeof(noBatteryIcon), 1);
         }
      }
      
   }
    delay(1000);  // wait one second, then get next set of samples
} //end of main loop


//////////////////////////////////////////////////////////////////////////////////
// detectBatteryType()  Detects the battery type and sets up the appropriate
//               status and thresholds
//////////////////////////////////////////////////////////////////////////////////
void detectBatteryType(unsigned int batteryNum, unsigned int battVoltage)
{
   if (battery[batteryNum].numSamplesAboveMin > 3)
   {
      if (battVoltage > MAX_VOLTAGE )
      {
         battery[batteryNum].battStatus = OVER_VOLTAGE;
      }
      else if (battVoltage > NIMH_MIN_VOLTAGE)
      {
         // Battery Type identified as: NiMH or NiCd Battery
         // Initialize variables and start discharge
         battery[batteryNum].lowerThreshold = NIMH_MIN_VOLTAGE;
         battery[batteryNum].battStatus = TEST_IN_PROGRESS;
         battery[batteryNum].charge = 0;
         battery[batteryNum].PrevTime = millis();
         digitalWrite(battery[batteryNum].dischargeControlPin, HIGH); // turn on the FET
      }
      else
      {
         battery[batteryNum].numSamplesAboveMin = 0;
      }             
   }
   else // not enough good samples yet
   {
      if (battVoltage > NIMH_MIN_VOLTAGE)
      {
         battery[batteryNum].numSamplesAboveMin++;
         battery[batteryNum].numSamplesBelowMin = 0;
      }
      else
      {
         battery[batteryNum].numSamplesBelowMin++;
         battery[batteryNum].numSamplesAboveMin = 0;
      }
   }
   if (battery[batteryNum].numSamplesBelowMin > 3)
   {
      battery[batteryNum].battStatus = NOT_INSTALLED;
   }      
}


//////////////////////////////////////////////////////////////////////////////////
// checkAllDone()  checks to see if ALL installed batteries are in the DONE state.
//                 return true if all tests are complete.
//////////////////////////////////////////////////////////////////////////////////
boolean checkAllDone()
{
  unsigned int batteryNum;
  unsigned int count=0;
  
   for (batteryNum= 0 ; batteryNum < MAX_BATTERIES ; batteryNum++)
   {
     if( battery[batteryNum].battStatus == TEST_IN_PROGRESS)
        return false;
   }
   return true;
}      
      
//////////////////////////////////////////////////////////////////////////////////
// printRightJustifiedUint() prints unsigned integer, right justified
//            on the LCD with the specified number of digits (up to 5)
//            supressing leading zeros. Prints asterisks if the number is too
//            big to be displayed.
//////////////////////////////////////////////////////////////////////////////////
void printRightJustifiedUint(unsigned int n, unsigned short numDigits)
{
  
  const unsigned int powersOfTen[]={1,10,100,1000,10000};
  boolean overflow = false, supressZero = true;
  unsigned int digit, d;
  
  for (d = numDigits ; d > 0 ; d--)
  {
     if (overflow || numDigits > 5)
     {
       lcd.print("*");
     }
     else
     {
       // pow() function doesn't work as expected - use array powersOfTen[]
       digit = n / powersOfTen[d-1];
       n = n % (powersOfTen[d-1]);
       if (digit == 0 && supressZero && d > 1)
          lcd.print(" ");
       else if (digit <= 9)
       {
          lcd.print(digit);
          supressZero = false;
       }
       else
       {
         overflow = true;
         lcd.print("*");
       }
     }
  }          
}

//////////////////////////////////////////////////////////////////////////////////
// printVoltage() prints unsigned integer (millivolts), as a voltage with
//        decimal point on the LCD from 0.000 to 9.999 volts
//        Prints asterisks if the number is too big to be displayed.
//////////////////////////////////////////////////////////////////////////////////
void printVoltage(unsigned int n)
{
  
  const unsigned int powersOfTen[]={1,10,100,1000,10000},  numDigits = 4;
  boolean overflow = false, supressZero = true;
  unsigned int digit, d;
  
  for (d = numDigits ; d > 0 ; d--)
  {
     if (overflow)
     {
       lcd.print("*");
     }
     else
     {
       // pow() function doesn't work as expected - use array powersOfTen[]
       digit = n / powersOfTen[d-1];
       n = n % (powersOfTen[d-1]);
       if (digit <= 9)
       {
          lcd.print(digit);
          if (d == numDigits)
             lcd.print(".");
       }
       else
       {
         overflow = true;
         lcd.print("*");
       }
     }
  }          
}


//////////////////////////////////////////////////////////////////////////////////
// ClearDisplayLine()  utility function to clear one full line of the display
//////////////////////////////////////////////////////////////////////////////////
void ClearDisplayLine(int line) 
{
  unsigned int i;
  lcd.setCursor(0, line);  // put cursor on first char of specified line
  lcd.clearLine();
  lcd.home();
}

//////////////////////////////////////////////////////////////////////////////////
// Read analog input for specified battery and maps into a voltage (in millivolts)
//////////////////////////////////////////////////////////////////////////////////
unsigned int getBatteryVoltage(unsigned int batteryNum)
{
   //return analogRead(battery[batteryNum].batteryVoltagePin), *4.887;
   return map(analogRead(battery[batteryNum].batteryVoltagePin), 0,1023,0,5000);
}

//////////////////////////////////////////////////////////////////////////////////
// Read analog input for specified battery's FET and maps into a voltage (in millivolts)
//////////////////////////////////////////////////////////////////////////////////
unsigned int getFetVoltage(unsigned int batteryNum)
{
  //return analogRead(battery[batteryNum].fetVoltagePin)*4.887;
   return map(analogRead(battery[batteryNum].fetVoltagePin), 0,1023,0,5000);
}

библиотеку по сцылке в начале скетча брал.

а задумка хороша... 

там, на авторской странице в обсуждениях, есть сцыль на Али - китайцы его продают ))

bodriy2014
bodriy2014 аватар
Offline
Зарегистрирован: 12.05.2015

karl2233 такой контроллер PCD8544 стоит в нокиа 3310/5110

Библиотека простецкая у меня несколько модификаций таких есть от разных авторов

вот так выводятся на экран данные

  lcd.print("Svet=");
  lcd.print(svet, 1);

В примерах с библиотекой глянь там все показанно.

karl2233
Offline
Зарегистрирован: 05.07.2015

bodriy2014, глянул.

сёння весь день убил на то, что бы сделать хотя бы меню и выложить в теме (всё равно на большее моих познаний не хватит), но увы (((

ещё попробую побороть, но что-то подсказывает мне что бесполезняк (((( я ни разу не программист.

моих познаний не хватает, а когда наберусь - уже надо к земле привыкать будет а не батарейки заряжать ))))

...а ведь идея многоканального зарядного+тестера хорошая. я в сети не нашел ничего подобного ни на 1602 ни на 5110, так, какие-то полуфабрикаты или заточены только под один тип, или с одной функцией.

...уже думаю собрать на трёх МК(разные схемы) в одном корпусе(*рукалицо*) и управлять этим богатсвом при помощи тумблера =)

 

 

karl2233
Offline
Зарегистрирован: 05.07.2015

попытка не удалась.

зато теперь понимаю всю сложность такого девайса и получил ответ почему никто не сделал такого(2-3 канальное; с алгоритмом для лития и никеля; с тестированием и регулировкой тока-напряжения разряда-заряда; с красивым меню).

вот, нашел интересное про управление зарядом-разрядом.

вот что подумал.

может есть ктонить кому в кайф программировать но лень с железом возиться? так это, давайте скооперируемся и сделаем мегадевайс =)

а то мне трудно(видать мозг не так фунциклирует) вникнуть в тонкости программирования, но в железе готов тестировать и собрать два девайса: себе и напарнику.

готов предложить схему и алгоритм.

yucan
Offline
Зарегистрирован: 20.04.2015

У меня уже года полтора трудится тестер литий-ионных аккумуляторов с радиокота: http://radiokot.ru/circuit/digital/measure/75/ Конечно не идеальная, но собранная на аттини 26, со своими 2 К памяти, меряет напряжение, ток заряда, разряда реально, а не рассчётами, как это обычно делают на ардуино. Хочется такую же функциональную. Это я к тому, что тема что то затихла...

karl2233
Offline
Зарегистрирован: 05.07.2015

затихла по причине моих недостаточных знаний, а знающим не интересно.

девайс по сцылке - что-то вроде "на безрыбье, и рак рыба".

 

karl2233
Offline
Зарегистрирован: 05.07.2015

вот, нарыл интересный проект. тока не пойму как его прикрутить к Ардуино

Okmor
Okmor аватар
Offline
Зарегистрирован: 16.10.2015

Я тоже делал зарядку. Даже графики на ПК рисовало, но потом забросил, ибо купить дешевле и вид не колхоз.

Большим плюсом есть функция повербанка.

Рекомендую следюющий набор:

karl2233
Offline
Зарегистрирован: 05.07.2015

нууу... то, что купить готовое дешевле - это факт.

вопрос в том, что там за алгоритмы, индикация(вывод информации на дисплей).

таким образом, алгоритм зарядки-разрядки и кол-во циклов это весьма существенно и его как раз можно сделать так, как нужно и столько, сколько нужно.

а корпус - можно купить готовый и туда приколхозить.

strix-iwan
Offline
Зарегистрирован: 08.08.2018

а как на счет 12в акумов - по замеру емксоти встречали что нить на ардунке? Просто так же валяется куча UPS шных снятых по ТО акумов - сдавать все подряд жаль

slider
Offline
Зарегистрирован: 17.06.2014

strix-iwan пишет:

а как на счет 12в акумов - по замеру емксоти встречали что нить на ардунке? Просто так же валяется куча UPS шных снятых по ТО акумов - сдавать все подряд жаль


Прикольно , крайне редко заглядываю в тему "проекты" , а тут пытливый ум до акб :)
Давно эт было.
В теме диспов от сотиков выкладывал фото.
Накопилось давно разных 50акб (7,12ач), с больших серверных упс (у нас акб менялись не по времени , а когда упс уже надоест изредкими своими познаниями что акб совсем уже того, хотя в серверную редко ходили, перебоев со светом небыло ) , собрал тестер , за раз 8 акб тестит , рисует графики сразу всех , по графикам можно понять много
1. дохляк , 2, небольшой засульфат. -ему поможет несколько КТЦ , 3. норм акб.

Можете сделать тоже , поверьте это не трудно , главный ресурс - это время потраченное на разработку и изготовление. детали копеечные.

Сдавать дохляк лучше на металлолом , там раз в 5 больше денег дают чем в магазах по продаже акб и их приему.

Года 2-3 назад , еще эти акб по 56руб за кг. сдавал в пункте металлолома. "Металлокасса"

strix-iwan
Offline
Зарегистрирован: 08.08.2018

я бы с удовольстивем но опыта работы с ардункой совсем нет - только только знакомлюсь еще. А  у вас не осталось зарисовок схем соборки? 

slider
Offline
Зарегистрирован: 17.06.2014

strix-iwan пишет:

я бы с удовольстивем но опыта работы с ардункой совсем нет - только только знакомлюсь еще. А  у вас не осталось зарисовок схем соборки? 

эт фигово, тогда лучше изучить.
  там не сложно , и у школьников  и у пенсионеров не имеющих хороших знаний в электронике , получается разобраться.

схем задукоментированных нет, все в голове. это как лампочку к батарейке подключить, вы же не рисуете схему для этого, берете и собираете этот конструктор. 

в программе тож ничего сложного , резистивный делитель, ардуиной считать аналоговое значение, нарисовать пиксель на дисплее . когда напряжение снизится до 10.8в , отключить мосфетом нагрузку.  в качестве нагрузки - стабилизатор тока на LM317 с низкоомным резистором. дисплей брать какой есть. если нет никакого, то 

вариант А

1. мож взять сразу шилд дисп.  SPI  320x240 чтоб сэкономить пины 

2. ардуину нано (у нее выведены все 8 аналоговых пинов)

3. для выключения мосфетов нагрузки - возможно регистр (расширитель портов), параллельный или последовательный HC595 (меньше с ним проводов кидать прийдется). Можно и без этого пункта обойтись , поставить зуммер , пусть пищит когда сядет аккум, чтоб вы успели его отключить. Но лучше чтоб в автомате это было, с ключами на мосфетах.

вариант Б

1. взять шилд дисп 8бит 320x240 или больше 480x320  для ардуино мега

2. ардуино мега (у нее пинов много, не понадобится никакого регистра.

 

// если появится свободное время, мож через неделю - месяц , то прозвоню и зарисую схему которая собрана, найду скетч, выложу.

лучше бы делать сразу на меге, там хоть 16 акб сразу тестить получиться, и дисплей побольше - 480x320 , чтоб 16 графиков сразу рисовать. Лучше конечно с графиками , сразу все видно по кривой и сравнивать можно.  Т.к. пинов свободных много, можно и зарядку умную замутить. Если тестить по 8АКБ , то другие 8 аналоговых пинов можно использовать для измерения токов, тогда можно было обойтись без стабилизаторов LM317 . И вообще сделать под любые АКБ , хоть под литий. 

//// если вы в крупной фирме , что меняете АКБ по времени , а не по выходу из строя, то вы запросто можете приобрести за счет фирмы приборчик "Кулон" измеритель емкости, он сразу может определить примерную емкость, по виду просадки посылаемого импульса в АКБ. 
   Благодаря подобному "секундному" приборчику у магазина, мне получилось купить за дешего залежавшиеся на складе 2-3года новые АКБ ИБП по 200ач  (измеренная емкость "секундным" приборчиком показала около 80-130ач, поэтому и продавали в 3-4раза дешевле), а проделанные мной КТЦ подняли емкость до 200ач,  которые хорошо отрудились 5лет в солнечной системе питая в летние сезоны весь дом и хозяйство, даж еще немного емкости осталось. Собственно столько АКБ и живет при ежесуточном разряде/заряде.

//////  если не хотите заморачиваться, и не использовать их для солнечной системы, запитки дома, электромобиля, то просто продайте, в местных форумах или через авито. ну или на металлолом. Некоторые люди "болеющие" автономкой покупают б/у АКБ и у GSMщиков  с вышек сотовой связи. Лучше конечно новые, кроилово ведет к паподалову :) .