{"id":485,"date":"2019-09-02T22:13:06","date_gmt":"2019-09-02T22:13:06","guid":{"rendered":"https:\/\/delphijustin.biz\/?p=485"},"modified":"2020-02-11T18:36:29","modified_gmt":"2020-02-12T00:36:29","slug":"unocharge-nimh-battery-charger","status":"publish","type":"post","link":"https:\/\/delphijustin.biz\/unocharge-nimh-battery-charger\/","title":{"rendered":"Unocharge NiMh battery charger"},"content":{"rendered":"\n<p>Here is my plan for John Zogg&#8217;s battery charger. It uses 3 analog inputs for each battery cell. I decided to use this one that <g class=\"gr_ gr_10 gr-alert gr_gramm gr_inline_cards gr_run_anim Grammar only-ins replaceWithoutSep\" id=\"10\" data-gr-id=\"10\">flyback<\/g> found on the internet is because it can turn off when it is done. It has a temperature sensor. It uses an Arduino Uno to control it. USB is not recommended for charging it as the 2x 10-ohm resistors go over the current limit on USB Current. The TMP-36 sensors must be attached to the batteries case. This is so it measures its temperature.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/*\n * UnoCharge - the arduino nimh charger\n * This is my version of the Arduino NiMh battery charger \n * its modifications include Charge LED and multiple Battery support\n * Orginally from https:\/\/www.allaboutcircuits.com\/projects\/create-an-arduino-controlled-battery-charger\/ \n * Modified by delphijustin\n * Special Thanks to John Zogg and flyback\n *\/\nbyte nBatteries=2;\/\/Number of batteries(1 through 5), other array variables must have the same number of values.\nbyte chargedLED = 2; \/\/ digital pin for LED\nint batteryCapacity[] = {2500,2500};     \/\/capacity rating of battery in mAh\nfloat resistance[] = {10.0,10.0};     \/\/measured resistance[b] of the power resistor\nint cutoffVoltage = 1600;     \/\/maximum battery voltage (in mV) that should not be exceeded\nfloat cutofftemperatureC = 35;     \/\/maximum battery temperature that should not be exceeded (in degrees C)\n\/\/float cutoffTemperatureF = 95;     \/\/maximum battery temperature that should not be exceeded (in degrees F)\nlong cutoffTime = 46800000;     \/\/maximum charge time of 13 hours that should not be exceeded\nbyte outputPin[] = {9,6};     \/\/ Output signal wire connected to digital pin 9\nint outputValue[] = {150,150};     \/\/value of PWM output signal \nbyte analogPinOne[] = {0,3};     \/\/first voltage probe connected to analog pin 1\nfloat ValueProbeOne[] = {0,0};     \/\/variable to store the value of analogPinOne[b]\nfloat voltageProbeOne[] = {0,0};     \/\/calculated voltage at analogPinOne[b]\nbyte analogPinTwo[] = {1,4};     \/\/second voltage probe connected to analog pin 2\nfloat valueProbeTwo[] = {0,0};     \/\/variable to store the value of analogPinTwo[b]\nfloat voltageProbeTwo[] = {0,0};     \/\/calculated voltage at analogPinTwo[b]\nbyte analogPinThree[] = {2,5};     \/\/third voltage probe connected to analog pin 2\nfloat valueProbeThree[] = {0,0};     \/\/variable to store the value of analogPinThree[b]\nfloat tmp36voltage[] = {0,0};     \/\/calculated voltage at analogPinThree[b]\nfloat temperatureC[] = {0,0};     \/\/calculated temperature of probe in degrees C\n\/\/float temperatureF = 0;     \/\/calculated temperature of probe in degrees F\nfloat voltageDifference[] = {0,0};     \/\/difference in voltage between analogPinOne[b] and analogPinTwo[b]\nfloat batteryVoltage[] ={0,0};     \/\/calculated voltage of battery\nfloat current[] = {0,0};     \/\/calculated current through the load (in mA)\nfloat targetCurrent[] = {0,0};     \/\/target output current (in mA) set at C\/10 or 1\/10 of the battery capacity per hour\nfloat currentError[] = {0,0};     \/\/difference between target current and actual current (in mA)\n\nvoid setup()\n{\npinMode(chargedLED,OUTPUT);\ndigitalWrite(chargedLED,LOW);\n  Serial.begin(9600);     \/\/  setup serial\n  for(byte x=0;x&lt;nBatteries;x++){\n  targetCurrent[x]=batteryCapacity[x]\/10;\n  pinMode(outputPin[x], OUTPUT);     \/\/ sets the pin as output\n  }\n}\n\nbyte chargeStatus(){\n  byte s=0;\n  for(byte b=0;b&lt;nBatteries;b++){\n    if(outputValue[b]==0){s++;}\n  }\nif(s==nBatteries){\n  digitalWrite(chargedLED,HIGH);\n  }\n  return s;\n}\n\nvoid loop()\n{\n  for(byte b=0;b&lt;nBatteries;b++){ \n  Serial.println(\"Battery \"+b);\n  analogWrite(outputPin[b], outputValue[b]);  \/\/Write output value to output pin\n\n  Serial.print(\"Output: \");     \/\/display output values for monitoring with a computer\n  Serial.println(outputValue[b]); \n\n  ValueProbeOne[b] = analogRead(analogPinOne[b]);    \/\/ read the input value at probe one\n  voltageProbeOne[b] = (ValueProbeOne[b]*5000)\/1023;     \/\/calculate voltage at probe one in milliVolts\n  Serial.print(\"Voltage Probe One (mV): \");     \/\/display voltage at probe one\n  Serial.println(voltageProbeOne[b]);  \n  \n  valueProbeTwo[b] = analogRead(analogPinTwo[b]);    \/\/ read the input value at probe two\n  voltageProbeTwo[b] = (valueProbeTwo[b]*5000)\/1023;     \/\/calculate voltage at probe two in milliVolts\n  Serial.print(\"Voltage Probe Two (mV): \");     \/\/display voltage at probe two\n  Serial.println(voltageProbeTwo[b]);  \n  \n  batteryVoltage[b] = 5000 - voltageProbeTwo[b];     \/\/calculate battery voltage\n  Serial.print(\"Battery Voltage (mV): \");     \/\/display battery voltage\n  Serial.println(batteryVoltage[b]); \n\n  current[b] = (voltageProbeTwo[b] - voltageProbeOne[b]) \/ resistance[b];     \/\/calculate charge current[b]\n  Serial.print(\"Target Current (mA): \");     \/\/display target current[b] \n  Serial.println(targetCurrent[b]);  \n  Serial.print(\"Battery Current (mA): \");     \/\/display actual current[b]\n  Serial.println(current[b]);  \n      \n  currentError[b] = targetCurrent[b] - current[b];     \/\/difference between target current[b] and measured current[b]\n  Serial.print(\"Current Error  (mA): \");     \/\/display current[b] error \n  Serial.println(currentError[b]);     \n\n  valueProbeThree[b] = analogRead(analogPinThree[b]);    \/\/ read the input value at probe three  \n  tmp36voltage[b] = valueProbeThree[b] * 5.0;     \/\/ converting that reading to voltage\n  tmp36voltage[b] \/= 1024.0; \n \n  temperatureC[b] = (tmp36voltage[b] - 0.5) * 100 ;     \/\/converting from 10 mv per degree wit 500 mV offset to degrees ((voltage - 500mV) times 100)\n  Serial.print(\"Temperature (degrees C) \");     \/\/display the temperature in degrees C\n  Serial.println(temperatureC[b]); \n \n \/*\n  temperatureF = (temperatureC[b] * 9.0 \/ 5.0) + 32.0;     \/\/convert to Fahrenheit\n  Serial.print(\"Temperature (degrees F) \");\n  Serial.println(temperatureF); \n *\/\n \n  Serial.println();     \/\/extra spaces to make debugging data easier to read\n  Serial.println();  \n\n\n\n  if(abs(currentError[b]) > 10)     \/\/if output error is large enough, adjust output\n   {\n    outputValue[b] = outputValue[b] + currentError[b] \/ 10;\n\n    if(outputValue[b] &lt; 1)    \/\/output can never go below 0\n     {\n      outputValue[b] = 0;\n     }\n\n    if(outputValue[b] > 254)     \/\/output can never go above 255\n     {\n      outputValue[b] = 255;\n     }\n    \n    analogWrite(outputPin[b], outputValue[b]);     \/\/write the new output value\n   }\n \n \n  if(temperatureC[b] > cutofftemperatureC)     \/\/stop charging if the battery temperature exceeds the safety threshold\n   {\n    outputValue[b] = 0;\n    Serial.print(\"Max Temperature Exceeded\");\n   }\n   \n  \/*\n  if(temperatureF > cutoffTemperatureF)     \/\/stop charging if the battery temperature exceeds the safety threshold\n   {\n    outputValue[b] = 0;\n   }\n   *\/\n   \n   if(batteryVoltage[b] > cutoffVoltage)     \/\/stop charging if the battery voltage exceeds the safety threshold\n   {\n    outputValue[b] = 0;\n    Serial.print(\"Max Voltage Exceeded\");\n   }  \n \n   if(millis() > cutoffTime)     \/\/stop charging if the charge time threshold\n   {\n    outputValue[b] = 0;\n    Serial.print(\"Max Charge Time Exceeded\");\n   }  \n   delay(10000);     \/\/delay 10 seconds for before next iteration\n}\nSerial.println();\nSerial.print(chargeStatus());\nSerial.print(\" Out of \");\nSerial.print(nBatteries);\nSerial.print(\" batteries fully charged\");\n}\n<\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" width=\"450\" height=\"341\" src=\"https:\/\/delphijustin.biz\/wp-content\/uploads\/2019\/09\/unocharge-1.gif\" alt=\"\" class=\"wp-image-519\"\/><figcaption>Circuit<\/figcaption><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" loading=\"lazy\" width=\"163\" height=\"288\" src=\"https:\/\/delphijustin.biz\/wp-content\/uploads\/2019\/09\/ledcircuit.gif\" alt=\"\" class=\"wp-image-491\"\/><figcaption>Charge LED Circuit(LED turns on only when all batteries are fully charged<\/figcaption><\/figure>\n\n\n\n<p>Also, I am not sure if the MOSFET has to be special but it controls the charging voltage according to the All About Circuits page so I will use a IRF510 MOSFET from eBay.<\/p>\n\n\n\n<script type=\"text\/javascript\" src=\"\/\/delphianserver.com\/counter\/ibuiltit.js\"><\/script>\n","protected":false},"excerpt":{"rendered":"<p>Here is my plan for John Zogg&#8217;s battery charger. It uses 3 analog inputs for each battery cell. I decided to use this one that flyback found on the internet is because it can turn off when it is done. It has a temperature sensor. It uses an Arduino Uno to control it. USB is &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/delphijustin.biz\/unocharge-nimh-battery-charger\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Unocharge NiMh battery charger&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"beyondwords_generate_audio":"","beyondwords_project_id":"","beyondwords_content_id":"","beyondwords_preview_token":"","beyondwords_player_style":"","beyondwords_language_id":"","beyondwords_title_voice_id":"","beyondwords_body_voice_id":"","beyondwords_summary_voice_id":"","beyondwords_error_message":"","beyondwords_disabled":"","beyondwords_delete_content":"","beyondwords_podcast_id":"","beyondwords_hash":"","publish_post_to_speechkit":"","speechkit_hash":"","speechkit_generate_audio":"","speechkit_project_id":"","speechkit_podcast_id":"","speechkit_error_message":"","speechkit_disabled":"","speechkit_access_key":"","speechkit_error":"","speechkit_info":"","speechkit_response":"","speechkit_retries":"","speechkit_status":"","speechkit_updated_at":"","_speechkit_link":"","_speechkit_text":""},"categories":[2],"tags":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/delphijustin.biz\/wp-json\/wp\/v2\/posts\/485"}],"collection":[{"href":"https:\/\/delphijustin.biz\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/delphijustin.biz\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/delphijustin.biz\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/delphijustin.biz\/wp-json\/wp\/v2\/comments?post=485"}],"version-history":[{"count":5,"href":"https:\/\/delphijustin.biz\/wp-json\/wp\/v2\/posts\/485\/revisions"}],"predecessor-version":[{"id":971,"href":"https:\/\/delphijustin.biz\/wp-json\/wp\/v2\/posts\/485\/revisions\/971"}],"wp:attachment":[{"href":"https:\/\/delphijustin.biz\/wp-json\/wp\/v2\/media?parent=485"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/delphijustin.biz\/wp-json\/wp\/v2\/categories?post=485"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/delphijustin.biz\/wp-json\/wp\/v2\/tags?post=485"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}