/* please put some text you'll search for one day here */
// version zero. 2S, just the four ohm load (2 amp nominal)
// report 1/s, toggle 10 seconds
// v2 on the way to a flight profile. for now, just using the 2 ohm load
// v3 first flioght profile idea, out to the wokwi and back...
// back from wokwi with power fight tm
# include "jbutton.h"
# define oneOhm 10
# define twoOhm 9
# define fourOhm 8
byte currentLoad = 0;
unsigned long currentTotal;
unsigned long flightCount;
unsigned long startTest;
unsigned long now;
# undef SIM
enum mode {IDLE, RUNNING, RESTING} testState;
# define KILL 6
# define START 2
# define STIFLE 3
# define BLOW 11
# define IND0 7
# define IND1 3
jButton kickStart;
// unit is inverse ohms or "amps"
//const byte flight[] = {0, 0, 0, 1, 1, 1, 4, 4, 8, 1, 1, 1, 8, 4, 4, 1, 1, 1, 0, 0, 0,};
// const byte flight[] = {0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 0, 0,};
// const byte flight[] = {0, 0, 0, 1, 1, 1, 2, 2, 4, 2, 2, 2, 4, 2, 2, 1, 1, 1, 0, 0, 0,};
const byte flight0[] = {
0,0,0,0,0,0,0,
1,1,1,1,1,1,1,
1,2,
2,2,4,
1,1,0,1,1,
2,2,4,
1,1,0,1,1,
2,4,2,
1,1,0,1,1,
4,2,2,
1,1,0,1,1,
4,2,2,
2,1,
1,1,1,1,1,1,1,
1,1,1,1,0,0,0,0,0,
};
const byte flight[] = {
2,4,
2,2,4,2,2, 1,1,1,1,1, 4,2,2, 1,1,1,1,1, 2,4,4,2, 1,1,1,1,1, 2,4,2,2,
1,1,0,0,0,0,0,
};
const byte flight1[] = {
2,4,
1,1,1,1,1,1,1,1,1, 1,1,1,1,1, 2,2,2, 2,2,2,2,2,2,2 ,2,2,0,0,0,0,0,
};
const byte flightLength = sizeof flight / sizeof *flight;
void setup()
{
mySetup(115200);
# ifdef SIM
xprintf("\nhello world.\n");
# else
xprintf("\nhello REAL world.\n");
xprintf("flight length %d\n", flightLength);
# endif
pinMode(KILL, INPUT_PULLUP);
pinMode(STIFLE, INPUT_PULLUP);
pinMode(IND0, OUTPUT);
pinMode(IND1, OUTPUT);
pinMode(BLOW, OUTPUT);
reset();
analysis();
kickStart.begin(START);
// analysis(); for (; ; );
// for (; ; ) testLamps();
}
void testLamps()
{
for (; ; )
for (unsigned char oh = 0; oh < 8; oh++) {
turnLoad(oh);
delay(400);
}
}
void testLamps0()
{
delay(300);
digitalWrite(oneOhm, HIGH);
digitalWrite(twoOhm, HIGH);
digitalWrite(fourOhm, HIGH);
delay(300);
digitalWrite(oneOhm, LOW);
digitalWrite(twoOhm, LOW);
digitalWrite(fourOhm, LOW);
}
unsigned int count[3] = {0, 0, 0};
void resetReport()
{
currentTotal = 0;
for (unsigned char ii = 0; ii < 3; ii++) count[ii] = 0;
}
void accumulate()
{
currentTotal += currentLoad;
flightCount++;
if (digitalRead(oneOhm) == HIGH) ++count[2];
if (digitalRead(twoOhm) == HIGH) ++count[1];
if (digitalRead(fourOhm) == HIGH) ++count[0];
}
void pReport()
{
xprintf("\nFlight length %ld units\n", flightCount);
xprintf("\n time in millis %ld\n", now - startTest);
unsigned char mask = 1;
for (unsigned char oh = 0; oh < 3; oh++, mask <<= 1)
xprintf("%d at %d ", count[oh], mask);
xprintf("\n");
}
void analysis()
{
unsigned char mask;
for (unsigned char ii = 0; ii < flightLength; ii++) {
mask = 1;
for (unsigned char oh = 0; oh < 3; oh++, mask <<= 1)
if (flight[ii] & mask) ++count[oh];
}
mask = 1;
for (unsigned char oh = 0; oh < 3; oh++, mask <<= 1)
xprintf("%d of %d ", count[oh], mask);
xprintf("\n");
}
static bool once;
void reset()
{
pinMode(oneOhm, OUTPUT);
pinMode(twoOhm, OUTPUT);
pinMode(fourOhm, OUTPUT);
// no load
digitalWrite(oneOhm, LOW);
digitalWrite(twoOhm, LOW);
digitalWrite(fourOhm, LOW);
resetReport();
once = false;
testState = IDLE;
}
// now - enhance so that if the time < MAX (3000, say) then the power is logged at the average of Vn-1 and Vn
// flag an error if a change from needing any power comes after MAX - why was load switched on unsupervised?
void turnLoad(byte theLoad)
{
// 1/ohm load oneL is but 1 ohm switched in it gets the MSB
digitalWrite(oneOhm, theLoad & 0x4 ? HIGH : LOW); // 1 ohm 100
digitalWrite(twoOhm, theLoad & 0x2 ? HIGH : LOW); // 2 ohm 010
digitalWrite(fourOhm, theLoad & 0x1 ? HIGH : LOW); // 4 ohm 001
// power will be in watt seconds 100 v * 100 v / r * millisconds // * 1000 * 10000
}
const float lowBatt = 3.55;
const float terminateTest = 3.33;
bool doWork;
bool checkPrint;
void runTestFSM()
{
switch (testState) {
case IDLE :
break;
case RUNNING :
break;
}
}
# define TICK 777
void loop()
{
static int counter;
static unsigned long lastTime;
static unsigned char wCount;
checkPrint = digitalRead(STIFLE) == HIGH;
float voltage = getCV();
now = millis();
digitalWrite(BLOW, voltage < lowBatt ? HIGH : LOW);
if (voltage < terminateTest || digitalRead(KILL) == LOW) {
// int ivoltage = 1000 * voltage;
// xprintf("stop at %d\n", ivoltage);
//if (digitalRead(KILL) == LOW) {
// no load
turnLoad(0);
if (doWork) {
Serial.print("STOP at ");
Serial.println(voltage);
Serial.println("\n\n LOAD REMOVED!");
}
doWork = false;
}
kickStart.update();
if (kickStart.uolPress()) {
reset();
wCount = 0;
doWork = true;
}
if (now - lastTime < TICK) return;
lastTime = now;
if (doWork) {
// read last tick power and log it
accumulate();
currentLoad = flight[wCount];
turnLoad(currentLoad);
// xprintf("%2d %x ", wCount, currentLoad); // the load being switched to
wCount++;
if (wCount >= flightLength)
wCount = 0;
}
else {
turnLoad(0);
static unsigned long lastVPrint;
if (!once++) {
pReport();
Serial.println(" not under load now.");
lastVPrint = 0;
}
if (checkPrint)
if (now - lastVPrint > 13000) {
Serial.print("+");
Serial.print(getCV()); Serial.print(" ");
Serial.println(millis());
lastVPrint = now;
}
}
if (doWork) {
static unsigned long lastPrint;
if (now - lastPrint > 5000) {
xprintf("%2d %x ", wCount, currentLoad); // the load being switched to
Serial.print(millis()); Serial.print(" ");
Serial.print(" : ");
Serial.print(voltage); Serial.print(" ");
Serial.println("");
lastPrint = now;
}
// if (voltage < lowBatt && doWork) Serial.println(" LAND NOW!");
}
counter++;
// no floats xprintf("%5d reading %4d volts %4d\n", counter, reading, voltage);
}
// return the adjusted average cell voltage.
// currently QND matches the voltage divider for 2S
// measurement is of entire battery
float getCV()
{
const float scale2S = 0.005; // adjust for 1/2 Vbatt, average cell voltage
static unsigned long counter = 0;
static float voltage = 7.4; // just so it doen't trip right away
float reading = analogRead(A1);
voltage = (reading / 755.5 * 738.5 + 0.5) * scale2S;
if (0) {
Serial.print(counter); Serial.print(" "); counter++;
Serial.print(reading, 3); Serial.print(" ");
Serial.print(voltage); Serial.print(" ");
Serial.println("");
}
return voltage;
}
//
// programmer misses printf...
void xprintf(const char *format, ...)
{
char buffer[256];
va_list args;
va_start(args, format);
vsprintf(buffer, format, args);
va_end(args);
Serial.print(buffer);
}
// programmer forgets day of week, version
void mySetup(unsigned long bandRate)
{
Serial.begin(bandRate);
char s[] = __FILE__;
byte b = sizeof(s);
while ( (b > 0) && (s[b] != 47)) b--;
char *u = s + b + 1;
xprintf("\nHEllo WOrld!\n");
xprintf("%s %s\n\n", __DATE__, u);
xprintf("!\n");
}
STOP....WARN....CHANGE
STOP....WARN....CHANGE
KILL
START
1A
2A
4A
LOW