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

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

Всем привет!

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

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

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

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

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

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

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

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

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

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

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

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

 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

 

karl2233
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
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
karl2233 аватар
Offline
Зарегистрирован: 05.07.2015

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

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

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

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

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

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

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

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

 

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

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

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

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

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

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

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

 

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

 

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

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

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

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

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

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

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

vlad72, спасибо!

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

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

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

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

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

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

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

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

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

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

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

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

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

 

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

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

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

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
karl2233 аватар
Offline
Зарегистрирован: 05.07.2015

bodriy2014, глянул.

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

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

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

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

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

 

 

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

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

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

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

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

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

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

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

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

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

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

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

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

 

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

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

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

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

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

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

karl2233
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щиков  с вышек сотовой связи. Лучше конечно новые, кроилово ведет к паподалову :) .