Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: OLED_SSD1306 MCP9808
Revision 1:7749656733dd, committed 2020-08-24
- 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));
}