const char* info0 = "ECP4 Build-01 ";
const char* info1 = "F/W 0501C1_v0.12";
const char* info2 = "Assy: CES180501N";
const char* info3 = "Date: 09/21/2018";
/*
* 0501C1_v0.12 9/21/18 ---------------------
* Common F/W for ECP4
* Ready for Acceptance Test
* Pending LCD Display I2C Address update
* Pending Vin+ PS+ Ics Calibration
* Program 49%, Memory 37%
* Modified from 0501M1_v0.12 9/21/18
* -------------------------------------------
* PCBASSY# CES180501N Pro Mini I2C 1602
* DMM V/A Input
* Counter Input
* DS1820B Temperature Sensor
* Optical Isolation I/O
* -------------------------------------------
* Pro Mini (TN168) PORT Assignments
* A7
* A6
* A5 I2C-SCL
* A4 I2C-SDA
* A3 DMM3
* A2 DMM2 (Ics 50A)
* A1 DMM1 (PS+ 100V)
* A0 DMM0 (VIN+ 40V)
* D13 IDE Reserved Onboard LED (LoopBeat LED)
* D12 Temperatur DS18B20
* D11
* D10
* D9 nRDX LO=EDMon
* D8 nTDX LO=NotReady
* D7
* D6
* D5 Key Selup
* D4 Key Seldn
* D3
* D2 FREQ Counter INPUT
* D1 IDE Reserved Programming TXD
* D0 IDE Reserved Programming RXD
*
* ============================================================
* (D9)(D8)(D7)(D6)(D5)(D4)(D3)(D2)(GND)(RES)(RXD)(TXD) < DTR >
* (GND) * * (RESET) < RX >
* (MOSI/D11) * * (SCK/D13) < TX >
* VCC+5V * * (MISO/D12) < VCC >
* A4 * * A6 < CTS >
* A5 * * A7 < GND >
* (D10)(D11)(D12)(D13)(A0)(A1)(A2)(A3)(VCC)(RES)(GND)(RAW)
* ============================================================
*/
// DCOMM Console Interface btw PWMGen4
#define nTXD 8
#define Ready HIGH
#define NotReady LOW
#define nRXD 9
#define EDMon LOW
#define EDMoff HIGH
byte EDMstatus;
byte Readystatus;
#define vinmin 11.5 //VIN threashold for Not Ready
// LCD 1602 with I2C
#include <FastIO.h>
#include <I2CIO.h>
#include <LiquidCrystal_I2C.h>
// the pins on the I2C chip used for LCD connections:
// addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
//LiquidCrystal_I2C lcd2(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // TESTER LCD
LiquidCrystal_I2C lcd2(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); //
// DS18B20 Temperature Sensor(s)
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#define Tport 12 // Port for Sensor
#define Tdata 9 // Resolution, 9-bit 0.5C 93.75mS, 10-bit 0.25C 187.5mS, 11-bit 0.125C 375mS, 12-bit 0.0625C 750mS
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(Tport);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// Arrays to hold device addresses
DeviceAddress Tsensor1, Tsensor2; // for Auto Config
//DeviceAddress Tsensor1 = { 0x28, 0xFF, 0x77, 0x95, 0x94, 0x16, 0x04, 0x85 }; // RR= Brown
//DeviceAddress Tsensor2 = { 0x28, 0xFF, 0xE8, 0x8E, 0x86, 0x16, 0x04, 0xF4 }; // LT= Blue
float TempC;
float TT1;
float TT2;
// Analog Ports
#define DMM0 A0 // VIN+
#define DMM1 A1 // PS+
#define DMM2 A2 // ICS
//#define DMM3 A3 //
// DMM PreScale
double dmk0 = 0.037471489; // 38.33V 220K/33K FSC @ 5.000V
double dmk1 = 0.094493320; // 96.67V 220K/12K FSC @ 5.000V
double dmk2 = 0.049873322; // 51.02A 18K/10K CS=0.035 FSC @ 5.000V
//double dmk3 = ; // notused
//double dmk0 = 0.038329969; // 38.61V 220K/33K FSC @ chk
//double dmk1 = 0.098442563; // 97.57V 220K/12K FSC @ chk
//double dmk2 = 0.050516031; // 51.02A 18K/10K CS=0.035 FSC @ chk
// DMM AnalogRead Array
const int ARcount = 10; // sample size
unsigned int dm0[ARcount]; // array data
unsigned int dm1[ARcount]; // array data
unsigned int dm2[ARcount]; // array data
//unsigned int dm3[ARcount]; // array data
unsigned int Aindex = 0; // array index
unsigned int dm0min; // MIN result byte
unsigned int dm0avg; // AVG result byte
unsigned int dm0max; // MAX result byte
unsigned int dm1min;
unsigned int dm1avg;
unsigned int dm1max;
unsigned int dm2min;
unsigned int dm2avg;
unsigned int dm2max;
//unsigned int dm3min;
//unsigned int dm3avg;
//unsigned int dm3max;
float dmmV;
float dmmA;
float dmmW;
// Counter
#define iFreq 2 // Frequencty Counter Input Port
long TtimeMAX = 25000; //10Hz minimum
float Htime; // integer for storing high time
float Ltime; // integer for storing low time
float Ttime; // integer for storing total time of a cycle
float frequency; // for storing frequency
// Key & SW
#define kselup 4 // Sel-Up Key
#define kseldn 5 // Sel-DN Key
// System Variable
#define loopbeat 13 // toggle per Loop
unsigned long msNow; //Current Wait Timer
unsigned long msScreen = 3000; //default Screen Wait time
unsigned long msLastscreen; //Last Screen Wait Timer
byte keyuphold = 0; // Keyup Hold Index
byte keydnhold = 0; // Keydn Hold Index
String mfg; // Long MSG
byte screen = 1; //Display Page index
byte dispscan = 1; // 1= scan mode
byte startscreen = 1; // Scan Start Screen
#define firstscreen 1 // scan 1st screen
#define DualTemp 1
#define Vin 2
#define PS 3
#define Ics 4
#define VAWavg 5
#define VAWmax 6
#define CntFreq 7
#define CntTime 8
#define lastscreen 8 // scan last screen
#define maxscreen 8 // Max screen counts from 0
/* ------------------------------------------------------------------------*/
/// Setup Start Here
void setup() {
//Temp DS18B20 setup
sensors.begin();
//DCOMM Console Interface
pinMode(nRXD,INPUT_PULLUP);
pinMode(nTXD,OUTPUT);
//LCD setup
lcd2.begin(16, 2);
//Key-In Setup
pinMode(kselup, INPUT_PULLUP); // Page Up Hold for scan
pinMode(kseldn, INPUT_PULLUP); // Page Dn Hold for scan
//Loop Beat
pinMode(loopbeat, OUTPUT);
//Display Info
lcd2.setCursor(0,0); lcd2.print(info0);
lcd2.setCursor(0,1); lcd2.print(info1);
delay(2000);
lcd2.setCursor(0,0); lcd2.print(info2);
lcd2.setCursor(0,1); lcd2.print(info3);
delay(2000);
}
/// Setup End Here
/* ------------------------------------------------------------------------*/
/// Program Start Here
void loop() {
// Get Dual Temp Data
sensors.requestTemperatures();
// Get DMM Value
DMMread(); // Read All Ports
DMMproc(); // Processing Max/Avg/Min
// Screen Display
switch(screen) {
case DualTemp:
//sensors.requestTemperaturesByAddress(Tsensor1);
TT1 = sensors.getTempC(Tsensor1);
//sensors.requestTemperaturesByAddress(Tsensor2);
TT2 = sensors.getTempC(Tsensor2);
lcd2.setCursor(0,0); // Temperatures
// print("0123456789012345")
lcd2.print(" <Inlet> <HS> ");
lcd2.setCursor(0,1); printTT( Tsensor1, 0, Tsensor2, 1 ); // Dual Temp
break;
case Vin: //dispV(int ddm1, double ddmk1, char* ddmn1)
if ((dispscan==1) && (Readystatus>0)) {screen++; break;} //skip on scan
lcd2.setCursor(0,0); dispV(dm0min, dmk0, "VIN+ min ");
lcd2.setCursor(0,1);
if (Readystatus==0) lcd2.print("** Low Voltage !"); else dispV(dm0max, dmk0, "VIN+ max "); // VIN+
break;
case PS:
if (dispscan==1) {screen++; break;} //skip on scan
lcd2.setCursor(0,0); dispV(dm1min, dmk1, "PS+ min ");
lcd2.setCursor(0,1); dispV(dm1max, dmk1, "PS+ max "); // PS+
break;
case Ics:
if (dispscan==1) {screen++; break;} //skip on scan
lcd2.setCursor(0,0); dispA(dm2min, dmk2, "Ics+ min ");
lcd2.setCursor(0,1); dispA(dm2max, dmk2, "Ics+ max "); // Ics+
break;
case VAWavg:
if (dispscan==1) {screen++; break;} //skip on scan
lcd2.setCursor(0,0); // PS VAW AVG
lcd2.print("<Avg. Power Out>");
lcd2.setCursor(0,1); dispVAW(dm1max, dmk1, dm2avg, dmk2); // Max Power
break;
case VAWmax:
lcd2.setCursor(0,0); // PS VAW MAX
lcd2.print("<Max. Power Out>");
lcd2.setCursor(0,1); dispVAW(dm1max, dmk1, dm2max, dmk2); // Max Power
break;
case CntFreq:
lcd2.setCursor(0,0); lcd2.print("<EDM System PWM>");
lcd2.setCursor(0,1); dispFD(frequency, Htime);
break;
case CntTime:
lcd2.setCursor(0,0); // Counter H/L Display
lcd2.print("<EDM H/L Timing>");
lcd2.setCursor(0,1); dispHL(frequency, Htime);
break;
} //end screen
// NotReady if VIN below vinmin
if ((dm0min*dmk0) < vinmin) {
Readystatus=0;
screen = Vin; msLastscreen = msNow;
} else Readystatus=1;
//DCOMM Console Status Interface
if (Readystatus==0) digitalWrite(nTXD,NotReady); else digitalWrite(nTXD,Ready);
if (digitalRead(nRXD)==EDMon) EDMstatus=1; else EDMstatus=0; //nRXD Active
// EDMstatus=1; //In-active set to ON
// Counter Input
if (EDMstatus > 0) {
Htime=pulseIn(iFreq,HIGH,TtimeMAX); //read high time
Ltime=pulseIn(iFreq,LOW,TtimeMAX); //read low time
Ttime = Htime+Ltime; // total time = high time + low time in uS
frequency=1000000/Ttime; //calculate frequency from Ttime in Micro seconds
}
// UP Key Inputs
if (digitalRead(kselup)==LOW) {
if (dispscan>0) {
lcd2.clear(); lcd2.print (" - Clear Scan ");
dispscan = 0;
}
if (keyuphold==0) {
screen--;
if ((screen < firstscreen) || (screen > maxscreen)) screen = maxscreen;
}
keyuphold++;
if (keyuphold>4) {
dispscan=1;
lcd2.clear(); lcd2.print (" + Scan Mode Set");
do {} while ((digitalRead(kselup)==LOW));
}
delay(250);
} else { keyuphold=0; }
//DN Key Input
if (digitalRead(kseldn)==LOW) {
if (dispscan>0) {
lcd2.clear(); lcd2.print (" - Clear Scan ");
dispscan = 0;
}
if (keydnhold==0) {
screen++;
if (screen > maxscreen) screen=firstscreen;
}
keydnhold++;
if (keydnhold>4) {
dispscan=1;
lcd2.clear(); lcd2.print (" + Scan Mode Set");
do {} while ((digitalRead(kseldn)==LOW));
}
delay(250);
} else { keydnhold=0; }
// Display Timer updater
msNow = millis();
if ((msNow-msLastscreen > msScreen) && (dispscan > 0)) {
msLastscreen = msNow;
screen++;
if (screen > lastscreen) screen = firstscreen;
}
// Loop Beat on D13 LED
if (digitalRead(loopbeat)==LOW) digitalWrite(loopbeat,HIGH); else digitalWrite(loopbeat,LOW);
}
/// Program End Here
/* ------------------------------------------------------------------------*/
/// Frequency/Duty Display "xxx.xxxKHz D:xx%"
void dispFD(float freq, float Ht) {
mfg = "";
float Tt = 1000000 / freq; // in uS
if (((freq/1000)>999) || (freq < 20)) { mfg=mfg+"! Invalid Data !"; } else {
//if (((freq/1000)>999)) { mfg=mfg+"! Invalid Data !"; } else {
if ((freq/1000)<10) { mfg=mfg+" "; } else if ((freq/1000)<100) { mfg=mfg+" "; }
mfg=mfg + String(freq/1000,3) + "KHz D="+ String((Ht/Tt)*100,0) + "%";
}
lcd2.print(mfg);
}
/// H/L Time Display "+xxxxxuS-xxxxxuS" // 16 chr
void dispHL(float freq, float Ht) {
mfg = "";
float Lt = 1000000 / freq - Ht; // in uS
if ((Ht)>1000) {
if ((Ht/1000)<10) { mfg=mfg+" "; }
mfg=mfg + "H" + String(Ht/1000,2) + "mS";
}
else {
if (Ht<100) { mfg=mfg+" "; } else if (Ht<1000) { mfg=mfg+" "; } else if (Ht<10000) { mfg=mfg+" "; }
mfg=mfg + "H" + String(Ht,0) + "uS";
}
if ((Lt)>1000) {
if ((Lt/1000)<10) { mfg=mfg+" "; }
mfg=mfg + "L" + String(Lt/1000,2) + "mS";
}
else {
if (Lt<10) { mfg=mfg+" "; } else if (Lt<100) { mfg=mfg+" "; } else if (Lt<1000) { mfg=mfg+" "; } else if (Lt<10000) { mfg=mfg+" "; }
mfg=mfg + "L" + String(Lt,0) + "uS";
}
lcd2.print(mfg);
}
/// DMM Display 0123456789012345 Name(4)+Data(12)
/// V Vin+: nnn.nnVDC
void dispV(int ddm1, double ddmk1, char* ddmn1) {
mfg = (ddmn1);
dmmV = ddm1 * ddmk1;
if (dmmV<100) mfg += " ";
if (dmmV<10) mfg += " ";
mfg += String(dmmV,2); mfg += "V";
lcd2.print (mfg);
}
/// DMM Display 0123456789012345 (16-chr)
/// Ics+ Ics+: nnn.nnADC
void dispA(int ddm1, double ddmk1, char* ddmn1) {
mfg = (ddmn1);
dmmV = ddm1 * ddmk1;
if (dmmV<100) mfg += " ";
if (dmmV<10) mfg += " ";
mfg += String(dmmV,2); mfg += "A";
lcd2.print (mfg);
}
/// DMM Display 0123456789012345 (16-chr)
/// VAW nnnV nn.nA nnnnW
void dispVAW( int dvm, double dvk, int dam, double dak ) {
mfg = "";
dmmV = dvm * dvk;
dmmA = dam * dak;
dmmW = dmmV * dmmA;
if (dmmV<100) mfg += " ";
mfg += String(dmmV,0) + "V ";
if (dmmA<10) mfg += " ";
mfg += String(dmmA,1) + "A ";
if (dmmW>9999) { mfg += " --- "; }
else {
if (dmmW<100) { mfg += " "; } else if (dmmW<1000) { mfg += " "; }
mfg += String(dmmW,0) + "W";
}
lcd2.print (mfg);
}
/// TEMP Disp Temperatures Sensors in "-xxx.xoC" 8chr
void printTT(DeviceAddress paddress1, byte pindex1, DeviceAddress paddress2, byte pindex2) {
mfg="";
if (!sensors.getAddress(paddress1,pindex1)) { mfg += " --- "; lcd2.print (mfg);}
else { printT2(TT1); }
mfg="";
if (!sensors.getAddress(paddress2,pindex2)) { mfg += " --- "; lcd2.print (mfg);}
else { printT2(TT2); }
}
/// TEMP Disp Justify print =OK=
// "01234567"
// "-100.3oC"
// " -10.3oC"
// " -1.3oC"
// " 0.3oC"
// " 10.3oC"
// " 100.3oC"
void printT2(float TC) {
if (TC<0) {
if (TC>-100) mfg += " ";
if (TC>-10) mfg += " ";
mfg += String(TC,1);
} else {
mfg += " ";
if (TC<100) mfg += " ";
if (TC<10) mfg += " ";
mfg += String(TC,1);
}
lcd2.print (mfg);
lcd2.print("\xDF" "C");
}
/// --------------------------------------------------------------
/// DMM Port Read
void DMMtest() {
Aindex++; if (Aindex == ARcount) Aindex = 0;
dm0[Aindex]+=1.5;
dm1[Aindex]+=2.8;
dm2[Aindex]+=3.4;
//dm3[Aindex]+=4.6;
}
void DMMread() {
Aindex++; if ((Aindex == ARcount) || (Aindex > ARcount)) Aindex = 0;
int j;
j = 3; if (j != 0) { dm0[Aindex] = analogRead(DMM0); j--; }
j = 3; if (j != 0) { dm1[Aindex] = analogRead(DMM1); j--; }
j = 3; if (j != 0) { dm2[Aindex] = analogRead(DMM2); j--; }
//j = 2; if (j != 0) { dm3[Aindex] = analogRead(DMM3); j--; }
}
/// DMM Processing Max/Avg/Min
void DMMproc() {
dm0min = dm0[Aindex]; dm0avg = dm0min; dm0max = dm0min;
dm1min = dm1[Aindex]; dm1avg = dm1min; dm1max = dm1min;
dm2min = dm2[Aindex]; dm2avg = dm2min; dm2max = dm2min;
//dm3min = dm3[Aindex]; dm3avg = dm3min; dm3max = dm3min;
int i=0;
for (i=0; i<ARcount; i++) {
if (dm0min > dm0[i]) dm0min = dm0[i];
if (dm1min > dm1[i]) dm1min = dm1[i];
if (dm2min > dm2[i]) dm2min = dm2[i];
//if (dm3min > dm3[i]) dm3min = dm3[i];
if (dm0max < dm0[i]) dm0max = dm0[i];
if (dm1max < dm1[i]) dm1max = dm1[i];
if (dm2max < dm2[i]) dm2max = dm2[i];
//if (dm3max < dm3[i]) dm3max = dm3[i];
dm0avg = ( dm0avg + dm0[i] ) /2;
dm1avg = ( dm1avg + dm1[i] ) /2;
dm2avg = ( dm2avg + dm2[i] ) /2;
//dm3avg = ( dm3avg + dm3[i] ) /2;
}
}
void DMMproc0() {
dm0min = dm0[Aindex]; dm0avg = dm0min; dm0max = dm0min;
int i=0;
for (i=0; i<ARcount; i++) {
if (dm0min > dm0[i]) dm0min = dm0[i];
if (dm0max < dm0[i]) dm0max = dm0[i];
dm0avg = ( dm0avg + dm0[i] ) /2;
}
}
void DMMproc1() {
dm1min = dm1[Aindex]; dm1avg = dm1min; dm1max = dm1min;
int i=0;
for (i=0; i<ARcount; i++) {
if (dm1min > dm1[i]) dm1min = dm1[i];
if (dm1max < dm1[i]) dm1max = dm1[i];
dm1avg = ( dm1avg + dm1[i] ) /2;
}
}
void DMMproc2() {
dm2min = dm2[Aindex]; dm2avg = dm2min; dm2max = dm2min;
int i=0;
for (i=0; i<ARcount; i++) {
if (dm2min > dm2[i]) dm2min = dm2[i];
if (dm2max < dm2[i]) dm2max = dm2[i];
dm2avg = ( dm2avg + dm2[i] ) /2;
}
}
/// Software Reset
void resetBoot() {
asm volatile (" jmp 0");
}
/// F/W End Here
/* ------------------------------------------------------------------------*/