大 电 / Mbed OS mbed-os5-F303-18650-Manager-tp4056

Dependencies:   OLED_SSD1306 MCP9808

Files at this revision

API Documentation at this revision

Comitter:
kuutei
Date:
Mon Aug 24 05:29:53 2020 +0000
Parent:
0:56122e281547
Child:
2:18d8f9d3286c
Commit message:
sort of working

Changed in this revision

DS1820.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DS1820.lib	Mon Aug 24 05:29:53 2020 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/hudakz/code/DS1820/#74a4ff420541
--- a/main.cpp	Mon Aug 24 04:09:04 2020 +0000
+++ b/main.cpp	Mon Aug 24 05:29:53 2020 +0000
@@ -6,11 +6,14 @@
 #include <sstream>
 
 #include "SSD1306I2C.h"
+#include "DS1820.h"
 
 #define OLED_ADR 0x3C
 #define OLED_SDA I2C_SDA
 #define OLED_SCL I2C_SCL
 
+#define DS18B20_DATA PB_4
+
 
 // Blinking rate in milliseconds
 #define BLINKING_RATE_MS                                                    5000
@@ -20,6 +23,10 @@
 
 Serial pc(USBTX,USBRX);
 
+SSD1306I2C oled_i2c(OLED_ADR, OLED_SDA, OLED_SCL);
+
+DS1820 ds1820_sensor(DS18B20_DATA);
+
 //DigitalIn mybutton(USER_BUTTON);
 AnalogIn   divider_analogin(A0);
 AnalogIn    vref(ADC_VREF);
@@ -27,21 +34,23 @@
 //AnalogIn adc_refint(VREF_INT);
 
 DigitalInOut toggleOut(PA_14, PIN_OUTPUT, OpenDrainNoPull, 0);
-bool enableChargingState = false; //reflects internal state of TP4056 control thread
+bool TP4056ChargingState = false; //reflects internal state of TP4056 control thread
 
 InterruptIn chargeButton(USER_BUTTON);
-bool buttonPressed = false; //set to true by button ISR, set to false when acknowledged
+volatile bool buttonPressed = false; //set to true by button ISR, set to false when acknowledged
 
-SSD1306I2C oled_i2c(OLED_ADR, OLED_SDA, OLED_SCL);
+bool batteryPresenceState = false;
 
 float bat_voltage = -1.11;
 float bat_voltage_avg = -1.11;
 float vddref_voltage = -1.11;
 
+float ds18b20_temperature = -301.0;
 
 //Configurable protection conditions
 float MAX_VOLTAGE = 4.25; //default: no more than 4.25v
 float MIN_VOLTAGE = 2.5; //default: no less than 2.5v
+float MIN_DETECT_VOLTAGE = 0.5; //default: no less than 0.3v
 float MAX_TEMPERATURE = 40.0; //default: no more than 40C
 float MIN_TEMPERATURE = 10.0; //default: no less than 10C
 uint64_t MAX_TIME_ms = 3600000; //default: no more than 1h
@@ -54,29 +63,26 @@
     
     while (true) {
         led = !led;
-        //thread_sleep_for(BLINKING_RATE_MS);
         ThisThread::sleep_for(BLINKING_RATE_MS);
     }
 }
 
-//TODO: make this an ISR that causes an immediate read of the analog pin
-void pa14_toggle()
-{
-
-}
 
 // Button to initiate / stop charging
 // Called on button rise
 // Set to true to signal to EN control thread that button was pressed
-void buttonISR
+void buttonISR()
 {
+    static uint64_t lastButtonPushTime = 0;
+    
     uint64_t now = Kernel::get_ms_count();
-    uint64_t lastButtonPushTime = now;
+    
     const uint64_t buttonMinimumWaitTime = 500; //minimum 500 ms wait between button pushes
     
     if(Kernel::get_ms_count() - lastButtonPushTime > buttonMinimumWaitTime)
     {
         buttonPressed = true;
+        lastButtonPushTime = now;
     }
        
 }
@@ -135,9 +141,31 @@
 // Reads DS18B20 sense temperature
 void TemperatureInputThread()
 {
+    int ds18b20_result = 0;
+    float temp;
+    
     while(true)
     {
+        ds1820_sensor.startConversion();   // start temperature conversion from analog to digital
+        // let DS1820 complete the temperature conversion
+        ThisThread::sleep_for(1.0);
+        ds18b20_result = ds1820_sensor.read(temp); // read temperature from DS1820 and perform cyclic redundancy check (CRC)
         
+        switch (ds18b20_result) {
+            case 0:                 // no errors -> 'temp' contains the value of measured temperature
+                //pc.printf("temp = %3.4f%cC\r\n", temp, 176);
+                ds18b20_temperature = temp;
+                break;
+
+            case 1:                 // no sensor present -> 'temp' is not updated
+                //pc.printf("no sensor present\n\r");
+                ds18b20_temperature = -302.0;
+                break;
+
+            case 2:                 // CRC error -> 'temp' is not updated
+                //pc.printf("CRC error\r\n");
+                ds18b20_temperature = -303.0;
+            }
         
         ThisThread::sleep_for(250);
 
@@ -147,10 +175,14 @@
 // Detect battery presence by voltage activity
 bool batteryPresent()
 {
-    if(bat_voltage_avg > 0.0 && bat_voltage_avg)
+    if(bat_voltage_avg > MIN_DETECT_VOLTAGE)
     {
         return true;   
     }
+    else
+    {
+        return false;   
+    }
 }
 
 void TP4056ControlThread()
@@ -164,13 +196,35 @@
        while(true)
        {
             //First check conditions to see if charging should be enabled or disabled
+            bool temperature_en = ( ( ds18b20_temperature < MAX_TEMPERATURE ) && ( ds18b20_temperature > MIN_TEMPERATURE ) );
+            bool voltage_en = ( ( bat_voltage_avg  < MAX_VOLTAGE ) && ( bat_voltage_avg > MIN_VOLTAGE ) );
+            bool presence_en = batteryPresent();
+            bool charge_time_exceeded = ( (Kernel::get_ms_count() - chargeStartTime ) > MAX_TIME_ms);
+            
             //Charging can be enabled if battery is present, no protections triggered, and user starts the charge
             if(enableCharging == false)
+            {                
+                if( voltage_en && temperature_en && presence_en && buttonPressed )
+                {
+                    enableCharging = true;
+                    buttonPressed = false;
+                }
+            }
+            //Charging must be stopped if overvoltage, overtemperature, overtime, battery removed, or user pushes button
+            else
             {
-                bool temperature_en = (MAX_TEMPERATURE);
+                //Disable charging if any protection condition is triggered
+                if( !voltage_en || !temperature_en || !presence_en )
+                {
+                    enableCharging = false;
+                }
+                //or if user pushed button
+                else if(buttonPressed)
+                {    
+                    buttonPressed = false;   
+                }
             }
             
-            //Charging must be stopped if overvoltage, overtemperature, overtime, battery removed, or user pushes button
             
             //With charge state calculated, realize it on the CE pin
             //Allow pullup to 5V to enable charging at CE pin
@@ -186,7 +240,7 @@
             } 
             
             //Update flag that indicates state of TP4056 CE pin to other threads
-            enableChargingState = enableCharging;
+            TP4056ChargingState = enableCharging;
         
            ThisThread::sleep_for(100);
        }
@@ -204,7 +258,7 @@
         std::string voltage_output = "Voltage: " + stream.str();
         oled_i2c.drawString(0, 0, voltage_output.c_str() );
         
-        if(enableChargingState){
+        if(TP4056ChargingState){
             oled_i2c.drawString(0, 16, "CE: Enabled");
         } else {
             oled_i2c.drawString(0, 16, "CE: Disabled");  
@@ -296,7 +350,7 @@
         pc.printf("ADC0 1s max: %6.4f\r\n", bat_voltage_max);
         pc.printf("ADC0 1s avg: %6.4f\r\n", bat_voltage_avg);
         pc.printf("VDDREF Reading: %6.4f\r\n", vddref_voltage);
-        pc.printf("ADC0 time (nominal 1000ms): %d\r\n", (now-lastADCStartTime));
+        pc.printf("ADC0 time (nominal 1000ms): %llu\r\n", (now-lastADCStartTime));
         
     }