Sure. I was hoping to show the hardware nicely installed in a box too, but that'll have to wait until the workshop reopens.
As for the code, well there's nothing too devastating to see (this is compiled with the IDE v1.0 beta-1, by the way). I'm new to the "++" part of C++ and was happy to discover that I could create an array of NewSoftSerial instances, even though the constructor takes parameters (line 9). That's important when you're running five serial ports.
dodis() initialises the displays, no matter what baud rate they're set to. This device is operating in a very noisy environment, and occasionally the interference causes one or more displays to switch their baud rate. Since baud rate configuration is stored in non-volatile memory, the software has to deal with it even after a reset.
dodat() displays a floating point number as best it can, within the limits of the 4-digit display.
#include <SoftwareSerial.h>
#include <Streaming.h>
#define CONDUCTANCE_CH1 100 // current scale: amps per volt [Ohm^-1]
#define CONDUCTANCE_CH2 60 // current scale: amps per volt [Ohm^-1]
#define SCALE_V 1.0 // voltage-divider ratio on voltage (read on pins A0, A1, A2, A3)
#define SCALE_I 0.5 // voltage-divider ratio on current (read on pins A4, A5)
SoftwareSerial dis[4] = { SoftwareSerial(2,3), // Ch. 1 : Power display: TX = pin-3
SoftwareSerial(4,5), // Ch. 1 : Resistance display: TX = pin-5
SoftwareSerial(6,7), // Ch. 2 : Power display: TX = pin-7
SoftwareSerial(8,9) }; // Ch. 2 : Resistance display: TX = pin-9
void setup() {
pinMode(A0, INPUT); digitalWrite(A0, LOW);
pinMode(A1, INPUT); digitalWrite(A1, LOW);
pinMode(A2, INPUT); digitalWrite(A2, LOW);
pinMode(A3, INPUT); digitalWrite(A3, LOW);
pinMode(A4, INPUT); digitalWrite(A4, LOW);
pinMode(A5, INPUT); digitalWrite(A5, LOW);
pinMode(13, OUTPUT);
dodis();
Serial.begin(19200);
}
void loop() {
int a[6]; // adcs
int adcmode, n, quit;
float w[6]; // voltage inputs
float v[2], i[2], p[2], r[2]; // power and resistance
float adcref[4];
Serial << endl;
adcref[DEFAULT] = 5.0;
adcref[INTERNAL] = 1.1;
adcmode=DEFAULT; // try DEFAULT=5V, then INTERNAL=1.1V, then EXTERNAL=quit
quit=0; while( !quit ) {
analogReference(adcmode); // set ADC full-scale reference voltage
digitalWrite(13,HIGH); delay(10); digitalWrite(13,LOW); delay(10); // flash during reads; also 20ms delay after changing Aref to charge decoupling cap
for ( n=0; n<6; n++ ) {analogRead(n); } // dummy reads whilst reference stabilises
for ( n=0; n<6; n++ ) {
a[n]=analogRead(n);
w[n]=a[n]; w[n]*=adcref[adcmode]/1024;
if (a[n]>200) quit=1; // quit loop early if any value exceeds scale crossover at 200/1024*5V = 0.98V
}
if ( adcmode == INTERNAL) {quit=1;} else {adcmode=INTERNAL;}
}
Serial << "a0 " << a[0] << " / a1 " << a[1] << " / a2 " << a[2] << " / a3 " << a[3] << " / a2 " << a[4] << " / a3 " << a[5] << endl;
Serial << "V0 " << w[0] << " / V1 " << w[1] << " / V2 " << w[2] << " / V3 " << w[3] << " / V2 " << w[4] << " / V3 " << w[5] << endl;
float c[] = { CONDUCTANCE_CH1, CONDUCTANCE_CH2 };
for ( n=0; n<2; n++ ) {
i[n]=w[4+n]*c[n]/SCALE_I;
v[n]=abs(w[0+n]-w[2+n])/SCALE_V;
p[n]=v[n]*i[n]; // power [W]
r[n]=v[n]/i[n]*1e3; // resistance [mOhm]
dodat(dis[0+n], p[n]); // units: Watts
dodat(dis[2+n], r[n]); // units: milli-Ohm
Serial << "Current " << i[n] << " [A] / Voltage " << v[n]*1e3 << " [mV] / Power " << p[n] << " [W] / Resistance " << r[n] << " [mOhm]" << endl;
}
delay(500);
}
void dodis() { // set baud, no matter what it's set to at the begining
char buf[] = " HELLO vvvv\x7F\001";
long baud[] = { 2400, 4800, 9600, 14400, 19200, 38400, 57600 };
int m,n;
for (n=0; n<4; n++) {
dis[n].begin(57600);
dis[n] << "vvvv z" << '\255' << "w" << '\000'; // reset; blank; brightness=min; decimal=off
dis[n].end();
}
for (m=0; m<6; m++) {
for (n=0; n<4; n++) {
dis[n].begin(baud[m]);
buf[18] = m+1;
dis[n] << (buf+13); // reset; set baud
dis[n].end();
}
delay(100);
}
for (n=0; n<4; n++) {
dis[n].begin(57600);
dis[n] << "vvvv z" << '\000' << "w" << '\000'; // reset; blank; brightness=full; decimal=off
}
for (m=0; m<10; m++) {
char c=buf[m+4]; buf[m+4]=0;
for (n=0; n<4; n++) { dis[n] << "v" << (buf+m); } // scroll "HELLO"
delay(100);
buf[m+4]=c;
}
for (n=0; n<4; n++) { dis[n] << "z\xFFv0000"; } // min. brightness, '0000'
m=255; while( m>0 ) { // fade in: 127-0
m>>=1; delay(100);
for (n=0; n<4; n++) { dis[n] << "z" << m; }
}
}
void dodat( SoftwareSerial &d, float f) { // print floating-pint number
int dec, i;
char buf[8];
if (f<10) {dec=1; i=f*1e3+0.5;}
else if (f<100) {dec=2; i=f*1e2+0.5;}
else if (f<1000) {dec=4; i=f*1e1+0.5;}
else if (f<10000) {dec=8; i=f+0.5;}
if (f<10000) {sprintf(buf,"%c%04u",dec,i);}
else {sprintf(buf,"%cHIGH",0x80);}
d << "vw" << buf; // reset; decimals; digits
// Serial << '<' << (buf+1) << '>' << endl;
}